MicroPython Basics
| MicroPython Basics | |
|---|---|
| Competency | Software |
| Difficulty | Beginner |
| Time Required | 3-5 hours (split across multiple sessions) |
| Prerequisites | None - complete beginner friendly |
| Materials Needed | Raspberry Pi Pico ($4), USB cable, computer with Thonny IDE (free), LED, resistor (220Ω), breadboard |
| Next Steps | SimpleBot assembly, MicroPython Programming, Electronics Fundamentals |
MicroPython Basics is your introduction to programming microcontrollers for robotics. This tutorial covers everything you need to write your first robot program, from installing MicroPython to controlling GPIO pins.
By the end of this tutorial, you'll understand:
- What MicroPython is and why it's great for robotics
- How to install MicroPython on Raspberry Pi Pico
- How to use Thonny IDE and the REPL
- Python basics: variables, functions, loops, conditionals
- How to control LEDs and read buttons
- How to write simple robot programs
This tutorial is hands-on. You'll write and run code on real hardware.
Part 1: What is MicroPython?
MicroPython is a version of Python designed for microcontrollers - tiny computers that control robots.
Why MicroPython for Robotics?
- Easy to learn - Python is one of the most beginner-friendly programming languages
- Interactive - Test code immediately with the REPL (Read-Eval-Print Loop)
- Fast development - Write code quickly without compiling
- Rich libraries - GPIO, PWM, I2C, SPI built in
- Low cost - Raspberry Pi Pico costs $4 and runs MicroPython perfectly
Comparison to other options:
- Arduino (C/C++) - Faster execution, larger community, but harder to learn
- Python on Raspberry Pi - Full Python ecosystem, but not real-time, more expensive
- MicroPython - Best balance of simplicity and capability for beginners
What is a Microcontroller?
A microcontroller is a tiny computer designed to control hardware:
- CPU - Processes instructions (runs your code)
- RAM - Temporary storage for variables (264 KB on Pico)
- Flash - Permanent storage for programs (2 MB on Pico)
- GPIO - General-Purpose Input/Output pins to connect sensors and motors
Raspberry Pi Pico specifications:
- Dual-core ARM Cortex-M0+ @ 133 MHz
- 264 KB RAM, 2 MB flash
- 26 GPIO pins (digital I/O, PWM, ADC, I2C, SPI, UART)
- USB for programming and power
- Costs $4
Part 2: Installing MicroPython
Step 1: Download MicroPython Firmware
- Go to MicroPython Downloads
- Download the latest .uf2 file (e.g., "rp2-pico-latest.uf2")
- Save it to your computer
Step 2: Flash MicroPython to Pico
- Hold the BOOTSEL button on Raspberry Pi Pico
- While holding BOOTSEL, plug USB cable into computer
- Release BOOTSEL button
- Pico appears as a USB drive named "RPI-RP2"
- Drag the .uf2 file to the RPI-RP2 drive
- Pico automatically reboots with MicroPython installed!
Troubleshooting:
- RPI-RP2 drive doesn't appear? Make sure you're holding BOOTSEL before plugging in USB
- File won't copy? Try a different USB cable (some are power-only)
- Pico disconnects after copying? This is normal! It's rebooting with MicroPython
Step 3: Install Thonny IDE
Thonny is a beginner-friendly Python IDE with built-in MicroPython support.
- Download from thonny.org
- Install Thonny (Windows: run installer, macOS: drag to Applications, Linux: apt install thonny)
- Open Thonny
- Click bottom-right corner where it says "Python" and select MicroPython (Raspberry Pi Pico)
- Connect Pico via USB - Thonny should detect it
You should see:
- A code editor (top half) - Write programs here
- A Shell/REPL (bottom half) - Interactive Python console
Part 3: Your First MicroPython Program
The REPL (Interactive Shell)
The REPL (Read-Eval-Print Loop) lets you test Python code immediately:
- Type in the Shell (bottom half of Thonny)
- Press Enter
- See the result instantly
Try this:
>>> print("Hello, Robot!")
Hello, Robot!
>>> 2 + 2
4
>>> name = "SimpleBot"
>>> print(f"My robot is {name}")
My robot is SimpleBot
Why the REPL is amazing:
- Test sensor readings instantly
- Debug code by checking variable values
- Learn Python by experimenting
Blink the Onboard LED
Raspberry Pi Pico has an LED on pin 25 (the "onboard LED"). Let's blink it!
Type this in the REPL:
>>> from machine import Pin
>>> import time
>>> led = Pin(25, Pin.OUT)
>>> led.on()
The LED should turn ON!
Now turn it OFF:
>>> led.off()
Make it blink:
>>> for i in range(10):
... led.toggle()
... time.sleep(0.5)
Note: After typing "for i in range(10):", press Enter, then type the indented lines, then press Enter twice to run.
Write Your First Program
Now let's write a complete program in the editor (top half):
from machine import Pin
import time
led = Pin(25, Pin.OUT)
while True:
led.toggle()
time.sleep(0.5)
Run the program:
- Click the green "Run" button (or press F5)
- Thonny will ask "Where to save?" - choose MicroPython device
- Save as blink.py
- The LED blinks forever!
Stop the program:
- Click the red "Stop" button or press Ctrl+C
What this code does:
- from machine import Pin - Import Pin class for GPIO control
- import time - Import time module for delays
- led = Pin(25, Pin.OUT) - Configure pin 25 as output
- while True: - Loop forever
- led.toggle() - Switch LED state (on→off or off→on)
- time.sleep(0.5) - Wait 0.5 seconds
Part 4: Python Basics for Robotics
Variables
Variables store values (sensor readings, motor speeds, states):
# Numbers
speed = 100
distance = 15.5
# Strings (text)
robot_name = "SimpleBot"
# Booleans (True/False)
line_detected = True
obstacle_ahead = False
Comments
Comments explain code (Python ignores them):
# This is a comment
speed = 100 # Set motor speed to 100%
Math Operations
# Basic math
x = 10 + 5 # Addition: 15
y = 10 - 3 # Subtraction: 7
z = 10 * 2 # Multiplication: 20
w = 10 / 4 # Division: 2.5
q = 10 // 4 # Integer division: 2
r = 10 % 3 # Modulo (remainder): 1
# Comparisons (result is True or False)
10 > 5 # Greater than: True
10 < 5 # Less than: False
10 == 10 # Equal: True
10 != 5 # Not equal: True
Conditionals (If/Else)
Make decisions based on sensor readings:
from machine import Pin
sensor = Pin(14, Pin.IN, Pin.PULL_UP)
if sensor.value() == 0:
print("Line detected!")
else:
print("No line")
Multiple conditions:
sensor_left = Pin(14, Pin.IN, Pin.PULL_UP)
sensor_right = Pin(15, Pin.IN, Pin.PULL_UP)
if sensor_left.value() == 0 and sensor_right.value() == 0:
print("Both sensors on line")
elif sensor_left.value() == 0:
print("Left sensor on line")
elif sensor_right.value() == 0:
print("Right sensor on line")
else:
print("No line detected")
Loops (While and For)
While loop - Repeat until condition is false:
count = 0
while count < 10:
print(count)
count += 1 # Shorthand for count = count + 1
Infinite loop - Robot main loop:
while True:
# Read sensors
# Make decisions
# Control motors
time.sleep(0.01) # Small delay
For loop - Repeat a specific number of times:
for i in range(5):
print(i) # Prints 0, 1, 2, 3, 4
# Blink LED 10 times
for i in range(10):
led.toggle()
time.sleep(0.2)
Functions
Functions organize code into reusable blocks:
def blink_led(times, delay):
"""Blink LED a specific number of times"""
for i in range(times):
led.toggle()
time.sleep(delay)
# Call the function
blink_led(5, 0.3) # Blink 5 times, 0.3 second delay
blink_led(10, 0.1) # Blink 10 times, 0.1 second delay
Functions with return values:
def read_sensor():
"""Read sensor and return True if line detected"""
sensor = Pin(14, Pin.IN, Pin.PULL_UP)
return sensor.value() == 0 # Returns True or False
# Use the function
if read_sensor():
print("Line detected!")
Part 5: GPIO Control
GPIO (General-Purpose Input/Output) pins connect sensors and actuators to the microcontroller.
Digital Output (Control LED)
Wiring:
- LED long leg → GPIO pin 15
- LED short leg → 220Ω resistor → GND
Code:
from machine import Pin
led = Pin(15, Pin.OUT)
led.on() # Turn LED on (pin = HIGH = 3.3V)
led.off() # Turn LED off (pin = LOW = 0V)
led.value(1) # Alternative: 1 = on, 0 = off
led.toggle() # Switch state
Digital Input (Read Button)
Wiring:
- Button one side → GPIO pin 14
- Button other side → GND
- Internal pull-up resistor (no external resistor needed)
Code:
from machine import Pin
button = Pin(14, Pin.IN, Pin.PULL_UP)
while True:
if button.value() == 0: # Button pressed (connects to GND = LOW)
print("Button pressed!")
else:
print("Button not pressed")
time.sleep(0.1)
Why Pin.PULL_UP?
- Without pull-up, the input "floats" (undefined voltage) when button is not pressed
- Pull-up resistor connects input to 3.3V by default (HIGH)
- When button pressed, it connects to GND (LOW)
- This is an active LOW button (pressed = LOW)
Example: Button-Controlled LED
from machine import Pin
button = Pin(14, Pin.IN, Pin.PULL_UP)
led = Pin(15, Pin.OUT)
while True:
if button.value() == 0: # Button pressed
led.on()
else:
led.off()
Improvement: Toggle LED on button press
from machine import Pin
import time
button = Pin(14, Pin.IN, Pin.PULL_UP)
led = Pin(15, Pin.OUT)
last_button_state = 1 # Not pressed initially
while True:
button_state = button.value()
# Detect button press (transition from HIGH to LOW)
if button_state == 0 and last_button_state == 1:
led.toggle()
time.sleep(0.2) # Debounce delay
last_button_state = button_state
time.sleep(0.01)
Part 6: Analog Input (Read Variable Voltage)
Some sensors output variable voltage (temperature, light, distance). Use ADC (Analog-to-Digital Converter) to read them.
Reading a Potentiometer
Wiring:
- Potentiometer middle pin → GPIO 26 (ADC0)
- Potentiometer left pin → 3.3V
- Potentiometer right pin → GND
Code:
from machine import ADC, Pin
import time
pot = ADC(Pin(26)) # GPIO 26 is ADC0
while True:
value = pot.read_u16() # Read 16-bit value (0-65535)
voltage = value * 3.3 / 65535 # Convert to voltage
percent = value / 65535 * 100 # Convert to percentage
print(f"Value: {value}, Voltage: {voltage:.2f}V, Percent: {percent:.1f}%")
time.sleep(0.5)
What this does:
- pot.read_u16() - Returns 0 (0V) to 65535 (3.3V)
- Turn potentiometer dial and watch the value change
- This is how robots read analog sensors (photoresistors, battery voltage)
Example: ADC-Controlled LED Brightness
Note: This requires PWM, which we'll cover in MicroPython Programming. For now, we'll use a simple threshold:
from machine import ADC, Pin
import time
pot = ADC(Pin(26))
led = Pin(15, Pin.OUT)
while True:
value = pot.read_u16()
if value > 32768: # If pot is more than 50%
led.on()
else:
led.off()
time.sleep(0.1)
Part 7: Your First Robot Program
Let's combine everything into a simple robot behavior:
Scenario: A robot with two line sensors that follows a line.
Simplified hardware (for testing without a robot):
- 2 buttons represent line sensors (pressed = line detected)
- 2 LEDs represent motors (on = motor running)
Wiring:
- Button 1 (left sensor) → GPIO 14 → GND, with Pin.PULL_UP
- Button 2 (right sensor) → GPIO 15 → GND, with Pin.PULL_UP
- LED 1 (left motor) → GPIO 16 → 220Ω → GND
- LED 2 (right motor) → GPIO 17 → 220Ω → GND
Code:
from machine import Pin
import time
# Sensors (buttons for testing)
sensor_left = Pin(14, Pin.IN, Pin.PULL_UP)
sensor_right = Pin(15, Pin.IN, Pin.PULL_UP)
# Motors (LEDs for testing)
motor_left = Pin(16, Pin.OUT)
motor_right = Pin(17, Pin.OUT)
def drive_forward():
motor_left.on()
motor_right.on()
def turn_left():
motor_left.off()
motor_right.on()
def turn_right():
motor_left.on()
motor_right.off()
def stop():
motor_left.off()
motor_right.off()
# Main loop
while True:
left = sensor_left.value()
right = sensor_right.value()
# Both sensors on line (both buttons pressed)
if left == 0 and right == 0:
drive_forward()
# Left sensor on line, right sensor off
elif left == 0 and right == 1:
turn_left()
# Right sensor on line, left sensor off
elif left == 1 and right == 0:
turn_right()
# Neither sensor on line
else:
stop()
time.sleep(0.01) # Small delay
Try this:
- Press left button only → left LED off, right LED on (turning left)
- Press right button only → left LED on, right LED off (turning right)
- Press both buttons → both LEDs on (driving forward)
- Release both buttons → both LEDs off (stopped)
This is the foundation of Activity:Line Following!
Part 8: Saving Programs to Pico
Where Code is Stored
- main.py - Runs automatically when Pico powers on
- Other .py files - Can be imported as modules
Create a Startup Program
- Write your code in Thonny
- Click "Save as..." and choose MicroPython device
- Name it main.py
- Disconnect Pico and reconnect it
- Your program runs automatically!
Tip: Add a delay at the start so you can interrupt it if needed:
import time
time.sleep(2) # 2-second delay before starting
# Your code here
Organize Code into Modules
You can split code into multiple files:
robot.py (on Pico):
from machine import Pin
class Robot:
def __init__(self):
self.led = Pin(25, Pin.OUT)
def blink(self, times):
for i in range(times):
self.led.toggle()
time.sleep(0.2)
main.py (on Pico):
from robot import Robot
bot = Robot()
bot.blink(10)
Part 9: Debugging and Troubleshooting
Print Debugging
The most useful debugging technique is printing values:
while True:
sensor_value = sensor.value()
print(f"Sensor: {sensor_value}") # See what the sensor reads
if sensor_value == 0:
motor.on()
print("Motor ON") # Confirm this branch executes
else:
motor.off()
print("Motor OFF")
time.sleep(0.1)
LED Indicator Debugging
When you can't connect to serial console (robot is moving), use LED patterns:
def indicate_error():
for i in range(5):
led.toggle()
time.sleep(0.1) # Fast blink = error
def indicate_success():
led.on()
time.sleep(1) # Long on = success
led.off()
Common Errors
IndentationError: Python uses indentation (spaces/tabs) to group code:
# Wrong - inconsistent indentation
if sensor.value() == 0:
motor.on()
led.on() # Error: too many spaces
# Correct - consistent indentation
if sensor.value() == 0:
motor.on()
led.on()
NameError: Variable not defined:
# Wrong
print(speed) # Error: speed not defined
# Correct
speed = 100
print(speed)
AttributeError: Calling wrong method:
# Wrong
led.turnon() # Error: no such method
# Correct
led.on()
REPL Error Messages
Read error messages carefully - they tell you what's wrong:
Traceback (most recent call last): File "<stdin>", line 5, in <module> NameError: name 'speed' is not defined
- Line 5 - Error is on line 5
- NameError - Variable name doesn't exist
- speed not defined - You forgot to create variable "speed"
Part 10: Skills Checklist
By now, you should be able to:
- ☐ Install MicroPython on Raspberry Pi Pico
- ☐ Use Thonny IDE to write and run code
- ☐ Use the REPL to test code interactively
- ☐ Write Python variables, conditionals, loops, functions
- ☐ Control digital outputs (LEDs)
- ☐ Read digital inputs (buttons)
- ☐ Read analog inputs (potentiometer, sensors)
- ☐ Write a simple robot behavior (line following simulation)
- ☐ Save programs to Pico (main.py)
- ☐ Debug with print statements and LED indicators
If you can check most of these boxes, you're ready to program SimpleBot!
Next Steps
Build SimpleBot
Apply your MicroPython knowledge to a real robot:
- SimpleBot - Full robot assembly guide
- SimpleBot:Line Following Implementation - Real line following code
- SimpleBot:Dead Reckoning Implementation - Encoder-based odometry
Learn More Programming
- MicroPython Programming - Interrupts, PWM, I2C, state machines
- State Machine Design - Organize complex behaviors
- Software - Full competency overview
Practice Projects
- Reaction timer - Press button, wait random time, LED lights, measure reaction
- Light tracker - Use photoresistor to control LED brightness
- Morse code - Blink LED in Morse code patterns
- Night light - Turn LED on when photoresistor detects darkness
Common Beginner Mistakes
- Forgetting to import modules - Always from machine import Pin at the start
- Using time.sleep() in interrupts - Interrupts must be fast (no delays!)
- Not configuring pin mode - Always specify Pin.IN or Pin.OUT
- Forgetting pull-up/pull-down resistors - Digital inputs need them to avoid floating
- Mixing up HIGH/LOW logic - Check if sensor is active HIGH or active LOW
- Infinite loops without sleep - Always add small delay to avoid maxing out CPU
Tools and Resources
Essential Software
- Thonny IDE (Free) - thonny.org
- MicroPython Firmware (Free) - micropython.org
Hardware Needed
- Raspberry Pi Pico - $4 from Raspberry Pi
- USB cable (micro USB) - $2-5
- Breadboard - $5-10
- Jumper wires - $5-10
- LEDs and resistors - $5-10 for assorted kit
External Resources
- MicroPython Quick Reference for Pico
- Raspberry Pi Pico Getting Started
- Raspberry Pi Pico Documentation
- Python Tutorial - Learn Python language
See Also
- Software - Full software competency overview
- MicroPython Programming - Next tutorial in the learning path
- SimpleBot - Build a robot using MicroPython
- Electronics Fundamentals - Understand the hardware you're controlling