Canbus filtering problem

hi

i have a problem with canbus filtering,

i have been writing a code for a dash display for an EV conversion using a donor car,
i have the canbus ids and what they do, and my code works so far but my next part is giving me some queries:

this is my code so far:

#include <SPI.h>
#include <mcp2515.h>
#include <MCUFRIEND_kbv.h>
struct can_frame canMsg;
MCP2515 mcp2515(10);
MCUFRIEND_kbv tft;

#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>
#include <FreeDefaultFonts.h>

#define BLACK       0x0000      /*   0,   0,   0 */
#define NAVY        0x000F      /*   0,   0, 128 */
#define DARKGREEN   0x03E0      /*   0, 128,   0 */
#define DARKCYAN    0x03EF      /*   0, 128, 128 */
#define MAROON      0x7800      /* 128,   0,   0 */
#define PURPLE      0x780F      /* 128,   0, 128 */
#define OLIVE       0x7BE0      /* 128, 128,   0 */
#define LIGHTGREY   0xC618      /* 192, 192, 192 */
#define DARKGREY    0x7BEF      /* 128, 128, 128 */
#define BLUE        0x001F      /*   0,   0, 255 */
#define GREEN       0x07E0      /*   0, 255,   0 */
#define CYAN        0x07FF      /*   0, 255, 255 */
#define RED         0xF800      /* 255,   0,   0 */
#define MAGENTA     0xF81F      /* 255,   0, 255 */
#define YELLOW      0xFFE0      /* 255, 255,   0 */
#define WHITE       0xFFFF      /* 255, 255, 255 */
#define ORANGE      0xFDA0      /* 255, 180,   0 */
#define GREENYELLOW 0xB7E0      /* 180, 255,   0 */
#define PINK        0xFC9F

void setup() {
  Serial.begin(115200);
  tft.begin(0x9486);
  tft.fillScreen(BLACK);
  tft.setRotation(1);
  tft.setTextColor(WHITE, BLACK);
  tft.setTextColor(WHITE);
  tft.setTextSize(4);
  tft.setCursor(135, 245);
  tft.setTextColor(WHITE, BLACK);
  tft.print("  v      %");
  tft.fillRect(100, 290, 285, 30, BLACK);
  tft.fillRect(100, 290, 10, 30, RED);
  tft.fillRect(375, 290, 10, 30, GREEN);
  tft.fillRect(240, 290, 10, 30, WHITE);
  tft.fillRect(240, 290, 10, 30, ORANGE);
  tft.fillRect(20, 250, 50, 50, WHITE); //LEFT
  tft.fillRect(410, 250, 50, 50, WHITE); //RIGHT
  tft.drawRect(90, 47, 20, 70, WHITE); // tyre car
  tft.drawRect(370, 47, 20, 70, WHITE); // door car
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS);
  mcp2515.setNormalMode();

  Serial.println("------- CAN Read ----------");
  Serial.println("ID  DLC   DATA");

}

void loop() {

  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    if (canMsg.can_id == 0x789 && canMsg.data[canMsg.can_dlc - 3] == 0x41) {                       //start of voltage meter
      int battvolt = canMsg.data[canMsg.can_dlc - 2] * 256 + canMsg.data[canMsg.can_dlc - 1] ; //commands for live car
      tft.setCursor(100, 245);
      tft.setTextColor(ORANGE, BLACK);
      tft.print(battvolt / 4);
      tft.fillRect(100, 290, 285, 30, BLACK);
      tft.fillRect(100, 290, 10, 30, RED);
      tft.fillRect(375, 290, 10, 30, GREEN);
      tft.fillRect(240, 290, 10, 30, ORANGE);
      if (battvolt >= 8 && battvolt < 1676) {
        Serial.println("3/4");
        tft.fillRect(110, 300, battvolt / 8, 10, WHITE);
      } else if (battvolt == 1676)
        tft.fillRect(110, 300, 265, 10, WHITE);            //end of voltage meter
    }
    if (canMsg.can_id == 0x789 && canMsg.data[canMsg.can_dlc - 3] == 0x46) {               //start of SoC
      int Soc = canMsg.data[canMsg.can_dlc - 2] * 256 + canMsg.data[canMsg.can_dlc - 1] ;
      tft.setCursor(270, 245);
      tft.setTextColor(ORANGE, BLACK);
      tft.print(Soc / 10);
    }
  }
  if (canMsg.can_id == 0x72C) {               //start of tyre pressure
    int RL = canMsg.data[canMsg.can_dlc - 2];
    int RR = canMsg.data[canMsg.can_dlc - 2];
    int FR = canMsg.data[canMsg.can_dlc - 2];
    int FL = canMsg.data[canMsg.can_dlc - 2];
    tft.setTextColor(BLUE, BLACK);
    tft.setTextSize(2);
    tft.setCursor(20, 98);
    tft.print(RL / 1.1);
    tft.setCursor(120, 98);
    tft.print(RR / 1.1);
    tft.setCursor(120, 52);
    tft.print(FR / 1.1);
    tft.setCursor(20, 52);
    tft.print(FL / 1.1);
  }
      if (canMsg.can_id == 0x768) {               //start of odometer
      int Odo = canMsg.data[canMsg.can_dlc - 3] + canMsg.data[canMsg.can_dlc - 2] +canMsg.data[canMsg.can_dlc - 1];
      tft.setCursor(30, 200);
      tft.setTextColor(ORANGE, BLACK);
      tft.print(Odo);
    }
    if (canMsg.can_id == 0x748) {
      //problem lies here
} 
}
void diag() {
  tft.fillScreen(BLACK);
  tft.setTextColor(WHITE);
  tft.setCursor(0, 160);
  tft.setTextSize(2);
  delay(500);
  void();
}

i have marked the area i am having trouble with.
the canbus sends the following data:

ID: 0x748 len: 8 data: 07 62 D1 12 80 00 00 00

the last 4 bytes change with which doors are open (to a maximum of 4) adding a new byte for each one.
eg:
80 00 00 00 = all closed.
01 00 00 00 = drivers door .
01 02 00 00 = drivers and passenger door.
01 02 04 00 = drivers , passgenger and LH rear.
01 02 04 05 = drivers , passgenger, LH rear and RH rear.
plus 10 and 20 for bonnet and boot.

i need to filter whats coming in and display something on my tft like the other parts of the code.
i know i can use if statements but im scratching my head on how to run them quickly going down the list.

would this work:

if (canMsg.can_id == 0x748)  {
if (canMsg.data[canMsg.can_dlc - 4] == 0x80  && canMsg.data[canMsg.can_dlc - 3] == 0x00 && canMsg.data[canMsg.can_dlc - 2] == 0x00 && canMsg.data[canMsg.can_dlc - 1] == 0x00) { 
// do something
}
if (canMsg.data[canMsg.can_dlc - 4] == 0x01  && canMsg.data[canMsg.can_dlc - 3] == 0x00 && canMsg.data[canMsg.can_dlc - 2] == 0x00 && canMsg.data[canMsg.can_dlc - 1] == 0x00) { 
// do something
}
if (canMsg.data[canMsg.can_dlc - 4] == 0x01  && canMsg.data[canMsg.can_dlc - 3] == 0x02 && canMsg.data[canMsg.can_dlc - 2] == 0x00 && canMsg.data[canMsg.can_dlc - 1] == 0x00) { 
// do something
}
if (canMsg.data[canMsg.can_dlc - 4] == 0x01  && canMsg.data[canMsg.can_dlc - 3] == 0x02 && canMsg.data[canMsg.can_dlc - 2] == 0x03 && canMsg.data[canMsg.can_dlc - 1] == 0x00) { 
// do something
}
if (canMsg.data[canMsg.can_dlc - 4] == 0x01  && canMsg.data[canMsg.can_dlc - 3] == 0x02 && canMsg.data[canMsg.can_dlc - 2] == 0x03 && canMsg.data[canMsg.can_dlc - 1] == 0x04) { 
// do something
}

or have i got my prgramming wrong?

show us your code so far...

1 Like

and what does your serial Monitor display? How does the string in your original post relate to "ID DLC DATA"?

So...

ID = 789 (hex)
DLC = 04 (hex)
DATA = 62 B0 41 06 8F

since you know how many data bytes arrived (canMsg.can_dlc), you can just grab the last two

int value = canMsg.data[canMsg.can_dlc-2] * 256 + canMsg.data[canMsg.can_dlc-1]

and then you can multiple value by whatever you want...

Hi,

Shouldn't that be sending known data so you can validate your filtering and level sensing?

3: if ( val >= 1602 && val <= 1679)
Display batthigh
4: if ( val >= 0 && val < 1002)
Display battlow
5: if ( val >= 1002 && val < 1602)
Display battnorm

Something like that should do it, that will mutually exclude any value > 1679 from causing a display change.

Tom... :grinning: :coffee: :australia: :+1:

What is that supposed to do?
https://www.arduino.cc/en/pmwiki.php?n=Reference/Else

If you wish to do nothing with void().
The just don't include the else part of the if function.

That is pseudo code, basically it means you put your code here to display the battnorm bar.
Such as battnorm() etc.

This is what is called pseudo code, some code some normal language to simplify an explanation.

You write the code.

Tom... :grinning: :+1: :coffee: :australia:

[code]
#include <SPI.h>
#include <mcp2515.h>
#include <MCUFRIEND_kbv.h>
struct can_frame canMsg;
MCP2515 mcp2515(10);
MCUFRIEND_kbv tft;

#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>
#include <FreeDefaultFonts.h>

#define BLACK       0x0000      /*   0,   0,   0 */
#define NAVY        0x000F      /*   0,   0, 128 */
#define DARKGREEN   0x03E0      /*   0, 128,   0 */
#define DARKCYAN    0x03EF      /*   0, 128, 128 */
#define MAROON      0x7800      /* 128,   0,   0 */
#define PURPLE      0x780F      /* 128,   0, 128 */
#define OLIVE       0x7BE0      /* 128, 128,   0 */
#define LIGHTGREY   0xC618      /* 192, 192, 192 */
#define DARKGREY    0x7BEF      /* 128, 128, 128 */
#define BLUE        0x001F      /*   0,   0, 255 */
#define GREEN       0x07E0      /*   0, 255,   0 */
#define CYAN        0x07FF      /*   0, 255, 255 */
#define RED         0xF800      /* 255,   0,   0 */
#define MAGENTA     0xF81F      /* 255,   0, 255 */
#define YELLOW      0xFFE0      /* 255, 255,   0 */
#define WHITE       0xFFFF      /* 255, 255, 255 */
#define ORANGE      0xFDA0      /* 255, 180,   0 */
#define GREENYELLOW 0xB7E0      /* 180, 255,   0 */
#define PINK        0xFC9F

void setup() {
  Serial.begin(115200);
  tft.begin(0x9486);
  tft.fillScreen(BLACK);
  tft.setRotation(1);
  tft.setTextColor(WHITE, BLACK);
  tft.setTextColor(WHITE);
  tft.setTextSize(4);
  tft.setCursor(135, 245);
  tft.setTextColor(WHITE, BLACK);
  tft.print("   v      %");
  tft.fillRect(100, 290, 285, 30, BLACK);
  tft.fillRect(100, 290, 10, 30, RED);
  tft.fillRect(375, 290, 10, 30, GREEN);
  tft.fillRect(240, 290, 10, 30, WHITE);
  tft.fillRect(240, 290, 10, 30, ORANGE);
  tft.drawRect(70, 47, 20, 70, WHITE); // tyre car
  tft.fillRect(200, 55, 50, 50, BLACK);
  tft.drawRect(200, 55, 50, 50, WHITE);
  tft.setTextColor(WHITE);
  tft.setTextSize(5);
  tft.setCursor(200, 61);
  tft.print("=)");
  tft.fillRect(200, 110, 50, 50, BLACK);
  tft.drawRect(200, 110, 50, 50, WHITE);
  tft.setTextColor(WHITE);
  tft.setTextSize(5);
  tft.setCursor(215, 127);
  tft.print("~ ");

  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS);
  mcp2515.setNormalMode();

}

void loop() {

  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    //start of voltage meter
    if (canMsg.can_id == 0x789 && canMsg.data[canMsg.can_dlc - 5] == 0x42) {
      decodevolts();
    }
    //end of voltage meter

    //start of SoC
    if (canMsg.can_id == 0x789 && canMsg.data[canMsg.can_dlc - 5] == 0x46) {
      decodesoc();
    }
    //end of SoC

    //start of tyre pressure
    if (canMsg.can_id == 0x72C) {
      decodeTyre();
    } //end of tyre pressure

    //start of odometer
    if (canMsg.can_id == 0x768) {
      decodeOdometer();
    }
    //end of odometer

    //start of doors
    if (canMsg.can_id == 0x748 && canMsg.data[canMsg.can_dlc - 5] == 0x12)  {
      decodeDoors();
    }
    //end of doors

    //start of lights
    if (canMsg.can_id == 0x748 && canMsg.data[canMsg.can_dlc - 5] == 0x17)  {
      decodelights();
    }
    //end of lights

    //start of temp
    if (canMsg.can_id == 0x7EB && canMsg.data[canMsg.can_dlc - 5] == 0x1B)  {
      decodecharge();
    }
    //end of temp

    Serial.print(canMsg.can_id, HEX); // print ID
    Serial.print(" ");
    Serial.print(canMsg.can_dlc, HEX); // print DLC
    Serial.print(" ");

    for (int i = 0; i < canMsg.can_dlc; i++)  {
      if (canMsg.data[i] < 0x10) Serial.print('0');
      Serial.print(canMsg.data[i], HEX);
      Serial.print(' ');
    }
    Serial.println();
  }
}

void decodeOdometer() {
  /* decode Odometer
      id = 0x0768
      dlc = 7
      example data[] = 06 62 B1 01 00 04 75 00
     data byte values 04 75
       24 bit value
  */
  uint32_t Odo =  (uint32_t) canMsg.data[canMsg.can_dlc - 3] * 256  + (uint32_t) canMsg.data[canMsg.can_dlc - 2];
  tft.fillRect(20, 195, 150, 40, BLACK);
  tft.setCursor(30, 200);
  tft.setTextSize(3);
  tft.setTextColor(ORANGE, BLACK);
  tft.print(Odo / 1.609344, 1);
}


void decodeTyre() {
  /* decode Tyre pressure
      id = 0x072C
      dlc = 8
      example data[] = 07 62 B0 01 41 36 41 41
     data byte values (last 4 bytes)
      byte 3 = front left
      byte 4 = front right
      byte 5 = rear right
      byte 6 = rear left
  */

  byte RL = canMsg.data[7];
  byte RR = canMsg.data[6];
  byte FR = canMsg.data[5];
  byte FL = canMsg.data[4];
  float pressrl = RL * 0.5823 - 0.15294;
  float pressrr = RR * 0.5823 - 0.15294;
  float pressfr = FR * 0.5823 - 0.15294;
  float pressfl = FL * 0.5823 - 0.15294;
  tft.fillRect(20, 47, 40, 70, BLACK); // tyre car
  tft.fillRect(98, 47, 40, 70, BLACK); // tyre car
  tft.setTextColor(BLUE, BLACK);
  tft.setTextSize(2);
  tft.setCursor(18, 96);
  tft.print(pressrl, 1);
  tft.setCursor(100, 96);
  tft.print(pressrr, 1);
  tft.setCursor(100, 52);
  tft.print(pressfr, 1);
  tft.setCursor(18, 52);
  tft.print(pressfl, 1);
}

void decodeDoors() {
  /*  decode open doors
      id = 0x0748
      dlc = 8
      example data[] = 01 62 D1 12 80 00 00 00
     data byte values (last 4 bytes)
      0x80 = no doors open
      0x01 = Driver door
      0x02 = passenger door
      0x04 = rear left door
      0x05 = rear right door
      0x10 = bonnet
      0x20 = boot
  */

  for ( int i = 4; i < canMsg.can_dlc; ++i ) {
    switch ( canMsg.data[i] ) {
      case 0x80:
        tft.fillRect(345, 27, 70, 100, BLACK);
        return; // nothing so no need to continue
      case 0x01:
        tft.drawRect(370, 47, 20, 70, WHITE); // door car
        tft.setTextColor(RED, BLACK);
        tft.setTextSize(3);
        tft.setCursor(398, 52);
        tft.print(">");
        break;
      case 0x02:
        tft.drawRect(370, 47, 20, 70, WHITE); // door car
        tft.setTextColor(RED, BLACK);
        tft.setTextSize(3);
        tft.setCursor(342, 52);
        tft.print("<");
        break;
      case 0x04:
        tft.drawRect(370, 47, 20, 70, WHITE); // door car
        tft.setTextColor(RED, BLACK);
        tft.setTextSize(3);
        tft.setCursor(342, 96);
        tft.print("<");
        break;
      case 0x05:
        tft.drawRect(370, 47, 20, 70, WHITE); // door car
        tft.setTextColor(RED, BLACK);
        tft.setTextSize(3);
        tft.setCursor(398, 96);
        tft.print(">");
        break;
      case 0x10:
        tft.drawRect(370, 47, 20, 70, WHITE); // door car
        tft.setTextColor(RED);
        tft.setTextSize(3);
        tft.setCursor(372, 32);
        tft.print("^");
        break;
      case 0x20:
        tft.drawRect(370, 47, 20, 70, WHITE); // door car
        tft.setTextColor(RED);
        tft.setTextSize(3);
        tft.setCursor(372, 105);
        tft.print("^");
        break;
    }
  }
}

void decodevolts() {
  /* decode Volts
      id = 0x0789
      dlc = 8
      example data[] = 05 62 B0 42 06 8C 00 00
     data byte values are 06 and 8C
       24 bit value
  */
  uint32_t battvolt =  (uint32_t) canMsg.data[canMsg.can_dlc - 4] * 256  + (uint32_t) canMsg.data[canMsg.can_dlc - 3];
  tft.fillRect(50, 240, 140, 40, BLACK);
  tft.setCursor(100, 245);
  tft.setTextSize(4);
  tft.setTextColor(ORANGE, BLACK);
  tft.print(battvolt / 4);
  tft.fillRect(100, 290, 285, 30, BLACK);
  tft.fillRect(100, 290, 10, 30, RED);
  tft.fillRect(375, 290, 10, 30, GREEN);
  tft.fillRect(240, 290, 10, 30, ORANGE);
  if (battvolt >= 8 && battvolt < 1676) {
    tft.fillRect(110, 300, battvolt / 8, 10, WHITE);
  } else if (battvolt == 1676)
    tft.fillRect(110, 300, 265, 10, WHITE);
}

void decodesoc() {
  /* decode Volts
      id = 0x0789
      dlc = 8
      example data[] = 05 62 B0 46 06 8C 00 00
     data byte values (last 3 bytes)
       24 bit value
  */

  uint32_t Soc =  (uint32_t) canMsg.data[canMsg.can_dlc - 4] * 256  + (uint32_t) canMsg.data[canMsg.can_dlc - 3];
  if (Soc >= 1000) {
    tft.fillRect(235, 240, 125, 40, BLACK);
    tft.setCursor(255, 245);
    tft.setTextSize(4);
    tft.setTextColor(ORANGE, BLACK);
    tft.print(100);
  }
  tft.fillRect(235, 240, 125, 40, BLACK);
  tft.setCursor(245, 245);
  tft.setTextSize(4);
  tft.setTextColor(ORANGE, BLACK);
  tft.print(" ");
  tft.print(Soc / 10);
}

void decodelights() {
  /*  decode lights
      id = 0x0748
      dlc = 8
      example data[] = 07 62 D1 17 04 20 00 00 - lights on
                       07 62 D1 17 00 20 00 00 - lights off
    data byte values
      0x04 = lights on
      0x00 = lights off
  */

  for ( int i = 4; i < canMsg.can_dlc; ++i ) {
    switch ( canMsg.data[4] ) {
      case 0x00:
        tft.fillRect(200, 55, 50, 50, BLACK);
        tft.drawRect(200, 55, 50, 50, WHITE);
        tft.setTextColor(WHITE);
        tft.setTextSize(5);
        tft.setCursor(200, 61);
        tft.print("=)");
        break; 
      case 0x04:
        tft.fillRect(200, 55, 50, 50, GREEN);
        tft.setTextColor(RED);
        tft.setTextSize(5);
        tft.setCursor(200, 61);
        tft.print("=)");
        break;
    }
  }
}

void decodecharge() {
  /*  decode charger
      id = 0x07EB
      dlc = 8
      example data[] = 04 62  B7  1B  00  00  00  00 -
                       04 62  B7  1B  01  00  00  00 -
    data byte values
      0x04 = charger connected
      0x00 = charger disconnected
  */

  for ( int i = 4; i < canMsg.can_dlc; ++i ) {
    switch ( canMsg.data[4] ) {
      case 0x00:
        tft.fillRect(200, 110, 50, 50, BLACK);
        tft.drawRect(200, 110, 50, 50, WHITE);
        tft.setTextColor(WHITE);
        tft.setTextSize(5);
        tft.setCursor(215, 127);
        tft.print("~ ");
        break; // nothing so no need to continue
      case 0x01:
        tft.fillRect(200, 110, 50, 50, GREEN);
        tft.setTextColor(BLACK);
        tft.setTextSize(5);
        tft.setCursor(215, 127);
        tft.print("~ ");
        break;
    }
  }
}
[/code]

this is where i got to.

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