Week 4 Embedded Programming - Student¶
McKinnon Collins, Max Negrin, Oliver Abbott, and Yian Hu
Xiao-RP2040 - McKinnon Collins¶
The Seeed Studio XIAO RP2040 is a small but powerful microcontroller using the RP2040 chip.
This week I programmed a input and output, to keep it simple since I am still pretty new to the XIAO RP2040, I used a button as an input and LED as an output. I wanted to press the button and then the LED turns on, then when I release the button the LED turns off.
XIAO RP2040 Setup¶
This week I recieved a fresh XIAO RP2040 from the factory. I needed to flash the micropython firmware onto it. I went to micropython to find the firmware. I downloaded the most recent .uf2 file then flashed it to the XIAO RP2040. To flash it, I held down the BOOTSEL button while plugging it into my PC. This put the RP2040 into boot mode. The RP2040 apperared as a drive in my File Explorer. I put the .uf2 file into the RP2040 and the RP2040 was setup with micropython.
XIAO RP2040 Pinout¶

I found this pinout from here. This week, I will be using the micropython pins.
Wowki¶
Wowki is a free browser based electronics simulator. The only problem is, Wowki does not have a Xiao RP2040. Luckly, Wowki has the Xiao ESP32C6 which looks identical to the RP2040 so I was able to layout my circuit.

I designed this circuit in wowki. I want P27 to read high, then when the button is pressed, it switches to ground and reads low because it is at 0V. Then I can have a simple if else statement saying P27 is 1, led is off, and if P27 is 0, led is on.
Because I have little to no experience with coding, I consulted microsoft copilot to generate my code. I asked it:
I am a fab academy student and this week I need to use a Xiao RP2040 along with an input and output. I have a 4 pin pushbutton (A and B style) and an LED. I wired my LED to P26 and GND and the pushbutton A pin to P27 and the the pushbutton B pin to GND. Could you generate micropython code so that when the Pushbutton is pressed the led turns on and then when the button is released the LED turns off?
Copilot responded with:
import machine
import time
button = machine.Pin(27, machine.Pin.IN, machine.Pin.PULL_UP)
led = machine.Pin(26, machine.Pin.OUT)
while True:
if button.value() == 0: # pressed (pulled to GND)
led.value(1)
else:
led.value(0)
time.sleep(0.01)
This week I used VSCode to compile and upload the code to the RP2040. To set up VSCode for this, I created a new folder then in the folder I had a .vscode and then under than I had tasks.json. On the same level as .vscode I had main.py. Mr. Dubick gave us the code for tasks.json. This would allow us to go to terminal, then run task, then all of the code would be uploaded to the RP2040.
Here is the code for tasks.json:

I put the code that Copilot generated into main.py:

I once I saved the code, I went to terminal, then run task, and then the code was sent to the rp2040 through a USB cable.
ESP32-C6 (Max)¶
The ESP32-C6 pinout diagram:

First, I started by installing the XIAO ESP32-C6 board manager following this tutorial.
Then, I loaded up wokwi and wrote a little script to turn on an LED when the button is pressed.

Here is the code:
title="ESP32_button" linenums= "1"
int button = 0;
void setup() {
pinMode(18, OUTPUT);
pinMode(20, INPUT_PULLDOWN);
}
void loop() {
button = digitalRead(20);
if (button == 1){
digitalWrite(18, HIGH);
} else {
digitalWrite(18, LOW);
}
delay(10);
}
And finally, I used the tutorial above to connect the ESP32 to my laptop via usb-c and ran the code using the Arduino IDE.
Initially, the code just wouldnt work, I was testing the microcontroller with example code, testing the led, and eventually just adding a serial output(I also switched the pins to digital, while troubleshooting):
int button = 0;
void setup() {
pinMode(D10, INPUT_PULLDOWN); // button input
pinMode(D9, OUTPUT); // output pin
Serial.begin(9600);
}
void loop() {
button = digitalRead(D10);
if (button == HIGH) {
Serial.println("High");
digitalWrite(D9, HIGH);
} else {
digitalWrite(D9, LOW);
Serial.println("Low");
}
}
This just let me know that everything was working correctly, as it output “high” when I pressed the button and “low” any other time. Finally I just took out the resistor that was connecting pin 9 to ground and connected it directly, and then the LED lit up. From this, I figured out that I was accidently using my only 100k ohm resistor that I was going to use as a pulldown. I switched it out for a 220 ohm and it worked fine.
The two resistors I confused.

You can download the .ino file here.
Raspberry Pi Pico 2 W RP2350 - Yian Hu¶
The Raspberry Pi Pico 2 is a compact microcontroller board built around the RP2350 chip, which provides dual-core processing, improved memory, and enhanced I/O capability. It is designed for embedded systems and prototyping, offering flexible GPIO and support for MicroPython or C/C++ to control electronic components and build efficient hardware projects.
Understanding the Pico 2 W¶
To develop an understanding of the microcontroller, I found the datasheet online, and consulted seller pages which summarized its features/specs. Using this information, I created the chart below.
| Feature | Raspberry Pi Pico 2W |
|---|---|
| Chip | RP2350A |
| CPU | Dual ARM Cortex-M33 (Armv8-M), or Dual RISC-V Hazard3 (RV32IMAC+) |
| CPU Clock | 48MHz, up to 150MHz |
| RAM Size | 520 KByte SRAM |
| Flash Size | 4 MByte Q-SPI Flash |
| Security | ARM TrustZone, 8KB OTP, Secure Boot |
| Wireless | IEEE 802.11 b/n/g (2.4GHz), Bluetooth 5.2 |
| Programming Language | MicroPython, CircuitPython, C, C++ |
| MCU Voltage | 3.3VDC |
| GPIO Voltage | 3.3VDC |
| GPIO | 26 x Digital Input/Output (Total) |
| PWM | 16 |
| Programmable IO | 3 x PIO v2 Blocks (12 PIO State Machines) |
| Debugging | ARM Serial Wire Debug (SWD) |
Setting up the Pico 2 W¶
To set up the Pico 2 W to work with MicroPython, I first downloaded the Pico 2 W UF2 firmware from the official micropython website (specifically from this page). Then, I put the microcontroller in BOOTSEL mode by holding the BOOTSEL button and then plugging it in. This opened a drive in my MacBook called RP2350. I then dragged the .uf2 file into the new drive. Once the drive disappeared, I could confirm that the Pico 2 W was successfully configured to run MicroPython.
To make working with MicroPython a lot easier, I installed the MicroPico VSCode extension (created by paulober). This extension allowed me to create and configure Python projects directly from the command palette, as well as freely load and run code onto my microcontoller. To create a new project, I first accessed the command palette by pressing Command + Shift + P, and then ran MicroPico: Create New Project. This generated a base file structure with all necessary MicroPython components.
Creating the Night Light Circuit¶
The idea for this circuit was heavily inspired by a list of ideas created by ChatGPT. The circuit itself and the corresponding code was based off of this video.
Here are the required components:
- x 1 Raspberry Pi Pico 2 W RP2350
- x 5 Male-to-Male Header Wires
- x 2 Female-to-Female Header Wires
- x 1 LDR Sensor Module
- x 1 LDR Photo Resistor
To start, I grasped an understanding of the circuit’s wiring by consulting the Pico 2 W’s pinout.

With this, I was able to wire the circuit
Arduino Uno R3 — Oliver Abbott¶
Browsing the ATmega328P Datasheet¶
The Arduino Uno R3 is built around the ATmega328P microcontroller from Microchip (formerly Atmel). Here are the key specs I found while browsing the datasheet:
- Architecture: 8-bit AVR RISC
- Clock Speed: 16 MHz (external crystal on the Uno)
- Flash Memory: 32 KB (0.5 KB used by bootloader)
- SRAM: 2 KB
- EEPROM: 1 KB
- Digital I/O Pins: 14 (6 provide PWM output)
- Analog Input Pins: 6 (10-bit ADC, 0–1023 range)
- Operating Voltage: 5V
- Communication: UART (Serial), SPI, I2C (TWI)
- Built-in LED: Pin 13
- USB Interface: ATmega16U2 handles USB-to-serial conversion
Compared to the ESP32-C6, the Uno is simpler — no WiFi or Bluetooth built in. But it runs at 5V logic, which makes it easier to interface with many sensors and modules directly without level shifting.
The Program — Button-Controlled LED¶
This program uses a pushbutton as local input and an LED as local output on the Arduino Uno R3. Each press of the button toggles the LED on or off using a simple state counter. The Arduino communicates with the computer over USB (UART serial) for uploading the code, satisfying the wired communication requirement.
Wiring¶
- LED: Pin 8 → 220Ω resistor → LED anode (+) → LED cathode (−) → GND
- Button: Pin 7 → one leg of button, other leg → 5V (with pull-down resistor to GND)
- USB cable: Connected to computer for uploading code (wired serial communication)
Arduino Code¶
// Arduino Uno R3 — Button Toggle LED
// Local I/O: pushbutton (input on pin 7) + LED (output on pin 8)
// Wired communication: USB serial for code upload
unsigned const LED = 8;
unsigned const BUTTON = 7;
unsigned int bState = 0;
void setup() {
pinMode(BUTTON, INPUT);
pinMode(LED, OUTPUT);
}
void loop() {
if (digitalRead(BUTTON) == 1) {
digitalWrite(LED, HIGH);
bState += 1;
if (bState % 2 == 0) {
digitalWrite(LED, LOW);
bState = 0;
}
delay(100);
}
}
How It Works¶
- LED (pin 8): Configured as OUTPUT — this is the local output device.
- Button (pin 7): Configured as INPUT — this is the local input device. When pressed,
digitalReadreturns 1 (HIGH). - Toggle logic: Each button press increments
bState. On the first press (bState = 1, odd), the LED turns on. On the second press (bState = 2, even), the LED turns off and the counter resets to 0. - Delay: The 100ms delay acts as a simple debounce to prevent multiple triggers from a single press.
- Wired communication: The program is uploaded to the Arduino over USB, which uses the ATmega16U2 chip for USB-to-UART serial conversion.
Tinkercad Circuit¶
Before building the physical circuit, I prototyped it in Tinkercad to verify the wiring and test the code in simulation:

Video — Working Demo¶
Here’s the circuit running on the real Arduino Uno R3. Each button press toggles the LED on or off — you can see the state change immediately after each press, with the 100ms delay preventing accidental double-triggers.
This demonstrates local interaction with both an input device (pushbutton) and an output device (LED), with the code uploaded via wired USB serial communication.