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

Alt Text

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:

Alt Text

Alt Text

Controlling the RGB LED on Seeed Studio XIAO RP2040

Specifications:

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

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

Building and Running the Program

  1. Write the Assembly Code: Save the above code to a file named hello_world.s.
  2. 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

  1. Convert to UF2: Use the elf2uf2 utility to convert the compiled ELF file to the UF2 format.

elf2uf2 hello_world.elf hello_world.uf2

  1. 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.
  2. 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:

  1. 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:

  1. 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.

  2. Create a build directory and navigate into it:

    mkdir build
    cd build
    
  3. 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

Alt Text

Photo:

Alt Text Alt Text Alt Text Alt Text

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:

Prototype Testing - Setup 1 Prototype Testing - Setup 2

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.