arduinocan-bus

Use of Arduino with a CAN bus shield


I'm trying to get a VGM CAN message out of a Reachstacker 42-45 tonnes.

Where I am using an Arduino Mega 2560 with a CAN bus shield.

This my current code:

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

// The SPI CS pin of the version after v1.1 defaults to D9.
// v0.9b and v1.0 defaults to D10
const int SPI_CS_PIN = 9;

MCP_CAN CAN(SPI_CS_PIN); // Set the SPI CS pin

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

    START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS)) // Init CAN bus: baud rate = 500 kHz
    {
        Serial.println("CAN bus shield initialisation is OK!");
    }
    else
    {
        Serial.println("CAN bus shield initialisation failed");
        Serial.println("Initialising the CAN bus shield again");
        delay(100);
        goto START_INIT;
    }
}


void loop()
{
    unsigned char len = 0;
    unsigned char buf[8];

    if(CAN_MSGAVAIL == CAN.checkReceive()) // Check if data has arrived
    {
        CAN.readMsgBuf(&len, buf); // Read data. 'len': data length. 'buf': data buffer

        unsigned char canId = CAN.getCanId();

        Serial.println("-----------------------------");
        Serial.println("Get data from ID: ");
        Serial.println(canId);

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

This was the result at the time of doing the test, the problem that I do not understand the result

Enter image description here

According to the documentation, it should have a result like this:

Enter image description here

This is another part of the documentation:

Enter image description here

If someone needs more information or does not understand what I'm looking for, you can request what you need to help me


Send data:

// Demo: CAN bus shield. Send data
#include <mcp_can.h>
#include <SPI.h>

// The SPI CS pin of the version after v1.1 defaults to D9.
// v0.9b and v1.0 defaults to D10
const int SPI_CS_PIN = 9;

MCP_CAN CAN(SPI_CS_PIN); // Set the SPI CS pin

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

    START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS)) // Init CAN bus: baud rate = 500 kHz
    {
        Serial.println("CAN bus shield initialisation is OK!");
    }
    else
    {
        Serial.println("CAN bus shield initialisation failed");
        Serial.println("Initialising the CAN bus shield again");
        delay(100);
        goto START_INIT;
    }
}

unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
void loop()
{
    // Send data:  id = 0x00, standard frame, data len = 8, 'stmp': data buffer
    CAN.sendMsgBuf(0x00, 0, 8, stmp);
    delay(100); // Send data every 100 ms
}

Solution

  • You have two pieces that do not fit between your documentation and the output you are generating:

    1. The data payload
    2. The ID of the CAN frames

    For the data payload, it is simply a matter of formatting. You print each byte as an integer value, whereas in the documentation it is printed as a hexadecimal values. Use

    Serial.print(buf[i], HEX)
    

    to get the payload printed as hexadecimal characters.

    For the ID of the CAN frames, you see from the documentation that they do not fit inside an unsigned char, as already mentioned in the comment by Guille. Actually, those are 29-bit identifiers, which you should ideally store in an appropriately sized variable. Ideally use an unsigned long:

    unsigned long canId = CAN.getCanId();
    

    In the documentation, the CAN ID is also printed in hexadecimal, so also here use:

    Serial.println(canId, HEX);