Firmware for DashKit, an ESP32-S3 controller for Tesla vehicles. DashKit plugs into the car's CAN buses so you can control the car, run automations on the device, and feed live vehicle data to the DashPilot app.
- 🎛️ Vehicle controls: open the frunk or glovebox, fold the mirrors, preheat the battery and more, from your phone or a gesture on the center screen
- ⚡ Automations: behaviours that run on DashKit itself, even with no phone connected
- 📊 Live data for DashPilot: real-time CAN data streamed to the app over Bluetooth
DashPilot sends these commands to DashKit, and DashKit turns them into CAN frames on the vehicle bus. You can also bind any of them to a multi-finger gesture.
- 🚗 Frunk / trunk
- 🪞 Mirror fold / unfold
- ↩️ Mirror dip on reverse
- 🔌 Charge port open / close
- 🧤 Glovebox
- 🌬️ Rear AC fan
- 🔄 AC swing
- 🔋 Battery preheat
Tip
Automations run on DashKit itself, so they keep working when the phone isn't connected. Their settings are saved on the device.
- ✋ Multi-finger gestures: bind a 3-, 4- or 5-finger tap on the center screen to any vehicle control.
- 🌧️ Auto wiper-off: turns the wipers fully off when they go from OFF to AUTO. Only acts while lane assist is engaged.
- 🏁 Sport kick-down: switches the pedal map to Sport while the accelerator is past a set threshold in Drive.
- ❄️ Keep climate on: keeps the cabin conditioned for a set time (1–60 min) after the driver leaves the car.
- Two CAN buses (chassis + vehicle), each on its own MCP2518FD controller.
- Hardware acceptance filters on each bus pass only the messages DashPilot uses, so no frames get dropped under load.
- An on-device DBC signal layer decodes and caches the latest value of every message it tracks. Automations read signals by name rather than by raw bytes.
- Frames are streamed to the phone over an encrypted, bonded BLE link.
- 🔑 Tesla BLE key: DashKit can enroll as a Tesla BLE key, with the car provisioned and paired from DashPilot. It reports presence, lock, sleep, charging and climate state to the app.
- ⬆️ OTA updates from DashPilot. If a new image crash-loops, the device rolls back to the previous one.
- 🔒 Secure pairing: only an already-paired phone can open a pairing window. Up to 3 phones can be bonded, with one active connection at a time.
- 🧹 Factory reset: hold 5 fingers on the center screen to clear all bonds and reboot.
- 🔘 BTHome buttons (experimental): use a Shelly BLU button as a physical trigger, e.g. to open the glovebox.
- Plug in DashKit. The LED turns blue while it boots and green when it's ready (red means a CAN or BLE init failure).
- In DashPilot, scan for and pair with DashKit.
- DashPilot displays live vehicle data. From its settings you can trigger controls, bind gestures, turn automations on or off, and install firmware updates.
- Optional: add DashKit as a Tesla BLE key from DashPilot. Tap your key card on the console when prompted, then confirm on the touchscreen (the LED turns cyan while it waits).
Projects people have built on top of DashKit:
- 🕶️ Tesla LilyGO Head-Up Display: a head-up display on a LILYGO T-Display-S3 AMOLED that reads live data from DashKit over BLE. It has a compact HUD layout (speed and essentials) and a "road scene" layout with lane markings, turn signals and blind-spot warnings.
Note
Built something with DashKit? Open a PR to add it here, or share it on Discord.
- macOS with Homebrew
- USB cable for flashing
brew install cmake ninja dfu-util
git submodule update --init --recursive
./esp-idf/install.sh esp32s3Activate ESP-IDF in every new terminal session (or add it to your ~/.zshrc):
. ./esp-idf/export.shidf.py set-target esp32s3
idf.py build
idf.py flash monitorPress Ctrl+] to exit the serial monitor.
Options under idf.py menuconfig → DashKit:
| Option | Default | |
|---|---|---|
CONFIG_DASHKIT_TESLA_BLE |
y | Tesla BLE vehicle-command client |
CONFIG_DASHKIT_BTHOME |
n | BTHome / Shelly BLU button listener |
For verbose CAN frame and status logging, uncomment CONFIG_DASHKIT_DEBUG_LOG=y in sdkconfig.defaults.
Run idf.py fullclean && idf.py build after changing options.
| Path | Contents |
|---|---|
main/can/ |
MCP251xFD driver, CAN manager, HW filters, DBC signal layer |
main/ble/ |
NimBLE GATT server, OTA service, app channel |
main/controls/ |
Vehicle control commands, battery preheat |
main/automation/ |
One file per automation, plus the registry |
main/tesla/ |
Tesla BLE key enrollment and vehicle-command client |
main/bthome/ |
BTHome button listener |
components/tesla-protocol/ |
Tesla vehicle-command crypto, session, protobufs |
dbc/ |
Vehicle DBC and the used_messages.txt manifest |
tools/ |
DBC/proto codegen, host tests, OTA publishing |
The DBC tables (main/can/dbc/dbc_generated.{c,h}) are generated from dbc/used_messages.txt and committed. If tools/.venv exists, idf.py build regenerates them automatically:
python3 -m venv tools/.venv && tools/.venv/bin/pip install -r tools/requirements.txt| Function | GPIO |
|---|---|
| SPI MOSI | 11 |
| SPI SCLK | 12 |
| SPI MISO | 13 |
| CAN0 CS / INT | 10 / 9 |
| CAN1 CS / INT | 7 / 8 |
| LED Red / Green / Blue | 39 / 40 / 41 |
Both CAN controllers are MCP2518FD with 40 MHz crystals and share the SPI2 bus at 10 MHz.
MIT. See LICENSE.