Week 4 Embedded Programming
This week I learned the basics of embedded programming and how microcontrollers work with input, output, and communication.
Group assignment
Demonstrate and compare the toolchains and development workflows for different embedded architectures.
Individual Assignment
Exploring Xiao Rp2040
Exploring Xiao Rp2040
I went through the RP2040 Datasheet that provides a detailed understanding of the icrocontroller
The chip name is based on the following naming convention:
The following diagram represents the system architecture of the RP2040 microcontroller.
Some of the key features of the RP2040 include:
Pin Out diagram
A "pinout diagram" is a diagram or list that shows the arrangement and function of the pins (or terminals) on an electronic component or connector, helping users understand how to connect and interact with the device. Shown below is the pinout diagram of a xiao rp2040 microcontroller.
Each individual GPIO pin can be connected to an internal peripheral through the GPIO functions defined below. Some internal peripheral connections are available in multiple locations, providing system-level flexibility. The SIO, PIO0, and PIO1 blocks can be connected to all GPIO pins and are controlled by software (or software-controlled state machines). Therefore, they can be used to implement a wide range of functions.
Understanding Arduino IDE and Micropython
Micropython
MicroPython is a lightweight version of Python designed for microcontrollers, while the Arduino IDE is a platform used for writing and uploading code to microcontroller boards, typically using C/C++. Both allow easy interaction with hardware through GPIO pins, sensors, and actuators.
Arduino IDE
It is a software environment for programming Arduino microcontroller boards. Arduin IDE provides an easy-to-use interface for writing, compiling, and uploading code to the board. It is widely used in hobbyist, DIY, and educational projects for electronics and robotics. It includes very helpful libraries and built-in functions to get started with a program and simplifies hardware interaction.
Programming
This week, I experimented with programming a microcontroller using both the Arduino IDE (C/C++) and Thonny (MicroPython).
To understand how programming works, we began by writing a simple LED blinking program.
Toolchain Comparison
Trying out Arduino IDE
Hardware Setup
I tested the code using the Seeed Studio XIAO RP2040 with the following components:
I had to install Arduino IDE first as this was my first time using it.
I found the Arduino IDE interface easy to understand and user-friendly. It also provides many reference libraries and built-in example codes, which makes it easier to learn and follow
To begin programming, we need to set up a new sketch according to the board being used. Go to Tools → Board and select the correct board (in this case, the Seeed Studio XIAO RP2040). Since this board is not available by default in the Arduino IDE, we need to install the required board package using the official Board Manager URL provided on the Seeed Studio website.
To do this, go to File → Preferences and paste the URL into Additional Boards Manager URLs, then click OK. After that, open Tools → Board → Boards Manager, search for Raspberry Pi Pico/RP2040, and install the package. Once installed, the XIAO RP2040 board becomes available for selection in the Arduino IDE.
Experiment 01: Blink Program from Library
I used a Seeed Studio XIAO RP2040 board and connected an external LED to it. I then used the built-in example code to blink the LED..
Board Pinout
connection diagram
Code
/*
Blink
Turns an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your Arduino
model, check the Technical Specs of your board at:
https://docs.arduino.cc/hardware/
modified 8 May 2014
by Scott Fitzgerald
modified 2 Sep 2016
by Arturo Guadalupi
modified 8 Sep 2016
by Colby Newman
This example code is in the public domain.
https://docs.arduino.cc/built-in-examples/basics/Blink/
*/
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
After writing the code, click the tick (✓) button to compile and verify the sketch. Once the compilation is successful, click the arrow (→) Upload button to upload the program to the board.
Experiment 02: Aeroplane Blink (RP2040)
This was my second trial using the RP2040, where I implemented an aeroplane-style LED blinking pattern.
#define LED_PIN 2
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// Flash flash (like airplane)
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
delay(100);
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
delay(700); // long gap before repeating
}
The aeroplane blink output was very satisfying and relaxing to watch. I also experimented by changing the delay values to adjust the blinking speed and pattern.
Experiment 03 – LED Chaser (RP2040)
This was my third trial on the RP2040. In this experiment, I programmed five LEDs to blink continuously in a sequence, similar to party lights.
int leds[] = {2, 3, 4, 5, 6};
void setup() {
for (int i = 0; i < 5; i++) {
pinMode(leds[i], OUTPUT);
}
}
void loop() {
for (int i = 0; i < 5; i++) {
digitalWrite(leds[i], HIGH);
delay(150);
digitalWrite(leds[i], LOW);
}
}
Experiment 04: LED Display Output Test
Components Required
Main Parts
Connection Items
Connection diagram
link.
In this experiment, I tested an LED display using the RP2040. The results were really cool, and I got a wonderful output. I recorded this output using a HeroShot video
#include#include #ifdef U8X8_HAVE_HW_SPI #include #endif #ifdef U8X8_HAVE_HW_I2C #include #endif U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); void setup(void) { Wire.begin(); u8g2.begin(); } void loop(void) { u8g2.clearBuffer(); // clear the internal memory u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font u8g2.drawStr(0,10,"ALI AG. HERE"); // write something to the internal memory u8g2.drawStr(0,30,"FROM"); u8g2.drawStr(0,50,"FABLAB KOCHI!"); u8g2.sendBuffer(); // transfer internal memory to the display delay(1000); }
HERO SHOT
Experiment 05: Push Button with Serial Monitor Output
push circut diagram
Components Required
In this experiment, I interfaced a push button with the Seeed Studio XIAO RP2040 and displayed the button status on the Serial Monitor. Whenever the button was pressed, the microcontroller detected the input and printed the output message through serial communication.
code
#define BTN D1 // D1
#define LED D2 // D2
bool lastState = HIGH;
void setup() {
pinMode(BTN, INPUT_PULLUP);
pinMode(LED, OUTPUT);
Serial.begin(115200);
delay(1000);
Serial.println("Serial Monitor Started!");
Serial.println("Press the button to toggle LED.");
}
void loop() {
bool currentState = digitalRead(BTN);
// Detect button press (HIGH -> LOW)
if (lastState == HIGH && currentState == LOW) {
Serial.println("Button Pressed!");
// Toggle LED
digitalWrite(LED, !digitalRead(LED));
if (digitalRead(LED) == HIGH) {
Serial.println("LED ON");
} else {
Serial.println("LED OFF");
}
delay(200); // small debounce
}
lastState = currentState;
}
Testing MicroPython in Thonny
This was the second software I used this week: Thonny, for programming the RP2040 using MicroPython.
Experiment 01: RGB Rainbow Effect
In the Thonny interface, go to Tools → Options to open the settings.
Select the Interpreter tab and set the device to MicroPython (Raspberry Pi Pico). Then choose the port option “Try to detect port automatically.”
Connect Seeed Studio XIAO RP2040 to the PC and Light It Up
Step 1: Press and hold the BOOT button, then connect the Seeed Studio XIAO RP2040 to the PC using a Type-C cable. If the connection is successful, a new drive named “RPI-RP2” will appear on the computer.
Step 2: Click Install or update MicroPython. Thonny will automatically detect the connected device and display it under Target Volume. In the MicroPython version selection below, we can leave it as the default option.
Click the Install button and wait until the installation status shows Done. After that, close the window. Once the firmware installation is complete, the following information will appear in the Thonny interface.
Step 4: Upload and run the code by clicking the “Run current script” button. The first time you run a program, Thonny will ask where you want to save the script file. You can choose either This Computer or Raspberry Pi Pico. If everything is working correctly, the onboard LED will blink on and off once per second. At the same time, an increasing number will be displayed in the Shell as output.
The connection is commplete and now we can proceed to the other projects.
import array, time
from machine import Pin
import rp2
# Configure the number of WS2812 LEDs.
#brightness = 0.2
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True,pull_thresh=24)
def ws2812():
T1 = 2
T2 = 5
T3 = 3
wrap_target()
label("bitloop")
out(x, 1) .side(0) [T3 - 1]
jmp(not_x, "do_zero") .side(1) [T1 - 1]
jmp("bitloop") .side(1) [T2 - 1]
label("do_zero")
nop() .side(0) [T2 - 1]
wrap()
class WS2812():
def __init__(self, pin_num, led_count, brightness = 0.5):
self.Pin = Pin
self.led_count = led_count
self.brightness = brightness
self.sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(pin_num))
self.sm.active(1)
self.ar = array.array("I", [0 for _ in range(led_count)])
def pixels_show(self):
dimmer_ar = array.array("I", [0 for _ in range(self.led_count)])
for i,c in enumerate(self.ar):
r = int(((c >> 8) & 0xFF) * self.brightness)
g = int(((c >> 16) & 0xFF) * self.brightness)
b = int((c & 0xFF) * self.brightness)
dimmer_ar[i] = (g<<16) + (r<<8) + b
self.sm.put(dimmer_ar, 8)
time.sleep_ms(10)
def pixels_set(self, i, color):
self.ar[i] = (color[1]<<16) + (color[0]<<8) + color[2]
def pixels_fill(self, color):
for i in range(len(self.ar)):
self.pixels_set(i, color)
def color_chase(self,color, wait):
for i in range(self.led_count):
self.pixels_set(i, color)
time.sleep(wait)
self.pixels_show()
time.sleep(0.2)
def wheel(self, pos):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if pos < 0 or pos > 255:
return (0, 0, 0)
if pos < 85:
return (255 - pos * 3, pos * 3, 0)
if pos < 170:
pos -= 85
return (0, 255 - pos * 3, pos * 3)
pos -= 170
return (pos * 3, 0, 255 - pos * 3)
def rainbow_cycle(self, wait):
for j in range(255):
for i in range(self.led_count):
rc_index = (i * 256 // self.led_count) + j
self.pixels_set(i, self.wheel(rc_index & 255))
self.pixels_show()
time.sleep(wait)
By saving the code in .py format and running it in Thonny, I was able to see the output directly in the Shell. This is how I completed my first experiment using MicroPython.
For my final project development, I prefer to continue using the Arduino IDE, because it feels more structured for building complete projects. At the same time, MicroPython is also useful for quick testing and learning, and both platforms provide many examples and resources to explore
what i learned in week04
In Week 04, I learned the basics of embedded programming and how to control real hardware using code. I understood how microcontrollers work, how GPIO pins behave as real HIGH/LOW electrical signals, and how small hardware mistakes can affect the output.
I worked with two toolchains:
By the end of the week, I learned how to read a datasheet, understand pin mapping, build breadboard circuits, use resistors correctly, control LEDs (blink, aeroplane blink, chaser light), and use a push button with Serial Monitor output
Useful links