Stoopalini
Member
I have an Arduino DUE right now, installed in my vehicle acting as "man in the middle" between the integrated center stack and the IHS canbus network. I'm using the due_can library to forward messages in both directions, but filtering out messages on can 0 with ID 0x3EA, and modifying Byte 3 before forwarding the modified message to can 1.
I now want to incorporate a 3rd canbus connection, so I can also send a command to the vehicle's C-bus, when the 0x3EA message is received on can 0.
So I purchased this Teensy 4.0 Triple CAN Bus Board from Copper Hill and am attempting to recreate my working code for the Teensy.
The FlexCAN_T4 library seems the best fit for the job but I'm struggling with the filtering logic for the message ID's.
Here is the code I have running on the Arduino:
And as stated, it's been working great for several weeks now.
Here is my attempt to create the same functionality with FlexCAN_T4, but I'm obviously not getting something correct with my use of the library:
It does compile successfully, but I'm getting several warnings.
The 1st one is related to line 68 in my code:
I assume it's got to do with me trying to use the message ID in the 1st argument, where that is supposed to be a mailbox ID instead?
Then I also get 3 more warnings related to the library itself:
I appreciate any help with what I'm doing wrong here. I'm not new to Arduino, Teensy, ESP8266, ESP32, etc ... but I'm certainly no coder ... I just keep working at things until I get them right.
I now want to incorporate a 3rd canbus connection, so I can also send a command to the vehicle's C-bus, when the 0x3EA message is received on can 0.
So I purchased this Teensy 4.0 Triple CAN Bus Board from Copper Hill and am attempting to recreate my working code for the Teensy.
The FlexCAN_T4 library seems the best fit for the job but I'm struggling with the filtering logic for the message ID's.
Here is the code I have running on the Arduino:
Code:
// **************************** DEFINITIONS ********************************
#include "variant.h"
#include <due_can.h>
#define Serial SerialUSB //Leave defined if using native port, comment if using programming port .. lots of traffic so best to use native
// ************************** SERIAL PRINT FUNCTION *************************
void printFrame(CAN_FRAME *frame, int filter) {
Serial.print("Fltr: ");
if (filter == 1) Serial.print("FWD");
else if (filter == 2) Serial.print("VHL");
else if (filter == 10) Serial.print("DSC");
else Serial.print("???");
Serial.print(" ID: 0x");
Serial.print(frame->id, HEX);
Serial.print(" Len: ");
Serial.print(frame->length);
Serial.print(" Data: 0x");
for (int count = 0; count < frame->length; count++) {
Serial.print(frame->data.bytes[count], HEX);
Serial.print(" ");
}
Serial.print("\r\n");
}
//************************************** CALLBACK FUNCTIONS **************************************
void gotFrame0(CAN_FRAME *frame) { //Function to identify any message received on CAN 0
//Serial.print("RX0: "); //uncomment line to print frames that are going out
//printFrame(frame, 1); //uncomment line to print frames that are going out
Can1.sendFrame(*frame); //Forward message received on CAN 0 to CAN 1
}
void gotFrame3EA(CAN_FRAME *frame) { //Function to identify CAN 0 messages with ID of 0x3EA
frame->data.byte[3]=0x29; //Modify Byte 3 with value 29 for SRT No, or 69 for SRT Yes
//Serial.println("Sending the following to CAN 1"); //uncomment line to print frames that are going out
//printFrame(frame, 2); //uncomment line to print frames that are going out
Can1.sendFrame(*frame); //Send modified message to CAN 1
}
void gotFrame1(CAN_FRAME *frame) { //Function to identify any message received on CAN 1
//Serial.print("RX1: "); //uncomment line to print frames that are going out
//printFrame(frame, -1); //uncomment line to print frames that are going out
Can0.sendFrame(*frame); //Forward message received on CAN 1 to CAN 0
}
//**************************************** INITIALIZATION *******************************************
void setup() {
//Serial.begin(115200); //Uncomment for serial
Can0.begin(CAN_BPS_125K); //Initialize CAN0, Set the proper baud rate
Can1.begin(CAN_BPS_125K); //Initialize CAN1, Set the proper baud rate
Can0.setRXFilter(0, 0x3EA, 0x7FF, false); //CAN 0 filter to identify messages with ID of 0x3EA
Can0.setRXFilter(0, 0, false); //CAN 0 catch all mailbox - no mailbox ID specified
Can1.setRXFilter(0, 0, false); //CAN 1 catch all mailbox - no mailbox ID specified
Can0.setCallback(0, gotFrame3EA); //Register callback function for VehConfig 3 messages
Can0.setGeneralCallback(gotFrame0); //this function will get a callback for any CAN 0 mailbox that doesn't have a registered callback
Can1.setGeneralCallback(gotFrame1); //this function will get a callback for any CAN 1 mailbox that doesn't have a registered callback
}
//**************************************** MAIN LOOP ************************************************
void loop(){ //note the empty loop here. All work is done via callback as frames come in - no need to poll for them
}
And as stated, it's been working great for several weeks now.
Here is my attempt to create the same functionality with FlexCAN_T4, but I'm obviously not getting something correct with my use of the library:
Code:
// **************************** DEFINITIONS ********************************
#include <FlexCAN_T4.h>
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;
// ************************** SERIAL PRINT FUNCTION *************************
void printFrame(CAN_message_t &frame, int filter) {
Serial.print("Fltr: ");
if (filter == 1) Serial.print("FWD");
else if (filter == 2) Serial.print("VHL");
else if (filter == 10) Serial.print("DSC");
else Serial.print("???");
Serial.print(" ID: 0x");
Serial.print(frame.id, HEX);
Serial.print(" Len: ");
Serial.print(frame.len);
Serial.print(" Data: 0x");
for (int count = 0; count < frame.len; count++) {
Serial.print(frame.buf[count], HEX);
Serial.print(" ");
}
Serial.print("\r\n");
}
//************************************** CALLBACK FUNCTIONS **************************************
void gotFrame0(const CAN_message_t &frame) { //Function to handle messages received on CAN 0
//Serial.print("RX0: "); //uncomment line to print frames that are going out
//printFrame(frame, 1); //uncomment line to print frames that are going out
Can1.write(frame); //Forward message received on CAN 0 to CAN 1
}
void gotFrame3EA(const CAN_message_t &frame) { //Function to handle CAN 0 messages with ID of 0x3EA
CAN_message_t modifiedFrame = frame; //Make a copy of the original frame
modifiedFrame.buf[3] = 0x29; //Modify Byte 3 with value 29 for SRT No, or 69 for SRT Yes
//Serial.println("Modified frame sent to CAN 1"); //uncomment line to print frames that are going out
//printFrame(frame, 2); //uncomment line to print frames that are going out
//*****Send message A to Can2*****
Can1.write(modifiedFrame); //Send modified message to CAN 1
//*****Send message B to Can2*****
}
void gotFrame1(const CAN_message_t &frame) { //Function to identify any message received on CAN 1
//Serial.print("RX1: "); //uncomment line to print frames that are going out
//printFrame(frame, -1); //uncomment line to print frames that are going out
Can0.write(frame); //Forward message received on CAN 1 to CAN 0
}
//**************************************** INITIALIZATION *******************************************
void setup()
{
Can0.begin();
Can0.setBaudRate(125000);
Can0.setMaxMB(9);
Can0.enableFIFO();
Can1.begin();
Can1.setBaudRate(125000);
Can1.setMaxMB(9);
Can1.enableFIFO();
Can2.begin();
Can2.setBaudRate(500000);
Can2.setMaxMB(9);
Can2.enableFIFO();
Can0.onReceive(0x3EA, gotFrame3EA); //Register specific callback for ID 0x3EA on CAN0
Can0.onReceive(gotFrame0); //Register general callback for CAN0
Can1.onReceive(gotFrame1); //Register general callback for CAN1
}
//**************************************** MAIN LOOP ************************************************
void loop(){ //note the empty loop here. All work is done via callback as frames come in - no need to poll for them
}
It does compile successfully, but I'm getting several warnings.
The 1st one is related to line 68 in my code:
Code:
warning: invalid conversion from 'int' to 'FLEXCAN_MAILBOX' [-fpermissive]
68 | Can0.onReceive(0x3EA, gotFrame3EA); //Register specific callback for ID 0x3EA on CAN0
| ^~~~~
| |
| int
I assume it's got to do with me trying to use the message ID in the 1st argument, where that is supposed to be a mailbox ID instead?
Then I also get 3 more warnings related to the library itself:
Code:
In file included from C:\Users\Stoop\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\FlexCAN_T4/FlexCAN_T4.h:558,
from Z:\Pics\cars\23_Durango_RT\Canbus\Teensy\CanbusTeensy\CanbusTeensy.ino:2:
C:\Users\Stoop\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\FlexCAN_T4/FlexCAN_T4.tpp:1050:59: note: initializing argument 1 of 'void FlexCAN_T4<_bus, _rxSize, _txSize>::onReceive(const FLEXCAN_MAILBOX&, _MB_ptr) [with CAN_DEV_TABLE _bus = CAN1; FLEXCAN_RXQUEUE_TABLE _rxSize = RX_SIZE_256; FLEXCAN_TXQUEUE_TABLE _txSize = TX_SIZE_16; FLEXCAN_MAILBOX = FLEXCAN_MAILBOX; _MB_ptr = void (*)(const CAN_message_t&)]'
1050 | FCTP_FUNC void FCTP_OPT::onReceive(const FLEXCAN_MAILBOX &mb_num, _MB_ptr handler) {
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
C:\Users\Stoop\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\FlexCAN_T4/FlexCAN_T4.tpp:1055:21: warning: array subscript 234 is above array bounds of 'void (* [64])(const CAN_message_t&)' [-Warray-bounds]
1055 | _mbHandlers[mb_num] = handler;
| ~~~~~~~~~~~~~~~~~~^
In file included from Z:\Pics\cars\23_Durango_RT\Canbus\Teensy\CanbusTeensy\CanbusTeensy.ino:2:
C:\Users\Stoop\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\FlexCAN_T4/FlexCAN_T4.h:542:13: note: while referencing 'FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16>::_mbHandlers'
542 | _MB_ptr _mbHandlers[64]; /* individual mailbox handlers */
| ^~~~~~~~~~~
I appreciate any help with what I'm doing wrong here. I'm not new to Arduino, Teensy, ESP8266, ESP32, etc ... but I'm certainly no coder ... I just keep working at things until I get them right.