Week 4 ยท Reading datasheets, simulating circuits, and programming a microcontroller
For the group assignment, our lab compared the toolchains and development workflows of two microcontroller architectures. I tested the ESP32-S3 while my partner worked on the RP2040 (Raspberry Pi Pico). Both boards were configured in the Arduino IDE and tested with basic programs to understand the differences in compilation, uploading, and debugging.
The functional block diagram from the ESP32-S3 datasheet shows how all internal components are organized and connected. The chip is divided into four main areas:
An embedded system toolchain is a set of software tools โ compiler, assembler, linker, and debugger โ that converts source code into machine code for a specific target processor. The toolchain follows a sequence: Compiler โ Assembler โ Linker โ Flash to device.
The documentation on the RP2040 (Raspberry Pi Pico), including the architecture breakdown, toolchain comparison, and IDE setup for both boards, is available on my colleague's page:
For this assignment I worked with the Seeed Studio XIAO ESP32-S3, since my final project requires Wi-Fi connectivity and addressable LED control. Before writing any code, I read through the datasheet to understand the hardware constraints and capabilities of the board.
The pinout diagrams show every GPIO pin, its primary function, and which peripherals it can be mapped to through the GPIO Matrix. Understanding this was essential before designing any circuit.
After reading the datasheet, I moved on to physically programming the XIAO ESP32-S3. I used the Arduino Blink example to light a through-hole LED connected to D1 (GPIO 2) through a 200 ฮฉ resistor, testing that the board could upload and run code correctly.
I wired the LED on a breadboard with a 200 ฮฉ current-limiting resistor connected between D1 and the LED anode, with the cathode to GND.
To program the XIAO ESP32-S3 in Arduino IDE, I installed the Seeed board support package:
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.jsonI used the standard Blink example, modified to target D1 (GPIO 2) which maps to pin 2 on the XIAO ESP32-S3
const int ledPin = 2; // D1 (GPIO2) on XIAO ESP32-S3
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
digitalWrite(ledPin, HIGH); // LED ON
delay(1000); // wait 1 second
digitalWrite(ledPin, LOW); // LED OFF
delay(1000); // wait 1 second
}
After uploading, the LED blinked on and off every second as expected, confirming the board, toolchain, and wiring were all working correctly.
Getting the LED to blink wasn't immediate โ two separate issues came up during assembly and wiring, both of which required careful diagnosis to fix.
When soldering the header pins onto the XIAO ESP32-S3, I accidentally bridged several adjacent pins with excess solder. The bridges created short circuits between GPIO pins, which would have caused unpredictable behavior or damaged the board if powered up that way.
I used a digital microscope (Tomilov) to magnify the solder joints and identify exactly which pins were bridged. Under magnification the cold joints and bridges were clearly visible โ something impossible to see reliably with the naked eye at this pitch.
I cleaned each bridge using the soldering iron tip and solder wick to wick away the excess.
After uploading the Blink sketch, nothing happened. I had written the code correctly targeting D1 (GPIO 2), but the LED didn't respond. After double-checking the code and the upload (both were fine), I traced the wiring and found I had connected the LED to D0 (GPIO 1) instead of D1 (GPIO 2).
The confusion: The XIAO ESP32-S3 labels its pins as D0, D1, D2โฆ but these do not map sequentially to GPIO 0, 1, 2. D0 is GPIO 1, and D1 is GPIO 2. Using the Arduino pin number 2 in code while wiring to the physical D0 header will always result in a mismatch.
Moved the LED wire from the D0 header to the D1 header. The LED blinked immediately on the next power cycle โ no code change needed. The lesson: always cross-reference the silkscreen label with the pin table in the datasheet before wiring.
Reading the datasheet before touching any hardware was genuinely useful. It revealed constraints I wouldn't have noticed until something broke โ particularly the strapping pin restrictions and the current requirements during RF operation. These are the kinds of details that prevent design mistakes before they happen.
The blink test was simple but important. It confirmed the entire chain works: board selection in Arduino IDE, USB upload, and GPIO output. Having a verified working baseline means any future code failures can be traced to the logic, not the setup or environment.
Overall, this week reinforced that datasheets are not just reference documents โ they are design tools. Checking electrical characteristics and pin functions before building a circuit helps identify potential problems early and avoids costly redesigns later.
AI Disclosure: Claude (Anthropic) was used as a writing tool to help proofread and structure the documentation on this page. All designs, fabrication, and technical decisions are my own.