Week 04 — Embedded Programming

This week focused on programming a microcontroller and understanding how code can interact with the physical world through LEDs, switches, sensors and motors.

Overview

The assignment this week was to browse the datasheet of a microcontroller and write a program that interacts with input and output devices.

I used the Seeed Studio XIAO RP2040 together with Arduino IDE. The week started with a simple blink test and gradually expanded into experiments using an external LED, push button input, a sound sensor module, a servo motor and a potentiometer.

By building small experiments step by step I was able to understand how a microcontroller reads inputs, processes logic and controls hardware outputs.

Tools Used

Key Outputs


Learning Process

At the beginning of the week I was not familiar with the workflow of the XIAO RP2040. I needed to understand how to install the correct board package in Arduino IDE and how the uploading process works.

After reading documentation and watching tutorials I successfully configured the board and started testing basic programs. From there I gradually added more hardware components and tested them one by one.


Group Assignment

For the group assignment, we worked at the Litchee Lab (Shenzhen, China) and explored embedded programming workflows while comparing development environments, toolchains, and hardware architectures. The goal was to understand how software interacts with microcontrollers through different levels of abstraction.

Arduino IDE Installation

We began by installing Arduino IDE (version 2.3.8), which provides an integrated development environment including code editing, compilation, library management, and uploading.

Arduino IDE download
Arduino IDE 2.3.8 installation interface.

Compared to traditional embedded development environments, Arduino IDE simplifies the workflow by integrating the toolchain and reducing setup complexity.


Adding RP2040 Support (Boards Manager)

Since RP2040-based boards are not included by default, we used the Boards Manager to install the required support package.

We accessed: Tools → Board → Boards Manager and searched for RP2040.

Boards Manager
Accessing the Boards Manager in Arduino IDE.

We installed: Raspberry Pi Pico/RP2040/RP2350, which provides support for RP2040-based boards.

RP2040 installed
RP2040 board package successfully installed.

After installation, we selected the board: Seeed Studio XIAO RP2040.

Board selection
Seeed XIAO RP2040 selected in Arduino IDE.

Hardware and Pinout Understanding

To better understand how the microcontroller interacts with hardware, we analyzed the physical structure and pinout of the XIAO RP2040.

Board structure
XIAO RP2040 structure showing USB-C interface, onboard LEDs, and control buttons.

The board includes a USB-C interface, a built-in RGB LED, a power LED, and BOOT and RESET buttons. These components support debugging and control.

Pinout diagram
Pinout diagram showing digital, analog, power, and communication functions.

Each pin can support multiple functions such as digital I/O, analog input, I2C, SPI, and UART. Understanding the mapping between labeled pins (D pins) and GPIO numbers was essential.

PWM Pin Mapping (XIAO RP2040)
Digital Pin GPIO Function
D0GPIO26PWM
D1GPIO27PWM
D2GPIO28PWM
D3GPIO29PWM
D4GPIO6PWM
D5GPIO7PWM
D6GPIO0PWM
D7GPIO1PWM
D8GPIO2PWM
D9GPIO4PWM
D10GPIO3PWM

All digital pins (D0–D10) support PWM output, which means any of these pins can be used to control a servo motor.

This understanding helped avoid wiring mistakes and ensured correct communication between software and hardware.


Workflow Comparison

We compared Arduino IDE with lower-level embedded development approaches.

Arduino abstracts many low-level details such as register access, making embedded programming more accessible while still enabling interaction with real hardware.


Conclusion

This assignment helped us understand the full embedded development workflow, from environment setup to program upload and hardware interaction. It also clarified how high-level tools relate to the underlying system.

Group assignment link: View group documentation


Programming Experiments

I approached this week as a sequence of small experiments. Each experiment helped me understand a different part of embedded programming.

1. Blink — Built-in LED

Blink example
void setup(){
pinMode(LED_BUILTIN, OUTPUT);
}

void loop(){
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}

2. External LED

External LED control
int led = 3;

void setup(){
pinMode(led, OUTPUT);
}

void loop(){

digitalWrite(led, HIGH);
delay(1000);

digitalWrite(led, LOW);
delay(1000);

}

3. Button Controlling LED

Button input
const int buttonPin = 28;
const int ledPin = 3;

void setup(){

pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);

}

void loop(){

int buttonState = digitalRead(buttonPin);

if(buttonState == LOW){
digitalWrite(ledPin, HIGH);
}
else{
digitalWrite(ledPin, LOW);
}

}

4. Sound Sensor Toggle LED

Sound module
const int soundPin = 28;
const int ledPin = 3;

bool ledState = false;
bool lastSoundState = HIGH;

unsigned long lastTriggerTime = 0;
const unsigned long debounceTime = 300;

void setup(){

pinMode(ledPin, OUTPUT);
pinMode(soundPin, INPUT);

digitalWrite(ledPin, LOW);

}

void loop(){

bool soundState = digitalRead(soundPin);
unsigned long now = millis();

if(soundState == LOW && lastSoundState == HIGH){

if(now - lastTriggerTime > debounceTime){

ledState = !ledState;

digitalWrite(ledPin, ledState ? HIGH : LOW);

lastTriggerTime = now;

}

}

lastSoundState = soundState;

}

5. Servo Sweep

Servo movement
#include <Servo.h>

Servo myservo;

int pos = 30;

void setup(){

myservo.attach(1);

}

void loop(){

for(pos = 30; pos <= 150; pos++){

myservo.write(pos);
delay(10);

}

for(pos = 150; pos >= 30; pos--){

myservo.write(pos);
delay(10);

}

}

6. Potentiometer Controlling Servo

Analog input
#include <Servo.h>

Servo myservo;

const int potPin = A0;
const int servoPin = 1;

void setup(){

myservo.attach(servoPin);

}

void loop(){

int potValue = analogRead(potPin);

int angle = map(potValue,0,1023,0,180);

myservo.write(angle);

delay(20);

}

Reflection

This week helped me understand how embedded systems connect software and hardware. Simple programs like Blink are useful for verifying that the board works, while sensors and actuators demonstrate how the microcontroller interacts with the environment.

The most interesting part for me was combining sensors and outputs, such as the sound module toggling an LED and the potentiometer controlling a servo motor.