CarMAN: Giving the Connected Colorado a Dashboard
My Colorado already had a name for its Wi-Fi network. I decided it should have a dashboard to go with it.
I still haven’t landed on a proper name for this one, so for now it’s CarMAN. The name grew out of CarFi, the Wi-Fi network my Connected Colorado already broadcasts. Once the car had its own network, it felt natural to build a management plane and a visual dashboard on top of it: something I could run on a tablet mounted in the car, and also as a mobile app when I’m away from it. The app itself is an iOS app I designed with the help of AI.
The brains: a Raspberry Pi
Behind the scenes, everything runs through a Raspberry Pi in the vehicle. It connects to CarFi, with a failover 4G Ethernet connection in case that drops out. Attached to it are an NESDR Nano 2 USB SDR (software-defined radio) receiver, a YARD Stick One transceiver, and the Pi’s own built-in Bluetooth. Between them, those three give the Pi a way to listen to, and in some cases talk to, almost everything electronic in and around the vehicle.
Reading the car itself
For data from the car’s own ECU, I’m using a basic OBD-II Bluetooth module. That gives me engine RPM, temperatures, fuel levels, battery levels and similar statistics, pulled straight from the car.
Making sense of the battery system
My Colorado runs a Kickass 12V dual-battery system in the canopy, which has its own built-in Bluetooth for the BMS (Battery Management System). Once I’d connected that Bluetooth to the Pi, I could start sniffing the packets of data the BMS was sending.
What followed was countless hours of working out what each packet actually meant. I used Python to interpret the data, map it to the correct packets, and line it up with the real battery information: current battery charge, current discharge rate, battery health, charge rate and so on. That then went into a simple PHP page inside CarMAN, showing the battery statistics alongside the OBD data from the car.
Knowing where the car is, and where it’s been
The next step was tracking. I bought a Teltonica GPS tracker through CoreGPS, and with great support from Daniel Nagy, had it up and running quickly.
The data it gives me is genuinely useful, not just a dot on a map:
- Mapped trips, and how far I’ve travelled over a period (currently by month).
- The actual routes taken.
- Any extended stops along the way.
- Speeds along the route.
- Geofences, with alerts whenever the car arrives at or leaves a fence I’ve set up.
Controlling the 12V panel
Then came the hard part. I have a wireless 12-gang 12V panel controlling various things on the vehicle, and I wanted to switch those on and off from anywhere, in keeping with the whole idea of CarMAN. This is where the YARD Stick One and NESDR Nano 2 came in.
The panel transmits on 433 MHz, and it wasn’t straightforward. Each of the twelve switches is its own piece of data, but the remote also sends a randomised string that only the wireless controller can decipher: a rolling code. That turned into a genuinely difficult problem over several days of testing.
Eventually I worked out an approach that lets me approximate the required string within a small margin of error, and for the most part it works. That gave me control of switches 1 through 12 from a simple PHP page and from the CarMAN app.
It didn’t stop there, though. Some of those switches power things that should never be turned off by accident, like the fridge, the Raspberry Pi itself, and a few other devices. So I added code to make sure those particular switches aren’t executable, whatever else happens on the panel.
Where it stands
At its current state, this has been a fully hands-on project: a lot of testing, a lot of trial and error, and a much better understanding of how devices talk to each other over BLE and 433 MHz than I had when I started. Between the Pi, the SDR gear, the BMS reverse engineering and the GPS tracking, CarMAN has turned into a genuinely useful way to see and manage what my car is doing, whether I’m in it or not.
I’ll keep documenting this one as it develops, including, hopefully, a better name for it.
— Daniel (Watti)