esp32.diy

ESP32 MicroPython Examples: Step-by-Step Setup Guide

Oct 13, 2026 · 6 min read · Beginner

ESP32 MicroPython Examples: Step-by-Step Setup Guide
TL;DR MicroPython runs on ESP32 and lets you write Python scripts for sensors, audio, and networking using tools like Thonny or uPyCraft. These examples walk through I2C sensor wiring, I2S audio streaming, and web API calls to get you building real projects fast.
I2S in official builds sinceJuly 5, 2021
Recommended IDEsThonny and uPyCraft
Firmware downloadmicropython.org/download/
Default I2C pinsSCL = Pin(22), SDA = Pin(21)
I2S peripherals availableTwo: I2S.NUM0 and I2S.NUM1
HTTP libraryurequests for web and API calls

What do you need before running MicroPython on ESP32?

Before writing any code, make sure you have the right firmware, an IDE, and — for hardware examples — the correct physical components and wiring.

Firmware

Download a MicroPython binary for your board from micropython.org/download/. I2S audio support was merged into the official build on July 5, 2021, so any binary released after that date includes it with no custom build required.

IDE

Two tools are widely used for ESP32 MicroPython development: Thonny and uPyCraft. Both give you a REPL (interactive Python prompt) over USB and a file manager for copying library files onto the device's filesystem.

Libraries

Some examples depend on third-party libraries that must be copied to the device before your script runs. The I2C sensor example below uses micropython-mpu9250, which ships as three separate Python files (mpu9250.py, mpu6500.py, ak8963.py). Missing even one of them causes an import error. The web example uses micropython-firebase-auth for authentication.

Hardware summary

Example Hardware needed
I2C sensor ESP32, GY-91 breakout (MPU9250 + BMP280), 4 jumper wires
I2S microphone ESP32, INMP441 microphone module, 3 jumper wires
I2S speaker ESP32, Adafruit I2S amplifier (MAX98357A), 3 jumper wires
Web API ESP32, Wi-Fi credentials
ESP32 development board used for MicroPython projects\2

ESP32 development board used for MicroPython projects Image: Edwiyanto, CC BY-SA 4.0, via Wikimedia Commons

How do I wire and read an I2C sensor with MicroPython?

The I2C bus is one of the most common ways to attach sensors to an ESP32. This example reads acceleration, gyroscope, magnetic field, and temperature data from an MPU9250 on the GY-91 breakout board.

Step 1 — Wire all four pins

GY-91 pin ESP32 pin
VIN 5 V
GND GND
SCL GPIO 22
SDA GPIO 21

Skipping the GND wire is the single most common I2C wiring mistake. The firmware will raise OSError: [Errno 19] ENODEV, meaning it cannot detect any device on the bus at all, even though power and data lines are connected.

Step 2 — Copy library files to the device

Using your IDE's file manager, copy mpu9250.py, mpu6500.py, and ak8963.py to the ESP32 before running any script.

Step 3 — Run the script

import utime
from machine import I2C, Pin
from mpu9250 import MPU9250

i2c = I2C(scl=Pin(22), sda=Pin(21))
sensor = MPU9250(i2c)

print("MPU9250 id: " + hex(sensor.whoami))

while True:
    print(sensor.acceleration)
    print(sensor.gyro)
    print(sensor.magnetic)
    print(sensor.temperature)
    utime.sleep_ms(1000)

If sensor.whoami prints a non-zero hex value without raising an exception, the I2C bus is healthy and the sensor is detected. The loop then streams all four data types once per second.

Espressif ESP-WROOM-32 Wi-Fi and Bluetooth module\2

Espressif ESP-WROOM-32 Wi-Fi and Bluetooth module Image: Brian Krent, CC BY-SA 4.0, via Wikimedia Commons

How do I use I2S audio examples on ESP32 with MicroPython?

I2S (Inter-IC Sound) is a serial audio bus for streaming digital audio to and from external chips. MicroPython's machine.I2S class wraps Espressif's ESP-IDF I2S API and supports two independent peripherals — I2S.NUM0 and I2S.NUM1 — so you can record and play at the same time.

Step 1 — Reading audio from an INMP441 microphone

from machine import I2S, Pin

bck_pin  = Pin(14)   # Bit clock
ws_pin   = Pin(13)   # Word select
sdin_pin = Pin(12)   # Serial data input

audio_in = I2S(
    I2S.NUM0,
    bck=bck_pin, ws=ws_pin, sdin=sdin_pin,
    standard=I2S.PHILIPS, mode=I2S.MASTER_RX,
    dataformat=I2S.B32,
    channelformat=I2S.RIGHT_LEFT,
    samplerate=16000,
    dmacount=16, dmalen=256
)

samples = bytearray(2048)
num_bytes_read = audio_in.readinto(samples)

Step 2 — Playing audio through a MAX98357A amplifier

from machine import I2S, Pin

bck_pin   = Pin(14)
ws_pin    = Pin(13)
sdout_pin = Pin(12)   # Serial data output

audio_out = I2S(
    I2S.NUM1,
    bck=bck_pin, ws=ws_pin, sdout=sdout_pin,
    standard=I2S.PHILIPS, mode=I2S.MASTER_TX,
    dataformat=I2S.B16,
    channelformat=I2S.ONLY_RIGHT,
    samplerate=16000,
    dmacount=16, dmalen=512
)

samples = bytearray(1024)
num_bytes_written = audio_out.write(samples)

Key constructor parameters

Parameter Purpose
bck Bit clock pin
ws Word select pin
sdin / sdout Data direction — only one allowed per instance
mode MASTER_RX to receive, MASTER_TX to transmit
dataformat Sample bit depth: B16 or B32
channelformat Stereo (RIGHT_LEFT) or mono (ONLY_RIGHT)
samplerate Samples per second
dmacount / dmalen DMA buffer count and per-buffer length

readinto() blocks until the bytearray is completely filled from DMA memory unless you pass a timeout in milliseconds. Setting timeout=0 returns immediately when no DMA data is ready, which enables non-blocking designs built around uasyncio.

How do I call a web API from ESP32 MicroPython?

MicroPython's urequests module lets you make HTTP and HTTPS requests once the ESP32 is on Wi-Fi. A common project pattern is reading from or writing to a cloud database such as Firebase Realtime Database.

Basic GET request

import urequests

def get_data():
    response = urequests.get(
        "https://<DATABASE_NAME>.firebaseio.com/<NODE>.json?auth=<ID_TOKEN>"
    )
    data = response.json()
    return data

Authentication — ID token, not UID

Firebase security rules validate an ID token, not a plain user UID. Passing only the UID returns {'error': 'Permission denied'} because the UID is not a secret and carries no authentication weight on its own.

The correct flow:

  1. Use the micropython-firebase-auth library to sign in with an email and password.
  2. Retrieve the ID token from the sign-in response.
  3. Pass that ID token in the auth query parameter of every urequests call.

If the ESP32 operates in a trusted environment such as a locked enclosure on a private network, the Firebase Admin SDK approach can bypass per-user authentication entirely.

How do I verify each example is working correctly?

Each category has a clear success signal you can check in the IDE's REPL window.

I2C sensor

I2S audio

Web API

What are the most common mistakes with these ESP32 MicroPython examples?

Most failures fall into a small set of predictable errors.

1. Missing GND wire on I2C sensors

Connecting VIN, SCL, and SDA but omitting GND makes the sensor completely invisible to the bus. MicroPython raises OSError: [Errno 19] ENODEV, which literally means no device was found. Always run four wires: power, ground, clock, and data.

2. Incomplete library files on the device

Libraries that span multiple files require every file to be present. The MPU9250 library needs three Python files. If any are missing the import chain breaks. Use your IDE's file manager to confirm each file is on the device before running.

3. Using a UID instead of an ID token for Firebase

A user UID is a public identifier — it is not a secret and cannot prove identity to Firebase's security rules. Obtain an ID token through micropython-firebase-auth and pass that instead.

4. Running firmware older than July 5, 2021 for I2S

Builds predating that date do not include the machine.I2S class. If from machine import I2S raises an ImportError, flash a current binary from micropython.org/download/.

5. Specifying both sdin and sdout in one I2S instance

Each I2S object accepts only one data-direction pin. Use I2S.NUM0 with sdin for recording and I2S.NUM1 with sdout for playback if you need both simultaneously.

Frequently asked questions

What does OSError: [Errno 19] ENODEV mean in MicroPython?

It means the firmware could not find any device on the I2C bus. The most frequent cause is a missing GND connection between the sensor and the ESP32.

Which IDEs work best for MicroPython on ESP32?

Thonny and uPyCraft are both commonly used. Both offer a REPL connection over USB and a file manager for uploading library files to the device.

When was I2S added to the official MicroPython build for ESP32?

I2S support was merged into the official MicroPython build on July 5, 2021. Any binary downloaded from micropython.org/download/ after that date includes it without requiring a custom compile.

How do I authenticate Firebase requests from ESP32 MicroPython?

Use the micropython-firebase-auth library to sign in and receive an ID token, then pass that token in your urequests call. Passing only the UID returns a Permission denied error.

Can I record and play I2S audio at the same time on ESP32?

Yes. Use I2S.NUM0 configured as MASTER_RX for the microphone and I2S.NUM1 configured as MASTER_TX for the speaker amplifier as two separate instances.

Bottom line

MicroPython makes ESP32 approachable for anyone comfortable with Python, covering practical ground from I2C sensor wiring to I2S audio streaming and cloud API calls with urequests. The patterns shown here — correct four-wire I2C connections, proper I2S peripheral configuration, and ID-token-based authentication — underpin the vast majority of real ESP32 MicroPython projects. Start with the latest official firmware from micropython.org, double-check every wire including GND, and copy all library files to the device before running your first script.

Sources

stackoverflow.comMicroPython: OSError: [Errno 19] ENODEVstackoverflow.comRetrieving firebase data from ESP32 using micropython with authenticationgithub.commiketeachman/micropython-esp32-i2s-examples (GitHub README)

This guide summarises the public sources listed above in our own words. Check the original documentation before relying on exact figures.