No description
- Python 76.7%
- OpenSCAD 22%
- Shell 1.3%
| .omo/run-continuation | ||
| case | ||
| design | ||
| lib | ||
| .gitignore | ||
| AGENTS.md | ||
| config.py | ||
| deploy.sh | ||
| FIRMWARE.md | ||
| main.py | ||
| README.md | ||
| requirements.txt | ||
| TODO.md | ||
Bike Computer MVP — ESP32-S3 MicroPython
Hardware target: LilyGo T-Display S3 (or any ESP32-S3 with SPI display) + ATGM336H GPS + BLE CSC sensor
MVP Scope
- GPS track recording (ATGM336H @ 115200 baud, NMEA)
- Real-time speed display
- Clock (synced from GPS UTC)
- BLE Cycling Speed & Cadence (CSC) client
- Track save to LittleFS/flash
- Basic UI: speed, time, distance, cadence
Pinout (LilyGo T-Display S3 1.9")
| Function | GPIO |
|---|---|
| Display SPI CS | 14 |
| Display SPI SCK | 12 |
| Display SPI MOSI | 11 |
| Display DC | 13 |
| Display RST | 15 |
| Display BL | 10 (PWM) |
| GPS UART TX | 43 (to GPS RX) |
| GPS UART RX | 44 (from GPS TX) |
| GPS PPS (optional) | 42 |
| Button 1 (Boot) | 0 |
| Button 2 | 14 (shared with CS - check schematic) |
| Battery ADC | 4 |
Adjust for your specific board — check schematic.
Project Structure
bike-computer-mvp/
├── main.py # Entry point
├── config.py # Hardware config, constants
├── lib/
│ ├── gps/
│ │ ├── __init__.py
│ │ ├── nmea.py # NMEA parser
│ │ └── driver.py # Async GPS driver with smoothing
│ ├── display/
│ │ ├── __init__.py
│ │ ├── st7789.py # Display driver
│ │ └── ui.py # UI rendering
│ ├── ble/
│ │ ├── __init__.py
│ │ └── csc.py # BLE CSC client
│ ├── storage/
│ │ ├── __init__.py
│ │ └── tracks.py # Track logging (LittleFS)
│ └── utils/
│ ├── __init__.py
│ └── time.py # GPS time sync
├── assets/
│ └── fonts/ # .fnt files for display
└── tests/
└── test_gps.py
Quick Start
# Flash MicroPython to ESP32-S3
esptool.py --chip esp32s3 --port /dev/ttyACM0 erase_flash
esptool.py --chip esp32s3 --port /dev/ttyACM0 write_flash -z 0x0 micropython-esp32s3-<version>.bin
# Copy files
ampy --port /dev/ttyACM0 put main.py
ampy --port /dev/ttyACM0 put config.py
ampy --port /dev/ttyACM0 mkdir lib
ampy --port /dev/ttyACM0 put lib/gps /lib/gps
# ... etc
# Or use mpremote (recommended)
mpremote connect /dev/ttyACM0 fs cp -r . :
mpremote connect /dev/ttyACM0 repl
Dependencies
- MicroPython 1.23+ (ESP32-S3 build with
_thread,bluetooth,framebuf) micropython-bluezfor BLE (included in recent builds)
GPS Notes
- ATGM336H default: 115200 baud, NMEA (GGA, RMC, GSA, GSV, VTG)
- Enable PPS on GPIO for precise time sync if needed
- Cold start ~30s, hot start ~1s
BLE CSC Service (UUIDs)
- Service:
0x1816(Cycling Speed and Cadence) - Measurement:
0x2A5B(notify) - Feature:
0x2A5C(read) - Sensor Location:
0x2A5D(read)
Track Format (JSON Lines)
{"t": "2026-07-11T05:13:19Z", "lat": 48.486057, "lon": -1.715130, "ele": 89.6, "speed": 5.2, "cad": 82}
{"t": "2026-07-11T05:13:20Z", "lat": 48.486084, "lon": -1.715156, "ele": 88.6, "speed": 5.3, "cad": 83}
One line per GPS fix. Append-only, rotate daily.
License
MIT