Go Down

Topic: CanBus Error detection (Read 2485 times) previous topic - next topic

Reinosoft

Hi,

I've got a question about buffer overloads with canbus using the Sparkfun MCP2515_CAN module, with library https://github.com/Seeed-Studio/CAN_BUS_Shield

I would like to use the CAN protocol, I readed that it's very stable and has a good error handling. But is the buffer overload handled?

For the test, I setted up 2 arduino's, one is sending data to the other.
My question is: How can i be sure if the data is received right?

For the test i'm sending a message with a frequence of 100ms, and read it out at the other side with 300ms. the receiver has a buffer of 2 messages, so i expected a error would occur at the sending site, that the message is'nt delivered well, because the buffer is full. But this doesn't happen.

When the receiver is checked with CAN.checkError(), the error num 5 is received (i expect this is buffer full)

Is the only way to check the receive status, to send a OK signal back to the sender?
this would increase the amount of data sended over the bus.

Can anyone help me with this question?

Thanks!

code of the Receiver
Code: [Select]


#include <SPI.h>
#include "mcp_can.h"


// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 53;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

void setup()
{
    Serial.begin(115200);

    while (CAN_OK != CAN.begin(CAN_500KBPS))              // init can bus : baudrate = 500k
  {
        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(100);
  }
    Serial.println("CAN BUS Shield init ok!");
}


void loop()
{
    unsigned char len = 0;
    unsigned char buf[8];
  delay(300);
   if (CAN.checkError()) {
    Serial.println(CAN.checkError());
   }
    if (CAN_MSGAVAIL == CAN.checkReceive())            // check if data coming
    {
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf

        unsigned int canId = CAN.getCanId();
       
        Serial.println("-----------------------------");
        Serial.print("Get data from ID: ");
        Serial.println(canId, HEX);

        for(int i = 0; i<len; i++)    // print the data
        {
            Serial.print(buf[i], HEX);
            Serial.print("\t");
        }
        Serial.println();
    }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/


code of the master
Code: [Select]
// demo: CAN-BUS Shield, send data
#include <mcp_can.h>
#include <SPI.h>

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 10;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

void setup()
{
    Serial.begin(115200);

    while (CAN_OK != CAN.begin(CAN_500KBPS))              // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(100);
    }
    Serial.println("CAN BUS Shield init ok!");
}

unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
void loop()
{
    // send data:  id = 0x00, standrad frame, data len = 8, stmp: data buf
    Serial.println(CAN.checkError());
    Serial.println( CAN.sendMsgBuf(0x02, 1, 8, stmp));
    delay(100);                       // send data per 100ms
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/



J-M-L

#1
Mar 20, 2017, 05:57 pm Last Edit: Mar 20, 2017, 05:58 pm by J-M-L
You can have a look at what is done in the sendMsg() call. what does your print tell you? (returns either CAN_OK, CAN_GETTXBFTIMEOUT or CAN_SENDMSGTIMEOUT)

Code: [Select]
byte MCP_CAN::sendMsg()
{
    byte res, res1, txbuf_n;
    uint16_t uiTimeOut = 0;

    do {
        res = mcp2515_getNextFreeTXBuf(&txbuf_n);                       // info = addr.
        uiTimeOut++;
    } while (res == MCP_ALLTXBUSY && (uiTimeOut < TIMEOUTVALUE));

    if(uiTimeOut == TIMEOUTVALUE)
    {
        return CAN_GETTXBFTIMEOUT;                                      // get tx buff time out
    }
    uiTimeOut = 0;
    mcp2515_write_canMsg( txbuf_n);
    mcp2515_start_transmit( txbuf_n );
    do
    {
        uiTimeOut++;
        res1= mcp2515_readRegister(txbuf_n-1 /* the ctrl reg is located at txbuf_n-1 */);  // read send buff ctrl reg
        res1 = res1 & 0x08;
    }while(res1 && (uiTimeOut < TIMEOUTVALUE));
    if(uiTimeOut == TIMEOUTVALUE)                                       // send msg timeout
    {
        return CAN_SENDMSGTIMEOUT;
    }
    return CAN_OK;

}
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Reinosoft

Hi,

If i'm reading the piece of library you sended, it looks you're right, but when i was testing it,

it seems the canbus can receive and overwrite existing data with new data in the buffer before the data is readed out from of the buffer, so the data can dissapear without the sender and receiver don't know it.

in some documentation i've readed that the receiver also can send a signal to the sender that it has to slow down.. i thought that signal should be send to the sender, so I receive an error on the sender side, that the buffer is full. but i receive a zero (CAN_OK).

The part that i don't understand is:

Can the data be overwritten in the chip's buffer before it's readed out, or must it first be readed out, before new data can be stored in the receive buffer?


J-M-L

I guess it depends on mcp2515_getNextFreeTXBuf() finding an available emission buffer. I'm not an expert there but buffer I think it depends also on the client to acknowledge or not it's OK to keep sending stuff
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up