A virtual pet game for ESP32 with MicroPython, featuring an SSD1306 OLED display and button controls.
- ESP32-C6 SuperMini development board
- SSD1306 OLED Display (128x64, I2C)
- 8 Push Buttons for input
mpremoteinstalled (pip install mpremote)
This is the wiring I used for the project. If you change these, then you'll want to update the values in src/config.py
Display (I2C):
| Display Pin | ESP32-C6 Pin |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SDA | GPIO4 |
| SCL | GPIO7 |
Buttons:
| Button | GPIO Pin |
|---|---|
| UP | GPIO0 |
| DOWN | GPIO1 |
| LEFT | GPIO2 |
| RIGHT | GPIO3 |
| A | GPIO20 |
| B | GPIO19 |
| MENU1 | GPIO18 |
| MENU2 | GPIO14 |
Each button connects between GPIO pin and GND (internal pull-ups enabled).
esptool.py --chip esp32c6 --port /dev/cu.usbmodem* erase_flash
esptool.py --chip esp32c6 --port /dev/cu.usbmodem* write_flash -z 0x0 ESP32_GENERIC_C6-*.binmpremote mip install ssd1306For the fastest iteration during development, use the dev.sh script which compiles Python to bytecode and runs via mpremote mount:
./dev.shThis script:
- Compiles all
.pyfiles insrc/to.mpybytecode inbuild/ - Mounts the
build/directory on the device - Runs the game
Using precompiled .mpy files provides faster startup and slightly lower RAM usage compared to raw .py files.
Note
Requires mpy-cross (pip install mpy-cross) and mpremote (pip install mpremote).
Any libraries used (like ssd1306) must already be installed on the device.
Verifies that your hardware is working correctly:
./test_hardware.shThis script:
- Resets the device
- Scans I2C to confirm the display is detected
- Enters an interactive button test (press buttons to see them register, Ctrl+C to exit)
Run this first when setting up a new device or debugging hardware issues.
Deploys the project to the ESP32's flash storage:
./upload.sh [port]This script:
- Installs the
ssd1306library viamip - Compiles all
.pyfiles to.mpybytecode - Cleans existing files from the device (preserves
lib/) - Uploads compiled
.mpyfiles andboot.pyto the device
Use this when you want the pet to run standalone without a laptop connection.
After uploading, the game starts automatically on power-up or reset.
To enter REPL mode instead: Hold A+B buttons while powering on or pressing reset. This skips auto-run so mpremote can connect.
To manually start the game from REPL:
mpremote
>>> import main
>>> main.main()If you see mpremote.transport.TransportError: could not enter raw repl when running ./dev.sh or other mpremote commands, it means boot.py is on the device and auto-running the game, blocking mpremote from connecting.
To fix this:
- Run
mpremoteto connect to the device - Press Ctrl+C to interrupt the running game
- Press Ctrl+B to exit raw REPL and enter friendly REPL
- Remove boot.py:
import os os.remove('boot.py')
- Press Ctrl+X to exit mpremote
Now ./dev.sh should work again.
Tip
During development, don't keep boot.py on the device. Only run ./upload.sh when you need standalone operation (battery-powered, showing friends, etc.). When you're done and want to return to development, remove boot.py using the steps above.
- D-pad: Navigate / Move character
- A/B buttons: Action buttons
- Menu buttons: Additional functions
