yes that will work, you could also just send it 10ms after the request
#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> Can1;
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) {
uint8_t flowControl[] = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
if (msg.buf[0] == 0x10){
ISOTP_data configFlowCont;
configFlowCont.id = 0x17FC0076;
configFlowCont.flags.extended = 1; /* standard frame */
configFlowCont.separation_time = 0; /* time between back-to-back frames in millisec */
tp.write(configFlowCont, flowControl, sizeof(flowControl));
}
}
void setup() {
Serial.begin(115200); delay(400);
Can1.begin();
Can1.setClock(CLK_60MHz);
Can1.setBaudRate(500000);
Can1.setMaxMB(16);
Can1.enableFIFO();
Can1.enableFIFOInterrupt();
Can1.onReceive(canSniff);
tp.begin();
tp.setWriteBus(&Can1); /* we write to this bus */
tp.onReceive(myCallback); /* set callback */
}
void loop() {
static uint32_t sendTimer = millis();
if ( millis() - sendTimer > 1000 ) {
CAN_message_t msg;
uint8_t buf[] = {0x07, 0x22, 0xF4, 0x33, 0xF4, 0x0F, 0xF4, 0x3C};
ISOTP_data config;
config.id = 0x17FC0076;
config.flags.extended = 1; /* standard frame */
config.separation_time = 0; /* time between back-to-back frames in millisec */
tp.write(config, buf, sizeof(buf));
//memcpy(msg.buf, buf, sizeof(msg.buf)); // Copy the data array into the message buffer
//msg.len = 8;
//msg.flags.extended = 1; // 29 bit header
//msg.id = 0x17FC0076; // request header for OBD
//Can1.write(msg);
sendTimer = millis();
}
}
0x10, 0x08, 0x07, 0x22, 0xF4, 0x33, 0xF4
0x21, 0xF4, 0x3C, 0x00, 0xF4, 0x33, 0xF4
0x07, 0x22, 0xF4, 0x33, 0xF4, 0x0F, 0xF4, 0x3C
yes send both as normal frames, the isotp is there just to assemble messages in stream
#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> Can1;
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) {
uint8_t flowControl[] = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
if (msg.buf[0] == 0x10){
memcpy(msg.buf, flowControl, sizeof(msg.buf));
msg.len = 8;
msg.flags.extended = 1;
msg.id = 0x17FC0076;
Can1.write(msg);
}
}
void setup() {
Serial.begin(115200); delay(400);
Can1.begin();
Can1.setClock(CLK_60MHz);
Can1.setBaudRate(500000);
Can1.setMaxMB(16);
Can1.enableFIFO();
Can1.enableFIFOInterrupt();
Can1.onReceive(canSniff);
tp.begin();
tp.setWriteBus(&Can1); /* we write to this bus */
tp.onReceive(myCallback); /* set callback */
}
void loop() {
static uint32_t sendTimer = millis();
if ( millis() - sendTimer > 1000 ) {
CAN_message_t msg;
uint8_t buf[] = {0x07, 0x22, 0xF4, 0x33, 0xF4, 0x0F, 0xF4, 0x3C };
memcpy(msg.buf, buf, sizeof(msg.buf));
msg.len = 8;
msg.flags.extended = 1;
msg.id = 0x17FC0076;
Can1.write(msg);
sendTimer = millis();
}
}
void AK60_init()
{
can1.begin();
can1.setBaudRate(1000000);
}
void run()
{
//buffer is a byte array containing the data to send
send_std_can_message(buffer, Position_Velocity);
can1.mailboxStatus();
}
void send_std_can_message(byte buff[], Mode mode = None)
{
CAN_message_t msg;
uint32_t id = TEENSY_CAN_ID;
bool extended = 0;
for (uint8_t i=0; i<8; i++){
msg.buf[i] = buff[i];
}
if (mode != None)
{
id = TEENSY_CAN_ID | (mode << 8);
extended = 1;
}
msg.flags.extended = extended;
msg.id = id;
msg.len = 8;
can1.write(msg);
}
if ( millis() - timeout > 200 ) {
send_std_can_message(buffer, Position_Velocity);
can1.mailboxStatus();
timeout = millis();
}
3V3: Tied to its Teensy's 3V3
GND: Tied to its Teensy's GND
RX: Tied to its Teensy's CRX1
TX: Tied to its Teensy's CTX1
CANH: Tied to the other transceiver's CANH
CANL: Tied to the other transceiver's CANL
I can include the code if necessary, but it is literally the example mentioned above, but with the ID swapped out to differentiate.
I half feel like I'm just missing something I should know, but otherwise I might just need to get some new transceivers. Any advice would be greatly appreciated.
Quick Edit:
Wanted to mention I've checked all wires for continuity, checked voltages at the transceivers, everything looks good there. I'm going to check for a short at the CANH / CANL resistor in a moment, as it is built into the chip I'm using but don't have my hands on my multimeter at the moment. I've also been able to verify setup execution by seeing the mailboxStatus() function execution output, as well as testing for the write() function execution from using Serial output, along with being able to see the transmitted messages on the teensy pin nodes.
The termination resistor is built in to the chip? What chip are you referring to? Maybe check the datasheet for the purpose of the 8th transceiver pin you didn't mention. It sometimes is a 'silent' logic pin that prevents the transceiver from ack'ing or sending.
Best to use an oscilloscope to view the CANL and CANH signal as it idle around 2.5v and the active state is around 3.5v for CANH and around 1.5 for CANL.