MCP2515 CAN Controller

I’ve successfully set up an Arduino UNO and Microchip MCP2515 CAN Controller and I’m down to one last little issue. I can reliably read messages generated by a Microchip test board, but when I send incremental test messages once a second the test board seems to drop the occasional message. I don’t get any transmission errors from my MCP2515, so I’m wondering if this is just a problem with the receiving board/software from Microchip? I would have though it more likely to be something wrong with what I’ve done, but with no errors being generated I’m at a loss.

Just wondering if anyone else has had similar issues? I’m not going to worry about it too much because my project is hardly mission critical, but it’s always nice to know what’s going on.

As an overview to my setup:

Hardware:

  • UNO, MCP2515/MCP2551, 16MHz ceramic resenator.
  • Resenator limits my set up to 125kHz transfer.
  • MCP2515DM demo board from Microchip set at its minimum rate of 125kHz.
  • Using INT pin on MCP2515 to notify of full RX buffer, empty TX buffer and Errors.

Software:

  • Checks INT and reads from RX buffer if full.
  • Prints outgoing message to Serial on each successful TX interrupt, (buffer goes to empty - supposedly successful transmission), and never misses a beat.
  • Uses millis() not delay() to time TX messages.
  • During this normal operation never get an Error interrupt.
  • Can force errors by trying a non-matching transfer speed, so I know the Interrupt works.

the test board seems to drop the occasional message

If both sides 1 are properly configured there are four possibilities…

  1. The other side received and acknowledged the message but didn’t process it.

  2. Your side did not send anything.

  3. Your side is ignoring some send failures.

  4. Your side does not always handle send failures.

#1 doesn’t seem too likely or other folks would have complained to Microchip.

Does the MCP2515 have a “send counter”? Does it increment with each (successfuly) send?

Have you (accidentally) enabled filtering on the other side?

If you don’t mind my asking, what did you choose for the transceiver?

1 “Your side” is the MCP2515 / Arduino side. “Other side” is the test board. I didn’t what to have to type MCP2515 too many times.

I agree with everything you've said, including writing MCP2515 too many times and the fact that it's unlikely to be a problem with the Microchip board.

As to your four possibilities:

  1. Possible, but this would fall under the problem being with Microchips board/PIC software/PC software, and we both think this is unlikely. This is where I hope other people might have experience they can share. I should also contact Microchip and see what they might have to say, or if they have user forums.

  2. Possible, but I'm not sure why it wouldn't have. It said it did but it could be lying to me. I'll hook up a 'scope tonight and check.

  3. Very possible. I'm not confident in my error handling, and although I am successfully using the interrupt for other things, and I can trigger it for certain errors, I'm not sure if I'm using it correctly for transmission errors. If the other side is rejecting/not acknowledging a message I'm not seeing it on my side for some reason.

  4. How are you differentiaing this from point 3?

The MCP2515 has a transmission error counter, (TEC). When TEC gets to 96 it sets an error warning flag, when it reaches 128 it switches the MCP2515 from error-active to error-passive, at 255 it goes off-bus.

After each message that I send I print the message, (a simple incrementing integer) and also the TEC, which is always 0. However I suppose TEC could be incrementing during attempts to send the message, and being reset when the message is sent, and so I'm not checking it at an appropriate stage in my code.

I don't think I've done anything particular to the other side to filter. The message ID I send is always the same, as are the first two data bytes and I simply increment the third data byte each second.

I'm using the MCP2551 as my transciever. I should also state that this is a bread board setup with just the MCP2515/MCP2551 and a 16MHz resonator, no additional resistors or capacitors. This wouldn't be a production circuit, but it seems to work pretty good, (apart from the occasional dropped message!)

And I have to add that the TX buffer empty flag only triggers the interrupt on succesful sending of the message, according to the flow diagram in the data sheet.

Not to say that success in this case isn't simply getting the message on the bus. I think I need to read the data sheet again. (Believe me I've read and re-read it, but I still might be missing something.)

  1. How are you differentiaing this from point 3?

Some CANBUS controllers have a "send once" mode. A single attempt is made to send the frame and no errors are reported. From your description, this could only be a problem if you've somehow accidently entered this mode. If the MCP2515 even supports such a mode. It's a long shot.

The MCP2515 has a transmission error counter, (TEC). When TEC gets to 96 it sets an error warning flag, when it reaches 128 it switches the MCP2515 from error-active to error-passive, at 255 it goes off-bus.

Standard CANBUS.

However I suppose TEC could be incrementing during attempts to send the message, and being reset when the message is sent

It is very unlikely that the count is reset to zero. The controllers I've worked with decrement the count when something good happens but never clear to zero.

I don't think I've done anything particular to the other side to filter. The message ID I send is always the same, as are the first two data bytes and I simply increment the third data byte each second.

Given that, I don't see how filtering could be the problem.

I'm using the MCP2551 as my transciever.

Thanks.

16MHz resonator

Resonators can be problem. (But would not account for this problem.) If you needed reliability, I would strongly suggest a crystal. For not-perfect communications, a resonator will work well.

no additional resistors

No bus termination resistors? (Again, this wouldn't explain this problem; just a general concern.)

And I have to add that the TX buffer empty flag only triggers the interrupt on succesful sending of the message, according to the flow diagram in the data sheet.

Huh. I'm out of ideas. Maybe something will come to me later.

Not to say that success in this case isn't simply getting the message on the bus. I think I need to read the data sheet again. (Believe me I've read and re-read it, but I still might be missing something.)

Man, I was in your shoes not too long ago! Imagine having to deal with three different controllers / APIs. Each with their own little quirks.

Sorry to bang on about it but have you got supply decoupling on both chips?

This controller does have a one shot mode. I'm not intentionally using it, so I'd better check that I'm not unintentionally using it!

You're right about the decrementing of TEC now that I think about it.

The resonator was just for breadboarding, I have a crystal for when I make the PCB version.

No bus termination resistors for this breadboarding attempt. Will need to figure out the final circuit. (Some inherrent errors due to poor design would actually be a good thing for testing if I could figure them out!) Maybe I've been concentrating too much on the controller and not enough on the transceiver.

Thanks for your help and for bouncing some ideas around. I have to admit that this is my first attempt at this kind of thing beyond copying other people's work.

Sorry to bang on about it but have you got supply decoupling on both chips?

Explain this for a newbie. :D I have CAN H, CAN L and GND connected between my side and the other side. The other side actually consists of two identical boards that send messages back and forth between each other. I would need to check the schematics of those to see what the connections bewteen them are.

On my side I have both controller and transceiver supplied by 5v out from Arduino.

Grumpy_Mike's suggestion applies to the power supply side of your circuit.

If you're using the correct cable, the CANBUS side isn't going to have capacitors. I believe the transceiver you're using provides bus isolation.

Explain this for a newbie.

http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

If they are commercial boards then you probably have.

No bus termination resistors for this breadboarding attempt. Will need to figure out the final circuit. (Some inherrent errors due to poor design would actually be a good thing for testing if I could figure them out!)

One of the "problems" with CANBUS is that it is EXTREMELY resilient. For short distances, low bit rates, low noise environments (like a desktop) I use whatever wire I pull out of a scrap box, no terminating resistors, and CAN_GND unconnected. The only time I get errors is when the cable gets a bit knotted and too close to a transformer.

In other words, trying to create problems for testing can be a right pain in the arse. You pretty much have to have a "fault simulator".

Maybe I've been concentrating too much on the controller and not enough on the transceiver.

Naw. In my experience, wringing-out the bus side is the easy part so long as you're: not trying to cover large distances; not trying to communicate in an especially noisy environment (Variacs are a problem), using reasonably good cable, connecting all three CANBUS wires, using a reasonable bit rate for the distance.

http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

If they are commercial boards then you probably have.

Yup. Checked the schematics and they're decoupled on the other side, but not on mine. Not sure what capacitors I have in my box o' bits but I'll try adding them. I'll also test separately swapping out the resanator for a crystal, (I orderd both at the same time).

One of the "problems" with CANBUS is that it is EXTREMELY resilient. For short distances, low bit rates, low noise environments (like a desktop) I use whatever wire I pull out of a scrap box, no terminating resistors, and CAN_GND unconnected. The only time I get errors is when the cable gets a bit knotted and too close to a transformer.

In other words, trying to create problems for testing can be a right pain in the arse. You pretty much have to have a "fault simulator".

Naw. In my experience, wringing-out the bus side is the easy part so long as you're: not trying to cover large distances; not trying to communicate in an especially noisy environment (Variacs are a problem), using reasonably good cable, connecting all three CANBUS wires, using a reasonable bit rate for the distance.

Well I can't see my test environment being particularly problematic then.

Well, thanks for all the help guys, I appreciate the advice. I tried a couple of things tonight. Decoupling didn’t seem to help, and when I scoped it out it looks like I’m getting a message on the bus every time. Having said that it’s a lot better than last night, (with or without the capacitors), so I’m just going to call it good and make the permanent board. It’s not perfect, but I think it’s more than adequate for my purposes.

So one last question - what’s good for bus termination? One schematic I’ve come across shows 100ohm resistor and 490pF capacitor in series from each of CAN H and CAN L to GND. Does that sound good or do I need to calculate something out? This guy was using a 6ft cable where as I’ll be probably at 2ft.

So one last question - what's good for bus termination?

If you're using the correct cable, 120 ohms at each end across H and L.

One schematic I've come across shows 100ohm resistor and 490pF capacitor in series from each of CAN H and CAN L to GND.

Given the experiences I've had, I would not trust a CANBUS termination that includes a capacitor without knowing why it's included. Essentially, what you're after is ... Each node should see 60 ohms resistence looking East and 60 ohms resistence looking West. In other words, each point on the bus should measure about 60 ohms resistence. This is not a hard-fast rule. The shorter the distance and the lower the bit rate, the lower the quality the bus can be.

Does that sound good or do I need to calculate something out? This guy was using a 6ft cable where as I'll be probably at 2ft.

At two feet you can pull two wires out of the trash, hook them to L and H, and call it good! :D

If you really want the gory details... http://standards.sae.org/j1939/15_200808/ http://standards.sae.org/j1939/11_200609/

But bring your wallet!

I'm just going to call it good and make the permanent board.

Please add decoupling capacitors to it because although you say it did not appear to help you, it does no harm and you can get into deployment situations where it's absence will cause trouble.

Well, great work! You have helped me to improve my knowledge about this field. Thank you so much for sharing.


watch movies online for free

Please add decoupling capacitors to it because although you say it did not appear to help you, it does no harm and you can get into deployment situations where it's absence will cause trouble.

Absolutely going to do this. And also switching the resonator to a crystal. Plus proper termination.

@Coding Badly: I dug around and found the termination info. It seems a popular method is split termination with two 60ohm resistors center tapped with a 10nF capacitor to ground. I'll probably just put a 120ohm resistor between H and L though because of the shortness of my cable.