What I did in Week 06
This week covered embedded programming fundamentals: reading datasheets, comparing microcontroller architectures, and writing programs that interact with inputs and outputs on a custom board.
- Group assignment: read and compared the RP2040 and ESP32-C3 datasheets across architecture, memory, speed, and development workflows.
- Individual assignment: programmed my Week 04 board to cycle RGB colors on button press.
- Extra credit: connected a Grove AHT20 sensor via I2C and used temperature readings to control RGB LED color with flashing feedback.
- Group: browse the datasheet for your microcontroller; compare performance and development workflows for other architectures.
- Individual: write a program for a microcontroller development board to interact with local input/output devices and communicate with remote devices.
- Extra credit: use different languages / development environments.
- Extra credit: connect external components to the board.
Week 06 assignments and links
These are the pages and resources associated with my Week 06 work.
Embedded Programming Notes
Core concepts covered during the week's lecture and reading sessions.
Architectures and processor types
- Von Neumann vs Harvard: Von Neumann shares memory bus for data and instructions; Harvard uses separate buses for higher throughput.
- RISC: reduced instruction set — each instruction executes quickly.
- CISC: complex instruction set — one instruction can do many things.
- Microcontroller: includes processor, memory, and communication in a single package.
- FPGA: programmable logic fabric reconfigurable after manufacture.
- Silicon Compiler / Spatial: software-defined chip design workflows.
- SAM D11C: block diagram example showing how all peripherals interconnect (~1,000-page datasheet, ~$1 chip).
Memory types
- RAM: working memory where the processor operates at runtime.
- EEPROM: retains small amounts of data when power is off.
- Flash: stores larger program data; typically lost on power-off unless specifically written.
Peripherals and communication
- Comparator: compares two voltage levels.
- USART / USB: serial communication modules.
- Word size: number of bits processed simultaneously.
- RISC-V: open-source ISA, increasingly used in embedded systems.
Programming languages
- HEX / machine code: runs directly in the processor.
- C: most common language for embedded programming.
- C++: extends C with object-oriented features; used by Arduino framework.
- Python / MicroPython: interpreted, high-level, interactive but slower than compiled C.
Group Assignment · Microcontroller Datasheets
Sources: Seeed Studio Wiki (RP2040) and Raspberry Pi documentation.
RP2040 · Specifications
| Processor | Dual-core Arm Cortex-M0+, up to 133 MHz |
|---|---|
| On-chip SRAM | 264 KB |
| External Flash | Up to 16 MB via dedicated QSPI bus |
| GPIO | 30 pins, 4 usable as analog inputs (ADC) |
| Communication | 2× UART, 2× SPI, 2× I2C, 16× PWM, USB 1.1 |
| PIO | 8 programmable I/O state machines for custom peripherals |
| Power modes | Active, Dormant, Off |
RP2040 · Key features
- External memory execution: code runs directly from external Flash via SPI, DSPI, or QSPI.
- Debug support: SWD interface for step-through debugging.
- DMA: handles repetitive data transfers, offloading the processors.
- PIO controllers: flexible custom I/O without needing dedicated hardware blocks.
- Clock management: two PLLs — fixed 48 MHz for USB/ADC and flexible up to 133 MHz for system.
- On-chip voltage regulator: supplies core voltage internally.
ARM Cortex-M0+ highlights
- Thumb instruction set — high code density with 32-bit performance.
- Single-cycle I/O access and hardware multiplier.
- Integrated sleep modes for low-power operation.
- Deterministic interrupt handling with Serial Wire Debug (SWD).
ESP32-C3 · RISC-V Microcontroller
Sources: Seeed Studio Wiki (ESP32-C3) and Espressif Systems.
ESP32-C3 · Specifications
| Processor | Single-core 32-bit RISC-V, up to 160 MHz |
|---|---|
| On-chip SRAM | 400 KB |
| ROM | 384 KB |
| Wireless | 802.11b/g/n Wi-Fi + Bluetooth 5 (BLE) |
| GPIO | 22 programmable GPIOs |
| ADC / DAC | 12-bit ADC · 8-bit DAC |
| Communication | UART, SPI, I2C, I2S, GDMA, PWM |
| Security | Hardware cryptography acceleration |
| Power modes | Active, Modem-sleep, Light-sleep, Deep-sleep, Hibernation |
The ESP32-C3 uses a RISC-V core instead of ARM and adds native Wi-Fi and Bluetooth — features the RP2040 lacks without additional hardware. Its primary development environment is ESP-IDF with C/C++, but the Arduino framework is also supported.
RP2040 vs ESP32-C3 · Comparison
| Feature | RP2040 | ESP32-C3 |
|---|---|---|
| Architecture | Dual-core ARM Cortex-M0+ | Single-core 32-bit RISC-V |
| Clock Speed | Up to 133 MHz | Up to 160 MHz |
| On-chip SRAM | 264 KB | 400 KB |
| Wireless | None (native) | Wi-Fi + Bluetooth 5 |
| GPIO | 30 (4 ADC) | 22 |
| Unique feature | 8× PIO state machines | Hardware crypto acceleration |
| Primary IDE | Arduino / MicroPython / C SDK | ESP-IDF / Arduino |
Development workflows
Both boards can be programmed via Arduino IDE or MicroPython with Thonny. They require different Board Manager URLs:
- XIAO RP2040:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json - XIAO ESP32-C3:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Individual Assignment · Program My MCU Board
Step 1 · RGB light testing (output)
Checking the XIAO RP2040 port map from the Seeed Wiki and the schematic diagram:
The RGB DIN input connects to GPIO12 of the RP2040. Code for cycling colors:
#include <Adafruit_NeoPixel.h>
int Power = 11;
int PIN = 12;
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
pinMode(Power, OUTPUT);
digitalWrite(Power, HIGH);
}
void loop() {
pixels.clear();
pixels.setPixelColor(0, pixels.Color(15, 25, 205));
delay(400); pixels.show();
pixels.clear();
pixels.setPixelColor(0, pixels.Color(103, 25, 205));
delay(400); pixels.show();
pixels.clear();
pixels.setPixelColor(0, pixels.Color(233, 242, 205));
delay(400); pixels.show();
pixels.clear();
pixels.setPixelColor(0, pixels.Color(233, 23, 23));
delay(400); pixels.show();
pixels.clear();
pixels.setPixelColor(0, pixels.Color(12, 66, 101));
delay(400); pixels.show();
delay(500);
}
Step 2 · Add button input
From the Week 04 schematic, the button is on port D1 (GPIO27). Each press cycles to the next RGB color:
#include <Adafruit_NeoPixel.h>
int Power = 11;
int PIN = 12;
int ButtonPin = 27;
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
pinMode(Power, OUTPUT);
digitalWrite(Power, HIGH);
pinMode(ButtonPin, INPUT_PULLUP);
}
int colorIndex = 0;
bool lastButtonState = HIGH;
void loop() {
bool currentButtonState = digitalRead(ButtonPin);
if (lastButtonState == HIGH && currentButtonState == LOW) {
colorIndex++;
if (colorIndex > 4) colorIndex = 0;
setColor(colorIndex);
}
lastButtonState = currentButtonState;
delay(50); // debounce
}
void setColor(int index) {
uint32_t colors[] = {
pixels.Color(15, 25, 205), // Blue
pixels.Color(103, 25, 205), // Purple
pixels.Color(233, 242, 205), // Light yellow
pixels.Color(233, 23, 23), // Red
pixels.Color(12, 66, 101) // Dark blue
};
pixels.clear();
pixels.setPixelColor(0, colors[index]);
pixels.show();
delay(400);
}
Extra Credit · Temperature & Humidity Sensing
Project concept
The XIAO RP2040 reads temperature and humidity from a Grove AHT20 sensor. When temperature falls below 22°C the RGB flashes blue; between 22–28°C it flashes green; above 28°C it flashes red. All components run on one integrated board.
Hardware
Microcontroller — XIAO RP2040
High performance, low cost Raspberry Pi debut microcontroller. XIAO RP2040 →
Input — Grove AHT20 Sensor
I2C industrial-grade temperature and humidity sensor with fast response and strong anti-interference. Grove AHT20 →
Output — Built-in RGB LED
Built-in NeoPixel RGB LED on the XIAO RP2040. RGB usage example →
Addition — XIAO Expansion Board Base
Rich peripherals for XIAO enabling quick prototyping. XIAO Expansion →
Prerequisite · I2C wiring
The Grove AHT20 uses I2C: SDA → D4 (GPIO6), SCL → D5 (GPIO7).
- Two-wire: SDA (Serial Data) + SCL (Serial Clock).
- Multi-master: multiple master and slave devices on the same bus.
- Addressing: each slave has a unique 7-bit address.
- Synchronous: all transfers are synchronized with the clock signal.
Prerequisite · Arduino IDE setup
- Download Arduino IDE from the official website.
- Go to Arduino IDE → Preferences and add the RP2040 Board Manager URL:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json - Open Boards Manager, search "RP2040", install the latest Raspberry Pi Pico/RP2040 package.
- Select board: Seeed XIAO RP2040.
Libraries
- Adafruit NeoPixel — RGB LED control.
- Seeed Arduino AHT20 — sensor communication.
Install via Sketch → Include Library → Add .ZIP Library or through the Library Manager.
Sensor test code
Validating AHT20 readings before integration (Seeed example):
#include <Wire.h>
#include "AHT20.h"
AHT20 AHT;
void setup() {
Serial.begin(115200);
Serial.println("AHT20 DEMO");
AHT.begin();
}
void loop() {
float humi, temp;
int ret = AHT.getSensor(&humi, &temp);
if (ret) {
Serial.print("humidity: ");
Serial.print(humi * 100);
Serial.print("%\t temperature: ");
Serial.println(temp);
} else {
Serial.println("GET DATA FROM AHT20 FAIL");
}
delay(100);
}
Integration · Full project code
Temperature thresholds: < 22°C → Blue · 22–28°C → Green · > 28°C → Red (all flashing).
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include "AHT20.h"
int Power = 11;
int PIN = 12;
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
AHT20 AHT;
void setup() {
Serial.begin(115200);
Serial.println("AHT20 & NeoPixel DEMO");
AHT.begin();
pixels.begin();
pinMode(Power, OUTPUT);
digitalWrite(Power, HIGH);
}
void loop() {
float humi, temp;
int ret = AHT.getSensor(&humi, &temp);
if (ret) {
Serial.print("humidity: ");
Serial.print(humi * 100);
Serial.print("%\t temperature: ");
Serial.println(temp);
if (temp < 22) {
setPixelColorWithFlash(0, 0, 255, 0); // Blue
} else if (temp <= 28) {
setPixelColorWithFlash(0, 255, 0, 0); // Green
} else {
setPixelColorWithFlash(255, 0, 0, 0); // Red
}
} else {
Serial.println("GET DATA FROM AHT20 FAIL");
}
delay(100);
}
void setPixelColorWithFlash(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
pixels.clear();
pixels.setPixelColor(0, pixels.Color(r, g, b, w));
pixels.show();
delay(400);
pixels.clear();
pixels.show();
delay(400);
}
Problem Encountered
dyld: Symbol not found: _mkfifoat
Referenced from: .../pqt-python3/1.0.1-base-3a57aed/python3
Expected in: /usr/lib/libSystem.B.dylib
Root cause identified on the Arduino forum: a broken Python dependency in the Raspberry Pi Pico/RP2040 boards platform. Fix by relinking Python via terminal:
$ ls -l ~/Library/Arduino15/packages/rp2040/tools/pqt-python3/1.0.1-base-3a57aed/python3
$ rm ~/Library/Arduino15/packages/rp2040/tools/pqt-python3/1.0.1-base-3a57aed/python3
$ ln -s "/System/Volumes/Data/opt/homebrew/bin/python3" \
~/Library/Arduino15/packages/rp2040/tools/pqt-python3/1.0.1-base-3a57aed/python3
Next step
With embedded programming fundamentals in place and a working sensor-actuator loop, the next weeks will integrate these skills into more complex circuits and final project electronics.