KevsRobots Learning Platform
72% Percent Complete
By Kevin McAleer, 9 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:
value = 42
voltage = 3.3
message = "Hello"
print(f"Value: {value}")
print(f"Voltage: {voltage:.2f}V") # 2 decimal places
print(f"{message} World")
# Or combine everything
print(f"Value: {value}, Voltage: {voltage:.2f}V, Message: {message} World")
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:
import time
print("Loading", end="") # No newline
for i in range(5):
print(".", end="") # No newline
time.sleep(1)
print(" Done!") # With newline
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:
x, y, z = 10, 20, 30
# Method 1: F-string (best)
print(f"X: {x}, Y: {y}, Z: {z}")
# Method 2: Multiple arguments
print("X:", x, ", Y:", y, ", Z:", z)
# Method 3: Old-style formatting
print("X: {}, Y: {}, Z: {}".format(x, y, z))
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:
voltage = 3.287
# F-string with formatting
print(f"Voltage: {voltage:.2f}V") # 2 decimals: 3.29
# More formatting examples
print(f"Voltage: {voltage:.3f}V") # 3 decimals: 3.287
print(f"Voltage: {voltage:.1f}V") # 1 decimal: 3.3
print(f"Hex: 0x{42:02X}") # Hex: 0x2A
print(f"Binary: {42:08b}") # Binary: 00101010
print(f"Padded: {42:05d}") # Padded: 00042
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