Week 4 โ Embedded Programming
What is the week about getting started with Embedded systems, knowing about basic electronic and electrical components, understanding microcontroller data sheet and programming a microcontroller.
Assignment Overview
- Demonstrate and compare the toolchains and development workflows for available embedded architectures.
- Browse through the data sheet for a microcontroller.
- Write and test a program for an embedded system using a microcontroller to interact with input and / or output devices and communicate with wired or wireless devices.
- Extra credit: assemble the system.
- Extra credit: try different languages and/or development environments.
| Day | Activity | Status |
|---|---|---|
| Thursday | Week Planning ๐ , LAB Activity ๐ and Documentation ๐ | Completed |
| Class - From silicon chips to computers to maker boards | Completed | |
| Class - Toolchains and development workflows | Completed | |
| Class - Introduction to XIAO RP2040 and homework | Completed | |
| Friday | Class - Assemble the system on a breadboard | Completed |
| Class - Write and test a program with input and output devices | Completed | |
| Saturday | Documentation ๐ | Completed |
| Sunday | Documentation ๐ | Completed |
| Monday | Class - MicroPython Vs. Arduino and LAB Activity ๐ | Completed |
| Complete Documentation - Regional Review ๐ | Completed | |
| Tuesday | Regional Review ๐จโ๐ซ๐ฌ | Completed |
| Lab Activity ๐ | Completed | |
| Wednesday | Final Documentation ๐ | Completed |
Group Assignment
In this weekโs group assignment, we explored, demonstrated and compared the toolchains and development workflows for different embedded architectures.
Below is my take away and reflection on group assignment.
Toolchain: The Complete Pipeline from Code to Silicon, a toolchain converts human-readable code into machine instructions and uploads it to the microcontroller.
Toolchain includes:
- Programming Language
- Compiler / Interpreter
- Board Support Packages (BSPs)
- Upload Tools
| Elements of Toolchain | Seeed Studio RP2040 + Arduino | Seeed Studio RP2040 + Thonny + MicroPython |
ATtiny44/84 + Microchip Studio + C Programming
This toolchain is part of Group Assignment |
|---|---|---|---|
| Programming Language | Arduino-style C/C++ [Fast, Low-Level] |
MicroPython [High-Level & Easy] |
Embedded C [Faster than Arduino-style C/C++] |
| Programming Environment | Arduino IDE [Code Editor + Build + Upload] |
Thonny [Editor + REPL + Flashing] |
Microchip Studio 7 [Editor + Compiler + Debugger] |
| Code Translation Method | Compiler [Converts C/C++ โ Machine Code] |
Interpreter [Executes Python Line by Line] |
Compiler [Converts C โ AVR Machine Code] |
| Upload Tools | UF2 Bootloader / OpenOCD [Flashes Firmware to Chip] |
Thonny Flasher [Installs MicroPython Firmware] |
Programmer (UPDI / ISP) [Uploads .hex File to ATtiny] |
| Libraries | Arduino + Vendor Libraries [OLED, GPIO, IยฒC, SPI, etc.] |
machine, utime, drivers [GPIO, IยฒC, LEDs, etc.] |
avr-libc [Delays, I/O Macros, Timers] |
| Runtime | Runs Directly on Hardware | Python Virtual Machine [Runs on Top of MCU] |
Runs Directly on Hardware |
| Flow Looks Like |
|
|
|
We compared four microcontroller platforms based on how easy it was to set up the toolchain and create a simple LED blink program.
Individual Assignment
Getting Started with Embedded Systems
โFrom silicon chips to maker boards, todayโs class connected the hidden world of microelectronics to hands-on microcontroller programming.โ
This session focused on understanding how modern computing systems are built, starting from microscopic semiconductor devices and progressing toward the microcontroller platforms commonly used in digital fabrication, embedded systems, and rapid prototyping.
๐ง From Microelectronics to Computer Systems
We began by exploring microelectronics and semiconductor manufacturing, watching industry videos that demonstrated how billions of transistors are fabricated onto silicon wafers using advanced processes such as photolithography, deposition, etching, and packaging.
To appreciate the incredible scale of modern integrated circuits, imagine fitting an entire city into an area no larger than the cross-section of a few human hairs. Modern microchips contain billions of nanoscopic transistors packed into an extremely small area, enabling remarkable computing power within compact devices.
We then expanded our perspective from individual chips to complete computer systems and discussed the relationship between:
- Input Devices โ keyboards, mice, sensors, cameras, and microphones.
- Output Devices โ displays, speakers, motors, LEDs, and actuators.
- Motherboards โ the central communication platform connecting all system components.
Additional hardware components discussed during the session included:
- CPU (Central Processing Unit)
- GPU (Graphics Processing Unit)
- RAM (Random Access Memory)
- Network Interfaces
- Storage Technologies โ Floppy Disk ๐พ โ CD/DVD ๐ โ HDD โ SSD
Microprocessor (CPU) vs Microcontroller (MCU)
One of the key topics covered was the distinction between a microprocessor and a microcontroller.
| CPU (Computer Brain) | MCU (Microcontroller) |
|---|---|
| Requires external RAM, storage, and peripheral devices. | Combines CPU, RAM, storage, and I/O peripherals on a single chip. |
| Runs operating systems such as Windows, Linux, and macOS. | Runs a dedicated embedded application directly. |
| Commonly used in laptops, desktops, and servers. | Commonly used in embedded systems, appliances, and electronics projects. |
In Summary:
- ๐ CPUs are designed to run complete computer systems.
- ๐ MCUs are designed to control dedicated devices and embedded applications.
โก Datasheet Study and Maker Board Evolution: From Arduino to RP2040
We explored the evolution of popular maker platforms and their increasing capabilities:
- Arduino Boards โ simple, beginner-friendly microcontroller platforms.
- Raspberry Pi โ powerful single-board computers capable of running a full operating system.
- Seeed Studio XIAO RP2040 โ a compact yet powerful microcontroller board based on the Raspberry Pi RP2040 chip.
To better understand modern embedded platforms, I compared the Arduino Uno, RP2040, and ESP32-S3 based on their processing power, memory, connectivity, and application areas.
I compared Arduino Uno, RP2040, and ESP32-S3 in terms of processing power, memory, connectivity, and application capabilities.
| Feature | Arduino Uno (ATmega328P) | Raspberry Pi Pico (RP2040) | ESP32-S3 |
|---|---|---|---|
| Processor | Single-core AVR (8-bit) | Dual-core ARM Cortex-M0+ (32-bit) | Dual-core Xtensa LX7 CPU (32-bit) |
| Clock Speed | 16 MHz | Up to 133 MHz | Up to 240 MHz |
| SRAM | 2 KB | 264 KB | 512 KB |
| Flash Memory | 32 KB | 2 MB (Onboard) | 4 MB to 16 MB |
| Operating Voltage | 5 V | 3.3 V | 3.3 V |
| GPIO Pins | 20 | 26 | 45 |
| Analog Inputs (ADC) | 6 Channels, 10-bit | 3 Channels, 12-bit | Up to 20 Channels, 12-bit |
| PWM Channels | 6 | 16 | 8 [LED PWM Controller, Two Motor Control PWM Units] |
| Communication Interfaces | 1 UART, 1 IยฒC, 1 SPI | 2 UART, 2 IยฒC, 2 SPI | 3 UART, 2 IยฒC, 2 SPI |
| USB Support | USB via Serial Converter | USB 1.1 Device/Host | USB 2.0 Full-Speed (12 Mbps) OTG Support |
| Programming Languages | C / C++ (Arduino IDE) | MicroPython, C, C++ | C/C++, MicroPython, CircuitPython |
| Wi-Fi | โ | โ | โ Wi-Fi (IEEE 802.11 b/g/n) |
| Bluetooth | โ | โ | โ Bluetoothยฎ 5 (LE) |
| Camera Support | โ | โ | โ 8-bit to 16-bit DVP Camera Interface |
| Onboard Sensors | โ | โ | โ IMU, Microphone, and More |
| Where Each Board Shines | Blinking LEDs, Push Buttons, and Simple Robotics | Displays, Fast PWM, and Real-Time Sensing | Wireless Communication, Audio Processing, Onboard Sensors, Camera Applications, and IoT Dashboards |
The Arduino Uno is an 8-bit microcontroller that is well-suited for basic input/output operations and embedded control applications with minimal overhead. The Raspberry Pi Pico, based on the RP2040, provides a more powerful 32-bit dual-core platform that is ideal for real-time applications, signal processing, and multimedia interfacing. The Seeed Studio XIAO ESP32-S3 Sense combines high processing performance with built-in Wi-Fi, Bluetooth, onboard sensors, and camera support, making it suitable for advanced IoT, sensing, computer vision, and edge machine learning projects.
The RP2040 offers an excellent balance between performance and size. Its compact form factor, combined with its dual-core architecture and rich peripheral support, makes it particularly attractive for embedded, portable, and wearable electronics projects.
โฑ What Does MHz Actually Mean?
MHz (Megahertz) represents how many clock cycles occur every second.
For example:
- 5 Hz = 5 cycles per second
- 10 Hz = 10 cycles per second
- 1 MHz = 1 million cycles per second
A higher clock frequency generally allows a processor to execute more instructions within the same amount of time.
โก Relating MHz to the RP2040
To better understand the performance of the RP2040, let's look at how much data it can process and how quickly it operates.
- ๐ Bit = A single binary switch (0 or 1)
- ๐ Byte = 8 bits grouped together
- ๐ RP2040 is a 32-bit microcontroller, meaning it can process 32 bits of data in a single operation
- ๐ The RP2040 operates at up to 133 MHz, which means it can perform approximately 133 million 32-bit operations per second
In simple terms:
- 133,000,000 ร 32 bits = approximately 4.25 billion bits per second
- 4.25 billion bits รท 8 = approximately 531 MB/s of theoretical data throughput
Therefore, under ideal conditions, the RP2040 is theoretically capable of processing approximately 531 MB of data per second. In practice, the actual throughput is lower due to instruction overhead, memory access time, peripheral operations, and software execution constraints.
๐ ESP32-S3 Datasheet Study and ๐ Hands-on with Seeed Studio XIAO RP2040
I explored the datasheet of the ESP32-S3 to better understand its architecture, memory organization, communication interfaces, and processing capabilities.
Official Datasheet: https://documentation.espressif.com/esp32-s3_datasheet_en.pdf
ESP32-S3 Overview
- Processor โ Dual-core Xtensa LX7 CPU (32-bit)
- Clock Speed โ Up to 240 MHz
- SRAM โ 512 KB
- Flash Memory โ 4 MB to 16 MB
- Operating Voltage โ 3.3 V
- GPIO Pins โ 45
- Analog Inputs (ADC) โ Up to 20 channels, 12-bit
- PWM Channels โ 8
- Communication Interfaces โ 3 UART, 2 IยฒC, 2 SPI
- Programming Languages โ C/C++, MicroPython, and CircuitPython
- Wi-Fi โ IEEE 802.11 b/g/n
- Bluetooth โ Bluetoothยฎ 5 LE
- Camera Support โ 8-bit to 16-bit DVP Camera Interface
- Onboard Sensors โ IMU, Microphone, etc.
Functional Block Diagram of the SoC (System on Chip)
The dark gray blocks represent low-power components that remain operational during Deep Sleep mode.
Xtensaยฎ 32-bit LX7 Dual-Core Processor
- Two processor cores operate in parallel.
- Maximum clock speed of 240 MHz.
Memory Architecture
- ROM: 384 KB
- SRAM: 512 KB (shared and accessible by both cores)
- RTC SRAM: 16 KB
- 128-bit Data Bus
- DMA Controller (Direct Memory Access)
- Flash Memory: 4 MB to 16 MB
Memory Organization
The following diagram illustrates the address mapping structure of the ESP32-S3.
GPIO Pin Layout
During the lab session, we received a Seeed Studio XIAO RP2040, LEDs, jumper wires, and a breadboard. We studied the RP2040 pinout and familiarized ourselves with breadboard connections before beginning our programming exercises.
โ ๏ธ Important RP2040 Safety Guidelines
Caution the 3.3 V operating voltage and GPIO limitations of the RP2040.
3.3 V Logic
- GPIO pins are NOT 5 V tolerant.
- Applying 5 V directly to a GPIO pin can permanently damage the board.
- Use level shifters when interfacing with 5 V sensors, Arduino modules, or other 5 V devices.
- The RP2040 microcontroller can be damaged instantly if 5 V is applied to any GPIO pin.
Current Limits
- Each GPIO pin should be limited to approximately 12 mA for safe operation.
- Do not drive high-power loads directly from GPIO pins. Use transistors, relays, or MOSFETs instead.
- Always use a current-limiting resistor (typically 220 ฮฉ to 1 kฮฉ) when driving LEDs.
- Motors and servos should be powered using an external power supply and appropriate driver circuitry.
๐งฐ Toolchain: The Complete Pipeline from Code to Silicon
A toolchain converts human-readable source code into machine instructions and uploads them to a microcontroller.
The toolchain includes:
- Programming Language
- Compiler / Interpreter
- Board Support Packages (BSPs)
- Upload Tools
| Elements of Toolchain | Seeed Studio RP2040 + Arduino | Seeed Studio RP2040 + Thonny + MicroPython |
ATtiny44/84 + Microchip Studio + C Programming
This toolchain is part of Group Assignment |
|---|---|---|---|
| Programming Language | Arduino-style C/C++ [Fast, Low-Level] |
MicroPython [High-Level & Easy] |
Embedded C [Faster than Arduino-style C/C++] |
| Programming Environment | Arduino IDE [Code Editor + Build + Upload] |
Thonny [Editor + REPL + Flashing] |
Microchip Studio 7 [Editor + Compiler + Debugger] |
| Code Translation Method | Compiler [Converts C/C++ โ Machine Code] |
Interpreter [Executes Python Line by Line] |
Compiler [Converts C โ AVR Machine Code] |
| Upload Tools | UF2 Bootloader / OpenOCD [Flashes Firmware to Chip] |
Thonny Flasher [Installs MicroPython Firmware] |
Programmer (UPDI / ISP) [Uploads .hex File to ATtiny] |
| Libraries | Arduino + Vendor Libraries [OLED, GPIO, IยฒC, SPI, etc.] |
machine, utime, drivers [GPIO, IยฒC, LEDs, etc.] |
avr-libc [Delays, I/O Macros, Timers] |
| Runtime | Runs Directly on Hardware | Python Virtual Machine [Runs on Top of MCU] |
Runs Directly on Hardware |
| Flow Looks Like |
|
|
|
| Feature | Compiler | Interpreter |
|---|---|---|
| Translation | Entire Program at Once | Line by Line |
| Output | Creates an Executable File | No Separate File |
| Speed | Faster Execution | Slower Execution |
| Error Detection | After Compilation | During Execution |
| Examples | C/C++, Rust | Python, JavaScript, Ruby |
๐ Hardware Connection
I connected the Seeed Studio XIAO RP2040 to my computer using a USB Type-C cable. Once powered, I observed that the onboard RGB LED, the Power LED, and the User LED were illuminated. This indicates that the board is shipped with a factory-programmed default firmware.
To upload new firmware, I pressed and held the BOOT button while connecting the USB cable between the XIAO RP2040 and my computer. The board entered bootloader mode, and a new removable storage device named "RPI-RP2" appeared on the system.
The illuminated Power LED confirms that the board is receiving power correctly and has been successfully connected to the computer.
๐ป Software Setup
I downloaded and installed the latest version of the Arduino IDE compatible with my operating system.
After launching the Arduino IDE, I added support for the Seeed Studio XIAO RP2040 board package by following these steps:
- Navigate to File โ Preferences.
-
In the Additional Boards Manager URLs field, add the following URL:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json - Click OK to save the settings.
Next, I installed the required RP2040 board package:
- Navigate to Tools โ Board โ Boards Manager.
- Search for "RP2040".
- Install the latest version of Raspberry Pi Pico/RP2040.
First Blink Code Test
The first code that I tried was the blink LED code. Below is the code that I generated it using reference of example blink code.
Circuit connection : D0 pin of XIAO RP2040 is connected to positive leg of LED, the negative leg of LED is connected to 1K resistor and the other end of resistor is connected to the GND. The Breadboard GND Bus is connected to Ground of XAIO RP2040's GND.
// the setup function runs once when you press reset or power the board
void setup()
{
pinMode(D0, OUTPUT); // initialize digital pin D0 as an output.
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(D0, HIGH); // turn the LED On (LOW is the voltage level)
delay(100); // wait for a second
digitalWrite(D0, LOW); // turn the LED Off (HIGH is the voltage level)
delay(100); // wait for a second
digitalWrite(D0, HIGH); // turn the LED ON (LOW is the voltage level)
delay(100); // wait for a second
digitalWrite(D0, LOW); // turn the LED off by making the voltage HIGH
delay(2000); // wait for a second
}
๐ง Assembling an Embedded System
I assembled an embedded system using a push button as the input device and an LED and OLED display as the output devices. All components were connected on a breadboard using jumper wires.
- Resistors โ Used to limit current flow and protect electronic components.
- Push Buttons โ Used as input devices to send user commands to the microcontroller.
- LEDs โ Light Emitting Diodes used as visual output indicators.
- Jumper Wires โ Used to make temporary electrical connections between components.
- Breadboard โ A prototyping board used for building and testing circuits. Below image explains the breadboard internal connections, supply bus and ground bus.
- Microcontroller โ A programmable electronic device that reads inputs, processes data, and controls outputs.
๐ป Programming the Embedded System
Using example programs from wiki.seeedstudio.com , I developed and uploaded a program that detects the push button state and turns on the LED while displaying "FAB LAB Kerala" on the OLED display when the button is pressed.
Wired communication using IยฒC is used between the Seeed Studio XIAO RP2040 and the OLED display.
Arduino-style C/C++ Code
/* Task : Write and test a program for an embedded system using a microcontroller to interact with input and / or output devices and communicate with wired or wireless devices. Flash LED and display something on serial monitor and OLED Display when the Push button is pressed.
Hardware assembly description
Development Board : Seeed Studio XIAO RP2040
Inputs : PIN D7 Push button
Outputs : PIN D0 Blue LED
Wired Communication : I2C with OLED Display
Created on : 14 Feb 2026
Author : Abhishek
Modification History: 17 Feb 2026
Library installed for this code are U8g2 by Oliver. (You can install Library Sketch > Include Library > Manage Libraries > Search U8g2 > Install)
Arduino Programming Reference : https://docs.arduino.cc/language-reference/
Seed Studio Reference : https://wiki.seeedstudio.com/XIAO-RP2040-with-Arduino/
*/
#include <Arduino.h> // this header file provides access to all the standard, built-in Arduino functions, variables, and constants. Without it, the compiler would not recognize basic Arduino commands. it is must include for VS Code and other programing environments.
#include <U8g2lib.h> // this header file provides a preprocessor directive in Arduino/C++ programming that imports the U8g2 library.
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C // this header checks if token U8X8_HAVE_HW_I2C has been defined earlier and check if OLED display supports I2C communication, if yes then include Wire.h library.
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
const int BlueLED = D0; // the number of Blue LED pin
const int PushButton = D7; // the number of PushB Button pin, note that here const mean "read-only" variable its value is set at initialization and cannot be changed later in the program, which helps prevent accidental modification of important values.
int ButtonStatus = LOW; // Variable for reading the pushbutton status
int i; // counter for for loop
void setup() // the setup function runs once when you press reset or power the board
{
pinMode(BlueLED, OUTPUT); // initialize digital PIN D0 as output
pinMode(PushButton, INPUT); // initialize digital PIN D7 as Input
Serial.begin(115200); // Set the data rate 115200 baud (bits per second) for serial data transmission.
Wire.begin(); // Activates the I2C hardware peripheral, Assigns SDA & SCL pins to I2C mode, Gets ready to send/receive data
u8g2.begin(); // initialize the display and prepare it for drawing with u8g2 Arduino graphics library
}
void loop() // the loop function runs over and over again forever
{
ButtonStatus = digitalRead(PushButton); //read the digital status of Push Button
if (ButtonStatus == LOW) //if Push Button Status in LOW then flash the LED as Airbus Strobe lights pattern for 5 times
{
for (i = 0; i<10; i++)
{
Serial.println("FABLAB Kerala!"); // this prints "FABLAB Kerala!" on the serial monitor
digitalWrite(BlueLED, HIGH); // turn ON Blue LED
delay(100); // delay of 0.1 second
digitalWrite(BlueLED, LOW); // turn OFF Blue LED
delay(100); // delay of 0.1 second
digitalWrite(BlueLED, HIGH); // turn ON Blue LED
delay(100); // delay of 0.1 second
digitalWrite(BlueLED, LOW); // turn OFF Blue LED
delay(400); // delay of 0.7 second
u8g2.setFont(u8g2_font_ncenB08_tr); // ncenB: New Century Schoolbook (font name), Bold (weight). Height of the font is 8 pixels
u8g2.drawStr(0,10,"Airbus Strobe light.."); // draw string at x = 0 and y = 10
u8g2.drawStr(0,30,"By"); // draw string at x = 0 and y = 30
u8g2.drawStr(0,50,"FAB LAB Kerala!"); // draw string at x = 0 and y = 50
u8g2.sendBuffer(); // transfer internal memory to the display
u8g2.clearBuffer(); // clear the internal memory
delay(700);
}
u8g2.sendBuffer(); // transfer internal memory to the display
}
else
{
digitalWrite(BlueLED, LOW); // turn Off Red LED
}
}
๐ Learning Note
Today, I learned how to quickly rename variables and perform bulk editing in Visual Studio Code.
- Place the cursor on a word (for example,
ledPin). - Press Ctrl + D to select the current occurrence.
- Press Ctrl + D again to select the next matching occurrence.
- Continue pressing Ctrl + D to select all matching occurrences and edit them simultaneously.
๐ค Using AI for Troubleshooting
While developing the program, I combined code snippets from three different examples available on wiki.seeedstudio.com . When the OLED display failed to show any output, I used AI to help identify the issue.
After reviewing the code, the AI identified that the OLED example used an incorrect constructor configuration and suggested adding Wire.begin() inside the setup() function to properly initialize IยฒC communication.
The ChatGPT prompt I used was:
"What is wrong in this code? It is not working, and the OLED is not displaying anything!"
I then pasted the complete source code into the AI chat for analysis.
โฌ๏ธ Uploading the Program
Before uploading the program, make sure that the correct Board and Port are selected from the Tools menu. These settings can also be accessed from the top-left corner of the Arduino IDE, as shown below.
๐ฅ๏ธ Exploring the Serial Monitor
Before using the Serial Monitor, the microcontroller must be connected to the computer and configured with the correct baud rate. In the Arduino IDE, the Serial Monitor can be opened by navigating to Tools โ Serial Monitor.
The baud rate defines the speed of serial communication between the microcontroller and the computer, measured in bits per second (bps).
In simple terms, the baud rate determines how fast bits travel across the communication channel.
The Serial Monitor was used to establish two-way communication between the computer and the RP2040 microcontroller. Text commands were transmitted from the computer and interpreted by the microcontroller to control multiple LEDs and update the OLED display in real time. This exercise demonstrated serial communication, real-time debugging, user interaction, and serial-based device control.
Arduino-style C/C++ Code
/* Exploring Serial Monitor
Baud rate = how many bits are sent per second
*/
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
const int RED = D0;
const int GREEN = D1;
const int BLUE = D2;
const int YELLOW = D3;
char cmd;
void setup()
{
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
pinMode(YELLOW, OUTPUT);
Serial.begin(115200);
while (!Serial);
Serial.println("Send R G B Y or O : ");
Wire.begin();
u8g2.begin();
delay(1000);
}
void loop()
{
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0,10,"Enter R G B Y or O :");
u8g2.drawStr(0,20,"Command:");
u8g2.sendBuffer();
if (Serial.available())
{
char cmd = Serial.read();
u8g2.drawStr(0,40,String(cmd).c_str());
u8g2.sendBuffer();
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
digitalWrite(YELLOW, LOW);
if (cmd == 'R') digitalWrite(RED, HIGH);
if (cmd == 'G') digitalWrite(GREEN, HIGH);
if (cmd == 'B') digitalWrite(BLUE, HIGH);
if (cmd == 'Y') digitalWrite(YELLOW, HIGH);
Serial.print("Command received: ");
Serial.println(cmd);
}
}
๐ค Asking AI to Generate Code
To explore AI-assisted programming, I provided the following prompt to an AI model:
Prompt ChatGPT:
"I have an LED connected to D3 and a push button connected to D0 on a Seeed Studio XIAO RP2040. I want a program that allows me to press the button once to start blinking the LED and press it again to stop blinking. The program should also print the LED status on the Serial Monitor."
I submitted the same prompt to multiple AI assistants. The response from Claude.ai was particularly interesting because, in addition to generating the code, it also provided a wiring diagram showing the required hardware connections based on the generated program.
The generated program uses a toggle mechanism to switch between blinking and non-blinking states. It also implements software debouncing and uses the millis() function for non-blocking timing instead of relying on delay-based execution.
Arduino-style C/C++ Code Generated by AI
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// XIAO RP2040 - Button Toggle LED Blink
// LED โ D3
// Button โ D0 (Active LOW, Internal Pull-up Enabled)
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// โโ Pin Definitions โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
#define LED_PIN D3
#define BUTTON_PIN D0
// โโ Timing Configuration โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
const unsigned long BLINK_INTERVAL = 500;
const unsigned long DEBOUNCE_DELAY = 50;
// โโ State Variables โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
bool blinking = false;
bool ledState = false;
int lastBtnState = HIGH;
unsigned long lastBlinkTime = 0;
unsigned long lastDebounceTime = 0;
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
void setup()
{
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(LED_PIN, LOW);
Serial.begin(115200);
while (!Serial);
Serial.println("=====================================");
Serial.println(" XIAO RP2040 - LED Toggle Blink");
Serial.println("=====================================");
Serial.println(" LED Pin : D3");
Serial.println(" BTN Pin : D0");
Serial.println(" Press button to START / STOP blinking");
Serial.println("=====================================");
Serial.println(" LED Status : OFF");
Serial.println();
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
void loop()
{
int currentBtnState = digitalRead(BUTTON_PIN);
if (currentBtnState != lastBtnState)
{
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY)
{
if (currentBtnState == LOW && lastBtnState == HIGH)
{
blinking = !blinking;
if (blinking)
{
Serial.println(" LED Status : BLINKING โ");
}
else
{
digitalWrite(LED_PIN, LOW);
ledState = false;
Serial.println(" LED Status : OFF");
}
}
}
lastBtnState = currentBtnState;
if (blinking)
{
if (millis() - lastBlinkTime >= BLINK_INTERVAL)
{
lastBlinkTime = millis();
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
}
}
}
๐ Exploring MicroPython with Thonny IDE
I explored MicroPython using the Thonny IDE, a different programming language and development environment for programming the Seeed Studio XIAO RP2040.
First, I downloaded and installed the latest version of Thonny for my operating system and launched the IDE.
Next, I navigated to Tools โ Options โ Interpreter, selected MicroPython (Raspberry Pi Pico) as the interpreter, and set the port to Try to detect automatically.
I then pressed and held the BOOT button while connecting the board to my computer using a USB Type-C cable. The appearance of the "RPI-RP2" drive confirmed that the board had successfully entered bootloader mode.
Returning to Tools โ Options โ Interpreter, I clicked Install or Update MicroPython, allowing Thonny to automatically detect the connected device. Under the version selection menu, I chose Raspberry Pi Pico / Pico H, clicked Install, and waited until the installation status displayed Done. Once completed, a firmware installation confirmation message appeared, as shown below.
With the development environment ready, I tested my first MicroPython program using the onboard NeoPixel example available on the Seeed Studio Wiki .
Since controlling the NeoPixel requires an external library, I downloaded the ws2812.py library file.
In Thonny, I navigated to File โ Open, selected the downloaded ws2812.py file, and saved it directly onto the board by choosing Raspberry Pi Pico as the target location. It is important to keep the filename unchanged as ws2812.py.
Next, I copied the NeoPixel example code from the Seeed Studio Wiki and used AI assistance to obtain a line-by-line explanation, helping me better understand how the program works.
In this example, Pin 11 is configured as a power output because it is connected to the VIN pin of the NeoPixel LED. The code sets this pin HIGH to supply power to the LED.
Pin 12 is passed to the WS2812() constructor because it is connected to the NeoPixel's data input pin, which is responsible for receiving color and control information.
MicroPython Code
# Import WS2812 class from the ws2812 library/module.
# This class is used to control WS2812 RGB LEDs (NeoPixels).
from ws2812 import WS2812
# Import the utime module for time-related functions.
import utime
# Import the machine module to access hardware features such as GPIO pins.
import machine
# Configure GPIO Pin 11 as an output and assign it to the variable power.
power = machine.Pin(11, machine.Pin.OUT)
# Set Pin 11 HIGH to provide power to the NeoPixel circuit.
power.value(1)
# RGB color definitions.
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
WHITE = (255, 255, 255)
# Create a collection of colors for easy iteration.
COLORS = (BLACK, RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE)
# Create a WS2812 object connected to Pin 12 controlling one LED.
led = WS2812(12, 1)
# Infinite loop.
while True:
print("Beautiful color")
for color in COLORS:
led.pixels_fill(color)
led.pixels_show()
utime.sleep(0.2)
To upload and run the code, I first clicked the "Run Current Script" button in Thonny.
During the first execution, Thonny prompted me to choose where to save the script file. Both This Computer and Raspberry Pi Pico are valid locations. However, if the program is intended to run independently without a computer connection, it must be saved directly on the board as main.py.
After saving the file, I clicked Run Current Script again to execute the program.
๐ LED Racer
๐ฏ Game Settings
I used Claude.ai to help develop this game. Special thanks to Nadec Biju for introducing me to Claude.
The final game was developed through an iterative conversation with Claude.ai. Below are the prompts I provided step by step, which gradually evolved into the final version of the game.
Claude Prompt 1: Do you know what a WS2812B LED strip is?
Claude Prompt 2: Does the length of a WS2812B strip matter?
Claude Prompt 3: It has 60 LEDs per meter.
Claude Prompt 4: Could you please provide the code and the required libraries? I have connected the LED strip data line to pin D3 and supplied 5 V and GND from an external DC power source.
Claude Prompt 5: I am using a Seeed Studio XIAO RP2040 and Arduino IDE.
Claude Prompt 6:
Claude Prompt 7:
Claude Prompt 8: OK, great! It's working.
Claude Prompt 9: Now comes the exciting part. I have created a race track using this 5 m WS2812B LED strip, and I want to build a racing game using two push buttons. One button acts as the Forward button (connected to pin D0). Each press should move the red LED forward by one position. For example, after 300 presses, the LED should move from position 1 to position 300 incrementally.
I have also connected a second push button called the Booster button to pin D1. When the Booster button and Forward button are pressed together, the LED should move forward faster, for example by 5 LEDs per button press.
The above functionality is for the Red player. I would also like to create a three-player game by adding a Green player and a Blue player. Could you please help with the code?
Claude Prompt 10: Can you modify the game so that instead of having a separate Booster button, a long press of the Forward button activates the Boost feature?
Claude Prompt 11: Hello Claude, I have created a track where LEDs 17โ31 form a hill, LEDs 33โ54 form another hill, LEDs 127โ183 form a three-loop spiral entered from the top and exited at LED 183, and LEDs 223โ273 form another three-loop spiral oriented vertically. Could you make the game more interesting by modifying the speed behavior in these sections?
Claude Prompt 12: Can you divide each hill into uphill and downhill sections? For uphill movement, use a speed factor of 0.5, and for downhill movement, use a speed factor of 2.
Additionally:
- If the Red player finishes first, LED 300 should remain Red.
- If the Green player finishes second, LED 299 should remain Green.
- If the Blue player finishes third, LED 298 should remain Blue.
I also needed one improvement. When the Red, Green, or Blue player enters Hill 1, Spiral 1, or Spiral 2, the player should always retain their original color. Previously, the track effect colors were mixing with the player colors and creating unintended colors.
Finally, instead of blinking only the first LED three times during startup, I requested that the entire track flash white three times before the race begins.
I also asked Claude.ai for suggestions on what to name the game.
๐ Reflection
Thursday: This session beautifully connected invisible microelectronics โ real-world embedded systems. Understanding how silicon devices, processors, toolchains, and firmware work together provided valuable insight into the foundations of embedded programming.
Friday: One important lesson I learned is to avoid trying to take three or four steps at once. It is better to learn concepts step by step, understand the fundamentals thoroughly, and then use advanced tools and shortcuts to improve productivity.
๐ References and Downloads
- Fab Academy โ Computer-Aided Design
- Seeed Studio XIAO RP2040 Documentation
- Arduino IDE
- Thonny IDE
- Arduino Code โ Airbus Strobe Light Project
- MicroPython Code โ NeoPixel Example