Arduino CAN Bus Interface

I’ve been working on an implementation of CAN for use in aircraft.  The protocol is called CAN-FIX and is a part of the MakerPlane Open Source Airplane project.  You can get more information on CAN-FIX here.

The idea for this project is to build an Arduino shield that will let it communicate over the CAN bus.  I had some Microchip MCP2515 and MCP2551 (CAN Controller and CAN Transceiver, respectively) laying around so I decided to make my own little Arduino shield so that I could quickly try out some ideas.  I started with the little ProtoShield that Sparkfun sells.  I also had some header material laying around so just getting the PCB without the rest of the kit worked for me.  An easier answer may be to get the full ProtoShield Kit.  This will give you some buttons and LED’s to play with too.

My intention for this particular device is to use it as a generic USB<->CAN converter.  Once I have that working, I’ll have a CAN interface for a computer and could use the same code with an Arduino Mini, or something similar, to interface to a Beagleboard, Rasberry Pi or other SBC.

CAN Shield Schematic
CAN Shield Schematic

The circuit is pretty simple.  It’s just an SPI interface to the MCP2515 CAN Controller IC.  This IC handles all of the low level details of the CAN protocol.  Things like timing, arbitration, error detection etc are all offloaded to this IC.  I purposely made mine similar to the CAN Shield that Sparkfun sells.  The pins are the same but I choose to use a 20MHz ceramic resonator instead of the 16MHz oscillator that’s on the CAN Shield.  The only reason I did that was because I had some.  It might make it work better at higher bit rates too but I haven’t tested any of that to know.

There are a couple of CAN Shields out there and they all have basically the same interface to the Arduino so this means that we should all be able to use the same software with all of them.  After all an SPI interface to the MCP2515 seems to be the most popular way to do CAN communication anyway.

Arduino Leonardo
Arduino Leonardo

One thing about my shield that is a bit odd is how I actually tied in the MISO, MOSI and SCK lines.  Since I decided to try this with a new Arduino Leonardo which has some differences in where these signals are located.  They don’t bring them out to the headers any more, so I connected them to the six pin ISP programming header.  This should work regardless of which type of Arduino used but I haven’t tried it on another type.

Top View of the CAN Shield
Top View of the CAN Shield

In this shot you can see the MCP2515 to the right and the MCP2551 in the top center.  The DB-9 connector is just one end of a serial cable that I had lying around (You can’t see it in this picture, but it’s on the other end of that thick black cable).  I just cut one end off of it and found pin 2 and 7 for use here.  There is a pad on the proto board for a small pushbutton switch.  I used two of those holes (the ones tied to GND) as place to solder some wire and hold the serial cable.  There are probably better ways.  The transistor looking thing to the left is an LM34 temperature sensor.  I threw it on there so that I’d have something analog on the board to use when I’m playing around with the CAN-FIX software.

Bad photo of the solder side of the CAN Shield
Bad photo of the solder side of the CAN Shield

In the above image you can see the two rows of female headers that I used for the ISP interface.  I didn’t have any two row female headers so I just cut a couple of single row headers and jammed ’em together.  As you can see there really isn’t much to it.

The code to make this work can be had from GitHub.  It’s not very far along but it can be used for testing the circuit at this point.



MCP2515 Datasheet

MCP2551 Datasheet

2 thoughts on “Arduino CAN Bus Interface”

  1. hello,

    firstly i want to thank you for your explanation, i want to know which Vcc,C4,C3 is needed in this schematic and now i trying to do code with arduino uno to receive ant transmit a message via CANbus,J1939 protocol.

    thank you

  2. You’re welcome. Vcc is 5VDC. It think the MCP2515 will work with 3.3 or 5V but the MCP2551 wants to see 5VDC so I just powered all of it from 5V. It’s also the voltage the Arduino uses. C4 and C3 are just bypass capacitors for each IC. I used Electrolytic caps but other types should work well. They need to be placed as close as possible to each IC.

    Here is a link to the GitHub page []. I’ll probably do a follow up post to this one soon describing what the Arduino code does.

Leave a Reply

Your email address will not be published. Required fields are marked *