CAN FD Arduino Shield Issue

Hello,

I am using the CAN-FD shield with Arduino. I am sending the messages via but I am seeing CAN errors on the bus via Canape. I added the following line of code to the “mcp2518fd_can_dfs.h” header file because my application uses a 1M data rate and 1M arbitration rate. I am sending frames less than 8 bytes. The messages are being transmitted and read fine by my CAN tool but CANape is reporting message errors.

static const uint32_t CAN_1000K_1M = ( 1UL << 24) |(1000000UL);

Is there some issue with adding the line above?

Not sure where I could be going wrong. Any assistance would be appreciated.

Thanks,
Matt

Also, it appears CAN-FD frames are not being sent (only CAN 2.0) despite presumably configuring for CAN-FD. Below is a snip of my code.

#include <mcp2518fd_can.h>
#include <mcp2518fd_can_dfs.h>
#include <mcp_can_fd.h>

#include <TimerInterrupt.h>
#include <TimerInterrupt.hpp>
#include <ISR_Timer.h>
#include <ISR_Timer.hpp>

#include <SPI.h>

#define MAX_DATA_SIZE 64

// Full Scale Pressure Range from Dyno
const float FullScalePressure = 231.46;

// pins for CAN-FD Shield
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;

mcp2518fd CAN(SPI_CS_PIN); // Set CS pin

//Variable Definitions
unsigned int VoltageCounts = 0;
float Voltage = 0;
float Pressure = 0; 
unsigned int Pressure16bitScaled = 0;
unsigned int Pressure16bitScaled2 = 0;
uint8_t PressureLowByte = 0;
uint8_t PressureHighByte = 0;
bool KL15 = 0;
bool IgnStat = 0;
uint8_t IgnStatValue = 1;
bool PushButton = 0;
unsigned int VoltageOffset = 0;
unsigned int VoltageCountsZeroed = 0;
unsigned int PreChargeSwitch = 0;
float PreChargeVoltage = 0;
uint8_t PKBSwitchState = 0;
uint8_t PKBApplyReleaseRequest = 5;
bool ApplyReleaseFlag = 0;
uint32_t TimeStamp = 0;
unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[MAX_DATA_SIZE];

/*
    can-fd baud rate:

    CAN_125K_500K
    CAN_250K_500K
    CAN_250K_750K
    CAN_250K_1M
    CAN_250K_1M5
    CAN_250K_2M
    CAN_250K_3M
    CAN_250K_4M
    CAN_500K_1M
    CAN_500K_2M
    CAN_500K_3M
    CAN_500K_4M
    CAN_1000K_4M
    CAN_1000K_1M
    CAN20_250KBPS
*/


void setup() {
  Serial.begin(115200);
  //while(!Serial){};
  
  //CAN.setMode(CAN_NORMAL_MODE);

  while (CAN_OK != CAN.begin(CAN_1000K_1M)) {             // init can bus : baudrate = 1000K_1M
  Serial.println("CAN init fail, retry...");
  delay(100);
    }
    
Serial.println("CAN init ok!");

//Setup Interrupts
//attachInterrupt(digitalPinToInterrupt(18), ApplyRelease, CHANGE);

pinMode(22, INPUT_PULLUP);
pinMode(23, INPUT_PULLUP);
pinMode(24, INPUT_PULLUP);
}

void loop() {
  
  // Read KL15 input switch, if TRUE then enter while loop below.  
  KL15 = digitalRead(22);

  if (KL15 == 0){
    VoltageOffset = analogRead(A0);
  }

  while(KL15 == 0){

    // Read Pressure Transmitter Voltage and Zero
    VoltageCounts = analogRead(A0);
    VoltageCountsZeroed = VoltageCounts - VoltageOffset;

    // Calculate PreChargeSwitch Voltage
    PreChargeSwitch = analogRead(A1);
    PreChargeVoltage = PreChargeSwitch*5.0/1023;

    //Check if Zeroed Voltage Count is OOR (negative) and set to 0 if negative.  This prevents the voltage counts from wrapping around.
    if (VoltageCountsZeroed > 1024) {
      VoltageCountsZeroed = 0;
    }

    // Calculate Voltage and Pressure from Zeroed Voltage Counts Value
    Voltage = VoltageCountsZeroed*5.0/1023;
    Pressure = (Voltage)*FullScalePressure/5;
  
    //Precharge determination logic, if Pressure >  bar then set 16 bit pressure output to analog pressure input
    if (Pressure > 5){
      Pressure16bitScaled = Pressure*51200/200;
    }
    // If precharge switch is activated then set pressure output to 4 bar
    else if (PreChargeVoltage > 4.5){
      Pressure16bitScaled = 1024; //Corresponds to 4 bar pressure
    }
    // Otherwise set pressure output to 0
    else {
      Pressure16bitScaled = 0;
    }

    /* This causes PKBApplyReleaseRequest to set to 27.  
    if ((ApplyReleaseFlag == 1) && ((millis() - TimeStamp) < 200)){
      PKBApplyReleaseRequest = 27;
  }
    else{
      PKBApplyReleaseRequest = 5;
    }

    // This causes PKBApplyReleaseRequest to set to 40.  Once 200 ms elapses the request set to 5.   
    if ((ApplyReleaseFlag == 0) && ((millis() - TimeStamp) < 200)){
      PKBApplyReleaseRequest = 40;
    }
    else{
      PKBApplyReleaseRequest = 5;

    }*/

    //Split 16 bit value into lower and upper bytes to be sent over CAN.  
    PressureLowByte = (byte) (Pressure16bitScaled & 0x00FF);
    PressureHighByte = (byte) ((Pressure16bitScaled & 0xFF00) >> 8);
    
    //Read IGN Status signal
    IgnStat = digitalRead(23);

    //Setting eBooster_CMD
    uint8_t eBooster_CMD[7] = {PressureLowByte, PressureHighByte,5,5,5,5,5};

    //Setting eBooster_Veh_Pwr
    if(IgnStat == 0){
    IgnStatValue = 4; //sets IgnCmdStat to RUN
    }
    else{
    IgnStatValue = 1; //sets IgnCmdStat to OFF
    }
    uint8_t eBooster_Veh_Pwr[2] = {IgnStatValue, 120};

    uint8_t eBooster_Veh_Data[2] = {0, 0};

    uint8_t eBooster_1[2] = {0, 0};

    uint8_t eBooster_2[1] = {0};

    uint8_t eBooster_3[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    uint8_t eBooster_4[2] = {0, 0};

  
  //Sending eBooster_CMD
  CAN.sendMsgBuf(0x07, 0, 7, eBooster_CMD); // send a standard frame to id 0x07
    
  //Sending eBooster_Veh_Pwr
  CAN.sendMsgBuf(0x112, 0, 2, eBooster_Veh_Pwr); // send a standard frame to id 0x112

  //Sending eBooster_Veh_Data
  CAN.sendMsgBuf(0x113, 0, 2, eBooster_Veh_Data);

  //Sending eBooster_1
  CAN.sendMsgBuf(0x14B, 0, 2, eBooster_1);

  //Sending eBooster_2
  CAN.sendMsgBuf(0x14C, 0, 2, eBooster_2);

  //Sending eBooster_3
  CAN.sendMsgBuf(0x158, 0, 2, eBooster_3);

  //Sending eBooster_4
  CAN.sendMsgBuf(0x11C, 0, 2, eBooster_4);

if (CAN_MSGAVAIL == CAN.checkReceive()) {
        CAN.readMsgBuf(&len, buf);            // You should call readMsgBuff before getCanId
        unsigned long id = CAN.getCanId();
        
        Serial.print("Get Data From id: ");
        Serial.println(id);
        Serial.print("Len = ");
        Serial.println(len);
            // print the data
        for (int i = 0; i < len; i++) {
            Serial.print(buf[i]); 
            Serial.print("\t");
        }
        Serial.println();
    }

  delay(1); // send data once every 1 ms

  //Read KL15 at end of while loop
  KL15 = digitalRead(22);

  Serial.println("IgnStat");
  Serial.println(IgnStat);
  Serial.println("IgnStatValue");
  Serial.println(IgnStatValue);

  }
 }

/*
//ApplyRelease request ISR
void ApplyRelease ()
{
  ApplyReleaseFlag = !ApplyReleaseFlag;
  TimeStamp = millis();
}
*/


// END FILE

Hi there, Is this a seed shield? Which Arduino?

can you show a picture of this setup?
Have you tried adding a longer Delay

to longer and see if it’s data or settling time on the buss.
slow it down and try that. at 1 meg for both the arduino may be sketchy.
HTH
GL :slight_smile: PJ
:v:

#define CAN_1000KBPS 18
fyi,  Implements CAN V2.0B at up to 1 Mb/s
CAN BUS Shield Work well with Arduino UNO (ATmega328), Arduino Mega (ATmega1280/2560)
as well as Arduino Leonardo (ATmega32U4).

Hi PJ! Thank you for your reply. It is indeed the Seeed shield purchased from the Seeed website.

I have tried adding a drastically longer delay (10, 100, and 1000 ms) an had no luck. The errors still appear on the bus.

I am using the mega 2560 Arduino.

I do see the CAN frames being transmitted but I don’t think they are CAN-FD frames. My debugger shows only regular CAN frames.

Also, I cannot receive any CAN-FD frames either. only regular CAN frames are received.

This indicates to me the controller is not configured correctly for CAN-FD.

Hi there,
I would concur, Try a different LIB.
Your mega Should be plenty.what are the buss resistors and any diagram how you have it connected.
GL :slight_smile: PJ
:v:

You’ll get it, keep looking. I’ll look at alternative LIB’s :+1:

Thanks PJ. I have two 120 ohm resistors, one at the ECU and one at the Arduino. I don’t suspect it is a hardware configuration issue.

I don’t have a diagram handy but I think hardware wise it is ok. Can you recommend another library for the arduino can fd shield?

Hi there,
Ok I would tend to agree if your getting the Standard Can messages Hardware is OK, try the older LIB, I see it is compatible.
Should be a doable task, not like your doing left field stuff. Hmm.
HTH
GL :slight_smile: PJ
:v:

Can you send a link to the library you are referring to? The one on github?

this is the library I am using.

Look over here, more are mentioned.
HTH
GL :slight_smile: PJ
:v:

ok, I will give it a try. thanks!

1 Like