Using signals from BMS using CAN-Bus shield and LED to indicate status of the system

Hi,

The code below appears to be working, but all it displays on the serial monitor is "Can init ok!" When the showColor() function is not used, the same code functions as intended.

The code isn't running because the CAN bus shield indicates that it is being interrupted. I'm not sure why, though. Please demonstrate how I can resolve this issue.

#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_red = 9;
const int led_green = 10;
const int led_blue = 11;
int contactors;
int condition;
int* binNum;
int isoVal;

void setup() {

  pinMode(led_red, OUTPUT);
  pinMode(led_green, OUTPUT);
  pinMode(led_blue, OUTPUT);
  Serial.begin(115200);

  while (CAN_OK != CAN.begin(CAN_1000KBPS)) {  // Initializing CAN-Bus : baudrate = 500k
    Serial.println("CAN init fail, retry...");
    delay(100);
  }
  Serial.println("CAN init ok!");
}


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

  // Receive and store messages and ID's
  if (CAN_MSGAVAIL == CAN.checkReceive()) {  // Check if data is available
    CAN.readMsgBuf(&len, buf);                  // Read data,  len: data length, buf: data buf

    unsigned long canId = CAN.getCanId();

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

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

    //For BMS_PackInfo2 > BMS_IsoVal_kohm
    if (canId == 1820) {
      if (buf[4] != 0) {
        isoVal = (buf[5] * 256) + buf[4];
      }
    }

    //For BMS_Status1 > BMS_HvBus1_Tract_OnFb_bool, BMS_HvBus2_Chrg_OnFb_bool, BMS_HvBus3_Anc_OnFb_bool
    if (canId == 656) {
      binNum = decToBin(buf[0]);
      if (binNum[7] == 0 && binNum[6] == 0 && binNum[5] == 0) {
        contactors = 0;
      } else if (binNum[7] == 1 || binNum[6] == 1 || binNum[5] == 1) {
        contactors = 1;
      }
    }

    //For BMS_Status2
    if (canId == 657) {

      if (buf[2] == 5) {
        Serial.print("Ignition off! ");
        condition = 0;  //Lights off
      }

      else {
        Serial.print("Ignition on! ");
        condition = 1;  //Green

        if (contactors == 1) {
          Serial.print("Contactors closed! HV system active!");
          condition = 2;  //Orange
        } else {
          Serial.print("Contactors open! ");
          condition = 1;  //Green

          if (isoVal < 48) {
            Serial.print(isoVal);
            Serial.print("Isolation value < 48 kohm! System not isolated! Fault detected!");
            condition = 3;  //Red
          } else {
            Serial.print("System isolated!");
            condition = 1;  //Green
          }
        }
      }
    }
    Serial.println();
  }
  updateLEDs(condition);
}

void updateLEDs(int condition) { 
  if (condition == 0) {
    showColor(0, 0, 0);
  } else if (condition == 1) {
    showColor(0, 255, 0);
  } else if (condition == 2) {
    showColor(255, 15, 0);
  } else {
    showColor(255, 0, 0);
  }
}

void showColor(byte r, byte g, byte b) {
  //Byte values for range 0-255
  analogWrite(led_red, r);
  analogWrite(led_green, g);
  analogWrite(led_blue, b);
}

int* decToBin(int decimalNumber) {
  static int binaryNumber[8];

  for (int i = 7; i >= 0; i--) {
    binaryNumber[i] = decimalNumber % 2;
    decimalNumber = decimalNumber / 2;
  }

  return binaryNumber;
}

Describe the indication...

Which manufacturer of the shield? Can you post a datasheet?

Immediately inside setup(), this waits for data... is data being supplied (is the remote end connected and sending)? If this fails, updateLEDs() is called.

Insert a temporary "condition"... that is to say, immediately inside setup() add int condition = random(3) to see a random LED colors.

Interesting result. That message is coming form your code. More details needed. Post an annotated schematic showing how you have wired this and also links to each of the hardware devices. At this point I have no idea of what Arduino or other hardware you are using. Hint: I have several different CAN shields, all require different software.

I see a conflict here.....

assuming you are using a UNO for SPI using pin 11, 12 and 13; so another conflit!
still assuming u are using a UNO, u could possibly swap your LED pins for 3 ,5 and 6 for as those can do 'analogWrite' as well :wink:

hope that helps....

This worked, thank you. Can you please explain in detail why was it getting interrupted (red INT light in CAN bus shield) ?

Red light (it says INT) on CAN bus shield for UNO R4.

I am using Vector CAN/LIN interface (VN1640A) to emulate CAN messages.

that is a bit tricky... from experience it becomes steady ON when there is issue with reading data,

otherwise under normal condition this LED would flicker (this LED is connected to the CAN_INT_PIN)

hope that helps....

Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.