Sending J1939 CAN-BUS messages with Sparkfun CAN-BUS Shield
Posted: September 26, 2012 | Author: Nuno Alves | Filed under: Embedded Systems | Tags: Arduino, C/C++, CAN |18 Comments »Keeping in the spirit of open-source, I have modified the libraries of the Sparkfun CAN-BUS shield. With these updated libraries we are now able to send messages using the standard identifier (11 bits) and also send messages with the extended identifier (29 bits).
I am running the following code in Arduino UNO. This particular CAN-BUS shield does not work with the latest Arduino board (Leonardo). Anyway, here is a simple Arduino program that continuously sends J1939 messages through the CAN network.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <Canbus.h> #include <defaults.h> #include <global.h> #include <mcp2515.h> #include <mcp2515_defs.h> void setup() { Serial.begin(9600); //Initialise MCP2515 CAN controller at the specified speed if(Canbus.init(CANSPEED_250)) Serial.println("CAN Init ok"); else Serial.println("Can't init CAN"); delay(1000); } void loop() { static char counter=0; tCAN message; message.id = 0x00FF50FF; message.header.rtr = 0; message.header.length = 8; message.data[0] = 0x02; message.data[1] = 0x01; message.data[2] = 0xFF; message.data[3] = counter; message.data[4] = 0x00; message.data[5] = 0x00; message.data[6] = 0x00; message.data[7] = 0x00; mcp2515_bit_modify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0), 0); mcp2515_send_message_J1939(&message); counter++; delay(1000); } |
The updated MCP2515 libraries can be found at http://www.nunoalves.com/source/canbus_nca26_09_2012.zip. To install this library and use it with your Arduino projects just drop it in the appropriate sub-directory (e.g. ~/Documents/Arduino/libraries in macosx). For reference here is the data sheet for the MCP2515 SPI CAN transceiver. I found all the information in there.
Finally… a big thank you to Fabian Greif and his initial efforts on the MCP2515 library.


I’m trying to test Can Bus using the Sparkfun device on a mega 2560 board. Do I need to connect to a can bus of anytype to test this, is there a way to find the command references.. Wayne
It depends what CAN network you are trying to interface with. Is the CANH and CANL connected by a 120 ohm resistor? Do you know the CAN interface parameters that you are supposed to us?
I havent tried with the mega 2560 board, but make sure that the MOSI, MISO from that arduino board are connected to the pins D11 and D12 of the shield. On some arduino boards, the SPI interface is on different pins.
That’s looks amazing. I’m trying to establish a connection with CAN myself and I bought an arduino uno + sparkfun can shield. I’ve tried several libraries but initializing the connection always fails (even with different speeds). Already tested on 4 different vehicles.
Any idea how I can get my CAN shield working? Do I have to modify anything in the library? Would be great if I could figure this out.
The latest arduino (Leonardo) has a different pinout, so it wont work with this shield without you making some modifications. To save you some hacking time, I would just buy a Arduino UNO or an earlier version (like the one I used). Then I’d start reading the messages you are getting from the CAN bus. Make sure the shield CANH is connected to your car CANH, the same thing for CANL and GND. See the spec sheet for information regarding the location of the pins. Once all that is taken care of, just start reading messages. If you start collecting data, then you can figure out whats going on.
As for the CAN bus speed… I do not know, you have to see what is the baud rate of your CAN network.
Good luck!
To continue your spirit of opensource (tyvvvvvm for posting this by the way, saved me so much) here is the modified defaults.h file required to get the Mega 2560 to run with with code (modify in the library)
#ifndef DEFAULTS_H
#define DEFAULTS_H
#define P_MOSI B,2
#define P_MISO B,3
#define P_SCK B,1
//#define MCP2515_CS D,3 // Rev A
#define MCP2515_CS B,0 // Rev B
#define MCP2515_INT D,2
#define LED2_HIGH B,0
#define LED2_LOW B,0
#endif // DEFAULTS_H
Excellent work. Thank you!
I forgot to mention, after making that change and compiling you need to trim pins 10-13 off the shield and then put female headers on it and connect the following:
53 10
51 11
50 12
52 13
Do you happen to have a quick copy paste example of sending standard frame messages with your same code?
Yeah… just use the function mcp2515_send_message(&message) instead of mcp2515_send_message_J1939(&message). Make sure your identifier can fit the number of available bits.
Thanks again sir!
Hi, when you declare the baud rate, is that number at a ratio? i am using high speed CAN, at 1.0 Mbps, i dont understand what value i would put there,
Thanks,
Chris
No.. That number is send to the chip via an SPI command. Check out the data-sheet for the appropriate signal.
hi guy im tring to receive sending data with arduino mega2560 due to bus can , a made de connection with using sparkfun arduino can bus schield, but and also made a gut connection betwenn the shield and the arduino
53 10
51 11
50 12
52 13
but it not work i no able to read the data com fron the bus , on serial port0.
i have to send this data to another arduino with the xbee schiled !!
can someone help me !!
thx!!!
Hi, this is great stuff! You don’t by any chance have a corresponding function, get_meassage for extended identifiers?
Regards Anton
Hey guys,
i am struggeling using this code. i have a sparfun can shield an arduino uno. when i set up everything i cannot read messages with a usb-can reader which is approved. do i have to change the ports? i guess it should be set up right in the libraries??
Thanks.
Did you add the 120 ohm resistor in the bus?
Are you using the extended CAN format?
Did you specify the CAN BUS frequency correctly? These libraries as they are send messages at 250KBps.
The libraries have nothing to do with the fact that you can’t read the CAN message in the computer. These libraries just send the messages in the CAN bus.
Nuno,
Not sure if you still check this but I just wanted to say thank you for this. It really helped me out! I did notice that your message.id is 0x00FF50FF but when you use CANviaUSB it shows as 0x00FF500F. I am having issues with this part as the last 2 of the message id are the source address. I am sending a message with source address 22 (0xff00422) but every time I check the broadcast it actually shows coming from 42 (0xff00442). it kinda looks like the digit before is repeated and the last digit dropped. I am going through the library and see if this is something easy to change. Let me know your thoughts. Thanks!
Hi,
Glad to hear that my library was useful.
I havent used this library in a while… But I may be able to help you out. I presume you are sending things in the J1939 format, which is defined in the function uint8_t mcp2515_send_message_J1939(tCAN *message). Open up the file mcp2515.cpp. When I wrote this library I based it directly from the datasheet naming conventions. So my suggestion is to read the datasheet and try to match what is in there with my code. The source address (and the rest of the message header) is written in the following lines:
TXBnSIDH = (message->id) >> 21;
TXBnSIDL = (message->id) >> 18;
TXBnSIDL = (TXBnSIDL < < 5) | 0x08 ;
if (GETBIT((message->id),17)==1) SETBIT(TXBnSIDL,1);
if (GETBIT((message->id),16)==1) SETBIT(TXBnSIDL,0);
TXBnEID8 = (message->id)>>8;
TXBnEID0 = (message->id)>>4;