Week 4. Embedded programming¶
Group Assignment¶
This week we completed a group assignment related to microcontroller programming. The goal of the week was to understand how a microcontroller works, how to write and upload a program, and how to study the operation of input and output pins.
We explored different types of microcontrollers, specifically Arduino and RP2040, along with their main features. During the group work, we conducted an experiment using the RP2040 microcontroller to study the fundamental principles of its programming. We wrote the required code, uploaded it to the device, and tested the built-in RGB LED by producing blinking lights in different colors.
Throughout this process, we became familiar with program structure, the uploading workflow, and the practical use of microcontroller input/output pins, which helped us better understand how microcontrollers operate.
The full documentation and results of the group assignment can be viewed at the following link: Group Assignment Link
Individual Assignment¶
Working with the Seeed Studio RP2040 board¶
This week, as part of the individual assignment, I worked with the Seeed Studio XIAO RP2040 microcontroller.
Installing the Arduino IDE¶
First, I downloaded and installed the Arduino IDE software. Then, I added RP2040 board support to the Arduino IDE using the Board Manager. For this, I added the following link in the Additional Boards Manager URLs field in Preferences:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
After that, I downloaded and installed the RP2040 package from the Board Manager.
How the Arduino IDE works¶
It is built to operate across various operating systems.
As part of this tutorial, I experimented with the RP2040. When the program is opened, it includes two main functions։ void setup() and void loop().
The setup() function runs only once at the beginning of the program and is used for initialization (such as setting pin modes or starting devices).
The loop() function runs continuously in a repeating cycle and contains the main logic of the program.
#define - The word pin1 is replaced with 14.
It does not use memory (RAM), because no variable is created, and it is a higher-level construct.
int - This variable stores an integer value. It is used for pins or for calculations.
float - This variable is used to store decimal (floating-point) numbers.
char = "Hello Gyumri" - This variable stores a string of characters (text).
A single char can store only one character (e.g., ‘A’).
To store a word or sentence, you need a character array
(char[]).
string = "Hello Gyumri"; - string is more convenient for working with text than char[] because it has built-in functions (such as concatenation, length calculation, etc.).
bool - This variable can have two values: true or false.
It is used in conditional statements.
const int - is useful for fixed values, and the value cannot be changed during the program.
pinMode(17, OUTPUT); - pinMode sets a pin as input or output.
The modes OUTPUT and INPUT allow controlling or reading the PIN, and you can use HIGH or LOW signals.
Serial.begin(9600) - This command initializes serial communication at a baud rate of 9600 bits per second, allowing the microcontroller to send and receive data through the serial port.
These fundamentals are the essential knowledge needed when writing code for Arduino or any microcontroller. They help properly set up the program, create continuously running loops, use different variable types, control input and output signals, and communicate with external devices. This knowledge forms the foundation for developing more complex, interactive, and efficient projects.
Blinking the Built-in LED (RP2040)¶
The Arduino IDE provides built-in examples that help you understand how the RP2040 board works. One of the simplest examples is the Blink program.
To open it, go to: File → Examples → 01.Basics → Blink
After opening it, you will see the following code:
// 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
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off
delay(1000); // wait for a second
}
The Arduino IDE includes a Verify function that checks your code for errors.
For example, if you remove a semicolon ;, the IDE will show where the error is so you can fix it.
If there are no errors, Verify will also display:
- how much memory your program uses
- how much memory is available
Next, connect your RP2040 board (e.g., Raspberry Pi Pico) to your computer using a USB cable.
If you get an error during upload, it is usually because the correct port is not selected.
Go to: Tools → Port → select the correct port
After selecting the port, click Upload to transfer the program to the board.
Once the program is successfully uploaded, the built-in LED on the RP2040 will start blinking:
- ON for 1 second
- OFF for 1 second
RGB LED Fade In / Fade Out Test¶
As a continuation of my experiments, I implemented a more dynamic lighting behavior by creating a fade-in and fade-out effect using the onboard RGB LED of the Seeed Studio XIAO RP2040.
In this test, instead of simply turning the LED on and off or switching between colors, I programmed the LED to gradually increase and decrease its brightness. This created a smooth transition effect, often referred to as a “breathing” light.
To achieve this, I used a loop to control the intensity of the red color channel, varying its value from 0 (off) to 255 (maximum brightness), and then back from 255 to 0.
As in the previous examples, I first enabled the power pin and initialized the NeoPixel library in the setup() function.
In the loop() function, I implemented two for loops:
- one for gradually increasing brightness (fade-in)
- one for gradually decreasing brightness (fade-out)
Fade Control Code¶
Below is the code used to create the fade-in and fade-out effect:
#include <Adafruit_NeoPixel.h>
int Power = 11;
int PIN = 12;
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
pinMode(Power, OUTPUT);
digitalWrite(Power, HIGH);
}
void loop() {
// Fade in Red
for(int i = 0; i <= 255; i++) {
pixels.setPixelColor(0, pixels.Color(i, 0, 0));
pixels.show();
delay(10); // controls the speed
}
delay(500);
// Fade out Red
for(int i = 255; i >= 0; i--) {
pixels.setPixelColor(0, pixels.Color(i, 0, 0));
pixels.show();
delay(10);
}
delay(500);
}
After uploading the program, the onboard RGB LED displayed a smooth transition effect: the red light gradually increased in brightness, reached its maximum intensity, and then slowly dimmed back to off. This cycle repeated continuously.
Extending Analog Input (Potentiometer)¶
In this experiment, I extended the functionality of the Seeed Studio XIAO RP2040 microcontroller by adding an analog input using a potentiometer.
Circuit Connection¶
The potentiometer was connected as a voltage divider in the following way:
One end → 3.3V Other end → GND Middle pin (wiper) → A0 (Analog input)
With this setup, rotating the potentiometer changes the voltage at the A0 pin from 0V to 3.3V.
Voltage Divider Explanation¶
The potentiometer works as a voltage divider. It can be represented as two resistors connected in series, where the middle point (wiper) is connected to the A0 pin.
The voltage divider formula is:
Vout=Vin⋅R1+R2R1
In this case:
- The total resistance is constant (e.g., 10kΩ)
- One part is R₁ = X
- The other part is R₂ = 10 - X
- Input voltage is 3.3V
Therefore:
Vpin=3.3V⋅10X
This means that as the potentiometer is rotated, the ratio between the resistances changes, and the voltage at the A0 pin varies from 0V to 3.3V.
Reading Analog Values¶
I wrote a simple program in the Arduino IDE to read the value from pin A0 and display it in the Serial Monitor:
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(100);
}
analogRead(A0)→ reads the input voltageSerial.println()→ prints the value
ADC (Analog to Digital Conversion)¶
The RP2040 microcontroller converts the analog voltage into a digital value using an ADC.
In the Arduino environment (10-bit resolution):
- 0V → 0
- 3.3V → 1023
So:
- Voltage range: 0 – 3.3V
- Digital range: 0 – 1023
While rotating the potentiometer:
- The values change smoothly
- The Serial Monitor displays values from 0 to 1023
This confirms that the analog input is working correctly.
Interfacing DHT11 with Seeed Studio XIAO RP2040¶
I conducted an experiment using the DHT11 sensor to measure environmental temperature and humidity. The sensor was connected to the Seeed Studio XIAO RP2040 microcontroller. During the setup, I ensured proper power supply to the sensor and correctly connected the data pin to the appropriate pin of the microcontroller.
For programming, I used suitable libraries that allow easy reading of the data transmitted by the sensor. During operation, the microcontroller periodically receives data from the sensor and converts it into readable values in terms of temperature (°C) and relative humidity (%).
The obtained data can be displayed on the serial monitor or used in other projects. As a result of this experiment, it was confirmed that the DHT11 sensor can effectively work with the Seeed Studio XIAO RP2040 microcontroller and provide the required measurements.
#include "DHT.h"
#define DHTPIN 27
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
dht.begin();
}
void loop() {
float temp = dht.readTemperature();
float hum = dht.readHumidity();
if (isnan(temp) || isnan(hum)) {
Serial.println("Error reading sensor");
return;
}
Serial.print("Temp: ");
Serial.print(temp);
Serial.print(" °C ");
Serial.print("Humidity: ");
Serial.print(hum);
Serial.println(" %");
delay(2000);
}
In the software part, I used the DHT.h library to read data from the DHT11 sensor. I defined the sensor pin and initialized it to work with the Seeed Studio XIAO RP2040 microcontroller.
In the main loop, the temperature and humidity values are read, and if the data is valid, they are displayed on the serial monitor. The program runs periodically, obtaining new data every 2 seconds.
Conclusion¶
This week, I learned the fundamentals of embedded programming by working with the Seeed Studio XIAO RP2040 microcontroller. I gained experience in writing, verifying, and uploading programs using the Arduino IDE, and I worked with digital outputs by controlling LEDs and creating simple lighting effects.
By using a potentiometer, I also understood how analog inputs work, including the concept of a voltage divider and how the ADC converts analog voltage into digital values. Additionally, I worked with the DHT11 to read environmental temperature and humidity. I learned how to interface the sensor with the microcontroller, read its data using appropriate libraries, and display the measurements on the serial monitor.
Overall, this week helped me understand how microcontrollers read inputs and control outputs in real-world embedded systems, including both analog sensors and digital sensors like the DHT11.