This is lap counter software for Trackmate Racing RC Lap Counter. It comes with free software but it's Windows only. This project aims to support other operating systems and hopefully allow for something that might fit more people's needs.
The name is a nod to Benjamin Franklin Miessner who was a radio engineer and inventor.
The system uses Redis for communication between components, allowing you to run the hardware interface and race UI in separate terminals.
┌─────────────────────┐ ┌─────────────┐ ┌──────────────────────┐
│ Franklin (TUI) │ │ Redis │ │ Hardware Comm │
│ Race Management │◄───────►│ Pub/Sub │◄───────►│ (Serial Interface) │
│ │ │ │ │ │
└─────────────────────┘ └─────────────┘ └──────────────────────┘
Terminal 1 Auto-started Terminal 2
by devbox
This project uses Devbox for environment management. Redis starts automatically when you enter the devbox shell.
# Enter the development environment
devbox shellTerminal 1 - Hardware Interface:
devbox shell
devbox run rust-hwTerminal 2 - Race UI:
devbox shell
python franklin.py --raceTerminal 1 - Hardware Simulator:
devbox shell
devbox run rust-hw-simTerminal 2 - Race UI:
devbox shell
python franklin.py --raceNo hardware interface needed - Franklin generates a fake race internally:
devbox shell
python franklin.py --fake- Ctrl+S - Start Race
- Ctrl+X - End Race
- Ctrl+T - Toggle Mode (Fake/Real/Training)
- Click "Start Race" / "End Race" buttons in the TUI
- Q - Quit
- S - Start race (sends reset commands)
- P - Stop race
- 1-4 - Simulate lap for racer 1-4
- Q - Quit
Edit franklin.config.json to configure your race:
{
"total_laps": 10,
"contestants": [
{"id": 1, "name": "Racer 1"},
{"id": 2, "name": "Racer 2"},
{"id": 3, "name": "Racer 3"},
{"id": 4, "name": "Racer 4"}
]
}The system uses two Redis pub/sub channels for inter-process communication:
{"type": "command", "command": "start_race"}
{"type": "command", "command": "stop_race"}
{"type": "command", "command": "simulate_lap", "racer_id": 1, "sensor_id": 1, "race_time": 12.5}{"type": "heartbeat"}
{"type": "status", "message": "Hardware connected"}
{"type": "lap", "racer_id": 1, "sensor_id": 1, "race_time": 12.345}
{"type": "debug", "message": "..."}
{"type": "raw", "line": "..."}devbox run hw-test# Check Redis is running
redis-cli -s ./redis.sock ping
# Monitor all messages
redis-cli -s ./redis.sock
> SUBSCRIBE hardware:out
# Send test command
redis-cli -s ./redis.sock
> PUBLISH hardware:in '{"type":"command","command":"start_race"}'If you see "Failed to connect to Redis", make sure you're in a devbox shell:
devbox shellRedis starts automatically when you enter the devbox shell.
If Franklin shows "Lap counter not detected":
- Check that
franklin-hardware-monitoris running in Terminal 1 - Look for heartbeat messages in Terminal 1's output
- Verify the hardware is connected to the correct serial port
- Check
hardware_redis.logfor errors
If you see duplicate lap events, you may have multiple instances running:
pkill -f 'franklin-hardware-monitor'
pkill -f 'python franklin.py'Then restart both processes.
The default serial port is:
- macOS:
/dev/tty.usbserial-AB0KLIK2 - Linux:
/dev/ttyUSB0
You can modify franklin-hardware-monitor to use a different port if needed.
race.log- Franklin race events and decisionshardware_redis.log- Hardware communication and serial data
devbox shell
pytestdevbox shell
basedpyright- ✅ Redis pub/sub architecture for flexible component communication
- ✅ Simulation mode for testing without hardware
- ✅ Real-time leaderboard display
- ✅ Lap time tracking and analysis
- ✅ Multiple race modes (Real, Fake, Training)
- ✅ Contestant management
- ✅ Automatic hardware initialization
- ✅ Comprehensive logging
- ✅ TUI with Textual framework