Help with buffers and CAN bus

Hello,
I am struggling with a CAN Bus project. I am not a programmer so struggling a little.
I am using and Arduino MCP2515 CAN bus module. I was using the the Canbus.h library but to support the MCP2515 with 8Mhz crystal I am now using the mcp_can.h library.
When a CAN message is received it is written into a buffer then printed using a loop, the code is below.

If I want to do within with the buffer data rather than just print it how do I write it to a string so I can use an if statement to trigger something?
This is my starting sketch

// Original author - omarCartera

#include <SPI.h>          //SPI is used to talk to the CAN Controller
#include <mcp_can.h>

MCP_CAN CAN(10);          //set SPI Chip Select to pin 10

unsigned char len = 0;
unsigned char buf[8];
unsigned int canID;

void setup()
{
  Serial.begin(115200);   //to communicate with Serial monitor
  
//tries to initialize, if failed --> it will loop here for ever
START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS))      //setting CAN baud rate to 500Kbps
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(100);
        goto START_INIT;
    }
}



void loop()
{
    if(CAN_MSGAVAIL == CAN.checkReceive())    //check if data is coming
    {
        CAN.readMsgBuf(&len, buf);    //read data,  len: data length, buf: data buffer
        canID = CAN.getCanId();       //getting the ID of the incoming message

        if (canID == 0xF2)            //it will only read messages with ID = 0xF2
        {
          Serial.print("ID is: ");
          Serial.print(canID, HEX);     //printing the ID in its standard form, HEX

          Serial.print("    Length is: ");
          Serial.println(len);
        
          for(int i = 0; i<len; i++)    //looping on the incoming data to print them
          {
              Serial.write(buf[i]);     //Serial.write prints the character itself
          }
          Serial.println("\n\t*****************\n");
        }
    }
}

Any help is appreciated.

I am not familiar with the library that you are using but what do yo see when you print len and when you print the contents of buf ? Is the length always the same and if so, what is it ?

buf is an array of chars so all that is needed to turn it into a C style string (NOT a String) is to terminate it with a zero, which the library may already be doing. If not then it is easy to add the zero to the array yourself as long as there is room in the array.

Once you have a string then there are a host of C functions that will allow you to test and manipulate it.

Please give some examples of messages received and their length

Jasont247:
Hello,
I am struggling with a CAN Bus project. I am not a programmer so struggling a little.
I am using and Arduino MCP2515 CAN bus module. I was using the the Canbus.h library but to support the MCP2515 with 8Mhz crystal I am now using the mcp_can.h library.
When a CAN message is received it is written into a buffer then printed using a loop, the code is below.

If I want to do within with the buffer data rather than just print it how do I write it to a string so I can use an if statement to trigger something?
This is my starting sketch

// Original author - omarCartera

#include <SPI.h>          //SPI is used to talk to the CAN Controller
#include <mcp_can.h>

MCP_CAN CAN(10);          //set SPI Chip Select to pin 10

unsigned char len = 0;
unsigned char buf[8];
unsigned int canID;

void setup()
{
 Serial.begin(115200);   //to communicate with Serial monitor
 
//tries to initialize, if failed → it will loop here for ever
START_INIT:

if(CAN_OK == CAN.begin(CAN_500KBPS))      //setting CAN baud rate to 500Kbps
   {
       Serial.println(“CAN BUS Shield init ok!”);
   }
   else
   {
       Serial.println(“CAN BUS Shield init fail”);
       Serial.println(“Init CAN BUS Shield again”);
       delay(100);
       goto START_INIT;
   }
}

void loop()
{
   if(CAN_MSGAVAIL == CAN.checkReceive())    //check if data is coming
   {
       CAN.readMsgBuf(&len, buf);    //read data,  len: data length, buf: data buffer
       canID = CAN.getCanId();       //getting the ID of the incoming message

if (canID == 0xF2)            //it will only read messages with ID = 0xF2
       {
         Serial.print("ID is: ");
         Serial.print(canID, HEX);     //printing the ID in its standard form, HEX

Serial.print("    Length is: “);
         Serial.println(len);
       
         for(int i = 0; i<len; i++)    //looping on the incoming data to print them
         {
             Serial.write(buf[i]);     //Serial.write prints the character itself
         }
         Serial.println(”\n\t*****************\n");
       }
   }
}





Any help is appreciated.

“buf[8]” contain the data which was read from the bus. So 2 things:

  1. Do you have multiple CAN IDs on the bus? If yes, then your first check (if statement) would be to check that you have the desired CAN ID (I see you have done that already in your code! :slight_smile: )

  2. In the data you received do you know its structure and in which bytes the desired value lie? If you can share that information then we can help you formulate a statement for your trigger