Skip to content

Python Basics for MicroPython

Introduction

MicroPython is a subset of Python optimized for microcontrollers. If you're familiar with C, you'll find MicroPython much easier to write and read. This section covers Python fundamentals relevant to embedded programming, with comparisons to C.

Variables and Data Types

Declaring Variables

Unlike C, where you must explicitly declare variable types (e.g., int x = 10;), Python uses dynamic typing, allowing you to assign values without specifying their type (e.g., x = 10). The Python interpreter automatically determines the data type at runtime, making the code more flexible but potentially less efficient in terms of performance.

C Example:

#include <stdio.h>

int main() {
    int a = 10;
    float b = 3.14;
    char c = 'X';

    printf("a = %d, b = %.2f, c = %c\n", a, b, c);
    return 0;
}

MicroPython Equivalent:

a = 10  # Integer
b = 3.14  # Float
c = 'X'  # Character (string in Python)

print(f"a = {a}, b = {b:.2f}, c = {c}")

Data Types in MicroPython

Type C Example MicroPython Example Description
Integer int a = 100; a = 100 Whole numbers
Float float b = 3.14; b = 3.14 Decimal numbers
String char str[] = "Hello"; c = "Hello" Text data (Python strings can compare directly)
Boolean int d = 1; // true d = True True or False
Array/List int e[] = {1,2,3}; e = [1, 2, 3] Ordered collection
Structure/Tuple struct Point {int x, y;}; f = (4, 5, 6) Immutable ordered collection
Dictionary N/A g = {'key': 'value'} Key-value pairs

Control Structures

If-elif-else Conditional Statements

C Example:

int a = 10;
if (a > 5) {
    printf("Greater than 5\n");
} else if (a == 5) {
    printf("Equal to 5\n");
} else {
    printf("Less than 5\n");
}

MicroPython Equivalent:

a = 10
if a > 5:
    print("Greater than 5")
elif a == 5:
    print("Equal to 5")
else:
    print("Less than 5")

If Conditional Statements with Logical Operators

Python supports logical operators like and, or, and not for more complex conditions.

Using and

Both conditions must be true.

a = 10
b = 20
if a > 5 and b > 15:
    print("Both conditions are true")

Using or

At least one condition must be true.

if a > 15 or b > 15:
    print("At least one condition is true")

Using not

Reverses the condition.

if not a < 5:
    print("a is NOT less than 5")


String Comparisons

Unlike C, where string comparisons require strcmp, Python allows direct comparisons:

C Example:

#include <string.h>

char str[] = "hello";
if (strcmp(str, "hello") == 0) {
    printf("Match!\n");
}

MicroPython Equivalent:

str_value = "hello"
if str_value == "hello":
    print("Match!")

Switch-Case Alternative in MicroPython

Python does not have a built-in switch-case statement like C, but you can use if-elif-else or dictionaries to achieve similar behavior.

C Example:

int num = 2;
switch(num) {
    case 1:
        printf("One\n");
        break;
    case 2:
        printf("Two\n");
        break;
    default:
        printf("Other\n");
}

MicroPython Equivalent (Using If-Elif-Else):

num = 2
if num == 1:
    print("One")
elif num == 2:
    print("Two")
else:
    print("Other")


Loops

For Loop

C Example:

for (int i = 0; i < 5; i++) {
    printf("%d\n", i);
}

MicroPython Equivalent:

for i in range(5):
    print(i)

While Loop

C Example:

int x = 0;
while (x < 5) {
    printf("%d\n", x);
    x++;
}

MicroPython Equivalent:

x = 0
while x < 5:
    print(x)
    x += 1


Functions and Where to Define Them

Defining and Calling Functions

Functions in Python must be defined before they are used, unlike C where function prototypes can be declared beforehand.

C Example:

#include <stdio.h>

// Function prototype (optional in C but good practice)
void greet(char* name);

int main() {
    greet("MicroPython");
    return 0;
}

void greet(char* name) {
    printf("Hello, %s\n", name);
}

MicroPython Equivalent:

def greet(name):
    print("Hello, " + name)

greet("MicroPython")  # Function must be defined before this line

Attempting to call a function before it is defined will result in an error:

say_hello("World")  # Error: NameError: name 'say_hello' is not defined

def say_hello(name):
    print("Hello, " + name)

To ensure proper execution, always define functions before calling them.


Importing Modules

In C, external functionality is accessed using the #include directive, which directly inserts the contents of header files (e.g., #include <stdio.h>) at compile time. In Python, external modules and libraries are brought in using import statements (e.g., import math), which load the module dynamically at runtime, allowing access to additional functions and classes.

C Example:

#include <stdio.h>
#include "my_library.h"

MicroPython Equivalent:

import machine  # Access to hardware interfaces
import time  # Provides sleep functions

Using Specific Functions from a Module

from machine import Pin
from time import sleep

This approach makes functions directly accessible without needing to use module.function() syntax.

Using import as for Aliases

To simplify long module names or avoid conflicts:

import machine as m
led = m.Pin("LED", m.Pin.OUT)  # Onboard LED on Pico/Pico 2

Common MicroPython Modules

Module Purpose
machine Access GPIO, I2C, SPI, UART, ADC, PWM
time Sleep and timing functions
os File system operations
network WiFi and networking (Pico W)
sys System-level functions

Creating and Importing a Custom Module

In Python, you can create your own module by writing functions in a separate file and importing them into your main script.

Step 1: Create a Custom Module (my_module.py)

def square(n):
    return n * n

def greet(name):
    return f"Hello, {name}!"

Step 2: Import and Use the Module

import my_module

print(my_module.square(4))  # Output: 16
print(my_module.greet("MicroPython"))  # Output: Hello, MicroPython!

Step 3: Import Specific Functions

from my_module import square

print(square(5))  # Output: 25

Creating modules in MicroPython allows you to organize reusable code, just like .h and .c files in C.


Indentation in Python vs. C

One of the key differences between Python and C is how code blocks are defined.

  • In C, code blocks are enclosed in {} (curly braces), and indentation is optional but recommended for readability.
  • In Python, indentation is mandatory and determines the structure of the code. Missing or inconsistent indentation leads to errors.

Example in C (Curly Braces for Blocks)

#include <stdio.h>

int main() {
    int x = 10;
    if (x > 5) {
        printf("x is greater than 5\n");
    } else {
        printf("x is 5 or less\n");
    }
    return 0;
}

Equivalent Code in Python (Indentation for Blocks)

x = 10

if x > 5:
    print("x is greater than 5")
else:
    print("x is 5 or less")
  • The indentation in Python defines the block of code, whereas in C, {} does that.
  • Python enforces indentation strictly, preventing unstructured code.

How to Use Comments in Python

Comments are crucial for explaining code logic, especially for complex algorithms or when working in a team.

Single-Line Comments

Use # for single-line comments:

# This is a comment explaining the next line of code
x = 42  # Assigning 42 to x

Multi-Line Comments

Python does not have a specific multi-line comment syntax like /* ... */ in C, but you can use triple quotes (""" ... """ or ''' ... ''') for documentation.

"""
This is a multi-line comment.
It is often used for function or module documentation.
"""
def greet():
    print("Hello, World!")

Commenting Best Practices

  • Be concise: Explain why something is done rather than what is done.
  • Avoid redundant comments: If the code is self-explanatory, comments may not be necessary.
  • Use docstrings (""" or ''') for functions and classes:
def add(a, b):
    """Returns the sum of a and b."""
    return a + b

By using proper comments and indentation, Python code remains structured, readable, and easy to maintain!

Don't state the obvious!

Inline comments are unnecessary and in fact distracting if they state the obvious. Don’t do this:

x = x + 1                 # Increment x
But sometimes, this is useful:
x = x + 1                 # Compensate for border


Handling Hardware with MicroPython

Using GPIO Pins

from machine import Pin

led = Pin("LED", Pin.OUT)  # Onboard LED on Pico/Pico 2
led.value(1)  # Turn on LED

Reading a Button Press

button = Pin(14, Pin.IN, Pin.PULL_UP)
if button.value() == 0:
    print("Button Pressed!")

Working with Time

from time import sleep

sleep(1)  # Pause for 1 second

Why Follow a Style Guide?

Writing clean, readable, and maintainable code is essential in software development. Adhering to a style guide simplifies development and enhances code consistency. For more details, check out the style guide.


➡ Next Steps