Skip to content

Latest commit

 

History

History
246 lines (195 loc) · 9.09 KB

File metadata and controls

246 lines (195 loc) · 9.09 KB

MicroPython

A workshop about MicroPython on ESP32.

Since not everyone has access to physical hardware, we can simulate esp32 microcontrollers using wokwi. This allows us to focus on programming before moving to real hardware. Everything done here can be transferred directly to physical ESP32 devices.

Setup

Start a new project here: wokwi-esp32, you can save it if you create an account, but it is not needed for this workshop You will mainly work with:

  • main.py → your program
  • diagram.json → hardware wiring

When you press Start simulation, Wokwi automatically transfer all files what is on the left and executes main.py.

Hello World

Let’s start with a simple LED test.

Step 1:

Replace diagram.json with led.json from the ./diagrams folder inside wokwi. Press the play button in Wokwi, the REPL will show the Serial Monitor with: >>>, Type something pythonic.

Step 2:

To test the led you can type this in the REPL:

from machine import Pin

led_pin = Pin(2, Pin.OUT)

led_pin.value(1)  # LED on
led_pin.value(0)  # LED off

If everything works, you should see the LED toggle.

Useful key Commands

  • CTRL-C → Stop current program
  • CTRL-D → Restart (boot.py + main.py)
  • CTRL-A → Raw REPL (used for uploading files)

Assignments — Core MicroPython

The REPL is useful for debugging, but real programs are written in:

boot.py → system setup (WiFi, MQTT, drivers) main.py → application logic MicroPython runs in this order: boot.py → main.py → REPL

  • boot.py runs once on startup
  • main.py runs your program
  • when main.py finishes → you return to REPL
  • CTRL + D → restarts everything

for assignments below we use the lib machine

Assigment_1 (output)

Turn on or off some output, output is always 3.3v on esp32 replace diagram.json with led.json

Make an LED blink:

  • start slow (1s delay)
  • gradually speed up (0.05s delay)
  • create a “charging effect”

Assigment_2 (PWM)

PWM simulates analog voltage by switching fast ON/OFF. This is mostly used in leds and motors. replace diagram.json with led.json

Make the Led Breath:

  • Update Assigment_1 to make the LED “breathe” like a tiny robot heart.

Assigment_3 (Input)

The same as the output the esp32 can check if a signal is high or low (3.3V or ground) replace diagram.json with button.json

Blink led when button is pressed:

  • When button is pressed the light should start blinking.
  • Blinking stops or restarts when button is pressed again.

Assignment_4 (ADC)

ADC converts voltage (0–3.3V) into digital values and returns as signal in range between 0-3.3 volts. replace diagram.json with potential_meter.json

Map value of potentiometer to led brightness

Assigment_6 (sleep cycles)

Deep-sleep is one of the reasons you could choose for a microcontroller. Deep-sleep is like turning everything off except the rtc (for counting). by this we can put the device (off) to save battery and turn it on in the morning to update some sensors.

Put the ESP32 to deepsleep to save power.

  • sleep for 10 seconds
  • wake up
  • print "hello world"
  • repeat

For more information deepsleep

Assigment_5 (Interrupts)

After putting the device to deepsleep we can "wake" them again by shorting a pin. replace diagram.json with button.json

Put the esp32 to deepsleep

  • let it sleep forever
  • wake up by pressing the button.

for more information deepsleep interrupt esp32

Assigment_6 (Timers)

Most sensors etc need some delays or waits before you get response, you give them a signal to do (like turning a motor) and want to wait 5 sec. the normal python sleep(5) will block the whole micropython loop. Try to keep the loop non-blocking(ish) replace diagram.json with stepper_motor.json

turn the motor clockwise or counterclockwise depending on the potential meter, while not blocking the loop. for more information visit timers and delays

Assigment_7 (modules)

Even though Wokwi runs main.py, you can structure like this: main.py led.py let's structure the stepper motor of asssignment 6 in its own module. like normal you can import it as

# main.py
from led import blink

blink()

Communication

WiFi

For connecting the device to wifi wokwi is serving a network with real network access. You can connect to the network with

WIFI_SSID = "Wokwi-GUEST"
WIFI_PASS = ""

and use the lib import network for more documentation network.

MQTT

So let's make a sender and listener/subcriber with mqtt, a protocol to send or subscribe to topics. heavily used in IoT for sending sensor data. mqtt is standard included in micropython together with wifi. and thus all diagrams.json will work just fine for this assigment. To listen or send messages to the simulated device go to hivemq and send a message to the topic or subscribe to topics. Use this for communication with mqtt after you connected to wifi.

from umqtt.simple import MQTTClient
MQTT_CLIENT_ID = f"micropython-sender_{NAME}"
MQTT_BROKER    = "broker.mqttdashboard.com"
MQTT_USER      = ""
MQTT_PASSWORD  = ""
MQTT_TOPIC     = "QSTARS_MQTT"

For more documentation check mqtt

When a sender is made and sends a message to a topic you can see ith with the hivemq and subscribe to the topic to see incomming messages when the listener is made you can send via hivemq also messages to a certain topic.

Communication Protocols

Here are the most used protocols in IoT devices, most of the time you would not interact directly with it, but with a lib written for the sensor. Only when you make your own sensor or using a sensor not frequently used you need to interact directly with these protocols. Therefore it is written here as demo, but no assignments are made.

UART -> Serial pipe between two devices (tx/rx)

from machine import UART

uart = UART(1, baudrate=9600, tx=17, rx=16)

uart.write("Hello UART\n")

while True:
    if uart.any():
        print(uart.read())

IC2 -> Many devices share same 2 wires

from machine import I2C, Pin

i2c = I2C(0, scl=Pin(22), sda=Pin(21))

devices = i2c.scan()

print("I2C devices found:", devices)

SPI -> More Wire More Speed

from machine import SPI, Pin

spi = SPI(
    1,
    baudrate=1000000,
    polarity=0,
    phase=0,
    sck=Pin(18),
    mosi=Pin(23),
    miso=Pin(19)
)

print("SPI initialized:", spi)

Assignments

LedStrip

We have 50 rgb led ring ws2812 you can send a message to the led ring and let them make a full circle. You can use the lib neopixel from Adafruit. In essence this lib will create the message you send through the pipeline, what every led is doing, it takes the first tuple (r,g,b) and execute it, after that it passes the rest of the message to the next pixel. This led is getting a message with 1 tuple less in the message until it is empty. Therefore you can couple more ledstrips to 1.

When the led ring is working, you can use the 1 empty pin on the led ring(DOut) to couple it to any other ws2812 input of ring 1. This way, you can make longer and more complicated designs.

import neopixel
NUM_LEDS = 50

For more documentation check neopixel.

extra:

  • add more rings / individual ws2812 or strips to the simulation.
  • add mqtt to device and control the led-ring colors via mqtt.

Display Temp

We're going to make 2 devices, device 1 with a dht22 sensor for reading out temp and humidity and device 2 for displaying the temp on a display. For device 1 (tab 1) we use lcd_display.json for device 2 (tab 2) we use dht22.json One device will read out the dht22 sensor with help of dhtt lib the lcd display can be set with:

from i2c_lcd import I2cLcd

# ---------- LCD ----------
I2C_ADDR = 0x27
totalRows = 2
totalColumns = 16

i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)

lcd = I2cLcd(i2c, I2C_ADDR, totalRows, totalColumns)

lcd.putstr("Waiting data...")

and we need to include the 2 files lcd_api.py and i2c_lcd.py sometimes you can download them via mip a micropython package manager, But due to low memory most of the time a stripped down version is saved inside the project.

Other libraries