#include <FlexCAN_T4.h>
#include <isotp.h>
isotp<RX_BANKS_16, 512> tp; /* 16 slots for multi-ID support, at 512bytes buffer each payload rebuild */
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
void myCallback(const ISOTP_data &config, const uint8_t *buf) {
Serial.print("ID: ");
Serial.print(config.id, HEX);
Serial.print("\tLEN: ");
Serial.print(config.len);
Serial.print("\tFINAL ARRAY: ");
for ( int i = 0; i < config.len; i++ ) {
Serial.print(buf[i], HEX);
Serial.print(" ");
} Serial.println();
}
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(" BUS: "); Serial.print(msg.bus);
Serial.print(" Buffer: ");
for ( uint8_t i = 0; i < msg.len; i++ ) {
Serial.print(msg.buf[i], HEX); Serial.print(" ");
} Serial.println();
}
void setup() {
Serial.begin(115200); delay(400);
can2.begin();
can2.setClock(CLK_60MHz);
can2.setBaudRate(500000);
can2.setMaxMB(16);
can2.enableFIFO();
can2.enableFIFOInterrupt();
can2.onReceive(canSniff);
tp.begin();
tp.setWriteBus(&can2); /* we write to this bus */
tp.onReceive(myCallback); /* set callback */
}
void loop() {
static uint32_t sendTimer = millis();
if ( millis() - sendTimer > 1000 ) {
uint8_t buf[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
const char b[] = "01413AAAAABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
CAN_message_t msg;
ISOTP_data config;
config.id = 0x7E0;
config.flags.extended = 0;
config.blockSize = 0;
config.separation_time = 20;
msg.id = 0x7E0;
msg.flags.extended = 0;
msg.len = 8;
msg.buf[0] = 2;
msg.buf[1] = 9;
msg.buf[2] = 2;
can2.write(msg);
tp.sendFlowControl(config);
sendTimer = millis();
//ISOTP_data config;
//config.id = 0x666;
//config.flags.extended = 0; /* standard frame */
//config.separation_time = 10; /* time between back-to-back frames in millisec */
//tp.write(config, buf, sizeof(buf));
//tp.write(config, b, sizeof(b));
//sendTimer = millis();
}
}
ID: 666 LEN: 121 FINAL ARRAY: 49 2 1 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 1 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 3 3 2 4 4 F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F 5
ID: 555 LEN: 121 FINAL ARRAY: 7 3 2 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 1 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 3 3 2 4 4 F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F 5
ID: 133 LEN: 16 FINAL ARRAY: 9 9 9 1 2 3 4 5 6 7 8 9 0 0 0 3
can0 7DF [8] 02 09 02 00 00 00 00 00
can0 7E8 [8] 10 14 49 02 01 33 46 41
can0 7E0 [8] 30 00 00 00 00 00 00 00
can0 7E8 [8] 21 44 50 34 46 4A 32 42
can0 7E8 [8] 22 4D 31 31 33 39 31 33
CAN_message_t msg;
msg.id = 0x7DF;
msg.len = 8;
msg.buf[0] = 0x02;
msg.buf[1] = 0x09;
msg.buf[2] = 0x02;
Can0.write(msg);
if ( msg.id == 0x7E8 && msg.buf[2] == 0x49 && msg.buf[3] == 0x02 ) {
CAN_message_t flow;
flow.id = 0x7E0;
flow.len = 8;
flow.buf[0] = 0x30;
flow.buf[2] = 0xF;
Can0.write(flow);
}
Add Tony's example to your global rx callback (canSniff)mm, what do u mean? Add this if to loop()?
I m try it, but looks no any 30 00 msg
Can0.begin();
Can0.setClock(CLK_60MHz);
Can0.setBaudRate(500000);
Can0.setMBFilter(REJECT_ALL);
Can0.setMBFilter(MB1, 0x7E8);
Can0.setMBFilter(MB2, 0x7E8);
Can0.enableMBInterrupt(MB1);
Can0.enableMBInterrupt(MB2);
Can0.onReceive(canSniff);
yes there is no software load when the hardware filters out messages. with 6 message deep FIFO your messages will be ordered. Even without filters, you should be fine without loosing messages if you have fifo/mb interrupt enabled and events() commented out (removed) from the loop().
Can0.begin();
Can0.setClock(CLK_60MHz);
Can0.setBaudRate(500000);
Can0.setMaxMB(16);
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.setFIFOFilter(REJECT_ALL);
Can0.setFIFOFilter(0, 0x7E8, STD);
Can0.onReceive(FIFO, canSniff);
#ifndef OBD2Reader_h
#define OBD2Reader_h
// standard libraries
// project specific libraries
#include "Globals.h"
#include "Utilities.h"
class OBD2reader
{//BEGIN class OBD2reader
private:
CAN_message_t rx_msg;
CAN_message_t tx_msg;
void dump_buffers(int status, CAN_message_t tx_msg, CAN_message_t rx_msg)
{//BEGIN dump_buffers()
char outbuf[128];
Serial.println();
Serial.println("*************************************************************************************************************");
sprintf(outbuf, "status = %i \n", status);
Serial.println(outbuf);
Serial.println("Request Response");
sprintf(outbuf, " Module : %04X ", (unsigned int)tx_msg.id); Serial.print(outbuf);
sprintf(outbuf, " %04X ", (unsigned int)rx_msg.id); Serial.println(outbuf);
sprintf(outbuf, " Data Len : %02d ", tx_msg.buf[0]); Serial.print(outbuf);
sprintf(outbuf, " %02d ", rx_msg.buf[0]); Serial.println(outbuf);
sprintf(outbuf, " Service : %02X ", tx_msg.buf[1]); Serial.print(outbuf);
sprintf(outbuf, " %02X ", rx_msg.buf[1]); Serial.println(outbuf);
sprintf(outbuf, " PID : %02X %02X ", tx_msg.buf[2], tx_msg.buf[3]); Serial.print(outbuf);
sprintf(outbuf, " %02X %02X ", rx_msg.buf[2], rx_msg.buf[3]); Serial.println(outbuf);
sprintf(outbuf, " Data : %02X, %02X", tx_msg.buf[4], tx_msg.buf[5]); Serial.print(outbuf);
sprintf(outbuf, " %02X, %02X ", rx_msg.buf[4], rx_msg.buf[5]); Serial.println(outbuf);
}//END dump_buffers()
public:
CAN_message_t init_tx_buffer
( bool extended_code,
uint16_t tx_module,
uint8_t service,
uint8_t pid_byte_1,
uint8_t pid_byte_2
)
{//BEGIN init_tx_buffer()
CAN_message_t msg;
msg.id = tx_module;
msg.flags.extended = 0;
msg.flags.remote = 0;
msg.len = 8;
if (!extended_code)
{//BEGIN standard PID
msg.buf[0] = 0x02;
msg.buf[1] = service;
msg.buf[2] = pid_byte_1;
msg.buf[3] = 0x00;
}//END standard PID
else
{//BEGIN extended PID
msg.buf[0] = 0x03;
msg.buf[1] = service;
msg.buf[2] = pid_byte_1;
msg.buf[3] = pid_byte_2;
}//END extended PID
msg.buf[4] = 0;
msg.buf[5] = 0;
msg.buf[6] = 0;
msg.buf[7] = 0;
return msg;
}//END init_tx_buffer()
//
// Function read_canbus
// poll a pid, returning whatever comes back; no error checking except timeout
//
int read_canbus
( CAN_message_t tx_msg,
CAN_message_t &rx_msg
)
{//BEGIN read_canbus()
Can0.write(tx_msg);
elapsedMillis waiting;
while (waiting < 1000)
{//BEGIN look for response messages for up to a second
if (Can0.read(rx_msg))
{//BEGIN process the inbound message
return 1;
}//END process the inbound message
}//END look for response messages for up to a second
return 555;
}//END read_canbus()
//
// Function poll_canbus()
//
int poll_canbus
( CAN_message_t tx_msg,
uint16_t rx_module,
CAN_message_t &rx_msg
)
{//BEGIN poll_canbus()
int status = 555; // process timed out with no messages received
Can0.write(tx_msg);
elapsedMillis waiting;
while (waiting < 1000)
{//BEGIN look for response messages for up to a second
if (Can0.read(rx_msg))
{//BEGIN process the inbound message
if (rx_msg.id == rx_module)
{//BEGIN modules are correct, process the PID
if (((tx_msg.buf[2] = 0x02) && (rx_msg.buf[2] = tx_msg.buf[2])) ||
((tx_msg.buf[2] = 0x03) && (rx_msg.buf[2] = tx_msg.buf[2]) && (rx_msg.buf[3] = tx_msg.buf[3])))
return 1;
else status = 777; // PID mismatch
}//END modules are correct, process the PID
else status = 888; // module mismatch
}//END process the inbound message
}//END look for response messages for up to a second
return status;
}//END poll_canbus()
//
// function_init()
//
void init()
{//BEGIN init()
Can0.begin();
Can0.setBaudRate(500000);
}//END init()
//
// function read()
//
int read
( int gid, // gauge ID
uint8_t &A, // 1st byte returned data value
uint8_t &B // 2nd byte returned data value
)
{//BEGIN read()
CAN_message_t tx_msg = init_tx_buffer(pid_table[gid].data_bytes == 3, pid_table[gid].send_to, pid_table[gid].service, pid_table[gid].pid1, pid_table[gid].pid2);
CAN_message_t rx_msg;
int status;
status = poll_canbus(tx_msg, pid_table[gid].receive_from, rx_msg);
// dump_buffers(status, tx_msg, rx_msg);
if (status)
{//BEGIN process the response
if (tx_msg.buf[0] == 2) { A = rx_msg.buf[3]; B = rx_msg.buf[4]; } // 1 byte PID
else { A = rx_msg.buf[4]; B = rx_msg.buf[5]; } // 2 byte PID
}//END process the respose
return status;
}//END read()
};//END class OBD2_reader
#endif
#include "ILI9341_t3n.h"
const int LCD_RST = 8; // reset on pin 8
const int LCD_DC = 9; // data on pin 9
const int LCD_CS = 10; // chip select on pin 10
const int LCD_SD_CS = 1; // SD card reader chip select pin 1
ILI9341_t3n lcd = ILI9341_t3n(LCD_CS, LCD_DC, LCD_RST);
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> Can0;
void dump_msg (const CAN_message_t &msg)
{//BEGIN dump_msg()
char outbuf[128];
sprintf(outbuf, "%8X | %4X | %4X | %1d | %1d | %1d | %1d | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %1d",
(unsigned int)msg.id, msg.timestamp, msg.idhit, msg.flags.extended, msg.flags.remote,
msg.flags.overrun, msg.flags.reserved, msg.len, msg.buf[0], msg.buf[1],
msg.buf[2], msg.buf[3], msg.buf[4], msg.buf[5], msg.buf[6],
msg.buf[7], msg.mb, msg.bus, msg.seq);
Serial.println(outbuf);
lcd.println(outbuf);
}//END dump_msg()
void setup(void)
{//BEGIN setup()
Serial.begin(115200);
delay(400);
Serial.println("setup() starting");
lcd.begin();
lcd.setRotation(3);
lcd.fillScreen(0x0000);
lcd.setFont();
lcd.setCursor(30, 10);
lcd.println("CANbus dump");
Can0.begin();
Can0.setBaudRate(500000);
Can0.setMaxMB(16);
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.onReceive(dump_msg);
Can0.mailboxStatus();
Can0.events();
Serial.println("setup() complete");
}//END setup
CAN_message_t msg;
void loop()
{//BEGIN loop()
msg.id = random(0x1,0x7FE);
for ( uint8_t i = 0; i < 8; i++ ) msg.buf[i] = 90 + i;
Can0.write(msg);
delay(200);
}//END loop()
#include "ILI9341_t3n.h"
const int LCD_RST = 8; // reset on pin 8
const int LCD_DC = 9; // data on pin 9
const int LCD_CS = 10; // chip select on pin 10
const int LCD_SD_CS = 1; // SD card reader chip select pin 1
ILI9341_t3n lcd = ILI9341_t3n(LCD_CS, LCD_DC, LCD_RST);
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> Can0;
CAN_message_t msg;
void dump_msg (const CAN_message_t &msg)
{//BEGIN dump_msg()
char outbuf[128];
sprintf(outbuf, "%8X | %4X | %4X | %1d | %1d | %1d | %1d | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %1d",
(unsigned int)msg.id, msg.timestamp, msg.idhit, msg.flags.extended, msg.flags.remote,
msg.flags.overrun, msg.flags.reserved, msg.len, msg.buf[0], msg.buf[1],
msg.buf[2], msg.buf[3], msg.buf[4], msg.buf[5], msg.buf[6],
msg.buf[7], msg.mb, msg.bus, msg.seq);
Serial.println(outbuf);
lcd.println(outbuf);
}//END dump_msg()
void setup(void)
{//BEGIN setup()
Serial.begin(115200);
delay(400);
Serial.println("setup() starting");
lcd.begin();
lcd.setRotation(3);
lcd.fillScreen(0x0000);
lcd.setFont();
lcd.setCursor(30, 10);
lcd.println("CANbus dump");
Can0.begin();
Can0.setBaudRate(500000);
Can0.setMaxMB(16);
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.onReceive(dump_msg);
Can0.mailboxStatus();
Serial.println("setup() complete");
}//END setup
void loop()
{//BEGIN loop()
msg.id = 0x07DF; // standard broadcast address
msg.buf[0] = 0x02; // 2 data bytes sent
msg.buf[1] = 0x01; // standard service 01 request
msg.buf[2] = 0x05; // engine coolant temp
Can0.write(msg);
delay(200);
}//END loop()
#include "ILI9341_t3n.h"
const int LCD_RST = 8; // reset on pin 8
const int LCD_DC = 9; // data on pin 9
const int LCD_CS = 10; // chip select on pin 10
const int LCD_SD_CS = 1; // SD card reader chip select pin 1
ILI9341_t3n lcd = ILI9341_t3n(LCD_CS, LCD_DC, LCD_RST);
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> Can0;
CAN_message_t msg;
CAN_message_t rx_msg;
void dump_msg (const CAN_message_t &msg)
{//BEGIN dump_msg()
char outbuf[128];
sprintf(outbuf, "%8X | %4X | %4X | %1d | %1d | %1d | %1d | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %02X | %1d",
(unsigned int)msg.id, msg.timestamp, msg.idhit, msg.flags.extended, msg.flags.remote,
msg.flags.overrun, msg.flags.reserved, msg.len, msg.buf[0], msg.buf[1],
msg.buf[2], msg.buf[3], msg.buf[4], msg.buf[5], msg.buf[6],
msg.buf[7], msg.mb, msg.bus, msg.seq);
Serial.println(outbuf);
lcd.println(outbuf);
}//END dump_msg()
void setup(void)
{//BEGIN setup()
Serial.begin(115200);
delay(400);
Serial.println("setup() starting");
lcd.begin();
lcd.setRotation(3);
lcd.fillScreen(0x0000);
lcd.setFont();
lcd.setCursor(30, 10);
lcd.println("CANbus dump");
Can0.begin();
Can0.setBaudRate(500000);
Serial.println("setup() complete");
}//END setup
void loop()
{//BEGIN loop()
msg.id = 0x07DF; // standard broadcast address
msg.buf[0] = 0x02; // 2 data bytes sent
msg.buf[1] = 0x01; // standard service 01 request
msg.buf[2] = 0x05; // engine coolant temp
Can0.write(msg); // send the request
elapsedMillis waiting;
while (waiting < 1000)
{//BEGIN wait up to a second for a response
while (Can0.read(rx_msg)) dump_msg(rx_msg); // dump all responses
}//END wait up to a second for a response
delay(200);
}//END loop()