Reading peripheral can data without flight controller

Hello!

I’m trying to use an arduino with the “CAN-BUS Shield V2” from seeeduino to read the output of a Mateksys “CAN-L4-BM” sensor. I am able to read the frames coming from the battery monitor. And while the transfer ID is incrementing, the data does not seem to change.

I am using the Seeed_Arduino_CAN library made for the shield, so I can’t take credit for most of the code, but the program I have been using looks like this:

// demo: CAN-BUS Shield, receive data with check mode
// send data coming to fast, such as less than 10ms, you can use this way
// loovee, 2014-6-13

#include <SPI.h>

#define CAN_2515
// #define CAN_2518FD

// Set SPI CS Pin according to your hardware

#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat:
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
const int SPI_CS_PIN  = BCM8;
const int CAN_INT_PIN = BCM25;
#else

// For Arduino MCP2515 Hat:
// 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 = 9;
const int CAN_INT_PIN = 2;
#endif


#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif

#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif

const int LED        = 8;
boolean ledON        = 1;

void setup() {
  SERIAL_PORT_MONITOR.begin(115200);
  pinMode(LED, OUTPUT);

  while (CAN_OK != CAN.begin(CAN_1000KBPS)) {             // init can bus : baudrate = 500k
    SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
    delay(100);
  }
  SERIAL_PORT_MONITOR.println("CAN init ok!");
}


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

  if (CAN_MSGAVAIL == CAN.checkReceive()) {         // check if data coming
    CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf

    unsigned long canId = CAN.getCanId();

    SERIAL_PORT_MONITOR.println("-----------------------------");
    SERIAL_PORT_MONITOR.print("get data from ID: 0x");
    SERIAL_PORT_MONITOR.println(canId, HEX);



    //------------------------------Start of the part I have modified------------------------------------------
    //print data bytes 0 to 6
    for (int i = 0; i < 7; i++) {
      SERIAL_PORT_MONITOR.print("Byte ");
      SERIAL_PORT_MONITOR.print(i);
      SERIAL_PORT_MONITOR.print(": ");
      SERIAL_PORT_MONITOR.print(buf[i]);
      SERIAL_PORT_MONITOR.print("\t");
    }
    //print the tail byte info
    SERIAL_PORT_MONITOR.print("Start of transfer bit: ");
    SERIAL_PORT_MONITOR.print((buf[7] & 0x80) >> 7);
    SERIAL_PORT_MONITOR.print("\t");

    SERIAL_PORT_MONITOR.print("End of transfer bit: ");
    SERIAL_PORT_MONITOR.print((buf[7] & 0x40) >> 6);
    SERIAL_PORT_MONITOR.print("\t");

    SERIAL_PORT_MONITOR.print("Toggle bit: ");
    SERIAL_PORT_MONITOR.print((buf[7] & 0x20) >> 5);
    SERIAL_PORT_MONITOR.print("\t");

    SERIAL_PORT_MONITOR.print("Transfer ID bits: ");
    SERIAL_PORT_MONITOR.print(buf[7] & 0x1F);
    SERIAL_PORT_MONITOR.print("\t");

    //--------------------------------End of the part I have modified------------------------------------------

    SERIAL_PORT_MONITOR.println();
  }
}

//END FILE

And I am able to get the frame but the data stays the same, as shown below:

I looked in the ArduPilot source code, and from what I was able to tell, the data to be received covers more than 7 bytes (maybe I’m looking at something unrelated), which tells me that I might need a multi frame transfer, yet both the start- and end of transfer bits are 1.

I’m hoping someone can help by telling me if that is the problem, if I need to request the data somehow, or if its its something completely different.

Thank you!

The DroneCAN protocol is fairly well documented, and I’d wager there’s probably even an Arduino compatible library out there already.

1 Like

Thanks for the reply!

What I’m understanding from you, and the documentation is that the DroneCAN protocol handles the data requesting and decoding of the frames into the correct data structure. And the message I’m seeing right now is the required periodic status message.

Currently I’m using a BMS with analog outputs, and that works fine in my case. I will return with my findings of using a specific DroneCAN library instead of a normal CAN library once I have tried it out!

You are receiving a dynamic node ID allocation message.

See 6. Application level functions - DroneCAN and 7. List of standard data types - DroneCAN.

The packet is an anonymous message frame with id 01.

I also have the CAN-L4-BM and was able to implement DNA but now I’m having issues parsing the BatteryInfo message as libcanard rejects some of the frames due to an incorrect toggle bit. If anyone has suggestions it’d be appreciated.

This is what I’m observing:
CAN frames 1 to 11 are for dynamic node allocation.
CAN frames 12 to 15 are the first BatteryInfo message.

-----+-----------+------------+--------+-------------------------------------------------------+
| NO | DIRECTION | ID         | LENGTH |  B0  |  B1  |  B2  |  B3  |  B4  |  B5  |  B6  |  B7  |
| 01 | incoming  | 0x18F47500 | 8      | 0x01 | 0x43 | 0x00 | 0x29 | 0x00 | 0x08 | 0x50 | 0xC4 |
| 02 | outgoing  | 0x18000161 | 8      | 0xF1 | 0x43 | 0x00 | 0x29 | 0x00 | 0x08 | 0x50 | 0xC0 |
| 03 | incoming  | 0x18DBF500 | 8      | 0x00 | 0x48 | 0x39 | 0x48 | 0x33 | 0x38 | 0x20 | 0xC5 |
| 04 | outgoing  | 0x18000161 | 8      | 0xDB | 0x57 | 0xF0 | 0x43 | 0x00 | 0x29 | 0x00 | 0x81 |
| 05 | outgoing  | 0x18000161 | 8      | 0x08 | 0x50 | 0x48 | 0x39 | 0x48 | 0x33 | 0x38 | 0x21 |
| 06 | outgoing  | 0x18000161 | 2      | 0x20 | 0x41 |      |      |      |      |      |      |
| 07 | incoming  | 0x18221900 | 6      | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0xC6 |      |      |
| 09 | outgoing  | 0x18000161 | 8      | 0x73 | 0xB1 | 0xF0 | 0x43 | 0x00 | 0x29 | 0x00 | 0x82 |
| 10 | outgoing  | 0x18000161 | 8      | 0x08 | 0x50 | 0x48 | 0x39 | 0x48 | 0x33 | 0x38 | 0x22 |
| 11 | outgoing  | 0x18000161 | 6      | 0x20 | 0x00 | 0x00 | 0x00 | 0x00 | 0x42 |      |      |
| 12 | incoming  | 0x18044478 | 8      | 0xC3 | 0x27 | 0x00 | 0x00 | 0x00 | 0x00 | 0xEC | 0x80 |
| 13 | incoming  | 0x18044478 | 8      | 0x00 | 0x00 | 0x00 | 0x1F | 0xC0 | 0x00 | 0x01 | 0x00 |
| 14 | incoming  | 0x18044478 | 8      | 0x42 | 0x61 | 0x74 | 0x74 | 0x4D | 0x6F | 0x6E | 0x20 |
| 15 | incoming  | 0x18044478 | 4      | 0x20 | 0x2D | 0x31 | 0x40 |      |      |      |      |