FlexCAN_T4 - FlexCAN for Teensy 4

@tonton81, could you please give some info if possible
I m want to send big block to ecu, and not need use row numbers. I mean not need use 21 , 22 and etc
Code:
21 00 00 00 00 00 00 00
22 00 00 00 00 00 00 00

Also, this block is at hex/ But looks isotp can send some data if its dec

So my question is - Possible send it ?
 
isotp works on sequences, you can't change that unless you change protocol. sending hex or decimal will result in same value either way, makes no difference to the ecu or teensy or any other device

if your sending big blocks to ecu that doesn't use isotp, you need to find out what protocol your using to send
 
Tonton81,

Well, that was part of the problem. I figured I'd done something dumb. Thanks for your help.

I'm now able to get messages directly to the interrupt handler. But, I can only get responses to to correctly formed queries. Is there a way to request everything?

Regards,

Randy
 
everything should come in unless your behind a gateway on ford (never played with a ford) or using filters, which i see your not. what are you physically connected to, OBD port?
 
Since I have a couple of Teensy3.6, I tried the ISOTP plugin to Teensy3.6, too. ISOTP plugin works without any problem with a small CAN setting change.
 
For testing I'm using the OBD2 port in a 2017 Jeep Wrangler. The Ford F53-based motorhome is in a storage lot that I visit when progress warrants. I've got everything working nicely for the 01 service PIDs, but there are several service 22 PIDs that I would really like to see as well. In the pic below, the "555"s are timeout errors because it isn't actually plugged in, but all of those gauges work. The "selected gear" (shown as "P"), oil temp, and tranny temp don't because they're service 22 PIDs that I haven't been able to get to so far.

IMG_0227 (1).jpg

I've seen references to a "gateway" on Fords, but haven't been able to find any details yet. I've not seen reference to one for Jeeps, but I haven't looked as hard either. For the Ford (Mustang, not truck chassis), I saw one article that said the gateway is physically located between the OBD port and rest of the CAN bus. It can be bypassed by splicing into the bus wiring pretty much anywhere else. I'm not sure I want to do that though.

I think what I'll try first is an exhaustive enumeration of all possible ECU ID/PID combinations for the 22 service and see what I get. I read somewhere that the service 22 PIDs are blocked by the gateway, but I also know that ELM 327 based apps can get them. What I don't know is if the ELMs get them from the CANbus or from one of the other busses available on the OBD2 port. I may have to buy an ELM device and see if I can make that work.

Thanks as always for your help.

Regards,

Randy
 
Since I have a couple of Teensy3.6, I tried the ISOTP plugin to Teensy3.6, too. ISOTP plugin works without any problem with a small CAN setting change.

yeah, it should work on all 3.x/4.x, as the isotp plugin is tied to an independant background frame callback of FlexCAN_T4, and isotp manages the frames data it sees :)
 
yeah, it should work on all 3.x/4.x, as the isotp plugin is tied to an independant background frame callback of FlexCAN_T4, and isotp manages the frames data it sees :)

So far, if ECU responds, my program can pick the response message using ISOTP callback properly. But at the moment I have difficulty to handle, for example disconnect the CAN line or, using wrong CANID (request or receive), when Teensy can not receive the response message within proper timing, such as P2CAN parameter (time out parameter:50ms).
At the moment, in such a case, the same value is displayed forever until new valid message is received.
 
if the connection is broken or a time difference between frame sequence causes them to be out of order, isotp aborts the rebuild until a new isotp frame is issued. the callback fires only once after a successful rebuild. if your value is the same i assume you are storing a variable/array with the isotp response? if so then yes depending on how you manage that code when there is no activity on the bus or a broken connection then it won't change. i usually use CAN frame data stored as a combo of bits (door states, 4 bits), and use the variable as a bool if any door is open.

you can always use a state machine variable to get notified if a variable is stale or updated, like i use a volatile millis() counter that is always updated when there is CAN frames rolling in. Now when i shut the car off that variable has 2 purposes. it serves as a timeout for CAN data and a state in the loop().


loop code:
Code:
if ( candata && ( millis() - can_data > 3000 ) ) {
  can_data = 0;
  Serial.println("CAN offline");
}

if ( can_data ) {
  // do whatever when bus is active
}

canSniff callback:
Code:
can_data = millis();
 
if the connection is broken or a time difference between frame sequence causes them to be out of order, isotp aborts the rebuild until a new isotp frame is issued. the callback fires only once after a successful rebuild. if your value is the same i assume you are storing a variable/array with the isotp response? if so then yes depending on how you manage that code when there is no activity on the bus or a broken connection then it won't change. i usually use CAN frame data stored as a combo of bits (door states, 4 bits), and use the variable as a bool if any door is open.

you can always use a state machine variable to get notified if a variable is stale or updated, like i use a volatile millis() counter that is always updated when there is CAN frames rolling in. Now when i shut the car off that variable has 2 purposes. it serves as a timeout for CAN data and a state in the loop().


loop code:
Code:
if ( candata && ( millis() - can_data > 3000 ) ) {
  can_data = 0;
  Serial.println("CAN offline");
}

if ( can_data ) {
  // do whatever when bus is active
}

canSniff callback:
Code:
can_data = millis();


Thank you, tonton81! Yes, I am storing the callback value to a array in order to convert CAN values to other parameters for display.
I am not good at using millis() yet, so your example is very helpful.
 
Hello, I am having some trouble getting the CAN interface to spit out data that has been on the bus. I am using a Teensy 4.0 and CAN1. This is my code:

Code:
#include <Arduino.h>
#include <FlexCAN_t4.h>
#define CAN_STBY 6

FlexCAN_T4<CAN1,RX_SIZE_256,TX_SIZE_16> canbus;

void printData(const CAN_message_t &msg) {
  Serial.printf("%lu, %x, %hx, %hx, %hx, %hx, %hx, %hx, %hx, %hx, %u\n",(uint32_t)millis(),msg.id,
    msg.buf[0],
    msg.buf[1],
    msg.buf[2],
    msg.buf[3],
    msg.buf[4],  
    msg.buf[5],
    msg.buf[6],
    msg.buf[7],
    psn_sensor_raw); // This is an ADC reading from another part of the code
}

void initCan() {
  pinMode(CAN_STBY, OUTPUT);
  digitalWrite(CAN_STBY,LOW); // STBY Low enables CAN

  canbus.begin();
  canbus.setClock(CLK_24MHz);
  canbus.setBaudRate(500000); // 500000 bits per second
  // canbus.setMBFilter(ACCEPT_ALL);
  canbus.setMaxMB(8);
  canbus.setMB(MB4,RX,EXT);
  canbus.enableMBInterrupts();
  canbus.onReceive(printData); // set message callback
  canbus.mailboxStatus();
}

void setup() {
  // put your setup code here, to run once:
  pinMode(PSN_SENSOR,INPUT);

  Serial.begin(BAUDRATE_USB); // Serial Initialization
  while(!Serial && millis() < 10000); // Wait for up to 5 seconds for serial monitor
  // pinMode(13,OUTPUT);
  initCan();

  adc_setup(); // This just configures an ADC for an interrupt-based read at 5 kHz
}

void loop() {
  delay(1);
}
This code only prints the mailboxStatus() but nothing else.

As far as I can tell, my CAN transceiver is pushing data to the CANRX pin (Pin 13). The device on the bus is a Bosch steering sensor that is at 500k baud with an extended CANID. I have verified Pin 13 is not damaged by toggling a square wave on it.
 
if you don't use events() in the loop() on the version in teensyduino, nothing will receive, either put events() in the loop() or update to latest commit on github
 
if you don't use events() in the loop() on the version in teensyduino, nothing will receive, either put events() in the loop() or update to latest commit on github

Thank you for the reply. I’m currently running the latest commit of the library and have tried with events() in the loop as well as, separately, in an interrupt that runs every 5ms, still no dice. Calling mailboxStatus() in the main loop reveals none of the RX mailboxes ever receive a message.
 
try transmitting in the loop and keep watching mailboxStatus(), if the TX mailboxes are filling up and not clearing, it means you have a connection issue, and is not the software.

You should be using pins 22 and 23 for CAN1.
 
try transmitting in the loop and keep watching mailboxStatus(), if the TX mailboxes are filling up and not clearing, it means you have a connection issue, and is not the software.

You should be using pins 22 and 23 for CAN1.

Thank you. I got sidetracked using Pin 11 and 13 (They have CAN functionality according to the datasheet, but I guess it needs a different configuration to use). Works great now.
 
Hi,

I'm working with a Teensy 4.0 and trying to communicate with a device that has a TCAN334 (I think) chip. I ran into an issue where the device isn't transmitting any data to the bus, or what appears to be very slow CAN messages. I think I need to send some sort of wake request on the bus (WUP, ISO11898-5, something like that). Is there any way to do that with this library? Does what I'm saying make any sense, even?
 
yes you can wake up devices on the bus. you need to let it goto sleep usually and start logging when you wake it up, you'll see the first frame needed that bursts onto the bus. Thats how I wake up the body controller on honda when necessary
 
Hi tonton81,

I'm working with Teensy 4.0 and FlexCan for the first time and found CAN 2.0 working very well. But I've some problems with CAN_FD I hope you can clarify: my CAN_FD environment is 500000/2000000 with BRS. Is that configuration implemented in the timings?
Because a Trace Tool with a Peak Interface always tells me about stuff Errors and ESI issues and doesn't show the transmitted messages.... Another question: I have to talk with all kinds of ECU without having the opportunity to switch the CAN Interface. So I want to configure CAN3 as CAN_FD but also want to send and receive 2.0 Messages without changing configuration (using Seeed and RPi4 this works, so it should be possible somehow)
Looking forward to your suggestions
 
for FD you need to use setClock(CLK_60MHz ) (or other clock) if needed to adjust the controller clock as the timings are different for many of it's bitrates. FD mode supports compatible CAN2.0B mode, receptions are automatic in both modes, however for transmitting a CAN2.0B frame the msg.brs (baud rate switching) AND the msg.edl (extended data length) flags must be set to 0.

CANFD has been tested up to 8Mbps and timings are slightly different at other clock speeds. Default controller clock is 24MHz. There are also multiple timings per clock for CANFD mode, should you decide to try them out, there is a advanced listing feature that gives you a selection of timings per clock.
 
Hello,

What would be the best the best way to verify if there are nodes on the BUS? This would be to detect if a cable was disconnected or if the other node is disconnected.

Thank you
 
Hy,

I'm trying to test out my Teensy canbus board with SN65HVD230 canbus transievers and a T4.1. I have 3 transievers, one for each output, but i can't seem to get the T4.1 sending messages. At first i tried just sending messages on one T4.1 and recieving it on the same one, but couldn't get it to work. So i made a schetch and placed it on 2 seperate T4.1's with one recieving and one sending. Still, i'm not able to get the T4.1 sending messages. i hooked up my osciloscope, and noticed the CTX pin is not sending anyting, even when changing canbus. However, the LED is flashing correctly, but i am never getting a "can2 recieved" message in my terminal.

Code:
#include <FlexCAN_T4.h>

#define Sender

FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> can2;
CAN_message_t msg;

#define en1 6
#define led 13

long unsigned nextmillis;

bool state = false;

void setup(void) {
  Serial.begin(9600);
  Serial.println("boot");
  can2.begin();
  can2.setBaudRate(250000);
  
  Serial.println("Canbus booted");

    //if using enable pins on a transceiver they need to be set on
  pinMode(en1, OUTPUT);
  pinMode(led, OUTPUT);

  digitalWrite(en1, LOW);

  msg.id = 0x100;
  msg.len = 8;
  msg.buf[0] = 10;
  msg.buf[1] = 20;
  msg.buf[2] = 0;
  msg.buf[3] = 100;
  msg.buf[4] = 128;
  msg.buf[5] = 64;
  msg.buf[6] = 32;
  msg.buf[7] = 16;
#ifdef Sender  
  Serial.println("beign sending");
 #endif
}

void loop() {
  #ifdef Sender
  Serial.println("Can2 Send");
  can2.write(msg);
  delay(100);
  state = !state;
  digitalWrite(led, state);
  #else
  if ( can2.read(msg) ) {
    Serial.println("Can2 recieved");
  }
  if(millis() > nextmillis)
  {
    Serial.println("Biep");
    nextmillis = millis()+500;
    state = !state;
    digitalWrite(led, state);
  }
  #endif
}

my schematic:
can.PNG
 
what does it show when you ask for can2.mailboxStatus()?

If the transmit mailboxes are full, it means your transceiver or bus is not wired or terminated properly.
second, you are using CAN3 for can2 object, which is fine, but make sure your using CAN3 pins 30 + 31 for the transceiver
 
Sender:
Code:
FIFO Disabled
	Mailboxes:
		MB0 code: RX_EMPTY	(Standard Frame)
		MB1 code: RX_EMPTY	(Standard Frame)
		MB2 code: RX_EMPTY	(Standard Frame)
		MB3 code: RX_EMPTY	(Standard Frame)
		MB4 code: RX_EMPTY	(Extended Frame)
		MB5 code: RX_EMPTY	(Extended Frame)
		MB6 code: RX_EMPTY	(Extended Frame)
		MB7 code: RX_EMPTY	(Extended Frame)
		MB8 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
		MB9 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
		MB10 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
		MB11 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
		MB12 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
		MB13 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
		MB14 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
		MB15 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x100)(Payload: A 14 0 64 80 40 20 10)
Reciever:
Code:
FIFO Disabled
	Mailboxes:
		MB0 code: RX_EMPTY	(Standard Frame)
		MB1 code: RX_EMPTY	(Standard Frame)
		MB2 code: RX_EMPTY	(Standard Frame)
		MB3 code: RX_EMPTY	(Standard Frame)
		MB4 code: RX_EMPTY	(Extended Frame)
		MB5 code: RX_EMPTY	(Extended Frame)
		MB6 code: RX_EMPTY	(Extended Frame)
		MB7 code: RX_EMPTY	(Extended Frame)
		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

//weirdly, now suddenly i actually get canmessages send on the bus when looking at my osciloscope. However, i'm still not recieving
i actually increased the delay, which made it possible to send messages. however, still not recieving anything :/

the transievers are correctly hooked to the T4.1:
CRX1: 23
CTX1: 22

CRX2: 0
CTX2: 1

CRX3:30
CTX3: 31
 
Last edited:
Back
Top