tonton81 / FlexCAN_T4

FlexCAN (CAN 2.0 / CANFD) Library for Teensy 3.x and 4.0
https://forum.pjrc.com/threads/56035-FlexCAN_T4-FlexCAN-for-Teensy-4
MIT License
196 stars 66 forks source link

Grab an specific byte From specific ID #41

Closed djgabriel2004 closed 1 year ago

djgabriel2004 commented 2 years ago

Hi, I’m working in the dashboard of my EV conversion, and I’m trying to make the dashboard works.

So far I have connected

Car Bus can1 Speed controller bus can2 Speedometer can3

The speedometer receives Specific Data (byte2= speed and byte 0 = parking brake) in the cob id 0x18FEF100,

The speed controller can be setup to transmit the speed data in the same ID. Doing this works but the speedo gets crazy receiving Mixed data (from ECU and speed controller) at the same time and after a couple runs it turns the bus off.

What I need to do is to grab Byte0 from Can1 and Byte2 from can2 and then Send them to Can3 (other bytes can be discarded) and then Let pass through everything else in the Bus

I will post my sketch with the roughly idea soon. Thanks in advance

djgabriel2004 commented 2 years ago

``

FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> FDcan3; // can3 port FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2; // can2 port FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1; // can1 port

int led = 13; IntervalTimer timer; uint8_t d=0;

CAN_message_t msg; uint8_t flag1= 0; uint8_t flag2= 0; uint8_t buf[8]= {0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00};

void setup(void) { Serial.begin(9600); can1.begin(); can1.setBaudRate(250000); can2.begin(); can2.setBaudRate(250000); FDcan3.begin(); FDcan3.setBaudRate(250000); }

void loop() {

     if ( can1.read(msg) ) 
     {
       if (msg.id == 0X18fef100) 
       {
           flag1= 1;
       }
       if (msg.id == 419351283) {
        msg.id = 273;// 0x18fecaf3 is 0x111

       }
       else             FDcan3.write(msg);  
           FDcan3.events();

static uint32_t timeout = millis(); if ( millis() - timeout > 100 ) { // send random frame every 1000ms msg.id = 0x18feca00; //WARNING LIGHT OFF

msg.buf[0] = 0;
msg.buf[1] = 0xFF; 
msg.buf[2] = 00; 
msg.buf[3] = 00; 
msg.buf[4] = 00; 
msg.buf[5] = 00;
msg.buf[6] = 0xFF;
msg.buf[7] = 0xFF;

FDcan3.write(msg);
timeout = millis();

}
}

     if ( can2.read(msg) ) 
     {
       if (msg.id == 0X18fef100) 
       {
           flag2= 1;           

           }

       else             FDcan3.write(msg);  

     }

     if(flag1  || flag2)         
     {
        for(int i= 0; i<8; i++)
        {
            msg.buf[i]&=buf[i];

            Serial.print(msg.buf[i],HEX);
            Serial.print(" ");
        }
        Serial.println("");
        FDcan3.write(msg);
        flag1= 0;
        flag2= 0;                          
     }

     if(FDcan3.read(msg))
     {
           can1.write(msg);
           can2.write(msg);          
     }

} `

djgabriel2004 commented 2 years ago

ok I been testing a lot of things back and forth.

This code is kinda working but not 100%..
I believe is a dumb mistake but I can't find it When I connect the can Analyezer to Can2 I can see the 0x18fef100 ID using Byte0 from can0 and Byte2 from can2 that part works perfect., However, I also need Everything else in the BUS (can0 and can1) to pass thru (both ways) (besides the 0x18fef100 that Is already passing thru modified)

If I add the line: else if (can2.write(msg);

Can2 will show everything else but the fist part of the code wont work (it will let pass thru all data in 0x18fef100 from can0 and can1, not only the modified one that i need)

Here is the code

`

include

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can0; FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can1; FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> can2;

CAN_message_t msg;

uint8_t message1,message2;

void setup(void) {

Serial.begin(115200); delay(400);

pinMode(6, OUTPUT); digitalWrite(6, LOW); / optional tranceiver enable pin /

can0.begin(); can0.setBaudRate(250000); can1.begin(); can1.setBaudRate(250000); can2.begin(); can2.setBaudRate(250000);

can2.setMaxMB(16); can2.enableFIFO(); can2.enableFIFOInterrupt(); can2.onReceive(canSniff); can2.mailboxStatus();

}

void canSniff(const CAN_message_t &msg) { Serial.print("MB "); Serial.print(msg.mb); Serial.print(" OVERRUN: "); Serial.print(msg.flags.overrun); Serial.print(" LEN: "); Serial.print(msg.len); Serial.print(" EXT: "); Serial.print(msg.flags.extended); Serial.print(" TS: "); Serial.print(msg.timestamp); Serial.print(" ID: "); Serial.print(msg.id, HEX); Serial.print(" Buffer: "); for ( uint8_t i = 0; i < msg.len; i++ ) { Serial.print(msg.buf[i], HEX); Serial.print(" "); } Serial.println(); }

void loop() {

if ( can0.read(msg) ) { Serial.print("CAN0 "); Serial.print("MB: "); Serial.print(msg.mb); Serial.print(" ID: 0x"); Serial.print(msg.id, HEX ); Serial.print(" EXT: "); Serial.print(msg.flags.extended ); Serial.print(" LEN: "); Serial.print(msg.len); Serial.print(" DATA: "); for ( uint8_t i = 0; i < 8; i++ ) { Serial.print(msg.buf[i]); Serial.print(" "); }

if (msg.id == 0x18FEF100)
message1=msg.buf[0];

Serial.print("  TS: "); Serial.println(msg.timestamp);

} if ( can1.read(msg) ) { Serial.print("CAN1 "); Serial.print("MB: "); Serial.print(msg.mb); Serial.print(" ID: 0x"); Serial.print(msg.id, HEX ); Serial.print(" EXT: "); Serial.print(msg.flags.extended ); Serial.print(" LEN: "); Serial.print(msg.len); Serial.print(" DATA: "); for ( uint8_t i = 0; i < 8; i++ ) { Serial.print(msg.buf[i]); Serial.print(" "); }

if (msg.id == 0x18FEF100)
message2=msg.buf[2];
Serial.print("  TS: "); Serial.println(msg.timestamp);

}

can2.events();

static uint32_t timeout = millis(); if ( millis() - timeout > 200 ) { CAN_message_t msg; msg.id = 0x18fef100; msg.flags.extended=1; msg.buf[0] =message1; msg.buf[2] =message2; can2.write(msg); timeout = millis();

}}`

tonton81 commented 2 years ago

else if (can2.write(msg); why checking for a bool? just use else instead of else if, so it writes without checking

djgabriel2004 commented 2 years ago

Thank you for your answer, I've modified the line. however now the arduino is sending messges like crazy 0.6ms and makes the bus too crowded and some messages are lost. seems like this command is not working.

static uint32_t timeout = millis(); if ( millis() - timeout > 200 ) {

tonton81 commented 2 years ago

you need to reset it in that scope timeout = millis()

that way the counter restarts and waits another 200ms

djgabriel2004 commented 2 years ago

yes, unfortunately, for some reason it starts to send messages like crazy 0.6ms and the bus gets overloaded. not sure why tho.

tonton81 commented 2 years ago
static uint32_t timeout = millis();
if ( millis() - timeout > 200 ) {
  // code here to run every 200ms
  timeout = millis();
}
djgabriel2004 commented 2 years ago

static uint32_t timeout = millis(); if ( millis() - timeout > 200 ) { CAN_message_t msg; msg.id = 0x18fef100; msg.flags.extended=1; msg.buf[0] =message1; msg.buf[2] =message2; can2.write(msg); timeout = millis();

}}

I have it like that. is there any other place where I can look

tonton81 commented 2 years ago

that should be fine, it shouldn't do it every 0.6ms. Is your can2 properly terminated at 60omhs? Did you try without using events()?