Skip to content

7. Embedded Programming

The assignment for this week was to write a program for a microcontroller development board that I made, that need to interact with local input and output devices communicated with remote wired or wireless device and used different languages of programming.

Group assigment

The group assignment for this week was to browse through the data sheet for our microcontroller compare the performance and development workflows for other architectures. Although I had programming knowledge, it was very interesting to once again get acquainted with the basics of electronics and packaging, applied technologies and devices that Babken presented to us. Babken introduced the Scratch programming environment for games and animations, which is quite interesting for beginners because it introduces the basic concepts of programming, such as functions, variables, conditions, loops, through blocks. I used it before and teach them my students. After that for our group assigment we decided to compare and study ATtiny and RP2040 microcontrollers and also languages.

RP2040 with C++ and Micropython

This performance comparison involves evaluating how efficiently a specific equation, 5 + 10 / n , is computed on a microcontroller. The equation is executed 100,000 times on the same microcontroller, but using different programming languages: C++ and MicroPython. Since MicroPython is a higher-level language, it’s expected that the machine will require more time to process the code compared to C++. This difference in processing time was anticipated and acknowledged in the results.

Code wrote in MicroPython The same code in C++ (Arduino IDE)

unsigned long startTime = micros();
// Your code to be timed
unsigned long endTime = micros();
unsigned long elapsedTime = endTime - startTime;

void setup() {
  Serial.begin(9600);
}

void loop() {
  long startTime = micros();
  double result = 0;
  for (int n = 1; n <= 100000; n++) {
    result += (5.0 + 10.0) / n;
  }
  long endTime = micros() - startTime;

  Serial.println(result);
  Serial.println(endTime);
  delay(1000); // Adjust delay as needed
}

The result was that RP2040 with C++ was 0.028416 second and with Micropython was 2.250147 seconds. And it was predictable.

RP2040 VS ATtiny1614

We did comparison on performance for equation calculation 5 + 10 / n for 1000 times.

Results ATtiny1614

Results RP2040

RP2040 with C++ took 0.002856 seconds and ATtiny with C++ took 0.033362 seconds.

High level programming language VS low level programming language

This time, we conducted tests using different levels of the same language, specifically on the RP2040 microcontroller. The objective was to explore the speed disparity between a program written in the Arduino environment (utilizing functions like pinMode() and digitalWrite()) and a program written “bare metal”, directly accessing the registers. Because bare metal programming was new for me I tried to understand what it is. This is the explanation that I found in this website. “Bare metal programming is a low-level type of programming that is hard-coded to a system at the hardware level. It operates without an abstraction layer or operating system (OS). It also interlinks with the hardware and takes a system’s specific components into account”.

Below is the code for the “bare metal” version:

int main() {
        /*
        0x400140d4: GPIO26_CTRL: GPIO 26 control including function select and overrides.
        0x05: from "2.19.2. Function Select": selects function SIO (Single-Cycle IO)
        */

        // same for GPIO26_CTRL
        *((volatile unsigned int*) 0x400140d4) = 0x05;    

        /*
        Output enable registers, GPIO_OE and GPIO_HI_OE, are used to enable the output driver. 0 for high-impedance, 1
        for drive high/low based on GPIO_OUT and GPIO_HI_OUT.
        sets the 27th bit of this register to 1 in order to enable output
        */
        *((volatile unsigned int*) 0xd0000020) = (1 << 26);  // GPIO_OE


        while( 1 )
        {
          //toggles the pin 26 high and low
          *((volatile unsigned int*) 0xd000001c) ^= ( 1 << 26);
        }

        return 0;
}

We saw the two version result in oscilloscope.

Arduino

Bare metal

The frequency of the PWM signal RP2040 with Arduino code was 590.590 kHz and with “bare metal” code 7.81258 MHz. As expected te bare metal code runs much faster than the Arduino code.

Individual assigment

Programming with Arduino IDE

As I wrote a program with local input and output devices in Electronic design week I decided this week to use remote wired devices. First I wrote program for RGB led. I wrote program with setColor function.Also I can write it without function. But when we use function code become more short and flexible.

RGB led

// Pin definitions for the RGB LED
int redPin= 3; 
int greenPin = 2;
int  bluePin =4 ;

void setup() {
  //Defining the pins as OUTPUT   
  pinMode(redPin,  OUTPUT);              
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}
void  loop() {
  // Set the color to red 
  setColor(255, 0, 0);  
  delay(1000); // wait 1 second
  // Set the color to green 
  setColor(0,  255, 0); 
  delay(1000); // wait 1 second
  // Set the color to red 
  setColor(0, 0, 255); 
  delay(1000); // wait 1 second
  // Set the color to white
  setColor(255, 255, 255); 
  delay(1000); // wait 1 second
  // Set the color to purple
  setColor(170, 0, 255); 
  delay(1000); // wait 1 second
  // Set the color to light blue
  setColor(127, 127,  127); // Light Blue
  delay(1000); // wait 1 second
}
// Function to set the color of the RGB LED
void setColor(int redValue, int greenValue,  int blueValue) {
  // Write the color values to the appropriate RGB pins
  analogWrite(redPin, redValue);
  analogWrite(greenPin,  greenValue);
  analogWrite(bluePin, blueValue);
}

Active buzzer

After that I tried active buzzer .We can use active buzzers in alarm systems and connect them with different sensors for example with flame, passive Infrared sensors.Here is a simple example how we can use a buzzer.

int buzzerPin=3;
int delayTime=500;
void setup() {
pinMode(buzzerPin,OUTPUT);
}

void loop() {
digitalWrite(buzzerPin,HIGH);
delay(delayTime);
digitalWrite(buzzerPin,LOW);
delay(delayTime);
}

Programming with MicroPython

As I have known the Arduino I decided this week also to try something new for me MicroPython. For that I followed the instruction of this webpage Seeed Studio XIAO RP2040 with MicroPython

  1. I downloaded and installed the latest version of Thonny editor according my computer operating system.
  2. Launched the Thonny.
  3. Clicked “Tools–>Options” to open the settings.
  4. Pressed and held the “BOOT” button and then connected the Seeed Studio XIAO RP2040 to the PC through the Type-C cable.
  5. Clicked Install or update MicroPython.
  6. It automatically searched for the device and displayed it on the Target Volume. I selected the version.

After that I wrote again RGB led code with MicroPython and pressed run button.

import machine
import utime

# Define the pin number connected to the RGB led pins
led_pin_blue = machine.Pin(2, machine.Pin.OUT)
led_pin_green= machine.Pin(4, machine.Pin.OUT)
led_pin_red= machine.Pin(3, machine.Pin.OUT)


# Define the blink interval in seconds
blink_interval = 3

# Main loop
while True:
    led_pin_blue.value(255)
    led_pin_green.value(0)
    led_pin_red.value(100)
    utime.sleep(blink_interval)
    # Wait for the specified interval
    led_pin_blue.value(0)
    led_pin_green.value(1)
    led_pin_red.value(1)
    utime.sleep(blink_interval)
    # Turn the LED off (set pin to high)
    # Wait for the specified interval

MicroPython was not very hard for me to understand because the algorithm is same just I needed learn syntax.

Conclusion

This week was quite interesting because I also learned some Micropython. Since I had enough knowledge of the Arduino programming language and wanted to study Python or Micropython for a long time, I took the opportunity to take my first steps. I also learned about bare metal code from our group assignment.

Files