KevsRobots Learning Platform
By Kevin McAleer, 8 Minutes
Arduino requires you to initialize serial communication with Serial.begin(). MicroPython’s print() function just works - no setup required. And the REPL (Read-Eval-Print Loop) gives you an interactive Python console on your microcontroller!
This is one area where MicroPython is dramatically simpler and more powerful than Arduino.
Arduino C++:
void setup() {
Serial.begin(9600); // Must initialize serial
}
void loop() {
Serial.print("Temperature: ");
Serial.println(temperature);
delay(1000);
}
MicroPython:
import time
while True:
print(f"Temperature: {temperature}")
time.sleep(1)
Key differences:
print() just worksprintln vs print - print() adds newline by defaultArduino C++:
int value = 42;
float voltage = 3.3;
String message = "Hello";
Serial.print("Value: ");
Serial.println(value);
Serial.print("Voltage: ");
Serial.print(voltage, 2); // 2 decimal places
Serial.println("V");
Serial.print(message);
Serial.print(" ");
Serial.println("World");
MicroPython:
Python’s f-strings are much cleaner!
Sometimes you want to print without a newline:
Arduino C++:
Serial.print("Loading");
for (int i = 0; i < 5; i++) {
Serial.print(".");
delay(1000);
}
Serial.println(" Done!");
MicroPython:
Use the end="" parameter to suppress the newline.
Arduino C++:
int x = 10, y = 20, z = 30;
Serial.print("X: ");
Serial.print(x);
Serial.print(", Y: ");
Serial.print(y);
Serial.print(", Z: ");
Serial.println(z);
MicroPython:
Here’s where MicroPython really shines. The REPL (Read-Eval-Print Loop) is an interactive Python prompt that runs on your microcontroller.
How to access the REPL:
screen /dev/tty.usbmodem* 115200You’ll see the Python prompt:
>>>
Now you can type Python commands and see instant results!
REPL Examples:
>>> print("Hello from MicroPython!")
Hello from MicroPython!
>>> 2 + 2
4
>>> from machine import Pin
>>> led = Pin(25, Pin.OUT)
>>> led.on()
>>> led.off()
>>> import time
>>> for i in range(5):
... print(i)
... time.sleep(0.5)
...
0
1
2
3
4
This is impossible in Arduino! You can’t interact with your code while it’s running. The REPL is perfect for:
The REPL has special commands:
Ctrl+C - Stop running program, return to REPL prompt Ctrl+D - Soft reboot (restarts MicroPython, runs boot.py and main.py) help() - Show help information help(object) - Show help for specific object
>>> help()
Welcome to MicroPython!
...
>>> from machine import Pin
>>> help(Pin)
# Shows Pin documentation
Arduino C++:
void loop() {
int sensorValue = analogRead(A0);
Serial.print("DEBUG: Raw value = ");
Serial.println(sensorValue);
if (sensorValue > 500) {
Serial.println("DEBUG: Value is high");
digitalWrite(LED_PIN, HIGH);
} else {
Serial.println("DEBUG: Value is low");
digitalWrite(LED_PIN, LOW);
}
delay(1000);
}
MicroPython:
from machine import Pin, ADC
import time
sensor = ADC(Pin(26))
led = Pin(25, Pin.OUT)
while True:
sensor_value = sensor.read_u16()
print(f"DEBUG: Raw value = {sensor_value}")
if sensor_value > 32768:
print("DEBUG: Value is high")
led.on()
else:
print("DEBUG: Value is low")
led.off()
time.sleep(1)
Pro tip: Use descriptive debug messages:
print(f"[SENSOR] Raw: {sensor_value}, Voltage: {voltage:.2f}V")
print(f"[LED] State: {'ON' if led.value() else 'OFF'}")
print(f"[ERROR] Sensor reading out of range: {sensor_value}")
Python has powerful string formatting:
Arduino C++:
float voltage = 3.287;
Serial.print("Voltage: ");
Serial.print(voltage, 2); // 2 decimals: 3.29
Serial.println("V");
MicroPython:
Format specification:
:.2f - Float with 2 decimal places:05d - Integer padded to 5 digits:08b - Binary with 8 digits:02X - Hex with 2 digits (uppercase)In Arduino, you read serial input with Serial.read(). In MicroPython, it’s trickier because the REPL uses the serial port. You can use sys.stdin.read() but it’s not commonly used in MicroPython projects.
Arduino C++:
void loop() {
if (Serial.available() > 0) {
char incoming = Serial.read();
Serial.print("Received: ");
Serial.println(incoming);
}
}
MicroPython (less common):
import sys
import select
poll = select.poll()
poll.register(sys.stdin, select.POLLIN)
while True:
events = poll.poll(0) # Non-blocking
if events:
char = sys.stdin.read(1)
print(f"Received: {char}")
Note: For most MicroPython projects, you don’t read from serial. Instead, you:
Arduino C++:
void loop() {
int temp = readTemperature();
int humidity = readHumidity();
Serial.print(millis());
Serial.print(",");
Serial.print(temp);
Serial.print(",");
Serial.println(humidity);
delay(1000);
}
MicroPython:
import time
def read_temperature():
# Your sensor code
return 25
def read_humidity():
# Your sensor code
return 65
while True:
temp = read_temperature()
humidity = read_humidity()
timestamp = time.ticks_ms()
# CSV format
print(f"{timestamp},{temp},{humidity}")
time.sleep(1)
This CSV output can be copied from the terminal and imported into Excel or Python for analysis.
Use a debug flag to toggle verbose output:
MicroPython:
from machine import Pin
import time
DEBUG = True # Set to False to disable debug output
led = Pin(25, Pin.OUT)
def debug(message):
if DEBUG:
print(f"[DEBUG] {message}")
while True:
debug("Turning LED on")
led.on()
time.sleep(1)
debug("Turning LED off")
led.off()
time.sleep(1)
For complex data, use formatting to make it readable:
MicroPython:
from machine import Pin, ADC
import time
sensor1 = ADC(Pin(26))
sensor2 = ADC(Pin(27))
while True:
s1 = sensor1.read_u16()
s2 = sensor2.read_u16()
v1 = (s1 / 65535) * 3.3
v2 = (s2 / 65535) * 3.3
# Pretty formatted table
print("=" * 40)
print(f"{'Sensor':<10} {'Raw':>10} {'Voltage':>10}")
print("-" * 40)
print(f"{'Sensor 1':<10} {s1:>10} {v1:>9.2f}V")
print(f"{'Sensor 2':<10} {s2:>10} {v2:>9.2f}V")
print("=" * 40)
time.sleep(2)
Output:
========================================
Sensor Raw Voltage
----------------------------------------
Sensor 1 32768 1.65V
Sensor 2 45678 2.30V
========================================
MicroPython:
from machine import Pin, ADC
import time
# Hardware setup
temp_sensor = ADC(Pin(26))
light_sensor = ADC(Pin(27))
led = Pin(25, Pin.OUT)
# Configuration
TEMP_THRESHOLD = 30000
LIGHT_THRESHOLD = 20000
DEBUG = True
def debug(message):
if DEBUG:
print(f"[DEBUG] {message}")
def read_sensors():
temp_raw = temp_sensor.read_u16()
light_raw = light_sensor.read_u16()
temp_voltage = (temp_raw / 65535) * 3.3
light_voltage = (light_raw / 65535) * 3.3
return temp_raw, light_raw, temp_voltage, light_voltage
def check_alerts(temp_raw, light_raw):
alert = False
if temp_raw > TEMP_THRESHOLD:
print("[ALERT] Temperature too high!")
alert = True
if light_raw < LIGHT_THRESHOLD:
print("[ALERT] Light level too low!")
alert = True
return alert
while True:
debug("Reading sensors...")
temp_raw, light_raw, temp_v, light_v = read_sensors()
debug(f"Temperature: {temp_raw} ({temp_v:.2f}V)")
debug(f"Light: {light_raw} ({light_v:.2f}V)")
alert = check_alerts(temp_raw, light_raw)
if alert:
led.on()
else:
led.off()
# Summary output
print(f"T:{temp_v:.2f}V | L:{light_v:.2f}V | LED:{'ON' if led.value() else 'OFF'}")
time.sleep(1)
Exercise 1: Interactive LED Control via REPL
Connect to the REPL and control an LED interactively:
No code to write - just interact with the REPL!
Answer:
# In the REPL:
>>> from machine import Pin
>>> import time
>>> led = Pin(25, Pin.OUT)
>>> led.on()
>>> time.sleep(2)
>>> led.off()
>>> led.toggle()
>>> for i in range(5):
... led.toggle()
... time.sleep(0.5)
...
Exercise 2: Data Logger
Create a program that logs sensor data in CSV format:
Answer:
from machine import Pin, ADC
import time
sensor = ADC(Pin(26))
# Print CSV header
print("Timestamp(ms),Raw,Voltage(V)")
start_time = time.ticks_ms()
while True:
timestamp = time.ticks_diff(time.ticks_ms(), start_time)
raw = sensor.read_u16()
voltage = (raw / 65535) * 3.3
# CSV format
print(f"{timestamp},{raw},{voltage:.3f}")
time.sleep(1)
Exercise 3: Formatted Sensor Dashboard
Create a continuously updating dashboard that displays:
Make it look professional!
Answer:
from machine import Pin, ADC
import time
sensor1 = ADC(Pin(26))
sensor2 = ADC(Pin(27))
sensor3 = ADC(Pin(28))
def get_status(value, low, high):
if value < low:
return "ALERT "
elif value > high:
return "WARNING"
else:
return "OK "
start_time = time.ticks_ms()
while True:
uptime = time.ticks_diff(time.ticks_ms(), start_time) / 1000
s1 = sensor1.read_u16()
s2 = sensor2.read_u16()
s3 = sensor3.read_u16()
# Clear screen (terminal escape code)
print("\033[2J\033[H", end="")
# Dashboard
print("=" * 50)
print(f" SENSOR DASHBOARD - Uptime: {uptime:.1f}s")
print("=" * 50)
print(f"{'Sensor':<12} {'Value':>10} {'Status':>10}")
print("-" * 50)
print(f"{'Temperature':<12} {s1:>10} {get_status(s1, 20000, 40000):>10}")
print(f"{'Light':<12} {s2:>10} {get_status(s2, 15000, 50000):>10}")
print(f"{'Pressure':<12} {s3:>10} {get_status(s3, 25000, 45000):>10}")
print("=" * 50)
time.sleep(1)
You can use the arrows ← → on your keyboard to navigate between lessons.
Comments