4. Embedded Programming¶
This week was all about embedded programming, which basically means making tiny computers (microcontrollers) do things.
Part 1:Understanding the Basics¶
What is Embedded Programming?¶
Embedded programming is writing code for microcontrollers—small, self-contained computers designed to perform specific tasks. Unlike laptops or desktops, which run multiple applications, a microcontroller is built to do one thing well—whether that’s controlling an LED, reading a sensor, or running a motor.
Microcontroller vs. Microprocessor¶
- Microcontroller (MCU): Microcontroller is like a small chip that works like a tiny computer. It has everything it needs—brain (CPU), memory, and connections for buttons, sensors, or screens—all in one place. t is used in simple devices like remote controls, washing machines, and automatic doors, where it does one job over and over. Since it has everything built in, it is small, cheap, and uses less power.
- Microprocessor (MPU): A microprocessor is just the brain and needs extra parts like memory and storage to work. It is found in bigger devices like computers, smartphones, and gaming consoles, where it can run many programs at the same time. Microprocessors are more powerful than microcontrollers, but they need more space, power, and extra parts to function.
Part 2: Group Assignment¶
For the group project me and Samrudhi Rovalekar worked together. We did a comparison of Toolchains and Development Workflows for ATmega and RP2040 ATmega (used in AVR microcontrollers) and RP2040 (used in Raspberry Pi Pico) are two popular embedded architectures. Below is a comparative demonstration of their toolchains and development workflows.
RP2040¶
The RP2040 is a 32-bit microcontroller used in the Raspberry Pi Pico.
Toolchain
Editor (To write the code):
- You can use VS Code, Arduino IDE, Thonny (for MicroPython), or PlatformIO.
- Programming is usually done in C, C++, or MicroPython.
Compiler (To convert human-readable code into machine code):
- The ARM GCC (GNU Compiler Collection for ARM Cortex-M) is used to compile C/C++ code.
What is ARM? ARM (Advanced RISC Machine) is a type of computer processor that is designed to be fast, energy-efficient, and small. It is widely used in smartphones, tablets, microcontrollers (like RP2040), and even laptops.
Linker (To connect different parts of the program):
- This arranges the compiled code properly for execution
Flasher/Programmer (To upload the code to the microcontroller):
- UF2 Bootloader: If using a Raspberry Pi Pico, you simply drag and drop a .uf2 file onto the Pico's USB storage.
- Picotool: A command-line utility to manage binaries and flash the RP2040.
- SWD Debugger (Optional): For advanced flashing, use OpenOCD with a hardware debugger (Picoprobe, J-Link, or Raspberry Pi as an SWD host).
Debugger (To check and fix errors in the program):
- GDB + OpenOCD: Allows debugging with breakpoints, memory inspection, and step-through execution.
- Printf Debugging: Serial output via USB (or UART) can be used for debugging.
Development Workflow
Step 1: Setup Environment
- Install Raspberry Pi Pico SDK or use Arduino IDE/MicroPython
- Choose programming language: C/C++, MicroPython, CircuitPython
- Set up development tools: Thonny, VS Code, or command-line toolchain
Step 2: Write Code
- Write program using CMake (for C/C++) or Python
- Define GPIO, peripherals, and logic
Step 3: Compile Code
- If using MicroPython: No compilation needed (upload .py script)
- If using C/C++ SDK: Compile using CMake to generate .uf2 file
Step 4: Upload Code
- Hold BOOTSEL button on RP2040 and connect to PC via USB
- Drag and drop the .uf2 file into the RP2040 storage
- If using MicroPython: Upload script via Thonny or rshell
Step 5: Debug & Test
- Use Serial Monitor (UART) for debugging
- Check outputs using LEDs, oscilloscope, or print statements
Step 6: Optimize & Finalize
- Optimize power consumption (sleep modes, low-power optimizations)
- Test performance with different clock speeds and peripherals
- Deploy final firmware and protect memory (if needed)
ATmega328¶
Toolchain
The ATmega328 is an 8-bit microcontroller commonly used in Arduino boards (like the Arduino Uno). To develop software for this microcontroller.
Editor (To write the code):
You can use Arduino IDE, PlatformIO, or a general editor like VS Code. Programming is usually done in C or C++. Compiler (To convert human-readable code into machine code)
Compiler (To convert human-readable code into machine code)
The AVR-GCC (GNU Compiler Collection for AVR) is used to compile the code.
Note: AVR stands for Advanced Virtual RISC. It is developed by Atmel (now part of Microchip Technology). These microcontrollers are designed with a simple and efficient RISC (Reduced Instruction Set Computing) architecture, allowing them to execute commands quickly and consume less power.
Linker (To connect different parts of the program)
This arranges the compiled code properly for execution.
Flasher/Programmer (To upload the code to the microcontroller):
The AVRDUDE (AVR Downloader/Uploader) is used to transfer the compiled code (.hex file) into the ATmega328 chip using an ISP (In-System Programmer) or USB-to-serial converter (like an Arduino bootloader).
Debugger (To check and fix errors in the program)
The SimAVR simulator or hardware debuggers like Atmel ICE can be used for debugging.
Development Workflow
Step 1: Setup Environment
- Install Arduino IDE or AVR toolchain (AVR-GCC, AVRDUDE)
- Choose programming method: USB (Arduino) or ISP (Bare ATmega328)
- Connect hardware (Arduino board or ATmega328 with ISP programmer)
Step 2: Write Code
- Write program in C/C++ (Arduino IDE or raw AVR)
- Define pin configurations, logic, and functions
Step 3: Compile Code
- If using Arduino IDE: Click Upload (compiles automatically)
- If using AVR-GCC: Compile manually to generate .hex file
Step 4: Upload Code
- If using Arduino IDE: Upload via USB
- If using ISP Programmer: Use AVRDUDE to flash the .hex file
Step 5: Debug & Test
- Use Serial Monitor (UART) for debugging
- Check outputs using LEDs or external debugging tools
Step 6: Optimize & Finalize
- Optimize power consumption and memory usage
- Burn bootloader (if required)
- Lock fuses to prevent accidental overwriting
Comparison with Other Microcontrollers¶
Feature | RP2040 (Raspberry Pi Pico) | ATmega328 (Arduino Uno) | ESP32 |
---|---|---|---|
Bit Width | 32-bit | 8-bit | 32-bit |
Clock Speed | Up to 133 MHz | Up to 20 MHz | Up to 240 MHz |
Power Usage | Low | Very low | Medium |
Ease of Use | Moderate | Easy | Moderate |
Programming Tools | ARM GCC, CMake, UF2 | AVR-GCC, Arduino IDE | ESP-IDF, Arduino |
Part 3: Datasheet¶
RP2040¶
Reference to the official RP2040 datasheet: DATASHEETS.RASPBERRYPI.
The RP2040 is a small but powerful microcontroller (a tiny computer chip) made by Raspberry Pi. It is used in electronic projects like robots, sensors, and smart gadgets.
Why RP2040 named chip
- RP - Made by Raspberry Pi
- 2 - Number of processor cores
- 0 - Uses Cortex-M0+ core
- 4 - The amount of RAM
- 0 - Storage capacity
The chip
The RP2040 microcontroller has different components working together inside the chip. Below is a simple breakdown of how it functions:
- Dual-Core Processor (Brain of the Chip): Two ARM Cortex-M0+ cores run tasks at up to 133 MHz.
- Memory (Short-Term Storage): 264 KB SRAM (temporary storage) + External Flash Memory (stores programs).
- GPIO (Input/Output Pins) : It has 30 pins
- Peripherals (Built-in Features): Built-in I2C, SPI, UART, PWM, USB for communication.
- PIO (Programmable I/O) – The Special Feature! : Special hardware for custom functions like LED strips and new protocols.
Seeed Arduino Xiao 2040¶
The Seeed Studio XIAO RP2040 is a tiny yet powerful development board based on the RP2040 microcontroller. It’s designed for compact, low-power, and high-performance projects. I explored the Seeed Studio XIAO RP2040 page to understand the RP2040 microcontroller betterand also looked into Andrian Torres Fab Lab documentation for additional details
Key Features
- Processor: Dual-core ARM Cortex-M0+, running up to 133 MHz
- Memory: 264 KB SRAM and 2 MB onboard Flash for storing programs
- GPIO Pins: 14 pins (supports I2C, UART, SPI, PWM, and analog input)
- USB Type-C: For power and programming
- Compatibility: Works with Arduino, MicroPython, and CircuitPython
Below are the front and back images of the Seeed Studio XIAO RP2040, showcasing its pin layout and components:
- Power Supply: 5V, 3V and GND
- Digital GPIO Pins: 0, 1, 2, 3, 4, 6, 7, 26, 27, 28, 29
- Analog GPIO Pins: 26, 27, 28, 2
- LED Indicators: GPIO 16 (Green), GPIO 17 (Red), GPIO 25 (Blue)
- I2C Communication: GPIO 6 (SDA: Data Line), GPIO 7 (SCL: Clock Line)
- Power: GPIO 11
- LED Control: GPIO 12
Quentorres Board¶
The Quentorres Board is a compact and versatile microcontroller development board designed for various electronics and IoT projects. It was first created during the 2024 Instructors Bootcamp in León by Quentin Bolsée and later redesigned by Adrián Torres.
Below is the pinout diagram of the Quentorres Board, showing the available power, GPIO, analog, and communication pins. This helps in understanding how to connect sensors, LEDs, and other components easily
The image below shows the schematic diagram of the Quentorres board which is designed around the Seeed Studio XIAO RP2040 microcontroller. I referred to this schematic while simulating the XIAO Seeed Studio.
Part 4: RP2040 on Arduino IDE¶
I referred to Adrian Torres amazing documentation page for my reference.
Programming the microcontroller development board¶
Step 1: Open the Arduino programme and add the Ardino board. Go to File > Preferences > Add URL. Add the URL given on Adrians doc. URL link:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
Step 2: Install the library by downloading the Pico Board in the Board Manager.
Step 3: Select the correct board
Step 4: Install the library for the RGB lights.
Step 5: Load the Blink programme. I took Neil’s code
Below is the video of my final operation
Errors encountered
One of the key mistakes I made was that I did not select the correct port, which led to issues in uploading the code initially. To solve it you need to go to Tools > Board Manager and check if the correct post is selected.
Connecting RP2040 onto the Quentorres board¶
I then soldered the components onto the Quentorres PCB.
Componenets required:
Printed circuit board (PCB) is a flat board made of a special material (usually fiberglass) that holds and connects electronic components like resistors, capacitors, and microchips. It has green solder mask with white silkscreen markings that indicate where components will be placed.
Soldering material includes a spool of solder wire and flux, which helps in making strong electrical connections.
Soldering station includes a power supply unit and a soldering iron which are the necessary tools used for soldering.
I started of by positioning and surface mountiing the XIAO-RP2040 on the PCB and by using tweezer to hold it in place and applying solder carefully to secure it.
After partially solderring it I used multimeter to check if the connection is correct.
My connection wasn't working so I examined the board under a digital microscope to look for any solder bridges or cold joints.
Soldered the RP2040 on the Quintoress Board.
After that I soldered the remaing componenets i.e the led, resistors push button.
Final assembly
Part 5: Wokwi¶
I had previously worked on Tinker CAD so I thought of exploring Wokwi. Wokwi is a stimulator for electronic projects.It t lets you test Arduino, ESP32, and other microcontrollers without using real hardware. You can write and run code in your browser, connect virtual components like LEDs and buttons, and see how they work
To get familiar with Wokwi, I explored various feature projects and tried to understand how the code and simulation work. I then proceeded step by step to create my own simulation:
Trying out Simulation¶
Starting from Scratch: I created a new project on Wokwi.
Selecting ATtiny85: Chose ATtiny85 as my microcontroller
Adding Components: Wokwi provides options to add LEDs, breadboards, and other components. You can just drag and drop them!
Connecting Components: After selecting and placing the components, I connected them properly.
Adding Code: I then wrote the required blink code for the LED.
Running the Simulation: Finally, I ran the simulation to test the blinking LED.
Push Button (Input Device): Building on this I made another stimulation where along with LED I added a push button to understand how input devices interact with microcontrollers.
Stimulating both Input and output devices¶
I further experimented by simulating an ultrasonic sensor to test distance measurement. The ultrasonic sensor acted as the input device, detecting the distance. To enhance the simulation, I added a buzzer as an output device, which would activate when the object was within a certain range.
Part 6: ATtiny85 on Arduino IDE¶
With the understanding of the stimulation, I moved on to building an actual circuit using the ATtiny85. To program the ATtiny85, an Arduino board is used as an In-System Programmer (ISP).
What is ISP?
ISP (In-System Programming) is a method used to program or update a microcontroller or other programmable chips without removing them from the circuit. It allows you to load new software (firmware) onto the chip while it is still connected to the device, making updates and debugging easier.
Step 1: First, I needed to configure Arduino IDE to recognize and program the ATtiny85. This step allows Arduino IDE to download and install the necessary board definitions for the ATtiny85. File > Preferences > Additional Board Manager and paste the URL. I got this URL from Chatgpt
https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
Step 2: Now, I installed the ATtiny85 board package by David A. Mellis. To do this go to Tools > Board > Boards Manager. This adds support for ATtiny microcontrollers in Arduino IDE so we can select and program them.
Step 3: Under File > Examples > ArduinoISP, you will find an example sketch named ArduinoISP
What happens when you select "Arduino as ISP"?
It allows Arduino Uno to act as a bridge. So instead of uploading the sketch to the Arduino Uno itself, it redirects the compiled code through the Arduino Uno to the ATtiny85. After this make sure to check your port.
Step 4: Wiring ATtiny85 to Arduino Uno for Bootloading Connecting the ATtiny85 to the Arduino via SPI (MISO, MOSI, SCK) along with power (VCC, GND) and a reset pin. For which I used ChatGPT to understand the Pin configuration.
ChatGPT Prompt: Generate a code for blinking a led add a push button using attiny85 also give a schematic an dpin confirmation.
Pro Tip: If your ATtiny85 is running at 5V, connect VCC to 5V. If it's running at 3.3V, use a 3.3V power source instead.
Building this ATtiny85 LED circuit by using Aurdino as the ISP and power supplier.
Step 5: Select ATtiny85 Board and Settings
Now, we tell Arduino IDE which board we're programming.
Why? These settings ensure that the compiled code matches ATtiny85's architecture and runs correctly.
How to do it: * Go to Tools > Board and select ATtiny85. * Set the Clock to 8 MHz (Internal). * Set Processor to ATtiny85. * Under Programmer, select Arduino as ISP.
Note: The clock setting is crucial! ATtiny85 runs at 1 MHz by default, but for most projects, 8 MHz (internal) is better for speed and compatibility.
Step 6: Burn the boothloader
Before uploading code, we need to burn the bootloader.
Why? * This sets the correct clock speed (8 MHz). * Configures fuse bits, which control how the ATtiny85 operates. To do this Go to Tools > Burn Bootloader. Wait for a few seconds and Now, the ATtiny85 is ready for programming!
Step 7: Uploading Code to ATtiny85
Since the code is already tested on Wokwi, we now upload it to the ATtiny8
Step 8 : Removing ATtiny85 & Building the Breadboard Circuit
Now that the ATtiny85 is programmed, we remove it from the Arduino Uno setup and place it on a breadboard for real-world use.
ATtiny85 Pin | Component |
---|---|
VCC (Pin 8) | 3V–5V Power |
GND (Pin 4) | Ground |
PB0 (Pin 5) | LED (via 330Ω resistor to GND) |
Step 9: Powering the Circuit & Testing Then power the ATtiny85 using a 3V–5V battery or an external power source and observed to check if the code runs correctly.