Longan-Labs / Arduino_CAN_BUS_MCP2515

Arduino CAN Bus library, MCP2515/MCP2551
https://www.longan-labs.cc/
MIT License
118 stars 371 forks source link

Second Mask and Filters Not Working #15

Open knopfcol opened 7 years ago

knopfcol commented 7 years ago

I am pulling CAN messages off a vehicle based off their CAN ID. I am able to get the first mask to work which corresponds to the first 2 filters. The issue is with the second mask and second set of filters (3-6). Is there something in the library I need to change to enable both masks?

I have attached code for reference.

Thank you.

`#include

include

// **** Section Below for LCD **** //****

include

include

define I2C_ADDR 0x27 // Define I2C Address where the PCF8574A is

                      // Address can be changed by soldering A0, A1, or A2
                      // Default is 0x27

// map the pin configuration of LCD backpack for the LiquidCrystal class

define BACKLIGHT_PIN 3

define En_pin 2

define Rw_pin 1

define Rs_pin 0

define D4_pin 4

define D5_pin 5

define D6_pin 6

define D7_pin 7

LiquidCrystal_I2C lcd(I2C_ADDR, En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin, BACKLIGHT_PIN, POSITIVE);

// * End LCD Setup ***** //**

MCP_CAN CAN0(10); // Set CS to pin 10

// * Variable declarations ***** double Special1; double Special2;

float RWHL_Spd; // average of rears engine Veh_V_ActlEng sb 48, len 16, res 0.01 offset = 0 kph 0x202 EngVehicleSpThrottle2

// Trail Control Section

float TrlCtlSetSpd; int BangBit; // Tom: message 0x76, start bit 32, length 1 forma name BrkCtrFnd_B_Stat int lsmcstate; int MSR_Status; // active = 1 int rtt; int RPMStatus; int TrailCtlStat = 0; long unsigned int rxId; unsigned char len = 0; unsigned char rxBuf[8]; char msgString[128]; // Array to store serial string

void setup()

{ //**** Section for LCD Initialization ****

lcd.begin(20,4); // 20 columns by 4 rows on display

lcd.setBacklight(HIGH); // Turn on backlight, LOW for off

// * Misc Set up ***** pinMode(8,OUTPUT);//Setup Pin 8 for and LED for BangBit:center found by Brakes

// *** Serial.begin(115200); if(CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.print("MCP2515 Init Okay!!\r\n"); else Serial.print("MCP2515 Init Failed!!\r\n"); pinMode(2, INPUT); // Setting pin 2 for /INT input

CAN0.init_Mask(0,0,0x07FF0000); // Init first mask... CAN0.init_Filt(0,0,0x04150000); // Init first filter... CAN0.init_Filt(1,0,0x02040000); // Init second filter...

CAN0.init_Mask(1,0,0x07FF0000); // Init second mask... CAN0.init_Filt(2,0,0x02020000); // Init first filter... CAN0.init_Filt(3,0,0x02030000); // Init second filter... CAN0.init_Filt(4,0,0x02050000); // Init third filter... CAN0.init_Filt(5,0,0x00760000); // Init fouth filter...

CAN0.setMode(MCP_NORMAL);

lcd.clear(); lcd.setCursor(0,0); lcd.print("Trail Control"); lcd.setCursor(0,1); lcd.print("Tom Box CAN Display"); lcd.setCursor(0,2); lcd.print("Version V12"); lcd.setCursor(0,3); lcd.print("Powered by Spartans!"); delay(2000); lcd.clear();

}

void loop()

{ if(!digitalRead(2)) // If pin 2 is low, read receive buffer { CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s) // Serial.print("ID: "); // Serial.print(rxId, HEX); // Serial.print(" Data: "); // for(int i = 0; i<len; i++) // Print each byte of the data // { // if(rxBuf[i] < 0x10) // If data byte is less than 0x10, add a leading zero // { // Serial.print("0"); // } // Serial.print(rxBuf[i], HEX); // Serial.print(" "); // } // Serial.println();

unsigned int canId = (rxId);
float CAN_Msg=canId;

// *Trail Control *** // message Brake 0x415 only on HS2 Pins 3 and 11

if (CAN_Msg == 0x415)// LsmcBrkDecel_D_Stat SB=32, length = 3, SED 1110 0000 { lsmcstate = rxBuf[4]>>5; } if (CAN_Msg == 0x41E) // BrakeSysFeatures_3 TrailCtl_D_Stat SB=48 Len = 3 HS2 only { Special1 = rxBuf[6]>>4; TrailCtlStat = Special1;//0 = off, 1 = enabled, 2 = active, }

// if (CAN_Msg == 0x43A) // // SB=51 len 3 on HS1, This MUST be commented out if connected to HS2 // { // Special1 = rxbuf[6]>>2 & 0x7; // TrailCtlStat = Special1;//0 = off, 1 = enabled, 2 = active, // } if (CAN_Msg == 0x204)// EngAout_N_Actl SB27, length = 13 { RPMStatus = ((((rxBuf[3] & 0x1F) 256) + rxBuf[4]) 2); //select what bytes you want to read }

//****Find Center****

if (CAN_Msg == 0x76) //msg 0x76 is BrakeSnData_2 "BangBit" BrkCtrFnd_B_Stat, position=32, len=1 bits0-63 { BangBit = (rxBuf[4] & 0x80)>>7;//uses bitwise AND not boolean AND which is &&, bit shift moves the bit from position 7 to 0

     // LED is ON until Center is Found, it is too bright to leave on the entire drive cycle at night
      if (BangBit == 1)
        {
          lcd.setCursor(0,1);
          lcd.print("          ");
          lcd.setCursor(0,1);
          lcd.print("Found");
        }
       else
        { 
          lcd.setCursor(0,1);
          lcd.print("          ");
          lcd.setCursor(0,1);
          lcd.print("Not Found");
        } 
    }

//**End Find Center

// **** get Trail Control Set Speed and Display **

if (CAN_Msg == 0x202) // EngVehicleSpThrottle2_HS1 // Veh_V_ActlEng sb 48, len 16, res 0.01 offset = 0 kph // Veh_V_RqCcSet SB=39 length = 9 res = 0.5 // 0-7,8-15,16-23,24-31,32-39,40-47,48-55,56-63 { // Get Trail Control Set Speed Special1 = (rxBuf[4] & 0x01); // grab bit 39 Special2 = rxBuf[5]; TrlCtlSetSpd = round((Special1256 + Special2) 0.5 0.621371); // kph to mph 0.621 TrlCtlSetSpd = ((Special1256 + Special2) 0.5 0.621371); // kph to mph 0.621 }

//*** End Trail Control Set Speed**

// * DEBUG ***PRINTS OUT RAW CAN MESSAGE BYTES ***** Serial.print("Get data from ID: "); Serial.println(canId, HEX); for(int i = 0; i<len; i++) // print the data { Serial.print(rxBuf[i], HEX); Serial.print("\t"); // tab }

// ** END DEBUG*****

//****LOGIC FOR RTT determination*****

if (MSR_Status == 0 && TrailCtlStat == 0) // if either is set don't dsiplay off, X1 uses MSR_Status, M1 uses TrailCtlStat { rtt = 0; //Display "OFF" }

if ((lsmcstate == 3 && TrlCtlSetSpd == 0) || (TrailCtlStat == 1))// enabled not active ** left of the OR X1, right of the OR M1 { rtt = 2; // display "ENABLED - NOT ACTIVE" }

if ((lsmcstate < 4 && lsmcstate > 0 && TrlCtlSetSpd > 0) || (TrailCtlStat == 2 && RWHL_Spd < 33)) //active ** left of the OR X1, right of the OR M1 { rtt = 1; //display "ENABLED - ACTIVE" }

if ((lsmcstate > 3 && MSR_Status == 1) || (TrailCtlStat == 2 && RWHL_Spd >= 33)) //over threshold ** left of the OR X1, right of the OR M1 { rtt = 3; //display "Overspeed" }

//****END LOGIC FOR RTT DETERMINATION**

//**Determine Vehicle speed**

Special1 = rxBuf[6]; Special2 = rxBuf[7]; RWHL_Spd = (( Special1 *256) + Special2) / 100; //kph

//****End determine vehicle speed**

//* Trail Control Set Speed ***

lcd.setCursor(0,0); lcd.print("Set Speed"); lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(0,3); lcd.print(" "); lcd.setCursor(11,0); lcd.print(TrlCtlSetSpd,0); lcd.setCursor(0,3); lcd.print(RPMStatus);

// * Trail Control Status ***

lcd.setCursor(0,2); if (rtt == 0) { lcd.print("OFF "); }

if (rtt == 1)
  {
    lcd.print("ACTIVE              ");
  }

if (rtt == 2)
  {
    lcd.print("ENABLED - NOT ACTIVE");
  }

if (rtt ==3)
{
    lcd.print("OVERSPEED              ");
}

// debug items //lcd.setCursor(0,3); //lcd.print(Special1); //lcd.setCursor(10,3); //lcd.print(TrailCtlStat); //lcd.setCursor(0,3); //lcd.print(TrailCtlStat); //lcd.setCursor(10,3); //lcd.print(rtt); //lcd.setCursor(0,1); //lcd.print(lsmcstate);

}
}

`

knopfcol commented 7 years ago

I made progress by placing the following code within the IF statements that pertain to them.

lcd.setCursor(0,0); lcd.print("Set Speed"); lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(0,3); lcd.print(" "); lcd.setCursor(11,0); lcd.print(TrlCtlSetSpd,0); lcd.setCursor(0,3); lcd.print(RPMStatus);

Along with this I eliminated the printing of blanks to erase previous text. This now applies all the filters to the canbus.

It is interesting though because I receive some messages much more frequently than others even though they should be sending at the same rate.

Could I just be overloading the arduino with how many messages it is receiving?

coryjfowler commented 7 years ago

I am able to get the first mask to work which corresponds to the first 2 filters. The issue is with the second mask and second set of filters (3-6). Is there something in the library I need to change to enable both masks?

There is no way to disable certain masks or filters. It is possible your program is doing too much in the receive if statement that messages are overflowing the first receive buffer in the protocol controller which moves that message to the second buffer, overwriting its contents. If you want to turn this off, you will need to modify the .cpp file of the library to disable the bukt bit, see below.

        //Change this
        mcp2515_modifyRegister(MCP_RXB0CTRL,
        MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
        MCP_RXB_RX_ANY | MCP_RXB_BUKT_MASK);

        //To this
        mcp2515_modifyRegister(MCP_RXB0CTRL,
        MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
        MCP_RXB_RX_ANY);

Could I just be overloading the arduino with how many messages it is receiving?

That is definitely possible. You are also updating the LCD with every received message. There are places where elseif statements would improve performance. I'd also suggest implementing a modified version of the "blink without delay" sketch included with the Ardunio IDE to update your LCD at a specific rate outside of the receive if statement.

It is interesting though because I receive some messages much more frequently than others even though they should be sending at the same rate.

I've explored CAN on several vehicles and I've never seen messages come at the same rate. Some are 10Hz, some at 1Hz and a few at 20Hz or faster.