Which CAN transceiver are you using ? How is it connected to the Teensy ?
Post a photo of your setup.
Which version of Teensy are you using ?
The MCP2551 is 5v supply with 5v IO. The Teensy 3.6 is not 5v tolerant on the input. You may have damaged the input pin.
I would use the MCP2562 with 5v supply and 3.3v IO.
Can0.begin();
Can0.setBaudRate(CANSpeed);
Can0.setMaxMB(16);
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.onReceive(canSniff);
Can0.mailboxStatus();
return;
FIFO Enabled --> Interrupt Enabled
FIFO Filters in use: 8
Remaining Mailboxes: 8
MB8 code: TX_INACTIVE
MB9 code: TX_INACTIVE
MB10 code: TX_INACTIVE
MB11 code: TX_INACTIVE
MB12 code: TX_INACTIVE
MB13 code: TX_INACTIVE
MB14 code: TX_INACTIVE
MB15 code: TX_INACTIVE
#include <FlexCAN_T4.h>
#include <Arduino.h>
#include <Bounce.h>
#include <RGB_LED.h>
#include "music.h"
#include "config.h"
void canCallback(const CAN_message_t &msg);
void canSend(uint8_t data);
void parseCAN(CAN_message_t msg);
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can;
CAN_message_t in_msg;
Bounce ir_detect(DETEC_PIN, 100);
RGB_LED rgb_led(RED_PIN, GREEN_PIN, BLUE_PIN);
#ifdef ARCHE_MASTER
Metro timer = Metro(INTERVAL_PONG);
Metro pong = Metro(INC_LED_PONG);
bool pong_state = true;
uint8_t led_inc = 0;
#endif
void setup() {
pinMode(DETEC_PIN, INPUT);
#if DBG
Serial.begin(115200);
while (!Serial) { delay(10); }
#endif
DBG_PRINT("Arche : ");
DBG_PRINTLN(ARCHE_NO);
can.begin();
can.setBaudRate(500000);
can.setMaxMB(16);
can.enableFIFO();
can.enableFIFOInterrupt();
can.onReceive(canCallback);
can.mailboxStatus();
//music_init();
rgb_led.set(0, 0, 0);
#ifdef ARCHE_MASTER
timer.reset();
#endif
}
void loop() {
can.events();
rgb_led.run();
if (can.read(in_msg)) {
DBG_PRINTLN("CAN RX");
parseCAN(in_msg);
}
delay(20);
}
void canCallback(const CAN_message_t &msg) {
parseCAN(msg);
}
void canSend(uint8_t data) {
CAN_message_t send_msg;
send_msg.id = ARCHE_NO;
send_msg.id = 0x00;
send_msg.len = CAN_FRAME_LEN;
send_msg.buf[0] = START_CAN_FRAME;
send_msg.buf[1] = data;
send_msg.buf[2] = STOP_CAN_FRAME;
can.write(send_msg);
//can.setMB(MB8, TX, STD);
}
void parseCAN(CAN_message_t msg) {
DBG_PRINTF("CAN RX ID : %d | Len : %d\n", msg.id, msg.len);
DBG_PRINT("Data : ");
#if DBG
for (int i = 0; i < msg.len; i++) {
DBG_PRINT(msg.buf[i]);
}
#endif
DBG_PRINTLN();
#ifdef ARCHE_MASTER
if ((msg.id > 0x01) && (msg.id < 0x06) && (msg.len == CAN_FRAME_LEN)) {
if (msg.buf[0] == START_CAN_FRAME && msg.buf[2] == STOP_CAN_FRAME) {
if (msg.buf[1] == DETECT_CAN_FRAME) {
DBG_PRINTLN("DETECT");
timer.reset();
pong_state = false;
} else {
DBG_PRINTLN("Wrong CAN frame");
}
}
}
#else
if ((msg.id > 0x00) && (msg.id < 0x06) && (msg.len == CAN_FRAME_LEN)) {
if (msg.buf[0] == START_CAN_FRAME && msg.buf[2] == STOP_CAN_FRAME) {
if (msg.buf[1] == DETECT_CAN_FRAME) {
rgb_led.set(0, 0, 0);
} else if ((msg.buf[1] & 0xD0) == PONG_CAN_FRAME) {
#if ARCHE_NO == 2
if (msg.buf[1] == 0xD1) {
rgb_led.set(LED_COLOR);
} else if (msg.buf[1] == 0xD2) {
rgb_led.set(0, 0, 0);
}
#elif ARCHE_NO == 3
if (msg.buf[1] == 0xD2) {
rgb_led.set(LED_COLOR);
}
else if (msg.buf[1] == 0xD3) {
rgb_led.set(0,0,0);
}
#elif ARCHE_NO == 4
if (msg.buf[1] == 0xD3) {
rgb_led.set(LED_COLOR);
}
else if (msg.buf[1] == 0xD4) {
rgb_led.set(0,0,0);
}
#elif ARCHE_NO == 5
if (msg.buf[1] == 0xD4) {
rgb_led.set(LED_COLOR);
}
else if (msg.buf[1] == 0xD0) {
rgb_led.set(0,0,0);
}
#endif
} else {
DBG_PRINTLN("Wrong CAN frame");
}
}
}
#endif
}
FIFO Enabled
Mailboxes:
MB8 code: TX_INACTIVE
MB9 code: TX_INACTIVE
MB10 code: TX_INACTIVE
MB11 code: TX_INACTIVE
MB12 code: TX_INACTIVE
MB13 code: TX_INACTIVE
MB14 code: TX_INACTIVE
MB15 code: TX_INACTIVE
#include <FlexCAN_T4.h>
#include <EasyNextionLibrary.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
#define OUTPUT_TERMINAL true // set to false not to output to serial terminal and before production compile
#define OUTPUT_TERMINAL_SERIAL if(OUTPUT_TERMINAL)Serial
CAN_message_t msg;
void canSniff(const CAN_message_t &msg) {
#if OUTPUT_TERMINAL == true
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++ ) // print the data
{
Serial.print(" ");
if (msg.buf[i] < 16) // Pad with 0 for HEX values less than 0x10
{
Serial.print("0");
}
Serial.print(msg.buf[i], HEX);
}
if (msg.len == 6) // Padding out with 00 for null byte fields so that debug output table looks nice
{
Serial.print(" ");
Serial.print("00");
}
Serial.print(" ");
#endif
unsigned int sensorID = (msg.buf[3] << 8) | msg.buf[4];
switch(sensorID){
case 0x5822: // HEX 5822 - Oil Temperature in C
{
unsigned char OilTemperature = msg.buf[5];
OilTemperature = OilTemperature - 60;
#if OUTPUT_TERMINAL == true
Serial.print("OilTemperature:\t\t");
Serial.print(OilTemperature);
#endif
}
break;
case 0x4300: // HEX 4300 - Coolant Temperature in C
{
unsigned char CoolantTemperature = msg.buf[5];
CoolantTemperature = CoolantTemperature * 0.75 - 48;
#if OUTPUT_TERMINAL == true
Serial.print("CoolantTemperature:\t");
Serial.print(CoolantTemperature);
#endif
}
break;
}
Serial.print("\tTS: "); Serial.print(millis());
Serial.print("\tTS: "); Serial.println(msg.timestamp);
}
void setup(void) {
#if OUTPUT_TERMINAL == true
Serial.begin(250000); delay(6000); // Delay to allow PlatformIO console monitor time to start. Otherwise miss the initial maiboxstatus
#endif
can1.begin();
can1.setBaudRate(500000);
can1.setMaxMB(16);
//can1.setMaxMB(9);
//can1.setMaxMB(32);
can1.enableFIFO();
can1.enableFIFOInterrupt();
can1.setFIFOFilter(REJECT_ALL);
can1.setFIFOFilter(0, 0x612, STD);
can1.onReceive(canSniff);
#if OUTPUT_TERMINAL == true
can1.mailboxStatus();
#endif
}
void rOilTemperature(){
//unsigned char stmp[8] = {0x12,0x03,0x22,0x58,0x22,0x00,0x00,0x00};
msg.buf[0] = 0x12; msg.buf[1] = 0x03; msg.buf[2] = 0x22; msg.buf[3] = 0x58; msg.buf[4] = 0x22; msg.buf[5] = 0x00; msg.buf[6] = 0x00; msg.buf[7] = 0x00;
can1.write(msg);
}
void rCoolantTemperature(){
//unsigned char stmp[8] = {0x12,0x03,0x22,0x43,0x00,0x00,0x00,0x00};
msg.buf[0] = 0x12; msg.buf[1] = 0x03; msg.buf[2] = 0x22; msg.buf[3] = 0x43; msg.buf[4] = 0x00; msg.buf[5] = 0x00; msg.buf[6] = 0x00; msg.buf[7] = 0x00;
can1.write(msg);
}
void loop() {
can1.events();
//msg.seq = 1;
msg.id = 0x6F1; msg.len = 8;
rCoolantTemperature();
rOilTemperature();
}
FIFO Enabled --> Interrupt Enabled
FIFO Filters in use: 8
Remaining Mailboxes: 8
MB8 code: TX_INACTIVE
MB9 code: TX_INACTIVE
MB10 code: TX_INACTIVE
MB11 code: TX_INACTIVE
MB12 code: TX_INACTIVE
MB13 code: TX_INACTIVE
MB14 code: TX_INACTIVE
MB15 code: TX_INACTIVE
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 45635 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16267
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 60608 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 16297
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 9926 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16327
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 24994 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16357
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 39848 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 16387
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 54940 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16417
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 4710 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16448
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 19326 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16477
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 34656 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16508
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 49272 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16537
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 64578 ID: 612 Buffer: F1 04 62 43 00 65 00 CoolantTemperature: 27 TS: 16568
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 13777 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 16597
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 28988 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 16628
FIFO Enabled --> Interrupt Enabled
FIFO Filters in use: 8
Remaining Mailboxes: 1
MB8 code: TX_INACTIVE
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 8309
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 43 00 66 00 CoolantTemperature: 28 TS: 8332
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 43 00 66 00 CoolantTemperature: 28 TS: 8361
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 43 00 66 00 CoolantTemperature: 28 TS: 8391
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 8421
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 8452
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 43 00 66 00 CoolantTemperature: 28 TS: 8482
MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer: F1 04 62 58 22 58 00 OilTemperature: 28 TS: 8511
you shouldn't need to strip mailboxes down to one using msg.seq = 1, it will only output to the absolute first mailbox. also you don't need events() in loop if you want direct firing interrupts, but that's optional. As far as I see your loop is flooding the bus and the ECU is responding whatever is available in memory of the burst. At this point since you're transmitting too fast to the ECU, the ECU will block some requests until it finishes with the response, which will flow back to you in a seemingly unordered state, but in reality it's the order the ECU prepared the response during a request while invalidating the excessive frames.usually you need at least a 10ms gap between ECU requests, I don't see any delays in your loop(), add a delay(15) somewhere in your loop and try it again
once it works, replace delay with millis() or elapsedmillis.
yes the 30ms is consistant with the gateway's responses, but your transmission speeds are too fast for the ECU/gateway to handle when you are constantly sending them in a forever loop, if it responds at 30, send at 45ms intervals for example, in some cases ECU responses may come quicker if it's not being flooded or talked to in awhile
void loop() {
static uint32_t coolant_timer = millis();
if ( millis() - coolant_timer >= 30 ) {
rCoolantTemperature():
coolant_timer = millis();
}
}
void loop() {
static uint32_t coolant_timer = millis();
static int send_switch = 0;
if ( millis() - coolant_timer >= 30 ) {
if ( send_switch > 1 ) send_switch = 0;
if ( send_switch == 0 ) rCoolantTemperature():
if ( send_switch == 1 ) rOilTemperature();
send_switch++;
coolant_timer = millis();
}
}