Learning MicroPython FAQ
Welcome to the Frequently Asked Questions page for Learning MicroPython and Physical Computing. Here you will find answers to the most common questions students, teachers, and makers ask. Use the search box at the top of the page to find a specific topic quickly.
Getting Started Questions
What is this course about?
This course teaches you how to write Python programs that control real hardware. You will blink LEDs, read sensors, spin motors, and even build robots — all using a tiny computer called a microcontroller. The branch of computer science that reads sensors and controls lights and motors is called physical computing, and this course is your hands-on introduction to it.
By the end of the course, you will be able to design and build your own projects from scratch. No prior programming or electronics experience is needed to begin.
See the Course Description for a full list of topics and learning goals.
Who is this course for?
This course was first built for students in 5th through 12th grade (ages 10–18), but people of all ages from around the world use it to learn MicroPython. If you have never programmed before and want to make things light up, move, and react to the world, this course is for you.
Parents, teachers, and hobbyists are also very welcome. The course moves at your own pace, so you can work through it as quickly or as slowly as you like.
What do I need to get started?
You need three things:
- A microcontroller — the $4 Raspberry Pi Pico is the recommended starting board.
- A USB cable — a standard USB Micro-B cable to connect the Pico to your computer.
- A few basic parts — LEDs, resistors, a solderless breadboard, and jumper wires. A starter kit costs under $20.
You also need a free program called Thonny on your computer. See Getting Started for a complete list and shopping links.
What is a microcontroller?
A microcontroller is a tiny computer built into a single chip. It has a processor, memory, and input/output pins all in one small package. Unlike a laptop or phone, a microcontroller does not run a full operating system. It runs one program at a time and uses its pins to talk to the physical world — reading sensors, lighting LEDs, or spinning motors.
The Raspberry Pi Pico uses the RP2040 chip. It costs $4 and has 264 KB of RAM — about 100 times more than an older Arduino Uno. That extra memory makes it easy to work with displays and complex programs.
See Introduction to Microcontrollers for more details.
What is the Raspberry Pi Pico?
The Raspberry Pi Pico is a small, low-cost microcontroller board made by the Raspberry Pi Foundation. It uses the RP2040 chip and costs about $4. The Pico has 26 GPIO (General-Purpose Input/Output) pins you can use to connect sensors, displays, motors, and more.
There are several versions:
- Pico — basic board, no wireless
- Pico W — adds Wi-Fi
- Pico 2 — newer version with more memory and speed
Most lessons in this course use the original Pico or Pico W. See Getting Started with the Raspberry Pi Pico for setup steps.
What is MicroPython?
MicroPython is a version of Python designed to run on small microcontrollers. It includes most of the features of regular Python, plus special libraries for controlling hardware — reading pins, driving motors, and talking to displays.
MicroPython was created by Damien George and first released in 2014. It is now the most popular way to program microcontrollers with Python because it is easy to learn, runs fast enough for most projects, and works on many different boards.
See the Glossary for a quick definition, or the Course Description for a comparison between MicroPython and standard Python.
How do I set up my computer to use MicroPython?
The easiest setup uses a free program called Thonny. Here are the basic steps:
- Download and install Thonny from thonny.org.
- Connect your Pico to your computer with a USB cable.
- Hold the BOOTSEL button on the Pico, plug it in, then release the button.
- In Thonny, go to Tools → Options → Interpreter and choose MicroPython (Raspberry Pi Pico).
- Click Install or update MicroPython to flash the firmware.
After these steps, you can type code directly into the Thonny shell and run it on your Pico. See Getting Started with Thonny for a full walkthrough with screenshots.
What is Thonny?
Thonny is a free, lightweight code editor designed for beginners. It runs on Windows, Mac, and Linux. Thonny lets you write and run MicroPython programs on your Pico, see error messages in plain language, and even step through your code one line at a time to find bugs.
It is the recommended editor for this course. Advanced users may prefer VS Code — see Getting Started with VS Code for that setup.
Can I use an ESP32 instead of a Raspberry Pi Pico?
Yes! The ESP32 is another popular microcontroller that runs MicroPython. It has built-in Wi-Fi and Bluetooth and typically costs around $5–$10. Many of the lessons in this course work on an ESP32 with small changes.
The main difference is that the Pico is simpler and cheaper for beginners, while the ESP32 is better for wireless projects from the start. See Getting Started with ESP32 for setup steps.
Do I need to know Python before I start?
No prior Python knowledge is required. The course starts from the very beginning and teaches you the programming concepts you need as you go. If you already know some Python, you will move through the early sections quickly.
The course covers variables, loops, functions, and modules — all the Python basics you need to write real hardware programs.
How long does the course take to complete?
That depends on how much time you spend on it. Most students can finish the Getting Started section and Basic Examples in a few afternoons. The full course — including sensors, motors, displays, sound, and robots — can take a semester at school or a few months of weekend learning at home.
There is no deadline. You can go at your own pace and skip to sections that interest you most.
Where can I ask questions or get help?
The best place to ask questions is the GitHub Discussions page for this project:
https://github.com/dmccreary/learning-micropython/discussions
You can also use the search function at the top of this website to find an answer quickly. If you find a bug or want to suggest a topic, open an issue on GitHub or see the Contributing Guide.
Core Concept Questions
What is physical computing?
Physical computing means writing programs that interact with the real, physical world. Instead of just showing text on a screen, a physical computing program might turn on a light when it gets dark, play a sound when a button is pressed, or stop a robot when an obstacle is detected.
Physical computing connects two worlds: software (the code you write) and hardware (the wires, sensors, and motors). MicroPython is one of the best tools for learning physical computing because you see results immediately.
See Introduction to Physical Computing for more.
What is a GPIO pin?
GPIO stands for General-Purpose Input/Output. These are the small metal pins on the side of your Pico. You can use them to:
- Output: send a signal to turn on an LED, buzzer, or motor
- Input: read a signal from a button, sensor, or switch
The Raspberry Pi Pico has 26 GPIO pins. Each one has a number (GP0 through GP28). When you write MicroPython code, you use these GP numbers to tell the Pico which pin to use.
See the Raspberry Pi Pico setup page for the full pinout diagram.
What is a breadboard?
A breadboard is a plastic board with lots of small holes that let you connect electronic parts without soldering. The holes are wired together in rows and columns underneath, so you can connect components like LEDs, resistors, and sensors by simply pushing their legs into the right holes.
Breadboards make it easy to try circuits, move parts around, and fix mistakes — perfect for learning. All labs in this course use a solderless breadboard.
See Getting Started with Breadboards for a guide to how breadboard connections work.
What is PWM?
PWM stands for Pulse-Width Modulation. It is a way to control the average power going to a device by switching it on and off very quickly. The percentage of time it is "on" is called the duty cycle.
For example: - 100% duty cycle → full brightness (or full speed) - 50% duty cycle → half brightness (or half speed) - 0% duty cycle → off
MicroPython uses the machine.PWM class to create PWM signals. You use PWM to fade LEDs, control motor speed, and move servo motors.
See Basic Examples: Fade In and Out for a hands-on PWM example.
What is I2C?
I2C (pronounced "I-squared-C") stands for Inter-Integrated Circuit. It is a simple two-wire communication protocol that lets your microcontroller talk to sensors and displays. The two wires are:
- SDA — Serial Data line (carries the data)
- SCL — Serial Clock line (keeps both devices in sync)
I2C is popular because you can connect many devices to the same two wires. Each device has a unique I2C address so the Pico knows which one to talk to. MicroPython uses the machine.I2C class to communicate over I2C.
Many sensors and OLED displays in this course use I2C. See Advanced Labs: I2C Scanner to learn how to find connected I2C devices.
What is SPI?
SPI stands for Serial Peripheral Interface. Like I2C, SPI lets your Pico talk to sensors and displays. SPI uses four wires (MOSI, MISO, SCK, and CS) and is generally faster than I2C, making it good for displays that need to refresh quickly.
MicroPython uses the machine.SPI class to communicate over SPI. Some of the graphical LCD displays in this course use SPI for faster drawing.
What is an ADC?
ADC stands for Analog-to-Digital Converter. Most of the world is analog — light, temperature, and sound all change smoothly between values. But microcontrollers only understand digital values (numbers). An ADC measures an analog voltage and converts it into a number your program can use.
The Raspberry Pi Pico has three ADC inputs (pins GP26, GP27, and GP28). Each one measures voltages from 0 to 3.3 V and returns a number from 0 to 65535. MicroPython uses the machine.ADC class to read these values.
See Sensors: Potentiometer for a simple ADC example using a potentiometer.
What is the REPL?
REPL stands for Read-Evaluate-Print Loop. It is the interactive shell you see at the bottom of Thonny. You type a line of Python, press Enter, and the Pico runs it immediately and shows the result.
The REPL is great for experimenting. You can test a single line of code without writing a full program. For example, type print("Hello!") in the REPL and press Enter — the Pico prints Hello! right away.
What is a loop in MicroPython?
A loop is a block of code that runs over and over. In MicroPython programs for hardware, the most common loop is while True: — this runs forever until you stop the program or the Pico loses power.
1 2 3 4 5 6 7 8 | |
A for loop runs a fixed number of times, like when you want to light up each NeoPixel in a strip one by one.
See Basic Examples: Blink for your first while True: program.
What is debouncing?
When you press a button, the metal contacts inside it bounce very quickly before settling into the pressed position. This can cause your program to see many button presses instead of just one.
Debouncing is the fix. Software debouncing adds a small delay after detecting a press before checking again, ignoring the noise. Hardware debouncing uses a capacitor to smooth out the signal.
See Basic Examples: Buttons for a debouncing example in MicroPython.
What is a NeoPixel?
A NeoPixel is a small, full-color LED that you can control with a single wire from your microcontroller. Each NeoPixel contains red, green, and blue LEDs, so you can set it to any color by mixing those three values. NeoPixels are also called "WS2812B" LEDs.
You can connect many NeoPixels in a strip or ring, and control each one individually. MicroPython has a built-in neopixel module that makes this easy.
See Basic Examples: NeoPixel for your first color program.
What is a servo motor?
A servo motor is a special motor that turns to a specific angle and holds it there. Servos are used in robots to move arms, tilt sensors, and steer wheels. A standard servo can turn between 0° and 180°. A continuous rotation servo spins like a regular motor but with speed control.
You control a servo with a PWM signal at 50 Hz. The length of each pulse tells the servo what angle to move to. MicroPython uses the machine.PWM class to generate this signal.
See Basic Examples: Servo for a hands-on servo example.
What is a sensor?
A sensor is a device that measures something in the physical world and converts it into an electrical signal your microcontroller can read. Common sensors in this course include:
- DHT11/DHT22 — temperature and humidity
- HC-SR04 — distance using ultrasonic sound
- VL53L0X — distance using a laser beam (time-of-flight)
- APDS9960 — gesture, color, and proximity
- HMC5883L — magnetic field (compass)
- Photoresistor (LDR) — light level
Each sensor has its own way of connecting and communicating. Many use I2C or simple digital/analog signals. See the Sensors section for labs covering each type.
What is computational thinking?
Computational thinking is a way of solving problems. It has four key steps:
- Decomposition — break a big problem into smaller, simpler pieces
- Pattern recognition — find similarities between problems you have already solved
- Abstraction — focus on the important parts, ignore the details that do not matter
- Algorithms — write a step-by-step plan for solving the problem
Every MicroPython project in this course uses computational thinking. When you build a robot, for example, you decompose it into: power, motors, sensors, and control logic — then solve each piece separately.
What is a function in MicroPython?
A function is a reusable block of code that you give a name. Instead of writing the same code over and over, you define a function once and call it whenever you need it. In MicroPython:
1 2 3 4 5 6 7 | |
Then you can call blink_led(15, 3) to blink the LED on GPIO 15 three times. Functions make your programs shorter, easier to read, and easier to fix.
What is a module in MicroPython?
A module is a file that contains Python code you can use in other programs. You load a module with the import statement. MicroPython has many built-in modules:
machine— controls hardware pins, ADC, PWM, I2C, SPIutime— provides timing functions likesleep()neopixel— drives NeoPixel LED stripsnetwork— connects to Wi-Fi (Pico W)
You can also install extra driver modules to support specific sensors and displays. See Getting Started: MicroPython Libraries for how to install them.
What is a wiring diagram?
A wiring diagram shows you how to connect the parts of a circuit together. It uses pictures of the components — LEDs, resistors, sensors, the Pico — and lines to show which wire goes where.
Every lab in this course includes a wiring diagram so you know exactly where to plug each wire. You do not need to know electronics theory to follow a wiring diagram — just match the colors and pin labels.
What is the difference between I2C and SPI, and when should I use each?
Both I2C and SPI are ways for your Pico to talk to sensors and displays, but they make different trade-offs:
| Feature | I2C | SPI |
|---|---|---|
| Wires needed | 2 (SDA + SCL) | 4 (MOSI, MISO, SCK, CS) |
| Speed | Slower (up to 400 kHz typical) | Faster (up to 40 MHz) |
| Devices on one bus | Many (each has a unique address) | One at a time per CS pin |
| Wiring complexity | Simple | More wires, one CS pin per device |
Use I2C when you have many devices (sensors, displays) to connect and speed is not critical. Most OLED displays and environmental sensors use I2C.
Use SPI when you need fast data transfer — for example, a color TFT display that redraws the full screen many times per second.
See Advanced Labs: I2C Scanner and Displays Graphical for side-by-side examples of both protocols in use.
What are the trade-offs between the HC-SR04 and VL53L0X distance sensors?
Both sensors measure distance, but they work differently and suit different projects:
| Feature | HC-SR04 (Ultrasonic) | VL53L0X (Time-of-Flight Laser) |
|---|---|---|
| Technology | Sound pulse | Infrared laser |
| Range | 2 cm – 400 cm | 3 cm – 120 cm |
| Accuracy | ±3 mm typical | ±1 mm typical |
| Cost | ~$1–$2 | ~$5–$8 |
| Interface | Two digital pins (Trigger + Echo) | I2C |
| Works on dark surfaces? | Yes | Yes |
| Works on soft/angled surfaces? | Less reliable | More reliable |
Choose the HC-SR04 for budget robot collision avoidance where rough distance measurements are enough. It needs 5 V power and two GPIO pins.
Choose the VL53L0X when you need more accurate readings in a smaller package, or when you are already using I2C for other sensors and want to keep wiring simple.
See Sensors: Ping Distance and Sensors: Time of Flight Distance for code examples for each.
How do I make patterns on a NeoPixel strip?
NeoPixel patterns work by setting each pixel to a color inside a loop, then calling np.write() to send all the colors to the strip at once. Here is a simple "chase" pattern:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
You can build rainbow effects by cycling through hue values, or meter effects by lighting a number of pixels based on a sensor reading. See Basic Examples: NeoPixel and the NeoPixel Kit labs for more pattern ideas.
Technical Detail Questions
What is the RP2040 chip?
The RP2040 is a custom microcontroller chip designed by the Raspberry Pi Foundation. It powers the Raspberry Pi Pico. Key specs:
- Processor: Dual-core ARM Cortex-M0+ running up to 133 MHz
- RAM: 264 KB of SRAM (much more than older Arduinos)
- Flash: 2 MB on-board (for storing your programs)
- GPIO: 26 multi-function pins
- ADC: Three 12-bit analog inputs
The RP2040 also has 8 programmable I/O (PIO) state machines, which let it emulate almost any communication protocol. See Getting Started with the Raspberry Pi Pico for the full specs.
What is a UF2 file?
A UF2 file is the file you drag onto the Pico to install MicroPython firmware. When you hold the BOOTSEL button while plugging in the Pico, it appears on your computer as a USB drive called RPI-RP2. You drag the MicroPython UF2 file onto that drive, and the Pico automatically installs the firmware and restarts.
You only need to do this once unless you want to update MicroPython to a newer version.
What is BOOTSEL?
BOOTSEL is a small button on the top of the Raspberry Pi Pico. When you hold it down while plugging the Pico into USB, the Pico enters bootloader mode and appears as a USB storage drive on your computer. This is how you install or update MicroPython firmware.
After flashing, the Pico restarts automatically and you can program it normally through Thonny.
What is the machine module?
The machine module is MicroPython's main hardware control library. You use it to:
machine.Pin— control GPIO pins (on/off, read buttons)machine.PWM— create PWM signals (fade LEDs, drive servos)machine.ADC— read analog voltages (sensors, potentiometers)machine.I2C— communicate with I2C devices (sensors, OLED displays)machine.SPI— communicate with SPI devices (fast displays)
Almost every program in this course starts with from machine import Pin or a similar import from the machine module.
What does Pin.OUT mean?
When you set up a GPIO pin, you tell MicroPython whether the pin is an output or an input:
Pin.OUT— the Pico sends a signal OUT through this pin. Use this for LEDs, buzzers, and motor control signals.Pin.IN— the Pico reads a signal coming IN on this pin. Use this for buttons and sensors.
Example:
1 2 | |
What is a pull-up resistor?
When a GPIO pin is set to input mode, it can float between high and low if nothing is connected — giving random readings. A pull-up resistor connects the pin to 3.3 V through a large resistor (usually 10,000 ohms), so the pin reads HIGH when the button is not pressed and LOW when it is pressed.
The Pico has built-in pull-up resistors you can turn on in software:
1 | |
This saves you from adding an external resistor to your circuit. See Basic Examples: Buttons for a full example.
What is an interrupt?
An interrupt is a signal that pauses your main program and runs a special function immediately. For example, if you press a button very quickly, your while True: loop might miss it if it is busy doing something else. An interrupt catches the button press no matter what.
In MicroPython, you set up an interrupt with the .irq() method on a Pin object:
1 2 3 4 5 | |
See Advanced Labs: Interrupt Handlers for a full example.
What is an I2C address?
Every device on an I2C bus has a unique address — a number that identifies it. When the Pico wants to talk to an OLED display, it sends the display's I2C address first so all devices on the bus know who should listen.
Common I2C addresses:
- SSD1306 OLED display: usually 0x3C or 0x3D
- DHT11 — not I2C (uses its own protocol)
- VL53L0X time-of-flight sensor: 0x29
If you are not sure what address your device uses, run an I2C scanner. See Advanced Labs: I2C Scanner for scanner code.
What is a framebuffer?
A framebuffer is a section of RAM that stores a picture of what should be on your display. When you draw a line, circle, or text in MicroPython, you are actually drawing into the framebuffer first. Then you call .show() to send the whole framebuffer to the display at once — this makes the screen update look smooth.
For a 128×64 pixel monochrome OLED, the framebuffer needs 128 × 64 = 8,192 bits (1 KB) of RAM. The Pico's 264 KB of RAM makes this easy. See Advanced Labs: Frame Buffer for details.
What is firmware?
Firmware is the software built into a device that makes it work. For the Raspberry Pi Pico, firmware is the MicroPython interpreter itself — the program stored in the Pico's flash memory that reads and runs your MicroPython code.
You install firmware once by dragging a UF2 file onto the Pico in bootloader mode. When you update MicroPython to a newer version, you are updating the firmware.
What is the utime module?
The utime module provides time-related functions in MicroPython. The most commonly used function is utime.sleep(), which pauses your program for a number of seconds:
1 2 3 4 | |
You also use utime.ticks_ms() to measure how much time has passed — useful for debouncing and timing events without using sleep().
What is a DHT11 sensor?
The DHT11 is a low-cost sensor that measures temperature and humidity. It connects to a single GPIO pin on your Pico and sends data using its own simple protocol. MicroPython has a built-in dht module that makes reading it easy:
1 2 3 4 5 6 7 | |
See Sensors: Temperature and Humidity for a full wiring diagram and program.
What is an OLED display?
OLED stands for Organic Light-Emitting Diode. An OLED display is a small, bright screen with high contrast and a wide viewing angle. The most common size in this course is 128×64 pixels — about 1 inch diagonally — and costs around $4–$5.
OLED displays connect over I2C or SPI and use the SSD1306 or SH1106 driver chip. MicroPython has a driver for both. You can draw pixels, lines, rectangles, and text onto the display.
See Displays Graphical: OLED Setup to get started.
What are PIO state machines and what can they do?
PIO stands for Programmable I/O. The RP2040 chip inside the Pico has 8 PIO state machines — tiny programmable processors that run independently from the main CPU. They are designed to handle precise, high-speed input/output tasks that would be too fast or too timing-sensitive for regular MicroPython code.
PIO state machines can:
- Generate WS2812B NeoPixel signals at exactly the right timing (MicroPython's built-in
neopixelmodule uses PIO under the hood) - Drive stepper motors with exact pulse timing
- Emulate communication protocols not natively supported by the hardware
- Read quadrature encoders at high speed without CPU interrupts
You program PIO state machines using a small assembly-like language called PIO assembly. This is an advanced topic — most projects use drivers that already handle PIO for you. See the PIO Labs section for an introduction.
How do I install the SSD1306 OLED driver?
The SSD1306 is the chip that controls most 128×64 OLED displays. MicroPython does not include the driver by default on all boards, so you may need to copy it to your Pico manually.
Option 1 — Use the built-in driver (Pico)
On the Raspberry Pi Pico, MicroPython includes ssd1306 as a built-in module. Just import it:
1 | |
If you get an ImportError, use Option 2.
Option 2 — Copy the driver file
- Download
ssd1306.pyfrom the MicroPython GitHub repository. - In Thonny, open the Files panel, find
ssd1306.pyon your computer, right-click it, and choose Upload to /. - Now
from ssd1306 import SSD1306_I2Cwill work.
See Displays Graphical: OLED Setup for the full wiring diagram and first drawing program.
Common Challenge Questions
My LED does not light up. What do I check?
Work through this checklist one step at a time:
- Polarity — LEDs only work one way. The longer leg (anode) connects to the GPIO pin. The shorter leg (cathode) connects to GND.
- Resistor — always use a current-limiting resistor (typically 330 Ω) in series with the LED. Without it, you may burn out the LED or damage the Pico.
- Pin number — check that the pin number in your code matches the GP number on the pin you used, not the physical pin number on the board.
- Code — make sure your code is actually running and has no errors. Check the Thonny shell for error messages.
- USB connection — confirm the Pico is connected and Thonny is set to the MicroPython interpreter.
See Basic Examples: Blink for a working starter program to test with.
I see an ImportError. What does that mean?
An ImportError means MicroPython cannot find the module you are trying to import. This usually means:
- The module name is spelled wrong — check capitalisation. Python is case-sensitive:
import neopixelnotimport NeoPixel. - The driver file has not been copied to the Pico. For example,
ssd1306.pymust be on the Pico before you canimport ssd1306.
To copy driver files to the Pico, use the Thonny file manager or the mpremote tool. See Getting Started: MicroPython Libraries for instructions.
My sensor gives wrong readings. What do I check?
Sensor problems are usually one of three things:
- Wrong wiring — double-check VCC, GND, SDA, and SCL connections against the wiring diagram. Swapping SDA and SCL is a common mistake.
- Wrong I2C pins — the Pico has two I2C buses (I2C0 and I2C1). Make sure the pins in your code match the physical pins you wired.
- Missing driver — some sensors need a driver file (like
bme280.py). Make sure it is copied to the Pico.
If you have an OLED or I2C sensor that shows nothing, run an I2C scanner first to confirm the device is detected. See Advanced Labs: I2C Scanner.
My display shows nothing. What do I check?
For an OLED or LCD display that is blank:
- Power — check that 3.3 V and GND are connected correctly.
- I2C wiring — confirm SDA and SCL are on the right pins.
- I2C address — the default address in most drivers is
0x3C. Your display may use0x3D. Run an I2C scanner to find the real address. - Calling
.show()— drawing functions update the framebuffer, but nothing appears on screen until you calloled.show(). Make sure that call is in your code.
See Displays Graphical: OLED Setup for a step-by-step setup guide.
My Pico will not connect to my computer. What do I do?
Try these steps in order:
- Try a different USB cable — many cables are charge-only and do not carry data.
- Try a different USB port on your computer.
- Reinstall the firmware — hold BOOTSEL, plug in the Pico, drag the MicroPython UF2 file onto the RPI-RP2 drive.
- Restart Thonny — close and reopen Thonny, then check that the interpreter is set to MicroPython (Raspberry Pi Pico).
If the Pico is stuck in a crash loop (a program with an error runs on boot), you can stop it by pressing the STOP button in Thonny right after connecting. See Debugging for more troubleshooting tips.
I get an IndentationError. What does that mean?
Python uses indentation (spaces or tabs at the start of a line) to show what code belongs inside a loop, function, or if-statement. An IndentationError means the indentation is inconsistent — for example, you mixed tabs and spaces, or you forgot to indent a line inside a while loop.
Fix: In Thonny, go to Options → Editor and check "Use spaces instead of tabs." Always use 4 spaces per level of indentation.
1 2 3 | |
My motor only runs in one direction. What do I check?
DC motors need an H-bridge circuit to run in both directions. The H-bridge lets you reverse the current through the motor. Common H-bridge chips used in this course are the L293D and DRV8833.
Check: 1. Are both motor control pins connected to the H-bridge? 2. Is your code setting both pins, not just one? 3. Is the H-bridge powered correctly (some need 5 V for the motor, 3.3 V for logic)?
See Motors: H-Bridge and Motors: L293D Chip for wiring diagrams and example code.
How do I know which GPIO pin to use?
All GPIO pins (GP0–GP28) can be used for basic digital input and output. However, some pins have special functions:
- GP26, GP27, GP28 — also ADC inputs (for reading analog sensors)
- Specific I2C pins — I2C0 uses GP0/GP1 by default; I2C1 uses GP2/GP3
- SPI pins — check the datasheet for default SPI pin assignments
The pinout diagram on the Raspberry Pi Pico setup page shows every pin and its functions. Keep that page handy when wiring new projects.
My code was working, and now it stops after a few seconds. What happened?
A few common causes:
- Power problem — if you are running motors or many LEDs from USB power, you may be drawing too much current. Add a separate battery pack for motors.
- Memory error — if you see
MemoryError, your program is using too much RAM. Free up memory by deleting unused variables or simplifying your code. - Infinite loop mistake — check if your loop has an exit condition that is being met accidentally.
- Hardware fault — check all wiring connections. A loose wire can cause intermittent failures.
See Debugging for a systematic approach to tracking down these issues.
Best Practice Questions
How do I organize my MicroPython project files?
A clean project structure makes your code easier to understand and fix:
1 2 3 4 5 | |
Keep all driver files in the same folder as main.py. Put hardware pin numbers and settings in a separate config.py file so you can change them without hunting through your main code.
See Basic Examples: Config for an example config.py.
What is a config.py file?
A config.py file stores the settings for your project — mainly which GPIO pins you connected things to. Instead of hard-coding pin numbers inside every function, you import them from config.py:
1 2 3 4 5 | |
Then in main.py:
1 | |
This is a key example of abstraction from computational thinking. If you rewire a motor to a different pin, you only change one line in config.py instead of hunting through your whole program.
How do I save my program so it runs automatically when the Pico powers on?
Save your program as main.py on the Pico. When the Pico powers on, it automatically runs main.py first. If you also have a boot.py, that runs before main.py — use it for setup tasks like connecting to Wi-Fi.
In Thonny, save your file using File → Save As and choose the MicroPython device, not your computer.
How do I install driver libraries on my Pico?
Driver libraries are .py files that you copy onto the Pico. You can do this two ways:
- Thonny file manager — open the Files panel in Thonny, find the driver file on your computer, right-click it, and choose "Upload to /".
mpremotetool — use the command line:mpremote cp ssd1306.py :ssd1306.py
After copying, you can import ssd1306 in your program just like any other module.
See Getting Started: MicroPython Libraries for a list of common drivers and where to find them.
When should I use while True: versus a timer?
Use while True: when your program only does one thing repeatedly — like reading a sensor and printing the value. It is simple and easy to understand.
Use a timer when you need things to happen at precise intervals without blocking the rest of your program. For example, a timer can flash an LED every 500 ms while the main loop reads buttons.
1 2 3 4 5 6 | |
See Advanced Labs: Timers for more timer examples.
How do I use AI tools to help me code MicroPython?
AI assistants like Claude and ChatGPT can help you understand MicroPython concepts, generate starter code, and debug errors. To get the best help:
- Be specific — mention your board (Raspberry Pi Pico), sensor (DHT11), and what you want to do (read temperature and print it).
- Paste your error message — AI tools can explain error messages and suggest fixes.
- Review before running — always read AI-generated code before running it. AI can make mistakes, especially with pin numbers.
- Ask follow-up questions — if the code does not work, describe what happened and ask for help.
See the Prompts section for example prompts that work well for MicroPython learning.
What is the right way to connect multiple I2C devices?
You can connect many I2C devices to the same two wires (SDA and SCL) as long as each device has a different I2C address. Simply connect all devices' SDA pins together, all SCL pins together, and all GND pins together.
Steps:
1. Run an I2C scanner to confirm each device has a unique address.
2. Create one I2C object in your code.
3. Initialize each driver with that same I2C object.
If two devices share the same address (a common problem), some sensors let you change their address by soldering a jumper or connecting an address pin to 3.3 V.
How do I share my project with others?
The best way to share is to put your code on GitHub. You upload your main.py, config.py, and any driver files, along with a README that explains what your project does and how to wire it.
You can also contribute to this course by submitting a pull request. See About This Site for the different ways to contribute, including Git pull requests, GitHub Issues, and even sending raw documents.
How does blocking timing with sleep() differ from non-blocking timing?
Blocking timing uses utime.sleep(). While the Pico is sleeping, it cannot do anything else — it is frozen. This is fine for simple programs that only do one thing at a time:
1 2 3 | |
Non-blocking timing uses utime.ticks_ms() to check how much time has passed without stopping the program. Your loop keeps running and can do other work:
1 2 3 4 5 6 7 | |
Rule of thumb: use sleep() when your program only does one thing. Use ticks_ms() (or a Timer) when you need to keep doing other work between readings, like updating a display while also polling buttons.
See Advanced Labs: Timers for timer-based non-blocking patterns.
Which microcontroller should I choose for a wireless sensor project?
For a project that needs to send sensor data over Wi-Fi, you have two main options:
| Board | Cost | Wi-Fi | Setup difficulty | Best for |
|---|---|---|---|---|
| Raspberry Pi Pico W | ~$6 | Built-in | Easy | Beginners, MicroPython projects |
| ESP32 | ~$5–$10 | Built-in | Easy | Beginners, wider community resources |
| Raspberry Pi Pico (original) | $4 | None | N/A — no wireless | Wired projects only |
Both the Pico W and the ESP32 are excellent choices. The Pico W uses the same RP2040 chip as the rest of this course, so your existing code needs fewer changes. The ESP32 has a larger online community and more code examples for IoT projects.
If you are already comfortable with the Pico, start with the Pico W. See Wireless: Connecting to Wi-Fi for a Pico W setup guide, or Getting Started with ESP32 for the ESP32 path.
How do I decide between using a servo and a DC motor?
Both move things, but they are designed for different jobs:
| Feature | Servo Motor | DC Motor |
|---|---|---|
| Motion type | Precise angle (0°–180°) | Continuous spinning |
| Speed control | Limited (position only) | Full range with PWM |
| Direction control | Implicit (set angle) | Needs H-bridge |
| Cost | ~$3–$5 | ~$1–$3 |
| Best for | Arms, tilts, steering | Wheels, fans, conveyor belts |
Choose a servo when you need to move something to a specific position and hold it there — a robot arm, a sensor pan-and-tilt mount, or a steering mechanism.
Choose a DC motor when you need continuous spinning — robot drive wheels, a fan, or a winch. Pair it with an H-bridge driver (like the DRV8833) to control speed and direction.
Some projects use both: DC motors for the wheels and servos for the arm or camera mount. See Basic Examples: Servo and Motors: H-Bridge for hands-on code for each type.
Advanced Topic Questions
How do I connect my Pico W to Wi-Fi?
The Pico W has a built-in Wi-Fi chip. To connect, use the network module:
1 2 3 4 5 6 7 8 9 10 | |
Once connected, you can make HTTP requests to fetch data from the internet, or build a simple web server that shows sensor readings in a browser.
See Wireless: Connecting to Wi-Fi and Wireless: Web Server for full examples.
How do I build a robot with MicroPython?
A basic collision-avoidance robot needs four things:
- Drive motors — two DC motors with an H-bridge driver (like the DRV8833)
- Distance sensor — an HC-SR04 or VL53L0X to detect obstacles
- Microcontroller — a Raspberry Pi Pico (or the Cytron Maker Pi RP2040, which has motors and drivers built in)
- Power — a battery pack
The robot runs a loop: measure distance, if too close then reverse and turn, else go forward. This is a simple but powerful example of computational thinking — a real algorithm controlling real hardware.
See Robots: Base Bot and the Kits: Maker Pi RP2040 Robot section for step-by-step assembly and code.
What is multi-core programming on the RP2040?
The RP2040 chip inside the Pico has two processor cores that can run code at the same time. This is called multi-core programming. You can run your main program on Core 0 and a background task (like reading a sensor) on Core 1.
MicroPython supports this with the _thread module:
1 2 3 4 5 6 7 8 | |
This is an advanced topic but very useful for projects that need to do two things at once — for example, playing music while also controlling a motor.
See Advanced Labs: Multi-Core Programming for a full example.
What is TinyML and can I use it on a Pico?
TinyML is Tiny Machine Learning — running machine learning models on small, low-power devices. The Raspberry Pi Pico has just enough RAM and processing power to run simple TinyML models for tasks like detecting a specific sound or recognizing a motion pattern.
This is an advanced topic that requires training a model on a computer first, then deploying the tiny version to the Pico. It uses libraries like TensorFlow Lite Micro.
See Advanced Labs: TinyML for an introduction to running ML on the Pico.
What is a spectrum analyzer?
A spectrum analyzer shows you the frequencies present in a sound — a visual display where each bar represents how loud a particular frequency is. Low bars are bass notes; high bars are treble notes.
Building a spectrum analyzer on the Pico uses a microphone (INMP441), the I2S bus to read audio data, and a Fast Fourier Transform (FFT) algorithm to break the audio into frequency bands. The results can be shown on an OLED display.
This project combines sensors (microphone), communication protocols (I2S), advanced math (FFT), and display programming — one of the most impressive things you can build with a Pico.
See Advanced Labs: Spectrum Analyzer for the full project.
How do I convert an Arduino or CircuitPython project to MicroPython?
Converting from Arduino (C/C++) to MicroPython means rewriting the code in Python. The logic stays the same, but the syntax and libraries are different. For example, digitalWrite(pin, HIGH) in Arduino becomes pin.on() or pin.value(1) in MicroPython.
Converting from CircuitPython to MicroPython is easier because both use Python. The main differences are in the libraries — CircuitPython uses board and busio, while MicroPython uses machine. You usually need to swap the import statements and adjust a few function names.
See Advanced Labs: Converting CircuitPython to MicroPython for a side-by-side comparison and conversion tips.
Where can I find more MicroPython projects after I finish this course?
After finishing the core labs, there are several related sites with more advanced MicroPython projects:
- Moving Rainbow — full curriculum around LED strips and costumes
- Clocks and Watches — dozens of clock projects using the Pico W
- Robot Day — details for running a robot-building event at your school
- Beginning Electronics — deeper electronics theory to complement your MicroPython skills
When you are ready to step beyond the Pico, the AI Racing League moves on to full Python, machine learning, and computer vision on Raspberry Pi single-board computers.
How do I send sensor data to a web server?
Once your Pico W is connected to Wi-Fi, you can send sensor readings to a web server using HTTP. The simplest approach is to run a tiny web server on the Pico itself, so any browser on your network can see the data:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
Open a browser on your phone or computer, type in the Pico's IP address, and you will see the live sensor reading. For a more complete example with a proper HTML page, see Wireless: Web Server and Wireless: Display Forecast on OLED.
What is the Maker Pi RP2040 kit?
The Cytron Maker Pi RP2040 is a $10 robotics board that packs everything you need to build a robot into one board. It uses the same RP2040 chip as the Raspberry Pi Pico and is designed to make robotics as easy as possible.
What is built in:
- Two motor drivers — drive two DC motors directly, no separate H-bridge needed
- 13 blue status LEDs — one per GPIO pin, so you can see your program's state at a glance
- 2 NeoPixel RGB LEDs — for color indicators
- Piezo buzzer — for sounds and tones
- 4 servo connectors — plug servos straight in
- 7 Grove connectors — connect sensors with a single cable, no breadboard needed
- 4 motor test buttons — test motors without writing any code
The kit is ideal for building collision-avoidance and line-following robots quickly. See the Maker Pi RP2040 Kit and the Maker Pi RP2040 Robot sections for labs and assembly instructions.
How does a line-following robot work?
A line-following robot uses IR (infrared) sensors mounted on the bottom of the chassis to detect whether the robot is over a line or off it. Each IR sensor shines infrared light downward and measures how much bounces back:
- Dark line on light floor → sensor reads
0(line detected) - Light floor → sensor reads
1(no line)
The robot's program reads two sensors — one on the left and one on the right — and adjusts the motors to keep both sensors near the edge of the line:
- Both sensors off the line → go straight
- Left sensor on the line → turn left (slow down left motor)
- Right sensor on the line → turn right (slow down right motor)
This is a classic example of a feedback control loop — the sensor output continuously corrects the motor output to follow the path. Getting it working requires carefully adjusting the IR sensor sensitivity trim potentiometers and tuning motor speeds for your surface.
A basic kit costs about $20. See Kits: Line Follower for the complete parts list, wiring, and MicroPython code.
What are MicroSims?
MicroSims are small interactive simulations that run in your web browser. They let you explore MicroPython and electronics concepts without needing any hardware. You can adjust sliders, press buttons, and see results instantly.
This course includes MicroSims for:
- The Learning Graph — explore how concepts connect and depend on each other
- Breadboard simulation — practice wiring before touching real hardware
- Concept importance — see which concepts are most central to the course
MicroSims are also available on Wokwi — a free online MicroPython emulator where you can write and run code for a virtual Pico without any physical board.
See the MicroSims section to explore all the interactive tools in this course.