Issues interpreting CAN bus data from vehicle

Good afternoon! I have decided to fill my “social distancing” time by attempting to communicate with my car’s CAN bus, but have run into some issues. I will do my best to provide all relevant information.

My vehicle is a 2008 Mazda CX-9 Sport
For a microcontroller, I am using a CH340 clone I purchased from AliExpress roughly 10 months ago.
For a CAN interface, I am using a ElecFreaks CAN-BUS Shield which houses a MCP2551 CAN transceiver (the same transciever used on virtually every avaliable CAN Shield, including the SparkFUN CAN-BUS Shield
For a connector, I have mutilated and “repurposed” a HyperTough HT309 OBDII Reader I purchased from Walmart.

Board Wiring
From the OBD2 connector (here is a color-coded diagram I made) I wired the CAN-HI and CAN-LO pins to the connectors on the board, and then soldered the ground wire onto the UART ground solder pad on the shield. I wasn’t sure if this was necessary, but I wanted to ensure a common ground was made. I then used the included blue extra-long header things to connect the shield to the CH340 board.

I’ll brief over the problems I have already encountered and solved in the off-chance that any of those “solutions” are causing my problems.
I started my journey using Seeed-Studio’s CAN_BUS_SHIELD library, specifically the recieive_check example. I was continuously receiving “CAN BUS Shield init fail” errors, so I looked closely at the board and realized that the software was calling for a “CS” pin of 9, while my board’s CS pin routed to D10. I swapped this and started seeing intermittent success, but often when the board was plugged into nothing, it would receive “ghost data”, and when it was plugged into the car, it would receive intermittent data. I figured out that this correlated to pushing the aforementioned “blue extra-long header things” outward, so I decided to remove them from the equation, and I soldered jumpers from the CH340 board to the shield on the jumpers that, as far as I could tell from finding schematics and visually inspecting the traces, were in use. Here is a list of connections that have jumpers: 5V, MISO, MOSI, SCK, and D10.

After further inspection while writing this, I noticed that I am missing D2, the “INT” pin, but some forums said that isn’t necessary. Regardless, I will be adding and testing it tomorrow morning. I am absolutely bewildered as to how this board seems to completely ignore the whole concept of “grounding”, but I am sure I am just not understanding something.

After I did all of this, I plugged it into the car, ran recieve_check, and got data! I tried a few different frequencies (500k, 250k, 125k), but only got data out of the 500k trial. I have attached about a minute’s worth of 500k data in a TXT file (line with single number is the CAD ID, line with 8 tabbed numbers is the data, same format from the recieive_check code, except the “Get data from ID:” printed before the number is removed because I was plugging the data into a Java program I wrote to look for patterns) The problem is, the data doesn’t really make any sense. There are some patterns, certain IDs always output the same data, but all of the CAN ids are above 100 (which definitely doesn’t seem correct from my limited exposure to CAN bus systems), and nothing matches up with data from other car enthusiast forums or the OBDII PID Standards. I tried various other libraries, including the OBDII and Arduino-CAN library pair from sandeepmistry, along with a few others, each time being sure to swap the CS pin to 10, and continued to get data that didn’t look like garbage, but didn’t make much sense either.

I was hoping someone had some insight into what I am doing wrong, or how to interpret the data correctly.


cardump.txt (125 KB)

There are some patterns, certain IDs always output the same data, but all of the CAN ids are above 100 (which definitely doesn't seem correct from my limited exposure to CAN bus systems)

Telemetry data is not automatically transmitted over CAN, you have to query for it. Because of this, these data packets most likely are not the data you're looking for. I don't have much experience working with CAN libraries, but it should be relatively easy to get your code to send a CAN query for the service/PID you care about and monitor for a response.

I tried something similar to what you're doing to make a car heads up display, but ended up finding it much easier to interface with an ELM327 than the CAN port directly. Not to mention that ELM327 devices can be cheaper than CAN interface boards.

If you decide to use an ELM327 or want some inspiration on forming PID queries, check out ELMduino.h.