Embedded Programming

The assignments for this week:

What is Embedded Programmimg?

Embedded programming refers to the process of writing software specifically designed to run on embedded systems, which are specialized computer systems built into larger devices or machinery to perform dedicated functions. These systems typically have limited resources, such as processing power, memory, and input/output capabilities, and are often designed to operate in real-time or under specific constraints. Embedded programming involves writing code in low-level languages like C or assembly language to interface directly with hardware components and control the behavior of the embedded system. It's commonly used in a wide range of applications, including consumer electronics, automotive systems, medical devices, industrial automation, and IoT (Internet of Things) devices.

About Quentorres Board

In week 4, the Quentorres board was introduced to us.The Quentorres,developed at the 2024 Instructors Bootcamp held in León is a board that can program the new AVR Series 1 and 2. It also has a button and an LED to learn to program in C, Rust, Go, Micropython etc. It has breakout pins to connect other external elements. It was created by Quentin Bolsée and redesigned by Adrián Torres.

About Seeed Arduino Xiao 2040

The Seeed Arduino XIAO 2040 is a compact development board based on the RP2040 microcontroller chip developed by Raspberry Pi. It is designed for embedded electronics projects and features a small form factor, making it suitable for applications where space is limited. The Seeeduino XIAO 2040 board includes various built-in peripherals, such as GPIO pins, analog inputs, PWM outputs, UART, SPI, I2C interfaces, and USB connectivity. It supports a wide range of development environments, including the Arduino IDE and CircuitPython, making it accessible to both beginners and experienced developers for prototyping and building projects involving sensors, actuators, displays, and more.



Programming the microcontroller development board

Programming the microcontroller development board to blink

In week 4, We used this example to check whether the builtin LED is blinking.
      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 (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second }

Programming the microcontroller development board's button

To get familiar with programming, I was asked by our instructor,Saheen, to check out the examples in the Arduino.Next, we were asked to learn how a program is written to turns on and off a LED (in this case,connected to digital pin 0) when pressing a pushbutton (here,attached to pin 27). Saheen suggested we write the algorithm for this to get familiar with the logic.
Step 1:-Start
Step 2:- Set pin 0 as output for LED and button pin ,27 as input
Step 3:- If button is pressed, go to step 5.
Step 4:- Set LED as off.Go to step 3.
Step 5:- Set LED as on.
Step 6:- Go to step 3.

      const int buttonPin = 27; // the number of the pushbutton pin
      const int ledPin = 0; // the number of the LED pin

      // variables will change:
      int buttonState = 0; // variable for reading the pushbutton status

      void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
      }

      void loop() {
      // read the state of the pushbutton value:
      buttonState = digitalRead(buttonPin);

      // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
      if (buttonState == HIGH) {
      // turn LED on:
      digitalWrite(ledPin, HIGH);
      } else {
      // turn LED off:
      digitalWrite(ledPin, LOW);
      }
      }

Using Boolean function

Now, to program a boolean function refers to a function that returns a boolean value, which is either true or false. This program is to turn an LED on if it is off or turn it off if it is on using a boolean function , flag. The algorithm fo this:
Step 1:-Start
Step 2:- Set buttonPin, 27 as input
Step 3:- Set the LED pin ,13 as output
Step 4:- If indicator is off, go to 5
Step 5:- If button is pressed, switch off LED, go to 7
Step 6:- If button is pressed, switch on LED
Step 7:- Set indicator to on ,Go to step 8
Step 8:- Set indicator to off
Step 9:-Go to step 3
      const int buttonPin = 27; // the number of the pushbutton pin is 27 in the Seed XIAO
      const int ledPin = 0; // the number of the LED pin
      bool flag = false;//this is an indicator which changes to true when button is on
      // variables will change:
      int buttonState = 0; // variable for reading the pushbutton status

      void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
      }

      void loop() {
      // read the state of the pushbutton value:
      buttonState = digitalRead(buttonPin);

      // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
      if (buttonState == HIGH) {
      flag=!flag;// opposite of bool flag, so if the button is high or on, the flag becomes true
      } 
      // turn LED off:
      digitalWrite(ledPin, flag);
      }

Debounce

Debouncing is a technique used to ensure that only one logical transition is registered for each physical transition of an input signal, particularly when dealing with mechanical switches or buttons. When a button is pressed or released, its contacts can momentarily make and break connection rapidly, causing the signal to fluctuate between HIGH and LOW states several times in quick succession. To mitigate this issue, debouncing involves introducing a delay mechanism in the code to ensure that only stable, reliable signals are acted upon. Debouncing can be implemented,here, by adding a short delay (a few milliseconds) after detecting a state change of a button and then rechecking the state of the button to confirm its stable state.

      const int buttonPin = 27; // the number of the pushbutton pin is 27 in the Seed XIAO
      const int ledPin = 0; // the number of the LED pin
      bool flag = false;
      bool pressed=false; 
      // variables will change:
      int buttonState = 0; // variable for reading the pushbutton status

      void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
      delay(2000);//to manage the bounce
      }

      void loop() { 
      // read the state of the pushbutton value:
      buttonState = digitalRead(buttonPin);

      // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
      if (buttonState == HIGH) {
      if(pressed==false){
      flag=!flag;// opposite of bool flag, so if the button is high or on, the flag becomes true 
      pressed=true;
      } 
      }else{
      pressed=false;
      delay(50);
      digitalWrite(ledPin, flag);
      }
      }
      

Serial communication

The Serial Monitor in the Arduino IDE is a tool used for communicating with the Arduino board via the serial port. It provides a simple interface for sending text data to the Arduino and receiving text data from the Arduino. Here are some key features and functions of the Serial Monitor:
Viewing Output: The Serial Monitor displays text output from the Arduino board. This output can be generated by using functions like Serial.print() and Serial.println() in your Arduino sketch.
Sending Input: You can send text input to the Arduino board through the Serial Monitor. This input can be used to control the behavior of your Arduino sketch or to interact with sensors and actuators connected to the Arduino.
Baud Rate Configuration: The Serial Monitor allows you to configure the baud rate, which determines the speed of communication between the Arduino board and your computer. The baud rate must match the baud rate set in your Arduino sketch using the Serial.begin() function.
Debugging: The Serial Monitor is a valuable tool for debugging Arduino sketches. You can use it to print out variable values, debug messages, and sensor readings, helping you to troubleshoot and understand the behavior of your code.

To open the Serial Monitor in the Arduino IDE, you can click on the magnifying glass icon in the toolbar or navigate to Tools > Serial Monitor. Once opened, you'll be able to interact with your Arduino board in real-time through the Serial Monitor interface.Here is the modified program with serial communication:

      const int buttonPin = 27;
      const int ledPin = 0;
      int buttonState = 0;
      bool flag = false;
      bool pressed = false;
      void setup() {
      Serial.begin(9600);// 9600 is the baud rate
      pinMode(ledPin, OUTPUT);
      pinMode(buttonPin, INPUT);
      delay(2000);
      Serial.println("button on off");
      }
      void loop() {

      buttonState = digitalRead(buttonPin);

      if (buttonState == HIGH) {
      if (pressed == false) {
      Serial.println("button is pressed");//this is what is to be printed/communicated
      if (flag == false) {
      digitalWrite(ledPin, HIGH);
      Serial.println("LED is on");//this is what is to be printed/communicated
      flag = true;
      } else {
      digitalWrite(ledPin, LOW);
      Serial.println("LED is off");//this is what is to be printed/communicated 
      flag = false;
      }
      pressed=true; 
      }
      }else{
      pressed = false;
      delay(50);
      }
      }
    

Calling function

Toggle between the LED when button is pressed using function

Using Chatgpt, I got a program to toggle between the three LEDs sequentially when the button is pressed each time.

      #define BUTTON_PIN 27 
      #define LED_1 0 
      #define LED_2 1
      #define LED_3 26 

      int buttonPressCount = 0; // Global variable to keep track of the number of button presses

      void setup() {
      pinMode(LED_1, OUTPUT);
      pinMode(LED_2, OUTPUT);
      pinMode(LED_3, OUTPUT);
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      Serial.begin(9600);
      delay(2000);
      Serial.println("This is LED button example for FAB ACADEMY 2024");
      }

      void loop() { 
      int buttonState = digitalRead(BUTTON_PIN);
      if (buttonState == HIGH) { 
      buttonPressCount++; // Increment the button press count
      toggleLED(); // Call the function to toggle the LEDs
      // Wait for the button to be released
      while(digitalRead(BUTTON_PIN) == HIGH); 
      delay(50); 
      } 
      }

      void toggleLED() { //recursive function
      if (buttonPressCount == 1) {
      digitalWrite(LED_1, HIGH);
      digitalWrite(LED_2, LOW);
      digitalWrite(LED_3, LOW);
      Serial.println("LED 1 ON");
      }
      else if (buttonPressCount == 2) {
      digitalWrite(LED_1, LOW);
      digitalWrite(LED_2, HIGH);
      digitalWrite(LED_3, LOW);
      Serial.println("LED 2 ON");
      }
      else if (buttonPressCount == 3) {
      digitalWrite(LED_1, LOW);
      digitalWrite(LED_2, LOW);
      digitalWrite(LED_3, HIGH);
      Serial.println("LED 3 ON");
      }

      if (buttonPressCount >= 3) { // Reset to 1 to start from the first LED again after the third press
buttonPressCount = 0; } }

Micro Python

MicroPython enables developers to write Python code to control hardware directly, making it easier to create projects involving sensors, actuators, and other electronic components.
Thonny, is an Integrated Development Environment (IDE) for Python programming. It provides a user-friendly interface for writing, editing, running, and debugging Python code.One of the notable features of Thonny is its built-in support for MicroPython, allowing developers to write and upload MicroPython code to microcontroller boards directly from the Thonny IDE.
For the software setup and to use MicroPython, I followed these instructions. It was very clear and in detail.
Seed Studio XIAO RP2040 with MicroPython



Connect Seeed Studio XIAO RP2040 to the PC and Light it up

      from machine import Pin, Timer

# Initialize the onboard LED pin
led = Pin(25, Pin.OUT)

# Initialize counter and function number variables
Counter = 0
Fun_Num = 0

# Define the callback function for the timer
def fun(tim):
    global Counter
    Counter = Counter + 1
    print(Counter)
    # Toggle the LED state
    led.value(Counter % 2)

# Initialize the timer
tim = Timer(-1)
tim.init(period=1000, mode=Timer.PERIODIC, callback=fun)


    


Light up RGB LED on the Seeed Studio XIAO RP2040

      from ws2812 import WS2812
import utime
import machine

# Initialize the power pin for the WS2812 LED strip
power = machine.Pin(11, machine.Pin.OUT)
power.value(1)

# Define colors
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
WHITE = (255, 255, 255)
COLORS = [BLACK, RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE]

# Initialize the WS2812 LED strip
led = WS2812(12, 1)  # WS2812(pin_num, led_count)

# Main loop to cycle through the colors
while True:
    print("Beautiful color")
    for color in COLORS:
        led.pixels_fill(color)
        led.pixels_show()
        utime.sleep(0.2)

    


Connecting external components to the board

Interfacing IR Sensor Module with Arduino

An infrared proximity sensor or IR Sensor is an electronic device that emits infrared lights to sense some aspect of the surroundings and can be employed to detect the motion of an object. As this is a passive sensor, it can only measure infrared radiation.







      // Define the pin connected to the IR sensor output
      const int irSensorPin = 2;  // Assuming pin 2 is connected to the sensor output
      
      void setup() {
        // Initialize serial communication for debugging
        Serial.begin(9600);
        
        // Set IR sensor pin as input
        pinMode(irSensorPin, INPUT);
      }
      
      void loop() {
        // Read the state of the IR sensor
        int sensorValue = digitalRead(irSensorPin);
        
        // Check if object is detected
        if (sensorValue == HIGH) {
          Serial.println("Object detected!");
        } else {
          Serial.println("No object detected.");
        }
        
        // Wait a short delay before reading again
        delay(500);
      }
    


Interfacing IR Servo motor, MG90S with Arduino

The MG90S servo motor is a compact and reliable motor designed for precise control in robotics and RC projects. With its metal gear construction and torque of up to 2.2 kg/cm, it offers powerful and accurate movement. This servo motor features 360-degree rotation, fast response time, and compatibility with various control systems.



Here is the code to move the servo by 90 degrees.

      #include < Servo.h >
        // Define the servo control pin
        const int servoPin = 1;  // Assuming pin 3 is connected to the servo
                // Create a servo object
        Servo servo;
                void setup() {
          // Attach the servo to the corresponding pin
          servo.attach(servoPin);
                   // Move the servo to the 90-degree position
          servo.write(90);
                    // Wait for a few seconds (adjust as needed)
          delay(3000);
                    // Detach the servo (optional)
          servo.detach();
        }
                void loop() {
          // Nothing here in this example
        }
        
      

Communicating using Bluetooth

The XIAO RP2040 does not have built-in Bluetooth capability, but you can add Bluetooth functionality using a Bluetooth module or shield, such as the HC-05 or HC-06. These modules allow you to establish a serial communication link wirelessly between the XIAO RP2040 and another Bluetooth-enabled device.




HC-05 is a Bluetooth module which is designed for wireless communication. This module can be used in a master or slave configuration. Bluetooth serial modules allow all serial enabled devices to communicate with each other using Bluetooth. It has 6 pins,
  • 1. Key/EN: It is used to bring Bluetooth module in AT commands mode. If Key/EN pin is set to high, then this module will work in command mode. Otherwise by default it is in data mode. The default baud rate of HC-05 in command mode is 38400bps and 9600 in data mode.
  • HC-05 module has two modes,
    1. Data mode: Exchange of data between devices.
    2. Command mode: It uses AT commands which are used to change setting of HC-05. To send these commands to module serial (USART) port is used.
  • 2. VCC: Connect 5 V or 3.3 V to this Pin.
  • 3. GND: Ground Pin of module.
  • 4. TXD: Transmit Serial data (wirelessly received data by Bluetooth module transmitted out serially on TXD pin).
  • 5. RXD: Receive data serially (received data will be transmitted wirelessly by Bluetooth module).
  • 6. State: It tells whether module is connected or not.
  • Connecting the Quentorres to the HC-05

  • Connect the VCC pin of the HC-05 to the 3.3V or 5V output pin of the Seeed Xiao RP2040.
  • Connect the GND pin of the HC-05 to the GND pin of the Seeed Xiao RP2040.
  • Connect the TXD (transmit) pin of the HC-05 to a digital I/O pin on the Seeed Xiao RP2040.
  • Connect the RXD (receive) pin of the HC-05 to another digital I/O pin on the Seeed Xiao RP2040.




  • Power on the HC-05: The HC-05 should be powered on and in pairing mode (usually indicated by a blinking LED).
  • Pair with the HC-05:On your mobile device, go to Bluetooth settings and scan for devices.
  • Find and pair with the HC-05 module (the default pairing code is usually 1234 or 0000).
  • Use the Arduino Bluetooth Control App:Download and open the Arduino Bluetooth Control app on your mobile device.
  • Connect to the HC-05 module from within the app.
  • Use the app to send commands like LED ON or LED OFF to the Seeed Xiao RP2040.
  • Here is the code when you input 1 or 0 in the phone and ON or OFF is seen in the serial monitor.
  •       #include < SoftwareSerial.h >
    
        const int ledPin = 0; // GPIO pin for the LED
        SoftwareSerial bluetoothSerial(3, 4); // RX, TX pins for HC-05
        
        void setup() {
            Serial.begin(9600);          // Initialize the serial communication for debugging
            bluetoothSerial.begin(9600); // Initialize Bluetooth serial communication
            pinMode(ledPin, OUTPUT);      // Set the LED pin as an output
        }
        
        void loop() {
            if (bluetoothSerial.available() > 0) {
            char command = bluetoothSerial.read();
        
            // Toggle LED based on received command
            if (command == '1') {
                digitalWrite(ledPin, HIGH); // Turn on LED
                Serial.println("LED ON");
            } else if (command == '0') {
                digitalWrite(ledPin, LOW);  // Turn off LED
                Serial.println("LED OFF");
            }
          }
        }   
        

    Using PlatformIO IDE for Arduino programming

    PlatformIO is a cross-platform, cross-architecture, multi-framework professional IDE tool for embedded system and software engineers to write embedded applications.If you need a simple and easy-to-use environment for a small project, Arduino IDE may be the better choice. If you need a more powerful and feature-rich development environment for a larger project that uses the Arduino framework, PlatformIO IDE may be the better choice.

    PlatformIO for VSCode

    Group assignment:

    Performance and development workflows


    Design files

    Arduino files