A desktop "simulator" for @echo-lalia's MicroHydra APIs, built on top of pygame. It lets you develop and debug MicroHydra/Cardputer-style apps on your PC before deploying them to real hardware.
Parts of this software, such as the lib.hydra libraries were written by @echo-lalia.
- Python 3.10 or newer
- Desktop OS with Python and
pip(tested on Windows, should also work on Linux/macOS) - For 3D examples (moderngl-based apps), a GPU/driver with OpenGL 3.3+ support
python3 -m venv venv
pip3 install -r requirements.txt
To start the launcher:
python3 applauncher.py
To launch a specific app:
python3 applauncher.py snake
The repository includes a dual-pane file manager app:
python3 applauncher.py Commander
Controls:
TABswitch active paneUP/DOWN(or;/.) move cursorENT(orRIGHT) open directoryLEFT/BSPCgo to parentCcopy selected item to opposite paneMmove selected item to opposite paneDdelete selected item (with confirmation)Ncreate directoryRrename selected itemPconnect to Cardputer over serialOdisconnect serialIinstall currentCommanderapp to Cardputer (/apps/Commander/__init__.py) over standard MicroPython REPLESCexit to launcher
Serial mode (real board over USB serial):
- Run
Commanderon the Cardputer. - Run
Commanderon the PC simulator, then pressPto open port selection. - The right pane (on the PC) is the remote Cardputer filesystem when connected.
- On Cardputer,
Commanderstill works as a local file manager while also responding to PC requests. - Press
Oon PC to disconnect. - If
Display/UserInputare unavailable,Commanderautomatically runs in headless server-only mode.
Put your apps in rootfs/apps. An example app demonstrating display and keyboard APIs can be found in rootfs/apps/example/__init__.py
Each app is either:
- a single
.pyfile inrootfs/apps, e.g.snake.py→python3 applauncher.py snake, or - a package directory in
rootfs/appswith an__init__.py, e.g.example/→python3 applauncher.py example. These apps can also include icons for the launcher.
Inside your app you can use the same APIs that exist on the MicroHydra/Cardputer (e.g. Display, UserInput, audio helpers, etc.). When you are ready to move to real hardware, you can usually copy the code with minimal or no changes.
applauncher.py– entry point and app launcherlibraries/– MicroPython compatibility layer and extra libraries (including 3D helpers inlibraries/custom)libraries/lib/– higher-level helpers: display, audio, UI components, input handlingrootfs/apps/– built-in and user apps (games, demos, tools)rootfs/config.json– configuration for the launcher (colors, language, volume, etc.)
This branch only has the APIs that MicroHydra (and micropython) has, and nothing more. Useful for writing apps only for MicroHydra/Cardputer/micropython.
This branch includes the MicroHydra APIs, but also has some extra ones, such as 3D rendering using moderngl. You can find these in libraries/custom. Useful for writing desktop apps/games
- Timing and performance may differ slightly from the real device.
- Hardware emulation is configurable and currently includes I2C emulation for M5Stack ENV3 (SHT30 + QMP6988).
- Additional bus emulation is available for ADC, SPI, GPIO, UART, and I2S.
- I2S includes functional
speaker(playback) andmicrophone(PCM capture waveform) emulated devices. - The goal is to make app logic and rendering portable, not to be a cycle-accurate emulator.
simulator_settings.json supports a Hardware section with per-bus and per-device enable flags.
Example:
"Hardware": {
"enabled": true,
"thread_hz": 20,
"I2C": {
"enabled": true,
"devices": {
"M5Stack_ENV3": {
"enabled": true,
"bus": 0,
"scl": 1,
"sda": 2,
"sht30_address": 68,
"qmp6988_address": 112
}
}
}
}The emulator runs in a dedicated background thread and can be accessed through normal machine.I2C calls (scan, writeto, readfrom, readfrom_mem, writeto_mem).
For other buses, machine.ADC, machine.Pin, machine.SPI, machine.UART, and machine.I2S also route through the emulator runtime.
If you have something like if __name__ == "__main__", then it won't work, as your __name__ is never __main__. Simply remove the if statement, and run the code directly.
Make sure you run UserInput.get_pressed_keys() in your loop.
MicroHydra (therefore this simulator) uses RGB565 colors instead of RGB888. So for example red in RGB888 is 0xFF0000, but in RGB565 its 0xF800. I recommend using the color_picker or hexto565 app.
Make sure you're running Display.show().
This project is distributed under the terms of the license in LICENSE. Please see that file for details.