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.

Assignments for the week:
  • 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

Memory types

Peripherals and communication

Programming languages

Assignment flow: Input (button) → serial port → processing → Output (RGB LED) → serial port feedback.

Group Assignment · Microcontroller Datasheets

Sources: Seeed Studio Wiki (RP2040) and Raspberry Pi documentation.

RP2040 · Specifications

ProcessorDual-core Arm Cortex-M0+, up to 133 MHz
On-chip SRAM264 KB
External FlashUp to 16 MB via dedicated QSPI bus
GPIO30 pins, 4 usable as analog inputs (ADC)
Communication2× UART, 2× SPI, 2× I2C, 16× PWM, USB 1.1
PIO8 programmable I/O state machines for custom peripherals
Power modesActive, Dormant, Off
[ Image: RP2040 Block Diagram — image1.png ]

RP2040 · Key features

[ Image: RP2040 Pin Diagram — image2.jpeg ]

ARM Cortex-M0+ highlights

ESP32-C3 · RISC-V Microcontroller

Sources: Seeed Studio Wiki (ESP32-C3) and Espressif Systems.

[ Image: ESP32-C3 Block Diagram — image3.png ]

ESP32-C3 · Specifications

ProcessorSingle-core 32-bit RISC-V, up to 160 MHz
On-chip SRAM400 KB
ROM384 KB
Wireless802.11b/g/n Wi-Fi + Bluetooth 5 (BLE)
GPIO22 programmable GPIOs
ADC / DAC12-bit ADC · 8-bit DAC
CommunicationUART, SPI, I2C, I2S, GDMA, PWM
SecurityHardware cryptography acceleration
Power modesActive, Modem-sleep, Light-sleep, Deep-sleep, Hibernation
[ Image: ESP32-C3 Pin Diagram — image4.png ]

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
ArchitectureDual-core ARM Cortex-M0+Single-core 32-bit RISC-V
Clock SpeedUp to 133 MHzUp to 160 MHz
On-chip SRAM264 KB400 KB
WirelessNone (native)Wi-Fi + Bluetooth 5
GPIO30 (4 ADC)22
Unique feature8× PIO state machinesHardware crypto acceleration
Primary IDEArduino / MicroPython / C SDKESP-IDF / Arduino

Development workflows

Both boards can be programmed via Arduino IDE or MicroPython with Thonny. They require different Board Manager URLs:

[ Image: Thonny IDE Interface — image5.png ]
[ Image: ESP-IDF Diagram — image6.png ]
[ Image: Workflow Overview — image7.jpeg ]

Individual Assignment · Program My MCU Board

Update (May 16): Using the board designed in Week 04 as instructed. Button as input, RGB LED as output.
Update (May 11): Catching up on assignments. Components ready; familiar with electronics so this was manageable.
[ Image: Custom MCU Board — image8.jpeg ]

Step 1 · RGB light testing (output)

Checking the XIAO RP2040 port map from the Seeed Wiki and the schematic diagram:

[ Image: XIAO RP2040 Ports — image9.jpeg ]
[ Image: RP2040 Schematic — image10.jpeg ]
[ Image: RGB GPIO12 Connection — image11.jpeg ]

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:

[ Image: Week 04 Schematic Map — image12.jpeg ]
#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

Extra Credit: Temperature & humidity sensing with RGB visual feedback using the Grove AHT20 sensor over I2C.

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

[ Image: XIAO RP2040 — image13.jpeg ]

High performance, low cost Raspberry Pi debut microcontroller. XIAO RP2040 →

Input — Grove AHT20 Sensor

[ Image: Grove AHT20 Sensor — image14.jpeg ]

I2C industrial-grade temperature and humidity sensor with fast response and strong anti-interference. Grove AHT20 →

Output — Built-in RGB LED

[ Image: RGB Light on XIAO RP2040 — image15.jpeg ]

Built-in NeoPixel RGB LED on the XIAO RP2040. RGB usage example →

Addition — XIAO Expansion Board Base

[ Image: XIAO Expansion Board — image16.jpeg ]

Rich peripherals for XIAO enabling quick prototyping. XIAO Expansion →

Prerequisite · I2C wiring

The Grove AHT20 uses I2C: SDA → D4 (GPIO6), SCL → D5 (GPIO7).

I2C key features:
  • 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.
[ Image: I2C Connection Diagram — image17.jpeg ]

Prerequisite · Arduino IDE setup

  1. Download Arduino IDE from the official website.
  2. 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
  3. Open Boards Manager, search "RP2040", install the latest Raspberry Pi Pico/RP2040 package.
  4. Select board: Seeed XIAO RP2040.
[ Image: Arduino Preferences — image18.jpeg ]
[ Image: Boards Manager RP2040 — image19.jpeg ]

Libraries

Install via Sketch → Include Library → Add .ZIP Library or through the Library Manager.

[ Image: Add ZIP Library — image20.jpeg ]
[ Image: Library Manager NeoPixel — image21.png ]

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);
}
[ Image: Serial Monitor Output (Sensor Test) — image25.jpeg ]

Integration · Full project code

Temperature thresholds: < 22°C → Blue · 22–28°C → Green · > 28°C → Red (all flashing).

[ Image: Connection Wiring Diagram — image22.png ]
[ Image: XIAO Expansion Board Assembly — image23.jpeg ]
[ Image: Board Selection in Arduino IDE — image24.jpeg ]
#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

Error on macOS:
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.