Week 6: Embedded Programming
February 29, 2024
Embedded Programming
This week, I had the opportunity to experiment with the RP2040 and Attiny 412. The most significant aspects of this experience were reading Datasheets and understanding the basics of assembly programming, communication protocols between electronic components, and gaining hands-on experience with microprocessors.
Group Assigment Page
This week’s group assignment
Programming with Attiny 412
This week, I conducted experiments using the Attiny 412. This provided an opportunity to delve into reading Datasheets and grasp the fundamentals of assembly programming, communication protocols between electronic components, and experience with microprocessors. The process allowed me to understand the operational capabilities and programming interfaces of the Attiny 412 microcontroller deeply.
Attiny 412 Programming
Attiny 412 Prototype for the TOGO Project
In addition to my work with the Attiny 412, I also embarked on booting the Seed Studio RP2040 and conducted a simple LED lighting experiment. The RP2040, with its advanced features and ease of programmability, stands out as a powerful microcontroller. This experience provided an opportunity to compare the different characteristics and capabilities of both the Attiny 412 and RP2040 through hands-on experimentation. The following simple “Light an LED” example was part of my experiment with the RP2040:
Controlling the RGB LED on Seeed Studio XIAO RP2040
Specifications:
- Microcontroller: RP2040 by Raspberry Pi Foundation
- Digital I/O Pins: 11, all of which can perform digital input and output functions.
- Built-in RGB LED: Programmable WS2812 RGB LED, also known as NeoPixel.
- Power Supply: USB Type-C connection or 3.3V pin.
The Seeed Studio XIAO RP2040 contains 11 digital pins, 4 analog pins, 11 PWM Pins, 1 I2C interface, 1 UART interface, 1 SPI interface, and 1 SWD Bonding pad interface.
Warning:
The operating voltage of the Seeed Studio XIAO RP2040 is 3.3V. If you connect the sensor to 5V incorrectly, the motherboard may not work properly.
Comparison of the Processing Power of the RP2040
Computer | CPU | Speed (MHz) | Memory | Bits | Cores |
---|---|---|---|---|---|
Apple II | MOS 6502 | 1 | 48 KB | 8 | 1 |
IBM PC | Intel 8088 | 4.77 | 640 KB | 16 | 1 |
Arduino Nano | ATmega 328 | 16 | 2 KB | 8 | 1 |
Arduino Due | ARM M3 | 84 | 96 KB | 32 | 1 |
RP2040 | ARM M0+ | 133 | 264 KB | 32 | 2 |
Pi Zero | ARM A53 | 1000 | 512 MB | 32 | 1 |
Pi 4 | ARM A72 | 1500 | 2/4/8 GB | 64 | 4 |
Raspberry Pi 5 | ARM AXX | YYY | ZZZ GB | 64 | N |
RP2040 Assembly “Hello World” Example
Objective
This example aims to introduce students to low-level programming on the RP2040 microcontroller using assembly language. It demonstrates how to print “Hello World” followed by an incrementing number on the serial output using the Pico SDK.
Prerequisites
- Seeed Studio XIAO RP2040 or any RP2040-based microcontroller board
- Raspberry Pi Pico SDK installed on your development environment
- A toolchain that supports ARM assembly language (e.g., arm-none-eabi-gcc)
- A serial terminal program to view the output (e.g., PuTTY, minicom)
Program Explanation
The program initializes a counter, uses the Pico SDK to print “Hello World” followed by the counter value, and loops indefinitely. Here’s the assembly code:
.thumb_func
.global main
main:
MOV R7, #0 @ Initialize counter to 0
BL stdio_init_all @ Initialize standard I/O
loop:
LDR R0, =helloworld @ Load the address of the string
ADD R7, R7, #1 @ Increment the counter
MOV R1, R7 @ Move the counter to R1
BL printf @ Print the string and counter
B loop @ Loop indefinitely
.data
.align 4
helloworld: .asciz "Hello World %d\n"
Key Components
.thumb_func
: Specifies that the function should be compiled in Thumb mode, which is required for compatibility with the Pico SDK..global main
: Exports the symbol ‘main’ as the entry point of the program.MOV R7, #0
: Initializes the counter to 0.BL stdio_init_all
: Calls thestdio_init_all
function to initialize all standard I/O channels.LDR R0, =helloworld
: Loads the address of the “helloworld” string into R0.ADD R7, R7, #1
: Increments the counter by 1.MOV R1, R7
: Moves the counter value to R1, which is used as the second argument toprintf
.BL printf
: Calls theprintf
function to print the string and counter value.B loop
: Creates an infinite loop.
Building and Running the Program
- Write the Assembly Code: Save the above code to a file named
hello_world.s
. - Compile the Code: Use
arm-none-eabi-gcc
to compile the assembly code. Example command:
arm-none-eabi-gcc -o hello_world.elf hello_world.s -nostartfiles -mcpu=cortex-m0plus -mthumb -T pico-sdk/src/rp2_common/pico_standard_link/memmap_default.ld
- Convert to UF2: Use the
elf2uf2
utility to convert the compiled ELF file to the UF2 format.
elf2uf2 hello_world.elf hello_world.uf2
- Upload to RP2040: Connect the RP2040 board to your computer in BOOTSEL mode and copy the
hello_world.uf2
file to the RPI-RP2 drive. - View the Output: Open your serial terminal program, connect to the RP2040’s serial port, and observe the “Hello World” messages with incrementing numbers.
Conclusion
This example provides a hands-on experience with assembly language programming on the RP2040 microcontroller. It lays the foundation for understanding low-level hardware interactions and prepares students for more complex embedded programming challenges.
RP2040 C/C++ “Hello World” Example
Setting Up the C/C++ SDK
To set up your environment for C/C++ development with the RP2040, follow these steps:
-
Update your Raspberry Pi OS:
sudo apt update sudo apt full-upgrade
Clone the Pico SDK and examples: git clone https://github.com/raspberrypi/pico-sdk.git cd pico-sdk git submodule update –init
Return to your project directory and clone the examples: cd .. git clone https://github.com/raspberrypi/pico-examples.git
Writing Your First Program
Create a new file named hello_world.c in your project directory and open it in a text editor. Add the following code to create a simple program that prints “Hello, world!” to the standard output.
#include <stdio.h> #include “pico/stdlib.h”
int main() { stdio_init_all(); printf(“Hello, world!\n”); while (1); }
This program initializes the standard input/output systems of the RP2040 and prints “Hello, world!” to the console. It then enters an infinite loop, effectively making the message print once.
Compiling and Running the Program
To compile and run your “Hello World” program on the RP2040, follow these steps:
-
Navigate to your project directory and create a
CMakeLists.txt
file with the following content:cmake_minimum_required(VERSION 3.13) include(pico_sdk_import.cmake) project(hello_world_project) pico_sdk_init() add_executable(hello_world hello_world.c ) target_link_libraries(hello_world pico_stdlib) pico_add_extra_outputs(hello_world)
This
CMakeLists.txt
file configures your project to build with the Pico SDK. -
Create a build directory and navigate into it:
mkdir build cd build
-
Generate the build files with CMake. Make sure to point
PICO_SDK_PATH
to the location of the Pico SDK:export PICO_SDK_PATH=../../pico-sdk cmake ..
This step prepares your project for building by generating necessary files and configurations.
Build the Project
Execute the following command in your build directory to compile the project:
make
After compiling, you will find hello_world.uf2 in the build directory. Connect your RP2040 board to your computer while holding the BOOTSEL button. This mounts the RP2040 as a Mass Storage Device.
Drag and drop the hello_world.uf2 file onto the mounted device. Your RP2040 will reboot, and the program will run, printing “Hello, world!” to the serial console.
Viewing the Output
To see the “Hello, world!” message, you need to open a serial terminal to the RP2040’s serial port at 115200 baud rate.
minicom -b 115200 -o -D /dev/ttyACM0
Conclusion
This guide has shown you how to set up the Raspberry Pi Pico C/C++ SDK, write a simple “Hello World” program, and run it on your RP2040 microcontroller.
RP2040 MicroPython “Hello World” Example
Setting Up MicroPython
Before you begin, ensure that MicroPython firmware is installed on your RP2040 device.
Writing the Program
After installing MicroPython, your RP2040 is ready to run Python code. You can write your “Hello World” program using any text editor, but it’s easier to use Thonny IDE, which provides direct support for MicroPython devices.
Open Thonny IDE and select Run > Select Interpreter from the menu. Choose MicroPython (Raspberry Pi Pico).
In the editor, type the following Python code:
print(“Hello, world!”)
Blinkly in C
This simple C program demonstrates how to blink an LED connected to GPIO 25 on the RP2040 microcontroller using the Pico C/C++ SDK.
#include "pico/stdlib.h"
// The LED is connected to GPIO 25
#define LED_PIN 25
// Main (runs on core 0)
int main() {
// Initialize the LED pin
gpio_init(LED_PIN);
// Configure the LED pin as an output
gpio_set_dir(LED_PIN, GPIO_OUT);
// Loop
while (true) {
// Set high
gpio_put(LED_PIN, 1);
// Sleep
sleep_ms(250);
// Set low
gpio_put(LED_PIN, 0);
// Sleep
sleep_ms(250);
}
}
Code Example Python RGB with FUN
Below is a simple MicroPython script to cycle through colors on the built-in RGB LED:
from ws2812 import WS2812
import utime
import machine
# Set and turn on the power pin for the NeoPixel LED
power = machine.Pin(11, machine.Pin.OUT)
power.value(1)
# Create a dictionary with RGB values and names of colors
COLORS = {
(0, 0, 0): "BLACK",
(255, 0, 0): "RED",
(255, 150, 0): "YELLOW",
(0, 255, 0): "GREEN",
(0, 255, 255): "CYAN",
(0, 0, 255): "BLUE",
(180, 0, 255): "PURPLE",
(255, 255, 255): "WHITE"
}
# Create a WS2812 LED strip object (pin 12, 1 LED)
led = WS2812(12, 1)
# Continuously show all colors in sequence in an infinite loop
while True:
for color, name in COLORS.items():
print(name) # Printing the color name to the serial port
led.pixels_fill(color) # Fill all LEDs with the specified color
led.pixels_show() # Apply the color change
utime.sleep(0.2) # A short delay between each color
Photo:
Video:
[Link to a video demonstration of the RGB LED cycling through colors.]
Prototype Sensor Testing Failin Time
In this phase of the project, I ventured into experimenting with sensors using the Raspberry Pi Pico alongside the TOGO project. My trials included working with the QRE113 sensor and the 74HC165 shift register. Admittedly, I can’t claim these experiments were entirely successful.
Neil’s advice to steer clear of breadboards was exemplified perfectly during this process. The challenges I encountered served as a practical lesson on the importance of understanding the hardware components and their interactions thoroughly before integrating them into a prototype.
Here are some visuals from the prototype sensor testing:
The outcomes of these trials, although not as successful as hoped, provided valuable insights into the practical aspects of sensor integration with microcontrollers. The experience underscored the complexities of hardware prototyping and the need for meticulous planning and execution.