Thursday, October 10, 2013

Arduino - Sending data over a CAN bus

I have been tinkering with CAN buses due to my interest in cars. It's fascinating to me that packets are flying around a modern vehicle controlling nearly everything. Gauges, lights, locks, engine sensors, etc. To have a better understanding of the basics of a CAN bus I wanted to build the simplest possible setup to send and receive CAN messages. I chose two Arduino Uno's with a Seeed Studio CAN-BUS shield attached to each Uno. The Seeed shield is very straight forward and inexpensive. The Sparkfun CAN-BUS shield has an SD card slot, LCD connector and GPS connector. All of which are cool but drive up the price and complexity. The Seeed shield only does CAN bus and includes screw terminals which are handy for testing.

Arduino Uno R3Seeed CAN-BUS Shield

What I wanted to do with this experiment was transmit the value of an analog pin hooked up to a linear potentiometer. The data would be sent from one Arduino to another over a CAN bus and then display that value on an LCD connected to the second Arduino. Here is a picture of my setup. (Ignore the Mega2560 above the LCD. It's not used here.)


And here is a Fritzing diagram minus the CAN-BUS shields.



CAN bus termination

A CAN bus requires 120 Ohm termination resistors at each end of the bus. The Seeed Studio shields have built in termination resistors. When you connect two Seeed CAN bus shields togther like I did in this example you will have a properly terminated CAN bus. If you plan on connecting into an existing CAN bus that already has termination you can disable the built in termination resistors. To disable termination you can cut trace P1 or you can desolder resistor R1.


Close up view of the Seeed CAN bus shield
 termination resistors.
**Note: I have recently discovered the Seeed Studio CAN-BUS shield v1.0 uses a 60 ohm termination resistor for R3. While that worked for this small demo I later ran into issues when trying to use this shield with other nodes on a CAN bus. This 60 ohm resistor caused me many hours of frustration. If you are going to use this shield with on a bus with multiple nodes I would recommend desoldering R3 and using the correct 120 ohm resistance at the ends of your bus. 

Connecting into an existing CAN bus

If you are planning on connecting into an existing CAN bus (like in a car) you need to remove/disable the termination resistor on the shield as explained above. The CAN bus in a vehicle already has termination resistors. Adding a new node with a termination resistor will cause errors and disrupt communication on the bus.

Another important step is to connect a common ground between your Arduino board and the vehicle. If you are connecting at the OBD2 port pin 5 provides a signal ground. If you can't find a signal ground wire a chassis ground will suffice.

CAN bus messages

So I should probably explain a bit about CAN bus messages. Each message is made up of an id and some data. The id's in hex start at 0x000 and go to 0x7FF or 0 to 2047 in decimal. In most systems lower id values are considered more important. The bus handles collisions by letting the lower id win the collision. The data can be between 1 and 8 bytes for each message. Each byte can have a value from 0 to 255 or in hex 0x00 to 0xFF. When you send a CAN bus message you transmit the id, how many bytes you are sending (this is called DLC) and the actual data. The receiver will only read the number of bytes you said should be in the message. So if you send a DLC of 4 but the message contains 8 bytes the receiver will only read the first 4 bytes. Eight bytes per message is a bit limiting but the tradeoff is the high reliability of the bus. So sometimes you have to be creative with stuffing data into those bytes. If the value you are sending is less than 255 you can just use a single byte. Larger numbers will require using multiple bytes. Ascii codes can be sent but only eight characters per message. Whatever method you use to stuff the data in will also have to be used to un-stuff the data on the receiver. In my simple example here I did some math to limit the range of values to 0-255. An analog pin produces values between 0-1024. I simply divided the result by four to give me data I could send in a single byte.
CAN buses can operate at several different speeds up to 1 Mbit/s. Typical rates are 100 kbit/s, 125 kbit/s and 500 kbit/s. Slower rates allow for longer length buses. All devices on a bus must transmit at the same speed. The CAN bus wikipedia page is a good place to start if you want to learn more about the CAN protocol.


Code

I started with the example code provided by Seeed and modified it to add in the LCD output on the 'receiver' device and added reading of the potentiometer on A0 for the value that is transmitted. They have basic examples for send and receive. You can find some good info on their wiki page. Their libraries are available here. On my Mac I created the directory ~/Documents/Arduino/libraries/CAN_BUS_Shield for the library files. I unzipped the file and copied over the .h and .cpp files into that new directory. The zip file also contains the send and receive examples.

Note that normally devices on a CAN bus are both receivers and transmitters of data. This is a simplified example where each device is only doing one task.



Sender code


Receiver code


Video




[Updated 2014-05-25: Noted value of A0 potentiometer in the Fritzing diagram]
[Updated 2014-07-21: Added section about termination resistors]
[Updated 2014-09-25: Added note about incorrect value of resistor R3 on Seeed's shield]
[Updated 2015-03-10: Added additional notes about termination resistors]
[Updated 2017-03-27: Added new section 'Connecting into an existing CAN bus']



101 comments:

  1. what kind of potentiometer did you use???

    ReplyDelete
    Replies
    1. It's a Philmore 10k ohm linear potentiometer.

      Delete
  2. Hi
    great little intro into the canBus
    I am trying to communicate with the volvo can bus which uses a longer can Id.
    Do you by any chance know how to change the size of the ID .
    any help would be appreciated.

    ReplyDelete
    Replies
    1. I read through the SeeedStudio mcp_can library and it looks like it supports the longer 29 bit CAN messages. I would recommend trying the generic receive.ino example that comes with their Arduino library and see if that works. Also make sure you are using the correct CAN bus speed for your vehicle.

      Delete
    2. hi Matt, I find it difficult to send CAN messages and send the same messages to serial port. Have you experiences something like this before?

      Delete
    3. jis, I haven't run into that myself. Actually I don't think I have tried doing that. Are you trying to just display the CAN messages on the serial console?

      Delete
    4. yes,i have to send around 10 CAN messages and receive 4 messages periodically.the same need to be displayed on my serial console

      Delete
  3. Good work! I happened to have a J1939 CAN generator and tested it with your code, it works fine. So this CAN shield should definitely work with extended CAN 2.0B or so called J1939 protocol. Just one question I am little bit confused with your code, seems you are using the digital input No.2 as a interruption trigger to read the CAN message,
    How does that happen? was that DI triggered by the CAN shield when it receives something or it has to be controlled by some external wiring?

    ReplyDelete
    Replies
    1. Jason, man I just realized I didn't answer your question and it has been almost a year! Sorry about that. The shield does connect to digital pin 2. The MCP2515 CAN controller chip on the shield has pin called 'INT' which goes low when it has messages in it's buffer to be read. This is used to trigger the interrupt on the Arduino. Digital 2 on the Arduino is configured as an external interrupt which triggers the code to read messages. The CAN-Bus shield is built to be used this way. When all messages have been read from the buffer the line goes high again and the code stops trying to read messages from the CAN controller.

      Delete
  4. Where did you define the id of each arduino?

    ReplyDelete
    Replies
    1. The Arduino's don't have an id. Each CAN bus message contains an id. Line 37 of the sender code contains the id of the message which is '0x7B' in hex or '123' in decimal:

      CAN.sendMsgBuf(0x07B, 0, 8, canMsg);

      CAN bus messages can have any id between decimal 0 and 255. Any device connected to the CAN bus can transmit messages with any id number. If you wanted to identify a particular device as the source of a message then you decide to only transmit certain CAN bus id's from certain Arduino's. The receiver device just listens for all messages on the bus.

      Delete
    2. Is it possible to use the Sparkfun shield with an arduino Mega?

      Delete
    3. I looked through the comments for that board on the Sparkfun site and it seems to be possible if you redefine the SPI pins in the MCP2515 library to use the proper SPI pin numbers for the Mega. The Uno uses 10,11,12,13 for SPI and the Mega uses 50,51,52,53.

      Delete
  5. Hi, this work fine. i havent got seeedstudio can bus shield. i have sparkfun can bus shield. if i use your code, will i run?? thanks

    ReplyDelete
    Replies
    1. It looks like the SparkFun board uses the same CAN bus transceiver and controller chips. I can't say for sure because I don't have one of the SparkFun boards but it might work. It certainly wouldn't hurt anything to try.

      Delete
    2. thanks your answer,
      Did you use 120 ohm resistance in this work??

      Delete
    3. Ah, you bring up a very good point. Yes a CAN bus requires 120 ohm resistors at each end of the bus. The Seeed Studio shields have built termination resistors. They can be disabled by cutting trace P1 or unsoldering resistor R3. If the Sparkfun shields don't have the built in termination resistors you would need to add them to each end of the bus. Thanks for pointing this out. I am going to update this post with that information.

      Delete
  6. Hi, small question. How many pins on the arduino board are used by the seeed shield? I mean, how many digital io and analog ports do I have left to use?
    Thanks

    ReplyDelete
    Replies
    1. The seeed shield communicates over SPI so on an Arduino UNO it uses pins D11, D12, D13 for SPI and D10 for CS. All other pins should be available.

      Delete
    2. I missed something in my previous reply. The Seeed shield also uses Digital pin 2.

      Delete
  7. Great write up Matt, I would like to invite you to my website cansniffer.com please contact me if you ever need any help or products.

    ReplyDelete
  8. Hi Matt McMillan, more or less i am working on a same project. i made a weight scale circuit using strain guages and instrumental amplifier. the output of instrumental amplifier are going to pin A2 and A3 on arduino and if i change the weights i can easily see the values on lcd like 30grams, 40grams,50grams...............

    Now i want to send these values from one can bus shield to another can bus shield.... could you please help me in this regards.

    Regards:
    Tahir Muzaffar

    ReplyDelete
    Replies
    1. Are you wanting to send the weight data from one Arduino to another?

      Delete
    2. yes exactly from one arduino to another using can bus

      Delete
    3. Well my example code above should give you most of what you need. What sort of help are you looking for?

      Delete
  9. a complete code to send the weight data from one Arduino to another !!

    ReplyDelete
    Replies
    1. Sorry man I don't have time to write code for you unless you are going to pay me to do it. Good luck with your project.

      Delete
  10. Replies
    1. You can message me on Twitter @matthewmcmillan

      Delete
  11. You lack the initialisation of the can object in both files:
    MCP_CAN CAN = MCP_CAN(10);
    where 10 or 9 is decided by the solder jumper on the board.
    Also CAN is bad naming, since it's an object it should start with a small letter, like can_bus or something.
    Thanks for the rest though

    ReplyDelete
    Replies
    1. Well Mr. Anonymous the initialization objects you are referring to are only used in coryjfowler's MCP2515 library not Seeed Studio's version of the library. This post is using Seeed Studio's library. Also the 'CAN' naming came straight from Seeed's example code so you'll have to take that issue up with them if you want to complain some more.

      Delete
  12. Hi, I've been trying to make this work with a Megasquirt 3 but haven't been successful.
    I'm using an Arduino UNO with your same CAN-Bus shield and I'm trying to send data from the Arduino to the Megasquirt 3. I'm guessing my problem is the termination resistor? Any help?

    ReplyDelete
    Replies
    1. Oh neat. I have an MS3Pro system on my truck but I haven't done anything with the CAN Bus yet. So are you trying to send sensor info to the Megasquirt? I read through the Megasquirt CAN documentation and it says they are running at 500k which would definitely need proper termination. The docs say the Megasquirt board has a 120 ohm termination resistor on it. If you don't have any other CAN devices on the bus (like a jbperf I/O extender) your CAN-Bus shield will need to provide termination for the other end of the bus. Like I mentioned in the blog post, the v1.0 of the Seeed CAN-Bus shield only has a 60 ohm termination resistor so that would need to be removed and you need to add a 120 ohm resistor. I have put the 120 resistor across the screw terminals and screwed it down with the CAN-H and CAN-L wires.

      If you are indeed trying to send CAN info to the Megasquirt, I would recommend first just trying to read the broadcast data to make sure your bus is working properly. You have to enable the CAN broadcast data in your config.

      You may have read through these docs already but if not there is a lot of good info:

      http://www.megamanual.com/com/CAN.htm
      http://www.msextra.com/doc/pdf/Megasquirt_CAN_Broadcast.pdf
      http://www.msextra.com/doc/pdf/Megasquirt_29bit_CAN_Protocol-2015-01-20.pdf

      Delete
    2. I feel so stupid, I was trying to do this without the 2 wires that go inside the megasquirt3 to enable CAN. So after long nights I finally got it working.. Was able to send analog data. NOW my mission is broadcasting data from the megasquirt to the Arduino. For some reason my CanBus shield's Recieving indicator LED and Recieving Int Indicator LED are both always on. The Int Led is brighter though.. I still have the 62 ohm resistor on it. Might it be that???

      Delete
    3. Way cool! Would you mind sharing your Arduino code you are using to send analog data to the megasquirt3? I'm very interested. That 62 ohm resistor could be causing problems. I would recommend removing the 62 ohm resistor and use a 120 ohm. Having different resistor values at each end of the bus is going to cause weird behavior.

      Delete
  13. This comment has been removed by the author.

    ReplyDelete
  14. Thank you for the great tutorial. Do you have any suggestions to send a CAN message with the full 1024 but resolution of the analog input pin instead of dividing it by 4?

    ReplyDelete
    Replies
    1. The simplest thing to do is use two bytes. You use one byte to store the number of times the other byte has rolled over past 255. This give you the ability to store a number up to 65,280 in two bytes.

      For example a value of 925 would be stored in a CAN message as:
      [160, 3, 0, 0, 0, 0, 0, 0]

      To get the value out it would be (3*255)+160

      Does that make sense?

      Delete
  15. Hi me again. I was wondering what CAN library are you using. Cause I see in your Reciever code you have #include "mcp_can.h" instead of .... I don't know if this makes a difference. But i'm interested to know because your code is the only one I find online that seems to work in your video and also you answer to your posts pretty quick. Been looking for help and you seem to be the only one answering so thank you!

    ReplyDelete
    Replies
    1. I this post I used the library published by SeeedStudio which can be downloaded here: https://github.com/Seeed-Studio/CAN_BUS_Shield

      In other posts on my blog I switched to CoryJFowler's fork of the library which can be downloaded here: https://github.com/coryjfowler/MCP_CAN_lib

      Cory's fork adds the ability to declare the CS pin in the code versus editing the library.

      Either one is included by using the statement #include "mcp_can.h"

      Delete
    2. do you mind explaining what this: "#define INT8U unsigned char" and this "INT32U canId = 0x000;" do in the code? I'm having trouble understanding it...

      Delete
    3. This code came from Seeed Studio's examples and all I did was modifiy the receiver code to output to an lcd display. Seeed used syntax that is more C specific syntax than 'Arduino' syntax.

      The line "INT32U canId = 0x000;" creates an unsigned integer variable 32 bits in size and fills it with the hex value of 0x000. Most Arduino coders would probably use the 'unsigned long' variable type instead of INT32U but they do the same thing. I think specifying the the bit size makes the code more portable.

      As for "#define INT8U unsigned char"... looking at the code again now that actually is not needed at all. lol. Must be something left over from Seeed's code that I removed when I modified their example code. This again is C code that being very specific about the size of the variable.

      That is my best understanding of those lines of syntax. Take that with a grain of salt as I am a hobbyist/terrible programmer!

      Delete
    4. That's ok. I just wanted to make sure. Thanks a lo for the help. I'm still waiting for my 120 ohm resistor to arrive to see if I'm able to send data from the Megasquirt to the Arduino. I'll keep you posted!

      Delete
  16. This comment has been removed by the author.

    ReplyDelete
  17. Hi Matt, do you know why im not getting any data to my CAN bus sniffer?

    I have a UNO and the shield https://www.sparkfun.com/products/10039 - i read this post and added a 120 ohm resistor to both the High and Low but this made no

    ReplyDelete
    Replies
    1. Mark are you connecting into a CAN bus in a car? If so you most likely don't need the 120 ohm resistor. Have you tried different CAN bus speeds?

      Delete
  18. I have a question:-
    We're working with an ECU, with a datasheet of data and message IDs. We wanna get the speed from the ECU, we can get the correct message ID and the bits that we need. We're unsure on how to calculate the speed though.

    Here is the information about the speed:
    Data is in big endian format.
    Message ID: 0x00200080
    Byte 6-7 are for speed.
    Bits 7-0

    Vehicle Speed
    Resolution: 1/256 MPH/bit, 0 offset
    Data Range: 0 to 255.996 MPH

    Any ideas?

    ReplyDelete
    Replies
    1. Can you post a few of the messages from a capture while the vehicle is moving? I like to watch the data change in the CAN Bus messages while comparing it to the readings on the gauge in the dash.

      Delete
  19. hi.
    really good post and realy helpfull for me.
    may i ask to you some quetion??
    in your post. the sender ID is 123. can i change it with another value ID??

    ReplyDelete
    Replies
    1. Yes you can change the CAN id. The possible values for 11 bit CAN id's are hex 0x000 through 0x7FF (decimal 0 to 2047).

      Delete
  20. Hello man

    I want to do a connection between the arduino due and the Bus-can shield, to receive the information of position of a servomechanism,What code do I have to use?

    Thanks

    ReplyDelete
  21. Hey Matt,
    Can i connect a Adafruit 1480 - Graphical LCD, using SPI on the Seeedstudio CAN shield. Both uses SPI, but what changes should I make in the code. Will it automatically set slave select for the LCD and shield and do a good job?

    Thanks

    ReplyDelete
    Replies
    1. You can connect multiple devices to the SPI bus but each one needs a separate SS pin. Your code will need select which device you are talking to and you will only be able to talk to one device at a time. Probably something like:
      1. enable SS for CAN shield
      2. read can data
      3. disable SS for CAN shield
      4. enable SS for LCD
      5. update LCD with new speed
      6. disable SS for LCD

      Delete
    2. damn i wish i could upvote the comments/replies here :)
      i, being a noob, find these super-simple snippets of info extremely valuable, even if just to confirm i got it right

      Delete
  22. Hello,
    wondering if you can help me out with my project.

    I'm sending various Messages with different id's and I cant find out how to do some maths for a message with on ID and do another mathematical approach for a second ID; my data i think is getting mixed together. Any pointers?

    ReplyDelete
  23. Hi, i can try that tutorial but, i haven't been succesfull. I can't run. I have two SeedStudio Can bus shield and two arduino uno. I cut trace P1 with knife. I can use SeedStudio Library for can bus. Unfortunately, it can't run. So, The Rx and Tx led disabled on the can-bus shild. I load send and receive program. But the rx and tx led light isn't not. Could you help me? Thanks..

    ReplyDelete
  24. Hello, and congratulations for the guidance , it is really very useful .
    I would saere if you can send multiple messages simultaneously on the line can
    It is whether this is possible , how?

    ReplyDelete
    Replies
    1. Multiple devices can broadcast on the bus at the same time. Just use different CAN id's for each device.

      Delete
    2. Thank you for your reply!
      if I wanted to send this message:

      ID -DLC - DATA
      215 -4 -FF FF FF F0
      35D -8 -00 03 20 00 FF 00 50 00



      I should write more often this into void loop? for example:

      void loop()
      {
      tCAN message;

      message.id = 0x215;
      message.header.rtr = 0;
      message.header.length = 4;
      message.data[0] = 0xFF;
      message.data[1] = 0xFF;
      message.data[2] = 0xFF;
      message.data[3] = 0xF0;


      mcp2515_bit_modify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0), 0);
      mcp2515_send_message(&message);

      delay(1000);

      tCAN message;

      message.id = 0x35D;
      message.header.rtr = 0;
      message.header.length = 8;
      message.data[0] = 0x00;
      message.data[1] = 0x03;
      message.data[2] = 0x20;
      message.data[3] = 0x00;
      message.data[4] = 0xFF;
      message.data[5] = 0x00;
      message.data[6] = 0x50;
      message.data[7] = 0x00;

      mcp2515_bit_modify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0), 0);
      mcp2515_send_message(&message);

      delay(1000);

      thank you so much.

      Carmine


      Delete
    3. Not exactly sure what you are trying to do but you can reduce those delays way down to like 10 ms if you want to blast the bus with tons of those messages.

      Delete
  25. hello, I have a question:
    if you wanted to convey this:
    ID = 0618A001 (hex)
    DLC = 8
    Message = 00 16 03 68 16 0F 52 00
    how could I do?
    if I run the program made available to you, it reads only the last three digits (in this case 001).
    Thanks for the attention

    ReplyDelete
    Replies
    1. You are using an extended (29 bit) CAN id. You need to set the extended ID flag. I have a different blog post that talks about how to use them: http://matthewcmcmillan.blogspot.com/2015/02/arduino-can-bus-and-29-bit-extended-ids.html

      Delete
  26. Hey Matt, really thanks for your effort and tutorial, it's been really helpful! May I ask you something? Can you provide a simple code for RTR message events? For example the sender sends an RTR request, the receiver reads that, sends the response back to sender and the sender reads the response.

    Thanks!!!!

    ReplyDelete
    Replies
    1. Sorry I haven't worked with RTR messages so I don't know much about them.

      Delete
  27. Hi, I'm using the Seeed CAN Bus shield with Arduino UNO and the https://github.com/Seeed-Studio/CAN_BUS_Shield library.

    The programs for send and receive from the CAN data bus work well, however I can't do a request for a specific PID value. Is this possible do it? If so, can you advise me on how to do it?

    ReplyDelete
  28. So you just have the two Arduinos connected with an OBD-II to OBD-II cable? It's not clear in the pictures, and looks more like USB cables...

    ReplyDelete
    Replies
    1. No, they are connected together with a CAN bus which is a pair of twisted wires with 120 ohm resistors at each end. OBD-II is not the same thing as CAN. OBD-II is a diagnostic port used in cars.

      https://en.wikipedia.org/wiki/CAN_bus

      https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/CAN-Bus_Elektrische_Zweidrahtleitung.svg/1000px-CAN-Bus_Elektrische_Zweidrahtleitung.svg.png

      Delete
  29. I am using can bus controller which is not a stand alone.Apart form spi connections is there any connection for the interrupt pin in the can bus controller

    ReplyDelete
  30. Hi Matt, I know this post is from a few years ago but I was hoping you would be able to answer some questions and help me out.
    I am interested in this post because I work for a vehicle manufacturer and we are looking into arduino boards to simulate a CAN much as you have done here, the reason we would like to do this is to create an inexpensive CAN test rig to show our mechanic's how CAN work's. Is it possible to know:
    Does the CAN network have the normal 2.5V on both the CAN High & Can Low wires?
    Does the CAN network have 120Ohm terminating resistors (Do a resistance check between CAN Hi & CAN Low, should be 60 Ohm if it has 2 120Ohm.
    If so, are they removable?
    Also if the resistor's are not in place, have you noticed any ghosting where a signal would be sent over and over as it goes back around the CAN Lines (this is what the resistors are for)

    What we want to do is have a CAN circuit where we can show the mechanic's the resistance and also show them the Voltage, we also would love to be able to remove the resistor's and press a button once on one of the nodes and see it ghost on the other node.

    Thank you if you can answer any of the above.

    ReplyDelete
    Replies
    1. That sounds like a fun project. I actually built something similar to what you are describing for the company I work for. I wrote a couple blog posts about it on Medium if you want to check those out:

      https://medium.com/silvercar-technology/how-do-you-fit-an-audi-a4-on-a-developer-s-desk-part-1-6788369a048b#.hfx5nu8b9

      https://medium.com/silvercar-technology/how-do-you-fit-an-audi-a4-on-a-developer-s-desk-part-2-4af854aa3ec8#.ti691ykhs

      To answer your specific questions:

      Q: Does the CAN network have the normal 2.5V on both the CAN High & Can Low wires?
      A: Yes, this circuit uses a 5v differential between CAN High and CAN Low.

      Q: Does the CAN network have 120Ohm terminating resistors (Do a resistance check between CAN Hi & CAN Low, should be 60 Ohm if it has 2 120Ohm.
      A: Yes it does have 120 ohm termination resistors on the ends of the bus with 60 ohm resistance when measured across high and low.

      Q: If so, are they removable?
      A: Depends how you build the device. If were to design something like that I would put a switch on it that could disable the termination resistor.

      Q: Also if the resistor's are not in place, have you noticed any ghosting where a signal would be sent over and over.
      A: At a bus speed of 100k I didn't see a lot of ghosting. At 500k it was pretty noticeable.

      Let me know if you have anymore questions.

      Delete
    2. Thank you very much for the answer, I will look into getting the arduino set up and may be back with a question or two in the future, thanks again!

      Delete
    3. simonkeeligan@tiscali.co.ukOctober 29, 2016 at 11:52 AM

      hi i have tried using the code you wrote to get my project working but when i try to verify its says CAN was not declared but i have copied the mcp_can.h into the library can you help ?
      cheers
      simonkeeligan@tiscali.co.uk

      Delete
    4. Simon,

      What version of the Arduino IDE are you using?

      Delete
  31. Hi I am having a trouble ... as am using my CAN shield in Loopback mode then I am receiving the msgs transmitted but am getting 'error sending message' in Normal mode when i tried to send data.... i am using CoryJFowler's librar of can shield..... can anyone please help what wrong with it????????

    ReplyDelete
    Replies
    1. Same here with the same library. The messages however gets through as I can see it on oscilloscope.

      Delete
    2. I figured it out. Just connect the receiver and you'll get the "Message sent successfully".

      Delete
  32. Hello
    very good a prototype for CAN communication

    How can we connect 3 nodes on CAN bus, question about cables ?
    Do the node in the center have 2 CAN shields, one for communication with node1 and 1 for communication with node3 ?
    Or something like a hub is necessary ?

    best regards
    Joel
    jmelan@free.fr

    ReplyDelete
    Replies
    1. No hub is needed. Each device can just tap into the bus. Take a look at this diagram: https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/CAN-Bus_Elektrische_Zweidrahtleitung.svg/2000px-CAN-Bus_Elektrische_Zweidrahtleitung.svg.png

      Delete
  33. can i send and receive using a single arduino at a time?, and can you provide me with the code

    ReplyDelete
  34. Hello
    (Noob question incoming, excuse me, I have started few days ago... :)
    Given the CAN-Bus shield utilizes D2,D10,D11,D12,D13, I assume I can't use it together with SD-card which connects to some of the same pins...? (This is how I connected the card: https://youtu.be/sS_oW81NweI?t=2m2s Works fine when tested without the shield wired to the ODB2-port.)
    I find it hard to believe one couldn't use both at the same time. I intended to log the CAN-Bus data onto the card.

    ReplyDelete
  35. I think I might have found the answer to my previous (not approved yet) question about possible collisions between multiple devices using the same pin.
    http://bit.ly/2lq7rjq

    ReplyDelete
    Replies
    1. Yes you need to use the SS pin to only talk to one SPI device at a time. The CAN controller has a bit of a buffer so you should be able to switch back and forth between writing to the SD card and reading from the CAN controller.

      Delete
  36. Hello
    Regarding your note about disabling the R3 resistor, does it mean one *has to* do this when connecting to a car? Or does it rather mean "I feel it would be better to do it?"
    I am unable to read any messages whatsoever, becoming rather desperate at this point. :) Do you think this could be related?

    I see RX LED blinking like crazy, the shield is initialized, yet I am getting no messages whatsoever... Sometimes the car behaves funny, despite my code including no sending of messages, merely listening. I tried several speeds, sticking to 500kbps lately just because all info I could find points to 500 being the correct one.

    Cheers

    ReplyDelete
    Replies
    1. If you are connecting to a vehicle you must disable the termination resistor R3. The vehicle already has the proper termination resistors on its bus. By adding your device with an additional termination resistor you are disrupting bus communication even without transmitting data.

      Delete
    2. !!! That was indaed one half of my issues! That, and also I had to connect GND (signal GND, i.e. pin 4 on the OBD-II access port)... Please consider adding that to your note about connecting to an existing in-car bus. And thanks a lot sir!

      Delete
    3. Glad you figured it out. In the section above labeled 'CAN bus termination' there is already text that says "If you plan on connecting into an existing CAN bus that already has termination you can disable the built in termination resistors."

      Delete
    4. I meant the GND part, which was the last obstacle for me.
      cheers :)

      Delete
    5. Ah, gotcha. Yep I'll add a note about having a common ground.

      Delete
  37. Hello!

    Great manual you've made here :)

    I have a question regarding "the resistor" (sounds kinda dark, isn't it? ;) ). So, I have a canbus shield by elecfreaks. It has 62Ohm resistor onboard.

    I'm able to read the data from Fiat & VW canbus net using it.

    Now, I've pulled the instrument cluster out from my Panda, gave it 12V, CAN from can shield, wrote some messages and... nothing happend. Either the cluster is not reactin (eg. for fuel level or speed), nor the shield isn't receiving anything from the instrument (I think it's supposed to, as the cluster need to verify car status).

    So, I've cut the jumper metioned by you. Still no luck. The bus' speed is set correctly (50kbps).

    Can you please help figure this out?

    Thank you in advance and best regards.
    Tom

    ReplyDelete
    Replies
    1. Since the instrument cluster is removed from the car you do not have a complete CAN bus with proper termination. You will need to add termination. You might be able to get away with just putting a 120 ohm resistor across the screw terminals on the CAN bus shield. If that doesn't work you will need to have 120 ohm resistors at the both ends of the CAN wires.

      Oh! one other thing that might be an issue... you need to have a common ground connection between the Arduino and the instrument cluster.

      Hope this helps.

      Delete
  38. Hi man really great work.

    My question is, do u think the library or your Code works for two Arduino Micros with the "Niren MCP2515 CAN interface" shown here: (http://shelvin.de/wp-content/uploads/2016/11/MCP2415-1000.jpg). It works with the MCP2515 however the CAN transceiver is a TJA1050.

    So there are two differences to your project: 1. The Arduino Micro 2. The CAN transceiver

    Thx for your work m8!

    ReplyDelete
    Replies
    1. The library only interacts with the MCP2515 CAN controller and it shouldn't notice a different transceiver. I haven't used any of the ATmega32u4 type boards (like the Micro). The library talks to the MCP2515 over SPI which the Micro does have. I guess in summary I would say I don't know for sure if the library will work as-is but I would say you have a good chance. If it doesn't work as-is it probably would just require a bit tweaking to get it to work on the Micro.

      Delete
    2. Thanks for your answer but unfortunately it doesn't want to work..
      I used the examples (Send and receive_check) brought with the GIT ZIP-file from Seedstudio.
      Do you maybe have any idea what changes i may have to make? I tried to look for some PIN configuration for SPI (maybe they defined some PINS fitting for the UNO but not my micro) but I didn't find such. Also I am sure that my termination is right.

      Delete
  39. Great work,

    Do you know how to communicate with two master and one slave. Can I just make in the slave program something like ...if(id=master1){do something}..else if(id=master2){do something}
    Should I set up some other parameters?
    Thanks

    ReplyDelete
    Replies
    1. There isn't really a concept of masters and slaves on a CAN bus. Any node can transmit any CAN id and all nodes recieve all CAN messages. You could accomplish what you are describing by deciding on CAN id numbering scheme for each the 'master' nodes.

      Delete
  40. Hi,
    thank you for sharing your work.
    I've a question: where's the right connection for the signal ground (Arduino Shield side)?
    I used the GND pin on the DB9 connector without any issue (see https://raw.githubusercontent.com/SeeedDocument/CAN_BUS_Shield/master/image/OBD.png), but it seems wonky.

    ReplyDelete
  41. Hi, Matt. Thank you for your post. I am trying to communicate to Arduinos UNO with Elecfreaks shields and when trying to download the library from Seeed, I get a message saying that it no longer exists. I downloaded the library from GitHub, that contains two files mcp_can.h and mcp_can_dfs.h and when I compile your Sender program I get an error saying CAN was not declared in this scope. I am using an Arduino IDE version 1.8.2. Please, could you provide some help? Thanks in adavance!

    Fernando.

    ReplyDelete
    Replies
    1. Check out this fork of the Seeed's can bus library: https://github.com/coryjfowler/MCP_CAN_lib
      Start with the examples in examples directory. My code here is based on an older version of the can bus library and may not compile anymore. Also the newer version of the Arduino IDE are much more strict on variable scope. You can try using an older version of the IDE or you will have to fix the code so things are properly scoped.

      Delete
    2. (Sorry for replying while not being Matt :)
      I am assuming we are both using the same library: https://github.com/Seeed-Studio/CAN_BUS_Shield

      If that is the case maybe I could help. This is how I inialize my CAN-Bus shield from Elecfreaks: https://pastebin.com/f51kg1Rr
      connectCanBus() shouuld be of your interest

      There is some extra functionality that you can ommit, I guess you should be able to extract from it what you need. Let me know if you need some assistance.

      Delete
    3. OK, thank you very much for your help.

      Delete

Please note all comments are moderated by me before they appear on the site. It may take a day or so for me to get to them. Thanks for your feedback.