Skip to content

4. Embedded Programming

Group assignment: demonstrate and compare the toolchains and development workflows for available embedded architectures

Benchmarking MicroPython, Arduino C++, and Register-Level C++

For this benchmark, we use the RP2040 with different codes doing the same thing: Setting an output pin HIGH and LOW as fast as possible.

To setup the RP2040 for MicroPython, we used the Thonny IDE and followed the same steps as here.

Here are the different versions of the code:

MicroPython

led = machine.Pin(26, machine.Pin.OUT)

while True:
  led.high()
  led.low()

c++ with Arduino Framework

void setup() {
  pinMode(1, OUTPUT);
}

void loop() {
  digitalWrite(1, HIGH);
  digitalWrite(1, LOW);
}

Register-Level c++

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 then tested the speed of each code using an oscilloscope. We connected the probes of the oscilloscope to the Xiao like this:

And after pushing the Autoset button on the oscilloscope, we were able to see the oscillation of the pin going HIGH and LOW and also read the frequency of this oscillation. For example, for the RP2040 with MicroPython:

The shape of the register level c++ oscillation was interesting:

We obtained the following values:

microcontroller language oscillation frequency
XIAO RP2040 MicroPython 82.8 kHz
XIAO RP2040 c++ with Arduino Framework 610.2 kHz
XIAO RP2040 register level c++ 12.5 MHz

RP2040 vs ESP32-S3 vs ATtiny1614 Comparison

Hardware comparison

In order to compare these three microcontrollers, we refered to their datasheets: ATtiny1614, ESP32-S3 and RP2040.

Feature XIAO RP2040 ESP32-S3R8 ATtiny1614
Register size 32-bits 32-bits 8-bits
Operating conditions 3.3 - 5.5 V 3.0 - 3.6 V 1.8 - 5.5 V
Flash memory 2 mB - 16 kB
SRAM 264 kB 512 KB 2 kB
Clock speed 133 MHz 240 MHz 20 MHz

We then compared their pins configurations:

For the ESP32:

For the XIAO RP2040:

And for the Attiny1614:

Oscillation Frequency Comparison

We used the same type of benchmark as when comparing the different codes: we turned an output pin to HIGH and LOW as fast as possible.

We used c++ with Arduino Framework as well as MicroPython. For the ESP32-S3, we had to change the code to this:

MicroPython for ESP32

import machine
led = machine.Pin(26, machine.Pin.OUT)

while True:
  led.value(1)
  led.value(0)

To upload the code on the ATTINY1614, we used Elen’s Quentorres as programmer and followed her documentation.

We read the oscillation frequency the same way as before on the oscilloscope:

We obtained the following results:

microcontroller language oscillation frequency
XIAO RP2040 MicroPython 82.8 kHz
XIAO ESP32-S3 MicroPython 76.8 kHz
XIAO RP2040 c++ with Arduino Framework 610.2 kHz
XIAO ESP32-S3 c++ with Arduino Framework 785.3 kHz
ATTINY1614 c++ with Arduino Framework 375.1 kHz

Last update: February 20, 2025