4. Embedded Programming¶
Overview¶
This week’s goal was to deepen my knowledge of multiple microcontrollers by working with the Seeed Studio XIAO ESP32-C3 and the Seeed Studio XIAO RP2040 I used both Arduino and MicroPython to program the first two controllers. I also learned how to download and use the relevant software for each platform.
Out of the two, the Seeed Studio XIAO ESP32-C3 (C3) quickly became my favorite. It’s a very reliable chip that can be programmed relatively easily, with little troubleshooting needed. It supports Wi-Fi, Bluetooth Low Energy, can be powered by a battery, and is relatively affordable.
Group work¶
Group assignment: Demonstrate and compare the toolchains and development workflows for available embedded architectures
Microcontrollers Used¶
Seeed Studio XIAO ESP32-C3¶
DataSheet Summary¶
Feature | Specification |
---|---|
Chip | ESP32-C3 |
Speed | Up to 160 MHz |
Flash / SRAM | 4 MB Flash, 400 KB SRAM |
GPIO Pins | 11 GPIO pins |
Analog Pins | 3 Analog pins (A0, A1, A2) |
Communication Protocols | UART, SPI, I2C, BLE, Wi-Fi |
ADC | 12-bit ADC |
From browsing the datasheet, I learned that the ESP32-C3 is a low-power microcontroller built around a RISC-V 32-bit core running up to 160 MHz. It comes with 4 MB of flash memory and 400 KB of SRAM, which is plenty for embedded applications with wireless connectivity. The board exposes 11 GPIO pins, including 3 analog inputs (A0–A2) that connect to its 12-bit ADC. Communication options are versatile: it supports UART, SPI, I²C, along with full wireless connectivity via Bluetooth Low Energy (BLE) and Wi-Fi, making it especially useful for IoT projects.
Arduino Programming¶
For the ESP32-C3, I test how a pull-down resistor works using a button and an LED. The button is set up such that when the button is not pressed, the input pin reads LOW, and when pressed, the input pin reads HIGH because the voltage flows through the button with the pull-down resistor pulling the input to ground when not pressed.
I first tested the circuit and code in Wokwi, an website where you can test circuits, to make sure the code worked without worrying about hardware issues. After that, I redid the setup physically on a breadboard using the ESP32-C3.
Here is the code I used in Arduino IDE:
#define LED_PIN D2
#define BUTTON_PIN D4
void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
pinMode(BUTTON_PIN, INPUT_PULLDOWN);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == HIGH) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
delay(100); // Small delay for debounce and readability
}
How it works¶
- Pin Definitions: Assign easy-to-read names to pins for clarity.
- Setup: Define LED_PIN as an OUTPUT and BUTTON_PIN as an INPUT with a built-in pull-down resistor. The LED starts off.
- Loop: Read the button state; if pressed, turn LED on, otherwise off.
Troubleshooting:
During upload, I had an exit status 1 error, which seemed came from hardware or connection problems rather than the code. After changing USB cables and using different computers, I eventually got it to work on one computer with good USB ports. Trouble shooting is not fun.
MicroPython Programming¶
Setting up MicroPython on the ESP32-C3 was more complicated. I had to:
- Download the generic ESP32-C3 firmware from the MicroPython website.
- Install esptool through Python to flash firmware using terminal commands.
- Identify the correct USB port (
ls /dev/cu.*
command on Mac). - Erase flash memory (if there was already code) by putting the ESP in bootloader mode.
- Flash the MicroPython firmware.
At first, Thonny did not recognize the device until I configured the interpreter to the correct port. I also faced “error 6” read failures but resolved them after taking a break and trying again.
Here’s the MicroPython code for the button and LED:
from machine import Pin
import time
LED_PIN = 2 # GPIO pin for LED on ESP32-C3
BUTTON_PIN = 3 # GPIO pin for button
led = Pin(LED_PIN, Pin.OUT)
button = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_DOWN)
while True:
button_state = button.value()
if button_state == 1:
led.value(1) # Turn LED on
else:
led.value(0) # Turn LED off
time.sleep(0.1) # Delay for debounce and readability
Seeed Studio XIAO RP2040¶
Datasheet Summary¶
Feature | Specification |
---|---|
Chip | RP2040 |
Speed | 133 MHz |
Flash / SRAM | 2 MB Flash, 264 KB SRAM |
GPIO Pins | 11 GPIO pins |
Analog Pins | 4 Analog pins (A0–A3) |
Communication Protocols | UART, I2C, SPI, I2S, PWM |
ADC | 12-bit ADC |
Arduino Programming¶
The RP2040 workflow was similar to the ESP32-C3’s. The main difference was changing the pin numbers based on the RP2040’s pinout and avoiding computers that had USB port issues from earlier.
Here is the Arduino code I used, similar to the ESP32-C3 but with adjusted pins:
#define LED_PIN A2
#define BUTTON_PIN A1
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
pinMode(BUTTON_PIN, INPUT_PULLDOWN);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == HIGH) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
delay(100); // Small delay for debounce and readability
}
MicroPython Programming¶
Setting up MicroPython on the RP2040 was much simpler compared to the ESP32-C3. I only had to:
- Download the firmware from the MicroPython website.
- Put the RP2040 into bootloader mode (by holding the BOOT button while plugging it in).
- Copy the firmware file directly onto the RP2040 drive that appears on my desktop.
No terminal commands, and the device was immediately recognized by Thonny.
MicroPython code for the RP2040 was basucally the same as the ESP32-C3 code, just with different pins:
from machine import Pin
import time
LED_PIN = 26 # Corresponding to A2 on RP2040
BUTTON_PIN = 27 # Corresponding to A1 on RP2040
led = Pin(LED_PIN, Pin.OUT)
button = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_DOWN)
while True:
button_state = button.value()
if button_state == 1:
led.value(1)
else:
led.value(0)
time.sleep(0.1)
Workflow Summary¶
Arduino¶
- Write your code in Arduino IDE using C++.
- Install necessary libraries via Board Manager (search for ESP boards).
- Select the correct board and port under the Tools menu.
- Verify and upload your code.
MicroPython¶
- Download the latest MicroPython firmware for your board.
- For ESP32-C3, install esptool and use terminal commands to erase flash and flash firmware.
- For RP2040, simply copy the firmware file onto the device in bootloader mode.
- Configure Thonny interpreter to connect to your device’s port.
- Upload MicroPython code and run.
Reflection: Independent¶
This week forced me to understand both hardware and software learning. Setting up and programming the ESP32-C3 taught me how important it is to clearly understand pin outs, built-in functions, and how features like pull-down resistors act in real circuits. I really liked how well the ESP32-C3 worked once it was programmed, especially with its Wi-Fi that can create many future project possibilities. The troubleshooting process like swapping the USB cables and computers when I hit upload errors showed me that persistence and problem testing one by one are key parts of any embedded work.
Reflection: Group¶
Our group explored and compared the toolchains and workflows for the ESP32-C3, RP2040, and ATTiny412 using both Arduino IDE and MicroPython. Arduino proved that it is a fast and reliable way to prototype with many libraries, while MicroPython allowed easy and quick testing but required extra setup. Changes in hardware, like GPIO pins, memory, and built-in functions, changed how easy it was to use each toolchain. Working together allowed us to share solutions when someone ran into upload or circuit issues, saving time and stopping frustration. Overall, this comparison gave me a clearer understanding of how different microcontrollers and workflows influence the project development of embedded programming .