Embedded Programming
March 4, 2024
Challenge
-
Group assignment:
- Browse through the datasheet for your microcontroller.π
- Compare the performance and development workflows for other architectures.
- Document your work to the group work page and reflect on your individual page what you learned.
-
Individual assignment:
- Write a program for a microcontroller development board to interact (with local input &/or output devices) and communicate (with remote wired or wireless devices).π€
Group Assignment:
As for this week assignment the task was theoretical, to read the Data sheet of some MCU in the LAB; I have chosen (Arduino UNO, ESP32, and Xiao RP2040), No clear reason for me why I have chooses them but I wanted to git deeper knowledge about them.
For more information about the assignment please refer to this LINK
Individual Assignment:
For this assignment I have decided to program my previously made board using (C Arduino) and (microPython).
—–> Lets Start Coding It Using (Arduino IDE) –> (C Arduino).
Note : For More Information on How to setup the Board and using it for the first time with (Arduino IDE) Please refer to this LINK
Arduino IDE (C-Arduino)
- I will start with a new sketch, as I will write the code from scratch.
- Then I will write what I have in my Board and each Pin associated to it.
- Now I will define all the pins so I can call them by name.
Note : It is not recommended to use define function –>AS (This can have some unwanted side effects though, if for example, a constant name that had been #defined is included in some other constant or variable name. In that case the text would be replaced by the #defined number (or text).) So to over come this use (const) instead
- Then I will Build my setup function by assigning the type of each pin I will deal with.
In my board there is 3 LED’s and 1 Button I can interact with.
So The LED’s are known as OUTPUT device so there pins are going to be set in OUTPUT Mode.
The Button is input device so I will set its pin as INPUT.
-
Now I can immediately use the Void Loop but I want to build functions and then call them from the void loop instead.
-
So I will build a function that turn on 2 LED’s and turn off the other on for half second and then turn of the 2 LED’s and turn On the other one for half second.
Then when I call this function in the Loop function the MCU will keep calling this function as long as the MCU is switched ON.
- Then we will choose the port and the MCU to then Upload the code.
Here we go the code works
My Code
/*
What we have in our Board
pin 26 --> LED1
Pin 0 --> LED2
pin 1 --> LED3
pin 27--> Button
Pin (1,2,3,4) Can Be used Externally.
*/
#define LED1 26 // We are telling the compiler to replace the name LED1 with 26 every time its used in the code.
#define LED2 0 // These lines are not going to be sent to the microcontroller so they are not going to take space within its memory the compiler will deal with them
#define LED3 1 // Its preferred not to use define statement because in some occasions it may interfere with other predefined by system so make sure to keep an eye on the define name.
#define Button 27 // Or you can use *const* function which is the recommended to be used.
void setup() {
// put your setup code here, to run once:
pinMode(LED1, OUTPUT); // Here we are telling the MCU how to deal with this pin {Whether INPUT or OUTPUT}
pinMode(LED2, OUTPUT); // So its a small function that decide to wait current from this pin or to give current.
pinMode(LED3, OUTPUT); // Simply we know that LEDs Take current to operate (OUTPUT devices) so I have implement there pins as OUTPUT.
pinMode(Button, INPUT); // Buttons are Input devices so The MCU is waiting for there state to make action accordingly.
}
/* Now let us think what we can do with these input and outputs we have -----?
Let me start with a very simple action and then I will start adding complexity.
This will be my actions for each stage in my code |<Q>|<W>|<S>|
1- My code will start by blinking 2 LEDs and turn of the third and then turn on the third and switch off the others.
*/
void loop() {
// put your main code here, to run repeatedly:
Blink(); // Calling the function To be executed.
}
void Blink() { // This function will blink 2 LEDs and turn off the third every half second.
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, HIGH);
delay(500);
digitalWrite(LED1, LOW);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, LOW);
delay(500);
}
Let’s Use the Button
I will use the button to blink the LED’s in a pattern when its pushed and nothing when its not pushed.
-
I will do as what I have done previously I will create function for when the push button is pushed and another when its not and I will call them from void Loop.
-
In void Loop I will check the state of the Button whether its Pushed or not using
digitalRead()
function and save the state inside an Integer to be used insideIF()
Statement.
- Then I will create the two Functions.
These functions are not necessary I can write the code directly inside the VOID LOOP but I want to keep my entire code lately so I can comment only the function.
- Then we are ready to upload the code.
Here we GO
My Code
/*
What we have in our Board
pin 26 --> LED1
Pin 0 --> LED2
pin 1 --> LED3
pin 27--> Button
Pin (1,2,3,4) Can Be used Externally.
*/
#define LED1 26 // We are telling the compiler to replace the name LED1 with 26 every time its used in the code.
#define LED2 0 // These lines are not going to be sent to the microcontroller so they are not going to take space within its memory the compiler will deal with them
#define LED3 1 // Its preferred not to use define statement because in some occasions it may interfere with other predefined by system so make sure to keep an eye on the define name.
#define Button 27 // Or you can use *const* function which is the recommended to be used.
void setup() {
// put your setup code here, to run once:
pinMode(LED1, OUTPUT); // Here we are telling the MCU how to deal with this pin {Whether INPUT or OUTPUT}
pinMode(LED2, OUTPUT); // So its a small function that decide to wait current from this pin or to give current.
pinMode(LED3, OUTPUT); // Simply we know that LED's Take current to operate (OUTPUT devices) so I have implement there pins as OUTPUT.
pinMode(Button, INPUT); // Buttons are Input devices so The MCU is waiting for there state to make action accordingly.
}
/* Now let us think what we can do with these input and outputs we have -----?
Let me start with a very simple action and then I will start adding complexity.
This will be my actions for each stage in my code |<Q>|<W>|<S>|
1- My code will start by blinking 2 LED's and turn of the third and then turn on the third and switch off the others.
2- Lets Use the Button to blink the LED's in a pattern.
*/
void loop() {
// put your main code here, to run repeatedly:
// Blink(); // Calling the function To be executed.
int sb = digitalRead(Button);
if (sb == 1) {
ButtonBlink();
}else if (sb == 0) {ButtonBlink0();}
}
/*void Blink() { // This function will blink 2 LED's and turn off the third every half second.
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, HIGH);
delay(500);
digitalWrite(LED1, LOW);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, LOW);
delay(500);
}*/
void ButtonBlink (){
digitalWrite(LED2, HIGH);
digitalWrite(LED3,LOW);
delay(200);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,LOW);
delay(200);
digitalWrite(LED3,HIGH);
digitalWrite(LED1,LOW);
delay(200);
}
void ButtonBlink0(){
digitalWrite(LED1,LOW);
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);
}
Let’s use the serial Monitor
I will use the serial monitor to fetch data to the RP2040 and then according to the input I will change the NEOPIXEL LED color.
-
I will start by trying to read from the serial monitor and then I will go for the LED Code.
-
Here I will use a new Sketch.
-
Then I will create a String (Color) to store the data in it from the serial monitor.
-
After this I will Add
Serial.begin (9600)
to set the bud rate to 9600 Then I will add a delay of 1 second to make sure the serial is working as I want –> All of this is in the Void Setup.
- Then In the Loop I will check if the serial is available to then wait for the user input using
Serial.readStringUntil('\n')
this means wait until new line which is Enter –> (\n).
Important Note : Use Single Notation (’’) Not Double ("") otherwise it will return an Error.
- Then I will Print the User input.
-
Now we are ready to upload the code.
-
After the code is uploaded open the Serial Monitor.
- Now lets Check.
Great Documentation To Read LINK
My Code
String color;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available()){
color = Serial.readStringUntil('\n');
Serial.println("You choosed the Color : " + color);
}
}
Neopixel
Now Let’s make the RGB LED on the Xiao works according to the user input.
- First of all we need to install the NEOpixel library from the Library Manager.
- Then we need to download the Adafruit NEOpixel Library.
-
Now we need to include the library by using
#include <Adafruit_NeoPixel.h>
, This Documentation Is very useful. -
Then we have to st the constructor by calling
Adafruit_NeoPixel "Name" (#of RGB , PIN , Type = NEO_GRB+NEO_KHZ800)
For me this constructor is declared in the global:
Adafruit_NeoPixel zaid (1,12,NEO_GRB+NEO_KHZ800);
- Then I will Initialize the Neo Class by calling the class
name.begin()
in the Void Setup.
For me its
zaid.begin()
- I need Also to make the output pin 11 HIGH in the void setup for the RGB to work.
-
Then In the Void Loop I will make sure to start with a cleared RGB using
name.clear()
-
Now within my Serial.available statement I will have my pixel color function.
-
In addition I have to use
name.show ()
In order to output the color on the RGB.
- Now lets Upload and test.
Here we are
My Code
#include <Adafruit_NeoPixel.h> // Header File
String color; // To stor the serial input
Adafruit_NeoPixel zaid(1,12,NEO_GRB+NEO_KHZ800); // My pixel class
void setup() {
// put your setup code here, to run once:
zaid.begin(); // Initallise the Pixel class
Serial.begin(9600); // declare the serial bud rate
pinMode(11,OUTPUT);
digitalWrite(11,HIGH);
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
zaid.clear();// clear the RGB class
zaid.setBrightness(255);// Set the Brightness of the RGB
if (Serial.available()){
color = Serial.readStringUntil('\n'); //wait for serial input followed by enter
Serial.println("You choosed the Color : " + color);
if (color == "Green" or color == "green"){
zaid.setPixelColor(0,0,255,0);// Set the RGB color
zaid.show();// SHow the Color on the RGB
}else if (color == "red" or color == "RED"){
zaid.setPixelColor(0,255,0,0);
zaid.show();
}else if (color == "blue" or color == "Blue"){
zaid.setPixelColor(0,0,0,255);
zaid.show();
}else if (color == "OFF" or color == "off" or color == "Off" or color == "Blank" or color == "blank" or color == "Nothing" or color =="nothing"){
zaid.setPixelColor(0,0,0,0);
zaid.show();
}else if (color == "white" or color == "White"){
zaid.setPixelColor(0,255,255,255);
zaid.show();
}
}}
Let’s use a Potentiometer
I’ll be using a potentiometer in order to change the RGB color and I will use the LED connected to pin 26 as a light sensor
Using the LED as a light sensor is something new to me I would like to try it.
-
For the potentiometer I will connect it to Analog 2 (A2) which is going to control the red color.
-
The Button will control the green color through generating random number between (20 and 200).
-
The LED connected to pin 26 or analog 0 will control the color BLUE.
-
Lets connect the potentiometer.
Now let’s build the Code
-
The code is very simple to build as I’m going to define my pins globally and some of my variables also.
-
I will define my NEOPixel constructor also globally.
- Then in the setup function I will initialize the serial monitor and the PINMode for each pin.
-
Then In the Loop function I will read the analog input coming from both the LED and the potentiometer and then map them to be between 0 and 255 as a value.
-
In addition to this I will check the state of the button o when it pressed a random number will be generated between 20 and 200.
-
Then each value is going to be reflected as a color in the RGB.
- The LED will reflect on the Blue LED.
- The Button will reflect on the Green LED.
- The Potentiometer will reflect on the Red LED.
-
At the end I will Print the values on the serial monitor as a check for me.
Here we are it works π
- LED values on the screen.
- All together.
My Code
#include <Adafruit_NeoPixel.h>
#define P_meter A2 // Analog pin A2 or pin 28 both are the same.
#define LED1 26
#define Button 27
Adafruit_NeoPixel Indicator (1,12,NEO_GRB+NEO_KHZ800);
int D ; // Variable to store the data coming from the potentiometer.
int gcolor=255;
void setup() {
// put your setup code here, to run once:
Indicator.begin(); // Initializing the NeoPixel class
Serial.begin(9600);
delay(100);
pinMode(11,OUTPUT);
pinMode(Button,INPUT);
pinMode(P_meter,INPUT); // Analog pin A2 now accept data
pinMode(LED1,INPUT); // making the LED pin as INPUT PIN
delay(100);
digitalWrite(11,HIGH); // power pin for the RGB
delay(100);
}
void loop() {
// put your main code here, to run repeatedly:
int bcolor = analogRead(LED1); // Reading the current generated from the LED -_-
bcolor=map(bcolor,0,1024,0,255); // mapping the values of the Bcolor to be between 0 and 255 so I can use them in the pixel set color.
D = analogRead(P_meter); // Storing the data of the potentiometer inside the variable
delay(10); //time for the MCU to finish
if (digitalRead(Button)==1){ // Read the state of the push button
gcolor = random(20,200); // generating random number between 20 and 200 when the push button is pressed.
}
int rcolor = map(D,0,1024,0,255);
Indicator.clear(); // Clearing the RGB
Indicator.setBrightness(255); // Set the brightness of the RGB to 100%
Indicator.setPixelColor(0,rcolor,0,bcolor); // Setting the color of the RGB
Indicator.show(); // Output the color on the RGB.
/* Now lets Print the data on the serial monitor.*/
//Serial.print("G=");
//Serial.println(gcolor);
Serial.print("B=");
Serial.println(bcolor);
//Serial.print("R=");
// Serial.println(rcolor);
delay(1000);
}
MU IDE
In this section I will try to use the MU IDE to code the Xiao RP2040, The code is gonna be simple (Blink the LED).
-
First Of all I have to download the MU IDE from This LINK.
-
Then I will be using CircuitPython to code so I have to download a Firmware.
-
Then I will connect the Board to the computer and upload the firmware to it.
-
Then I will Use Seed Documentation to code my first try.
-
I’ll Use the same code they have provided to test.
-
Before this I have to set the mode in MU IDE to CircuitPython.
- Then let’s paste the code.
-
Here the code will blink the User LED every half second.
-
Then Save the code and make sure to name it code.py so the MCU can Read IT otherwise it will neglect it.
Here we go it works
My Code
"""Example for Pico. Blinks the built-in LED."""
import time
import board
import digitalio
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
Now let me try Blinking the LED’s On the Board
- At the beginning I will define the LED’s pins and their mode (Direction as INPUT or OUTPUT).
- Then at the while loop I will Define the value of each LED variable (For me its digital so its whether true(High) or False(LOW)).
Here we Are The code Works
My Code
# Write your code here :-)
"""Example for Pico. Blinks the built-in LED."""
import time
import board
import digitalio
led = digitalio.DigitalInOut(board.D0)
led1 = digitalio.DigitalInOut(board.D6)
led2 = digitalio.DigitalInOut(board.D7)
led.direction = digitalio.Direction.OUTPUT
led1.direction = digitalio.Direction.OUTPUT
led2.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
led2.value = False
time.sleep(0.5)
led.value = False
led1.value = True
time.sleep(0.5)
led1.value = False
led2.value = True
time.sleep(0.75)
My Reflection
Both IDE are great and very easy to use but I have been used to ARDUINO IDE from my early stages of coding and I like always to write codes in C specially when it comes to hardware as it give more flexibility and more powerful. But When it comes to Python I have never used it to code hardware this was my first time and it looks easy and very clear when it comes to syntax but It looks awkward to code without semicolons. However I can’t judge MU from first use but I’m (C-language) lover, But in the future I think I will consider more python as it looks promising in terms of clarity and more user friendly syntax.