After looking around at CAN controllers, I settled on the MCP2510 by Microchip. It takes care of all the low-level CAN stuff for you, allowing you to just read the CAN messages over SPI. It also has hardware message filtering features, which I would probably never need, but are nice to have just in case. I would have liked to use an Atmel micro with built-in CAN, but I wasn’t able to find one in a DIP package, which I consider essential for prototype projects like this one.
This turned out to be just as well, because after messing around for a bit, I decided to order an Arduino to use as a development platform. I’d wanted to play with one anyway, and this seemed to be a good opportunity. The Arduino is easy to program over USB and handles USART over USB for you as well. The MCP2510 is a good choice for integration with the Arduino, so everything turned out well.
The MCP2510 requires an additional CAN transciever chip to do the actual interfacing with the CAN bus. Unfortunately, I couldn’t find one of these in a DIP package either. I did find a Maxim chip in a SOIC package, which is about the friendliest SMD package. Maxim is excellent about sending samples, and happily sent me several of these devices. I ordered my Arduino from Adafruit in a kit that also came with a protoshield board and tiny breadboard. This was perfect for the project, as the breadboard made for easy prototyping with the MCP2510 and the protoshield has SOIC pads broken out to solder points.
I didn’t do enough reading before placing my parts order, and so didn’t realize that the 2510 needs a clock source. Not wanting to order and wait for a crystal oscillator, I found that the ATMega328 on the Arduino can output its clock on a pin. This can be enabled by setting the eFuses a certain way. It was an easy fix to update the fuses and use the microprocessor clock to drive the 2510. I’ve since ordered a 16MHz crystal for it so that the Arduino fuses don’t have to be altered, but it works both ways.
The final build turned out to look like this:
The wiring’s a little messy, but it works! My only gripe about the protoboard is that if you populate the 5v and GND headers at the bottom, your breadboard will cover up some of the SOIC breakout points. This might be a design oversight, but I think it comes from a conscious layout choice to keep through-hole connections from being grounded by the casing on the USB jack. I luckily noticed this before placing the breadboard and was able to run the SOIC breakout wires from the bottom of the board, so it worked out. If you’re planning on using the breadboard and the SOIC spot on the protoboard, make sure to leave off the GND and 5V headers and place the breadboard low enough to allow access to the SOIC breakout points.
Several years ago, I read somewhere about the on-board diagnostic (OBD) systems in cars and got excited. There’s a whole heap of stuff your car is just dying to tell you, and all you have to do is know how to listen in! I had dreams of a dash-mounted display, showing all sorts of engine parameters and other car information while I drove. At the time, I didn’t know much about developing for microcontrollers, and couldn’t find a lot of information about the protocol, so the project fell aside.
A couple years later I got a new car, a Mazda 3. Like most newer cars, this one had a more standard OBD interface based on the Controller Area Network (CAN) bus. The CAN bus is a communication protocol designed for efficiency, reliability, and robustness. We had studied the CAN bus in school, writing programs for CAN-controlling microprocessors. I again got excited, because this time I knew what was needed to access the car electronics.
After a bit more looking, I was again disappointed. Even though the CAN communication protocol is a freely-published standard, the information sent across it is not. There are standards for automotive CAN, but they are not freely available. Unfortunately, standards companies charge several hundred dollars for access to their standards. This fee is nothing for a company selling millions of dollars in products based on these standards, but is a high barrier for any hobbyist just trying to figure out how something works. The expense, combined with not knowing exactly which standard (or standards) I needed to access to be able to decipher the CAN bus derailed my efforts a second time.
A few months ago, I found a blog entry of a similar hobbyist who also had a Mazda3. This time, I wasn’t taking no for an answer. I had previously assumed that there were layers to the CAN protocol, much like the TCP/IP stack. Even if you could read the data-link layer, you had no idea what was going on in the layers above, and especially not in the (probably proprietary) application layer. However, this guy had figured it out. An individual CAN message wasn’t just a fragment of a larger communication, but stood on its own, independent of the messages around it. I intended to repeat his experiment with my own hardware.
I’ve had some success with this project, and am planning to write up the details in several future posts. However, for the time being, if anyone knows of any source of freely-available information about automotive CAN standards, please post it up! I’d love to see it.