Hi, all: I'm trying to build a network of three nodes using CAN bus. Two nodes are built using Arduino Uno with can-bus shields from sparkfun and the third node is an embedded system running linux system. The can-bus shield uses MCP2551 with MCP2515 and the embedded system uses SN65HVD230 instead. Right now, the two Arduino boards can communicate well via CAN bus but I can't make them talk with the embedded system. The oscilloscope showed that the dominate state of the differential output of SN65HVD230 was 1.62V while the recessive state was 80mV while the outputs of MCP2551 were 4.16V and 80mV respectively. The two terminal resistors have been applied and the bit rate was set to be 125k. According to the user manual of SN65HVD230, it's possible for the communication between the 3.3V and 5V transceivers. But can SN65HVD230 communicate with MCP2551 via CAN bus? Or should I get some can-bus shield built with SN65HVD230?
I’ve never used TI’s 3.3V transceiver, but if the rest of the design conforms to CAN bus specifications there is no reason that nodes with 5V and 3.3V transceivers can’t communicate with each other. I’ve attached two pdf files from Microchip that you may find helpful. From Table 1 of the physical layer pdf it seems that dominant differential on the SN65HVD230 is within spec, but that your MCP2551 output is not (differential dominant should be between +1.5 and +3.0 volts). A couple questions: (1) what is the recessive differential on the 2551?, (2) do the two nodes share a common ground?, (3) if not, does connecting a common ground wire between them (if possible) help the situation? (4) can you look at the signal waveforms of each node with an oscilloscope?
On the other hand, the most common problem in getting CAN communications to work is bit timing, and the fact that you get reliable messaging between the Arduino+CAN shield nodes, but not with the other one, makes me suspicious of this (or of a common mode bias because of offset ground voltages). You may have set all nodes to the same bps, but if they don’t all have accurate crystals (and not ceramic resonators), or if the various within-frame bit timing parameters don’t match, timing may be just enough out of phase that communications fail. I’ve even seen a case where this happened to some real pro engineers when filtering added to the CANH and CANL lines made communications intermittent even at 100Kbps.
The CAN forum at the Microchip web site is sometimes not as friendly a place as these Arduino forums, but there are some long-time CAN implementers there who might be able to help you. (I’m just an amateur who, so far, has had good luck.) CAN is a remarkably robust protocol, but it is rather specialized and not always easy to pull off.
CAN basics.pdf (142 KB)
CAN Physical Layer.pdf (259 KB)
I'm really sorry for the late response. Thank you for your reply.
For your questions:
(1) what is the recessive differential on the 2551? It's 80mv.
(2) do the two nodes share a common ground? No.
(3) if not, does connecting a common ground wire between them (if possible) help the situation? I connected their ground together. The output signals didn't change much. I still couldn't my arduino to read data from the embedded system.
(4) can you look at the signal waveforms of each node with an oscilloscope? Sure. I had a arduino sending '1' with id 0x123 and the the embedded system sending 0x12 with id 0x123. The probes were attached to the CANH (postive) and CANL (negtive). As I said, the bitrates of all the nodes were set to be 125000. I referred to the canduino project for the codes on arduinos and used socketcan to generate CAN message on embedded system. From the waveforms in the image, it's not too hard to understand why the arduino boards can't receive the message form the embedded system. But I don't know why the bitrate of message from the embedded system looks much higher than the message from the arduino. Maybe I should reduce the bitrate of CAN on embedded system. By the way, the crystal on the can shield is 12 MHz while the one on the embedded system is 20 MHz.
i'm trying to do a code for communication in CANbus J1939 protocoles with arduino uno,but i don't know how to begin,please advise me
Can you describe what your J1939 project goal is?
First you should buy a Sparkfun CAN-bus shield in order to get your CAN-bus network up and running. https://www.sparkfun.com/products/10039
Yes, the scope image reveals at least one basic problem: bit rates must match within about 1% and you will have to adjust the timing parameters with care to get your nodes to communicate. Your scope image shows the faster node as several times faster than the slower one! Indeed, there’s a lot to adjust with some tradeoff within the in-frame and between-frame timing parameters possible between bit rate, bus length and timer accuracy, but nothing is going to cope with this kind of difference. If you look at your full size scope picture, can you tell which one is close to 125k and which one is way, way off? Starting with different crystal frequencies probably doesn’t help as you then have to contend with how accurately that gets divided to establish the transmission rate. Microchip has a CAN forum and a search there may lead you to some posts (and data sheets/application notes) that you might find useful.
Another poster’s suggestion is a place to start, but you’ve already done this: set up a net (of at least two nodes) with just Arduino boards and get that working reliably, then add your “foreign” node. The CANbus shield is OK, but a 2515/2555 circuit is actually simple enough that roll-your-own isn’t very hard either, and you report reliable communication between your two Arduino nodes. I do find the low CANH-CANL differential troubling, however, so you’d best do a pin-by-pin, wire-by-wire, solder joint-by-solder joint check of your circuit. Also, check the resistance CANH-CANL with power off to make sure that the 120 ohm termination on the two end nodes is correct - you should get close to 120 ohms for each of those with the nodes disconnected from each other, and 60 ohm when the net is wired up. Another physical check would be two connect two 1K (or even 10k) resistors in series acrosss CANH and CANL so that the center tap of this voltage divider will give you (CANH+CANL)/2 measured against ground. When the 2551 is running, this should be very close to (just slightly below) 1/2 Vcc of your Arduino. If it’s lower than that, you definitely have a wiring or power source problem. My recollection is that the 2151/2551 are fussier about low voltage than is the Atmel on the Arduino (but my biological RAM is very leaky).
To get your third node communicating, however, you really do have to solve the timing problem.