Author Topic: CAN bus - how to not miss packets?  (Read 7560 times)

0 Members and 1 Guest are viewing this topic.

Offline e100Topic starter

  • Frequent Contributor
  • **
  • Posts: 567
CAN bus - how to not miss packets?
« on: February 11, 2017, 08:43:28 am »
I'm using the MCP2515 CAN bus controller that has a 2 message receive buffer. I'm running it at 10 kbps so my micro cannot be busy doing other things (such as reading a temperature sensor) for more than about 25 ms otherwise packets will be missed.
The MCP2515 talks through SPI, so reading the data via an interrupt isn't an option.

My code is currently sprinkled with polling checks so see if the MCP2515 has data in its Rx buffer. It sort of works but it's not very elegant.

Do systems running at higher baud rates (cars use 500 kbps) use some kind of synchronised time slot protocol whereby there are quiet periods set for when sensors are being read and then talkative periods when the micros are exchanging data?
 

Online hans

  • Super Contributor
  • ***
  • Posts: 1640
  • Country: nl
Re: CAN bus - how to not miss packets?
« Reply #1 on: February 11, 2017, 08:53:47 am »
You really need interrupts. The MCP2515 can generate those, but you need an additional wire to the MCU to signal that. It's true you can't send the interrupt over SPI, but then also it shouldn't.

The MCP2515 has the INT Pin which I suppose is re-programmable, and additional RXxBF/TXxRTS pins.

If you're running SPI at 10kbps that will cause problems  at high bus loads.
If you're running the CAN bus at 10kbps; then that is quite slow.

Large CAN busses do not use synchronization. The beauty of CAN is that any device can put a message on the bus at any time, but due to dominant bits during message ID phase the most important messages will be send first.

But to be honest, you probably want to set up acceptance masks and filters in order to reduce the number of data via SPI.
 

Offline e100Topic starter

  • Frequent Contributor
  • **
  • Posts: 567
Re: CAN bus - how to not miss packets?
« Reply #2 on: February 11, 2017, 09:09:16 am »
You really need interrupts. The MCP2515 can generate those, but you need an additional wire to the MCU to signal that. It's true you can't send the interrupt over SPI, but then also it shouldn't.

But to be honest, you probably want to set up acceptance masks and filters in order to reduce the number of data via SPI.

The MCP2515 has an INT (data available)  hardware line, but if I use that to generate an interrupt then I cannot use SPI within the  interrupt to get the data.
I'm using 3 filters to look for 3 packet IDs but sometimes packets arrive when the micro is busy and with only 2 receive buffers data gets missed.
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: CAN bus - how to not miss packets?
« Reply #3 on: February 11, 2017, 09:17:37 am »
Perhaps cut your other tasks into smaller slices, so the longest wait time on the system is still smaller than the time it takes to overwrite your buffer,

For reading temperature sensors, most micros do the conversion of ADC's in the hardware and write a flag when done, if a digital sensor, most 1 wire or I2C ones have quite a lengthy timeout window, equally some micros I2C interfaces need you to only fill the buffer and tell it to write, and has a buffer for read, allowing you to let the hardware do your heavy lifting.

Same goes for TTL serial out if your sending data that way, use the hardware buffer for your read and write operations.

This way you dont need to use interrupts, just make the first thing you check that status pin of the chip before starting a new task. otherwise plod on through the state machine
 

Online voltsandjolts

  • Supporter
  • ****
  • Posts: 2300
  • Country: gb
Re: CAN bus - how to not miss packets?
« Reply #4 on: February 11, 2017, 09:55:59 am »
... but if I use that to generate an interrupt then I cannot use SPI within the  interrupt to get the data...

Yes you can and thats exactly what you should do but you must implement SPI transfers using interrupts.
The MCP2515 interrupt handler starts the first SPI transfer, sets up the SPI interrupt, disables the MCP2515 interrupt then exits. That takes a few microseconds.
After the first SPI transfer completes you get another interrupt to handle that...and so on until all the SPI transfers are done.
Then (in the last SPI transfer interrupt) enable the MCP interrupt again ready for next message.
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: CAN bus - how to not miss packets?
« Reply #5 on: February 11, 2017, 10:35:28 am »
i don't understand why you can't use the interrupt. yes you can, you absolutely can (and should)
 

Offline Lunasix

  • Regular Contributor
  • *
  • Posts: 142
  • Country: fr
Re: CAN bus - how to not miss packets?
« Reply #6 on: February 11, 2017, 10:45:15 am »
And never use delay loop (except for some us and when it can't be avoided) in software. If a function can not respond and should wait, return and call it later, when result will be available. Use DMA when necessary. 25ms is no more real time for me.
 

Offline SKPang

  • Supporter
  • ****
  • Posts: 89
  • Country: gb
    • SK Pang Electronics Ltd
Re: CAN bus - how to not miss packets?
« Reply #7 on: February 11, 2017, 10:47:18 am »
I would definitely use interrupt.

Increase the clock speed of your SPI so that when an interrupt occurs, inside your ISR it will read the MCP2515 quickly and exit.
skpang.co.uk
 

Offline kaz911

  • Super Contributor
  • ***
  • Posts: 1052
  • Country: gb
Re: CAN bus - how to not miss packets?
« Reply #8 on: February 11, 2017, 11:58:22 am »
you could also change to TI Tiva w/CAN - there you can have filters in "hardware" so an interrupt is only generated on the packets you are interested in. :)
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: CAN bus - how to not miss packets?
« Reply #9 on: February 11, 2017, 12:53:53 pm »
i didn't want to mention it because maybe he doesn't want to change hardware (and this "problem" sounds like it is in software anyway, given the geological eras between events :))
but yes, you could use any MCU with a can controller built in. there are thousands of them, even from simple 8 bitters
 

Offline e100Topic starter

  • Frequent Contributor
  • **
  • Posts: 567
Re: CAN bus - how to not miss packets?
« Reply #10 on: February 11, 2017, 02:59:59 pm »
This is on an Arduino Mega2560. I tried using SPI within the interrupt but the micro would freeze after a few seconds, after processing a dozen or so messages. I kind of assumed that SPI isn't allowed within an interrupt. Looks like I was wrong.

This is the library I'm using https://github.com/coryjfowler/MCP_CAN_lib.

I shall try to create a minimal test case that does nothing except receive messages.
« Last Edit: February 11, 2017, 03:14:34 pm by e100 »
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: CAN bus - how to not miss packets?
« Reply #11 on: February 11, 2017, 03:25:05 pm »
don't assume, check with the debugger. Oh of course, you cant. Ditch the arduino crap altogether and get full control of the chip
 

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: CAN bus - how to not miss packets?
« Reply #12 on: February 11, 2017, 05:25:03 pm »
Definitely interrupts. 10kbps on CAN is WAY slow.

If you are having issues with 10k CAN, you are programming poorly. You should be able to poll SPI to cover that. My guess is you are writing blocking code and have a software technique problem more than a hardware problem.

I don't like that the 2515/25625 have 2 receive buffers, but with a hardware interrupt you should be fine.

Can't run SPI from an ISR, I agree, is reason to dump that chip! That said, my above point stands and if you are smart about it, the ISR should set a flag and it will be handled in your main context.
 

Offline e100Topic starter

  • Frequent Contributor
  • **
  • Posts: 567
Re: CAN bus - how to not miss packets?
« Reply #13 on: February 11, 2017, 06:46:50 pm »
My buggy code. Sometimes the receive message interrupt occurred while another part of the code was already in the process of sending a message out through the same MCP2515.

My current fix is to temporarily disable interrupts before sending a message and re enable them afterwards. I'm not sure this is the correct way to do this, but it's working.
 

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: CAN bus - how to not miss packets?
« Reply #14 on: February 11, 2017, 10:58:39 pm »
My buggy code. Sometimes the receive message interrupt occurred while another part of the code was already in the process of sending a message out through the same MCP2515.

My current fix is to temporarily disable interrupts before sending a message and re enable them afterwards. I'm not sure this is the correct way to do this, but it's working.

I don't know that chip or arduino, but I've had similar issues in PIC where interrupt while in an interrupt wasn't working, the solution in that last case was to enable priority interrupts and specific somethings high and low.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf