My Misadventure with Embedded Devices
Starting Out
I jumped into embedded development out of sheer curiosity. The parts are dirt cheap, and I had some free time to tinker. My first mistake? Not owning a multimeter. Lesson one: get a multimeter. Trust me, it’s a lifesaver when things go wrong.
Lighting Up an LED
The “hello world” of hardware is lighting up an LED. I did it, and it felt like a small victory. You don’t need to be an electrical engineer for this, just some basic know-how. Connect the ground to the ground pin, power to the LED’s long leg (the anode), and add a resistor to keep it from frying. If you smell smoke or something funky, you messed up, unplug it fast. As I said, get a multimeter.

Start with cheap LEDs to learn the ropes. You’ll figure out why resistors are crucial (they limit current to protect the LED) and what happens if you skip them. Spoiler: I burned out two LEDs and accidentally fried a door locker in my early experiments. Once you get the hang of it, it’s straightforward and pretty darn cool.
Adding a Switch
After mastering the LED, I wanted more interactivity. Adding a button to turn the LED on and off was the next step. It’s a small upgrade, but pressing a button and seeing the LED respond feels like real progress. With these baby steps under my belt, I moved on to bigger challenges with an ESP32. (Side note: I find the ESP32 easier than pure hardware projects, as it’s mostly software. I could build circuits with just electrical components, but I haven’t dived into that yet.)
Programming the ESP32
First things first: check the model number on your ESP32 chip. I used Visual Studio Code with the PlatformIO extension to streamline development.
PlatformIO
PlatformIO is powerful but, let’s be honest, a bit of a mess. I ran commands to identify my board’s model and specs, or you can use PlatformIO’s board detection tab. Installing it on NixOS was a nightmare due to dynamic linking issues. I tried the “Nix way” but gave up and enabled ld (the GNU linker) to make it work. Not elegant, but it got the job done.
Most online tutorials and YouTube videos are frustratingly repetitive, copy-pasted Arduino code with little explanation. Where’s the good content? PlatformIO’s serial terminal gave me grief due to a known bug. The fix? Even though I set DTR (Data Terminal Ready) to off in platformio.ini, I had to toggle it on and off (Ctrl+T, Ctrl+D, twice) while the terminal was open. Only then did the ESP32’s output appear. Annoying, but it worked.
After scorching a few more LEDs, I started experimenting with an ESP32, an NFC reader/writer, and a small LCD screen.
Using an LCD Display
I used an HD44780 LCD with an I2C interface, connected via a PCF8574 I/O expander. The ESP32 has a ton of pins, but I only needed four for the LCD: ground, VCC (power, 3.3V or 5V), SCL (Serial Clock Line), and SDA (Serial Data Line). Here’s how I wired it:
SCL (GPIO22): Synchronizes data transfer between the ESP32 and the LCD.
SDA (GPIO21): Carries the actual data.
VCC: Powers the LCD (I used 3.3V).
GND: Connects to the ESP32’s ground.
The I2C protocol lets the ESP32 (the master) communicate with the LCD (the slave) over a shared bus, with SCL providing the clock signal and SDA transferring the data.
The goal was to configure the ESP32’s I2C master to talk to the PCF8574, which drives the HD44780 LCD. I tried writing my own driver. After eight hours of battling libraries, I realized the issue wasn’t my code: the LCD’s backlight was too dim to see anything. Everything was working; I just couldn’t see it! Classic rookie move. I adjusted the backlight (usually via a potentiometer or I2C command) and switched to an Arduino library for simplicity. Check the HD44780 datasheet for details. I also found a forum post where someone got roasted for asking about initialization.
NFC with Screen
Next, I paired an NFC reader/writer (PN532 module) with the LCD to display card data. To avoid software bugs, I used the Adafruit PN532 library, ensuring any issues were hardware-related. The PN532 supports three protocols for the ESP32:
I2C
- Wiring: SDA → GPIO21, SCL → GPIO22, VCC → 3.3V/5V, GND → GND
- Pros: Uses only two pins, simple wiring, supports multiple devices on the same bus.
- Cons: Slower than SPI, may need pull-up resistors (4.7kΩ) for reliable communication.
SPI
- Wiring: MISO → GPIO19, MOSI → GPIO23, SCK → GPIO18, CS → GPIO5, VCC → 3.3V/5V, GND → GND
- Pros: Faster and more stable for high-speed data.
- Cons: Requires more wires and is limited to one device per bus.
UART
- Wiring: TX → GPIO16 (RX), RX → GPIO17 (TX), VCC → 3.3V/5V, GND → GND
- Pros: Simple, uses only two pins.
- Cons: Slower and limited by the ESP32’s UART ports.
I used a breadboard for prototyping, no soldering needed, and it held up fine. I started with an Adafruit PN532 example in SPI mode, but my module refused to cooperate. Switching to I2C worked like a charm. Reading and writing data was straightforward: I used a Mifare Classic 1K card (16 sectors, 4 blocks, 16 bytes each). Sector 0, block 0 holds manufacturer info, and each sector needs a key (which can vary). For messages longer than 16 bytes, I concatenated blocks. After a few hours, I could manage users and permissions with NFC cards and display the info on the LCD. Pretty awesome!
My next project? Pairing the NFC reader with a door locker.
Oled screen
I couldn’t resist trying out an OLED screen for my ESP32 projects. Compared to the HD44780 LCD, OLEDs have a higher refresh rate, a slightly larger display, and feel more versatile for dynamic visuals. After stumbling across a post on X about an adorable animated character with moving eyes, I was inspired to create my own “little guy” on the screen. Spoiler: it was a blast, but way harder than I expected.
Animating a pair of eyes that bounce around the screen sounds simple, right? Wrong. It’s a coding rollercoaster. You have to track the pupil’s position, the eye’s boundaries, and their movement direction—all while keeping the animation smooth. It’s like juggling while riding a unicycle. I ended up “vibe coding” my way through it, tweaking coordinates and redraws until it looked right. The result? A quirky pair of eyes that dart around, giving my project some serious personality. Hard work, but totally worth it.
Results
Libraries like Adafruit’s make embedded development a breeze, but writing your own drivers is trickier—especially with vague datasheets. It’s like regular software development, just with tighter memory and compute constraints. Now that I’m getting the hang of it, I’ve started a new project: an air quality monitor with sensors for temperature, humidity, and gases. It’s the next chapter in my embedded quest, and I’m ready for more misadventures. Stay tuned!