CAN two Arduinos communicate (CAN bus Shield)

Excuse the horrible pun. I'm having a terrible Monday.

My project involves controlling a servo motor using an Arduino Mega. Working perfectly, a remote control button would be pressed, which the Arduino would read and then begin turning the motor. Once the motor achieves its final position, the Arduino (Mega) should send out a CAN signal which another Arduino reads. The second Arduino then displays what has happened on the Serial Port.

Currently, I've successfully got the Mega reading the remote signal, moving the motor, and sending out (what I think is) the correct signal. However, the other Arduino seems to read absurd values, and therefore, my "

if(message.data[5] == 17)

" code falls flat on its face.

I'm using the MCP2515 library that some gentleman called David Harding had created, and I saw it modified somewhere random online. The library's CAN signal has a message.ID which is a "long" variable, and a "byte data[8]" array for sending 8 bytes of CAN data. I am comparing "message.data[5]" with no success.

I tried displaying the data at both ends. So, "Serial.println(message.data[5])" at the transmission end shows the correct value, but the same thing at Receiver end doesn't. What is remarkable is that the Receiver always displays the same two values, always alternately, regardless of what CAN message is actually transmitted.

This might be an issue with the MSBFirst thing, although I've had it this way for both sides, or maybe something to do with buffers not getting cleared? It has two RX buffers, but it always receives in the first node, so I don't think that is an issue either.

The code is pretty long, so I have attached both the Transmit and Receive sketches.

Any help will be most appreciated. I'm losing my head!

XUVRemoteandCANTx.ino (14.5 KB)

XUVRemoteandCANRx.ino (4.18 KB)

From XUVRemoteandCANTx.ino...

      MsgTest.dlc = 8;
      MsgTest.data[8] = 0x13;

MsgTest.data[8]? How big is the MsgTest.data array? What is the maximum array index?

      MsgTest.dlc = 7;
			
      MsgTest.data[0] = 1;
			MsgTest.data[1] = 1;
			MsgTest.data[2] = 128;
			MsgTest.data[3] = 65;
			MsgTest.data[4] = 65;
			MsgTest.data[5] = 33;
			MsgTest.data[6] = 75;
			MsgTest.data[7] = 65;

MsgTest.dlc = 7? Looks like you're trying to send eight bytes not seven.

      MsgTest.dlc = 8;
      MsgTest.data[0] = 0x13;

MsgTest.dlc = 8? Looks like you're trying to send one byte not eight.

Hi Coding Badly

Thanks for the reply. Unfortunately, switching back and forth between Arduino's IDE and Notepad++ has jumbled my brain a bit, and so your handle is apt chastening. Hence the errors. Fortunately for my sake, these errors are located in regions of the program that I am currently not using (I will soon delete them, keeping them for reference for now).

The meat of the program is when I send the full CAN matrix, 8 bytes. And in these places, I am still unable to receive a proper CAN message at the Rx end. Any clues why?

For reference, this is the message.data that is displayed on the Serial Port (Rx end):
212 246 134 171 62 159 78 32
124 245 193 154 141 219 54 154
212 246 134 171 62 159 78 15
124 245 193 154 141 219 54 253

pretty much regardless of my input. That last byte being different is the poor coding, but I'm comparing the 6th byte (message.data[5])

I have a stinky suspicion (for once!), that it might not be just my code that is wrong, rather some underlying lack of understanding of the library I'm using.

For reference, here is where I found the library: http://arduino.cc/forum/index.php/topic,8730.0.html

Thanks again.

Hi IzzyStradlin,

IzzyStradlin:
The meat of the program is when I send the full CAN matrix, 8 bytes. And in these places, I am still unable to receive a proper CAN message at the Rx end. Any clues why?

Not without you indicating where the "meat of the program" is.

Damn. Sorry about that. Let me start from the top. The remote has buttons 1 through 5 which I'm using currently. The Left/Right/Up/Down buttons (where I send only 1 byte instead of 8 ) were an earlier iteration. The buttons 1-5 correspond to different modes of the servo (the Face, Face-Leg etc things. The servo is an HVAC controller on an automobile). Now, when I press 1,2,3,4 or 5, it goes to the corresponding zone and transmits a unique message. The message ID is the same for all 5 cases, but message.data[] changes.

This seems to transmit fine, as I said, because I do Serial.println at Tx end, and it shows correct. Its only at the receiving end where the whole thing goes for a toss.

Thanks for the help. I've run out of ideas.

Can you post your FULL code? it doesnt matter how long it is.

IzzyStradlin:
Fortunately for my sake, these errors are located in regions of the program that I am currently not using

That is not correct. Fix all the problems setting MsgTest (Frame) and then report back.

What you see in the transmission serial monitor it is not of much use. In my experience, you have to find a way to "see" what the transmitter CAN port is sending. Try to borrow a scope, otherwise, check it with a meter or a LED, and don't forget to double check the termination resistors (120 ohm) on both ends of the buss.

Hello again,

Unfortunately, a death in the family left me unable to reply sooner. So, don't mind if I bump up this thread.

I followed the advice of both Coding Badly and Palliser and have firstly removed the offensive code, leaving only the relevant parts in it. I also took the code, and checked what was getting transmitted on a CAN software called "Vector CANoe".

It says that I have a bit stuffing error. Straight off, that tells me that the 120ohms are not problematic.

From what I've been able to make of the error through the past few hours of reading is that the error occurs when I have more than five consecutive bits of dominant or recessive type, because it affects the synchronization of NRZ CAN-bus. However, it seems that this bit stuffing should be done by the CAN Controller not the Arduino.

The dilemma is that the sparkfun website says the CAN shield is compatible with CAN v2 2.0B, so in theory it should match my car's CAN protocol.

I've reattached the full code again, this time much cleaner hopefully. Again, any help will be much appreciated.

XUVRemoteandCANRx.ino (4.04 KB)

XUVRemoteandCANTx.ino (10.8 KB)

Hello,

IzzyStradlin:
It says that I have a bit stuffing error. Straight off, that tells me that the 120ohms are not problematic.

Huh?

However, it seems that this bit stuffing should be done by the CAN Controller not the Arduino.

It is. The Arduino is not involved.

The dilemma is that the sparkfun website says the CAN shield is compatible with CAN v2 2.0B, so in theory it should match my car's CAN protocol.

What about the car's bitrate? Have you matched that?

Hi Coding Badly

The 120 ohms thing was that I was worried that the CAN message might not even be getting sent properly because of improper soldering of the terminal resistors. But that is not the case because the software does show a message received, only the message has the bit stuffing error

And if the Arduino has no say in bit stuffing, that sort of puts me in a more difficult position, because it looks like there isn't too much wrong in my code, and not a lot that I can do at this point.

Also, yes the bit-rate matches. My car and the arduino both are using CAN at 1 Mbps. The code I'm using checks for the bit-rate initialization. If the correct bit rate is not obtained, an error is displayed on the Serial Port.

Any suggestions? I should probably also contact Sparkfun and see what their take is on this.