Having had a Toyota GT86 for a while I quite enjoyed the built-in rev alarm and winding the engine all the way round, until an old lady made it an insurance write off. Though, I did have the luxury of driving a BMW 430d M Sport hire car from my insurance for a few months. I now have a 2006 Honda Civic Type-S GT hatchback, and really miss that alarm (and the rest of the 86, really).
So… lets make a DIY rev alarm! Using an Arduino and a cheap MCP2515 module I sniffed the traffic between an ELM327 diagnostics tool and the Civics OBD-II port. I found that the CAN bus runs at 500Kbps, and spews out a lot of standard 11-bit ID CAN messages. By issuing the ‘010c’ command to the ELM327 to request the engine RPM parameter I saw that it was sending extended 29-bit CAN messages with an ID of 0x18DB33F1, and that replies had an ID of 0x18DAF110 (I won’t be going into specifics about the OBD-II protocol regarding physical and functional addressing here, googling the two hex numbers returns some interesting results). Great! That was all I needed to get the project started.
Sample capture output
Standard ID: 0x3F8 DLC: 8 Data: 0x00 0x00 0x00 0x00 0x02 0x20 0x19 0x44 Standard ID: 0x164 DLC: 8 Data: 0x04 0x00 0x00 0x38 0x7B 0x00 0x00 0x84 Standard ID: 0x0D0 DLC: 7 Data: 0x00 0x00 0x00 0x00 0x00 0x00 0x29 Extended ID: 0x18DB33F1 DLC: 8 Data: 0x02 0x01 0x0C 0x00 0x00 0x00 0x00 0x00 Extended ID: 0x18DAF110 DLC: 8 Data: 0x04 0x41 0x0C 0x0B 0xE4 0x55 0x55 0x55 Standard ID: 0x13F DLC: 8 Data: 0x01 0x2E 0x01 0x22 0x00 0x00 0x00 0x0F Standard ID: 0x0D0 DLC: 7 Data: 0x00 0x00 0x00 0x00 0x00 0x00 0x38 Standard ID: 0x294 DLC: 8 Data: 0x00 0x16 0x00 0x02 0x8D 0x52 0x00 0x04
The rev alarm plugs into the vehicles OBD-II port, and contains an RT6200 buck regulator to drop the cars 12V down to around 5V, which is used to power the ATmega328P microcontroller, MCP2515 CAN controller and MCP2561 CAN transceiver.
The Arduino platform and this MCP2515 library were used to code up the device. The alarm trigger point is set by revving the engine to the desired RPM and pressing the button on the right. The 7 segment display can cycle between displaying the selected gear, RPM to the nearest 1000 or nothing by pressing the left button. The display brightness is automatically adjusted with the help of an LDR.
Since there are no selected gear parameters in the standard OBD PIDs I had to instead work it out from the engine RPM, vehicle speed, wheel circumference and gear ratios. This unfortunately means that the gear ratios and wheel circumference need to be reprogrammed whenever the device is to be used in a different vehicle. Also any inaccuracies with the vehicles speedometer, tyre wear and pressure can throw off the calculations at lower speeds (generally less than 20MPH) so some fine tuning may be required, though this is easily done by adjusting the wheel circumference setting until the gear display is stable. For my Civic I had to reduce the wheel circumference setting by 4%.
As the OBD port is always powered, even when the vehicle is off, the usual low power sleep features had to be coded in so the car doesn’t end up with a dead battery. Most of the electronics in the rev alarm draw no more than 70uA in sleep, however the buck regulator draws around 2.7mA. This is a little higher than I was hoping for, but it’s still low enough not to drain the battery for a long time.
The Arduino code and various other things are available on the GitHub repo.