Week 03: Embedded Programming
Workflow
For this week, we compared the two development workflows discussed in class, Arduino and MicroPython:
-
Arduino. Arduino is a compiled C/C++ workflow that spans the entire range from hardware to coding environments. You write a script with
setup()andloop()in the Arduino IDE, a toolchain on your computer cross-compiles it to native machine code, and you flash that binary onto the board over USB. Once it is running, the program executes directly on the microcontroller, and a large library ecosystem covers common sensors and peripherals. Every change goes through an edit–compile–upload cycle, and there is no interactive prompt, so debugging here is mostly counting on serial prints. -
MicroPython. MicroPython is a Python 3 interpreter that runs on the microcontroller itself. You write
.pyscripts, copy them onto the board’s filesystem with Thonny, and the on-chip interpreter directly executes them. The very useful part of it is the REPL ((Read-Eval-Print Loop)): you can connect over serial and try pins, sensors, and functions live without Arudino style flashing. However, its interpreted code is generally slower and uses more RAM than compiled C.
Arduino set up was fairly straightforward. After installing and software and resetting the RP2040. I verified its built LED blinking code to have its on borad LED flashing.
Setting up MicroPython was slightly more work. After installing the Thonny, I needed to manually download and flash the firmware for XIAO RP2040 (https://micropython.org/download/SEEED_XIAO_RP2040/). Then it allows the excution of python on board.
Above showed that while their underlying implmentations differ. It’s possible to realize exactly the same function trough two workflows.
Performance Test
CPU Speed
For testing CPU speed on Arudino, I used be below code to have it excute a simple set of computations:
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
volatile unsigned long x = 0;
unsigned long start = micros();
for (unsigned long i = 0; i < 10000; i++) {
x += i;
x ^= (x << 1);
}
unsigned long t = micros() - start;
Serial.print("Elapsed time(us): ");
Serial.println(t);
}
void loop() {}
Out:
Elapsed time(us): 853
And same test for MicroPython:
import time
x = 0
start = time.ticks_us()
for i in range(10000):
x += i
x ^= (x << 1)
t = time.ticks_diff(time.ticks_us(), start)
print("Elapsed time (us):", t)
Out:
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot
Elapsed time (us): 3069559
Same deal for GPIO Speed test for Arduino and MicroPython:
#define PIN LED_BUILTIN
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
pinMode(PIN, OUTPUT);
unsigned long start = micros();
for (int i = 0; i < 10000; i++) {
digitalWrite(PIN, HIGH);
digitalWrite(PIN, LOW);
}
unsigned long t = micros() - start;
Serial.print("10000 toggles tale ");
Serial.print(t);
Serial.println(" us");
}
void loop() {}
10000 toggles tale 8231 us
from machine import Pin
import time
led = Pin(25, Pin.OUT)
start = time.ticks_us()
for _ in range(10000):
led.value(1)
led.value(0)
t = time.ticks_diff(time.ticks_us(), start)
print("10000 toggles took ", t, "us")
Out:
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot
10000 toggles took 181957 us
The full comparison is here. As expected, MicroPython is slower than arduino, which runs on C:
| Test | Arduino (µs) | MicroPython (µs) | Slowdown |
|---|---|---|---|
| CPU loop, 10,000 iterations | 853 | 3,069,559 | 3,599× |
| GPIO toggle, 10,000 cycles | 8,231 | 181,957 | 22× |