FlexCAN_T4 - FlexCAN for Teensy 4

I just tried again with a T3.2 modified version (CAN0) of the T4.1 code above, but there is nothing on the TX pin according to the logic analyser?

(sorry for posting multiple times. On Mobile, the Edit button leads to a Page that inadvertedly makes you delte the messaged when trying to update it)
 
Ok. Back at my desk and I found that now I get something on the output pin, but it does not look sensible? My logic analyzer (enclosed image) shows it as 17 bits low (17us long @ 1000000 baud) and then 25 bits high. After that, there is a series of 1 low (1us) and then 25 high bits (25us). This repeats 15 times and then there is a pause of 1.4 ms and the same sequence repeats. No data seems to be sent. I'm getting this both with and without the transceiver connected.

I'm trying to communicate with an Maxxon Epos4 CAN motor controller using a SN65HVD230 transceiver connected according to the attached Fritzing diagram. This should be quite easy, but I'm obviously missing something basic here?

This is the code I have on the T4.1:

Code:
#include <FlexCAN_T4.h>
#define DRIVER1_ADDRESS 0x601

FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can;
CAN_message_t msg;
int counter = 0;
void sendMessage();

void setup(void) {
  can.begin();
  can.setBaudRate(1000000);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, INPUT_PULLDOWN); // button on pin 2
}

void loop() {
  if( digitalRead(2) )
  {
    digitalWrite( LED_BUILTIN, HIGH );
    delay(200); // debounce
    sendMessage();
    digitalWrite( LED_BUILTIN, LOW );
  }
}

void sendMessage()
{
  uint16_t index = 0x6040;
  uint32_t data = 0x80;
  msg.id = DRIVER1_ADDRESS;
  msg.buf[0] = 0x2B;                 // Command specifier
  msg.buf[1] = (index >> 8) & 0xFF;  // Index bit 1
  msg.buf[2] = (index >> 0) & 0xFF;  // Index bit 2
  msg.buf[3] = 0x00;                 // Subindex
  msg.buf[4] = (data >> 24) & 0xFF; // Data bit 1
  msg.buf[5] = (data >> 16) & 0xFF; // Data bit 2
  msg.buf[6] = (data >> 8) & 0xFF;  // Data bit 3
  msg.buf[7] = (data >> 0) & 0xFF;  // Data bit 4
  can.write(msg);
}

CANnot_bb.jpgSkjermbilde 2020-12-10 224120.jpg
 
Sorry i am at work. periodically check mailboxStatus() to see if the transmit mailboxes all show full. if that is the case you either have a connection problem with the transceiver or termination not at the endpoint transceivers. another node must be on the bus to ACK the packet else the controller goes into bus-off state and sits there until data is available on the CAN bus so it wakes back up, the easiest way to see if its a connection issue is to check mailboxStatus(), and if the transmit mailboxes are all filling up and not sending, that means you entered bus off state.

check wiring
check termination
check baudrate
 
Oh my. I had swapped the CAN HI / CAN LO wires on the bus. The bus had a good resistance value of 60.4 ohm, but the voltage measured 0.017v rather than the much more sensible 1.49V. Sigh... I did indeed miss something basic.
I'm now successfully talking to the EPOS4 motor driver. Thanks for helping @tonton81

Skjermbilde 2020-12-11 115323.jpg
 
Hello,
excuse me for my English.
I'm stuck reading data from an engine management megasquirt with a uno and mcp29xx everything is ok.

With a teensy4 I have done a lot of reading tests I manage to get the id and the data is ok but does not update. if for example the tps is at 0 ok if I press on the accelerator it remains at 0 if I keep pressing and restart teensy4 there I have the new value but which also remains blocked.

See that I am receiving the data but blocked I think I am misusing your code. Please look at you.

Code:
#include <Arduino.h>
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can0;
static CAN_message_t msg;


//-------------------------------VARIABLE-----------------------------------------------
unsigned int rpm;
unsigned int temp;
unsigned int tps;
unsigned int kpa;


//----------------------------------------------------------------------------------
//---------------------------------SETUP--------------------------------------------
//----------------------------------------------------------------------------------

void setup() {
  

  Serial.begin(9600); delay(400);
  Can0.begin();
  Can0.setClock(CLK_60MHz);          // on and off no différence !
  Can0.setBaudRate(500000);          //, LISTEN_ONLY); on and off no différence !
  //Can0.setMaxMB(16);               //activate no différence
  //Can0.enableFIFO();               //activate no différence
  //Can0.enableFIFOInterrupt();      //activate no différence
  //Can0.onReceive(canSniff);        //activate no différence FIGED value
  //Can0.mailboxStatus();            // RX ----> MB6
  //Can0.enableMBInterrupts ();      //activate no différence
 
}

//---------------------------------FIN SETUP----------------------------------------


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(" Buffer: ");
  for ( uint8_t i = 0; i < msg.len; i++ ) {
//    Serial.print(msg.buf[i], HEX); Serial.print(" ");
  } //Serial.println();
  //Serial.print(" ID: "); Serial.print(msg.id);
    switch (msg.id) {
          case 1512: // hex= 0x5F0
           rpm = 256*msg.buf[2]+msg.buf[3];
           tps= (256*msg.buf[6]+ msg.buf[7])/10; 
           kpa  = ((256*msg.buf[0]+ msg.buf[1])/10);
           temp = ((256*msg.buf[4] + msg.buf[5])/10 -32) *5/9; //CLT
           break;
         }
}

//-----------------------------------------BOUCLE----------------------------------------------
void loop() {
//Can0.events();


Can0.read (msg); //read lance une nouvelle lecture
 //   switch (msg.id) {
   //       case 1512: // hex= 0x5F0
           rpm = 256*msg.buf[2]+msg.buf[3];
           tps= (256*msg.buf[6]+ msg.buf[7])/10; 
           kpa= ((256*msg.buf[0]+ msg.buf[1])/10);
           temp= ((256*msg.buf[4] + msg.buf[5])/10 -32) *5/9; //CLT
  //         break;
  //       }

    
Serial.print("tps: "); Serial.println(tps);  //Serial.print("temp: "); Serial.print(temp); Serial.print("kpa: "); Serial.println(kpa); 
//power on Tps = 0 ok!
//tps 100% Tps = 0 no ok !
//restart teensy and TPS 100% = Tps 100% ok
//tps 0 = tps =100% !
//no refresh data ?
//thanks

//Can0.mailboxStatus();
}

Help me
thanks
 
check your CAN termination, if you got 1 frame and it stopped it may not be ACKing the megasquirt

Thank's your respons

I have 61,7ohms canH -- canL
do you think it's too high?

........................................UNO and mpc2515 is ok data (whitout resistor)
......................................<----------------|-------------------->
.............................................................. |
Teensy4 & SVD230 120ohms------------------|---------------------Megasquirt 120ohms
 
in your loop your constantly calling read() but not using it's return (1). you really should use

Code:
if ( Can0.read(msg) ) {
// do whatever with a read message
}

failing to do that you'll likely see it spewing 0 values accross serial monitor :)

I assume you are on CAN2 as per your sketch, try the FIFO with interrupt example on CAN2. Should that not work then you should verify your connections
 
Hello,
So here are the tests this morning:

I read on this forum that on the VP230 chip it was necessary to put the pin 8 to the ground. what I have done ! I don't know if this will improve the problem!


NEW Code:
Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can0;

unsigned int rpm;
unsigned int temp;
unsigned int tps;
unsigned int kpa;

void setup(void) {
  Serial.begin(115200); delay(400);
  //pinMode(6, OUTPUT); digitalWrite(6, LOW); /* optional tranceiver enable pin */
  Can0.begin();
  Can0.setBaudRate(500000);
  Can0.setMaxMB(16);
  Can0.enableFIFO();
  Can0.enableFIFOInterrupt();
  Can0.onReceive(canSniff);
  Can0.mailboxStatus();
}

void canSniff(const CAN_message_t &msg) {
    if (msg.id==1512) {
          //case 1512: // hex= 0x5F0
           rpm = 256*msg.buf[2]+msg.buf[3];
           tps= (256*msg.buf[6]+ msg.buf[7])/10; 
           kpa  = ((256*msg.buf[0]+ msg.buf[1])/10);
           temp = ((256*msg.buf[4] + msg.buf[5])/10 -32) *5/9; //CLT
//Serial.print("tps: "); Serial.print(tps);Serial.print("temp: "); Serial.print(temp); Serial.print("kpa: "); Serial.println(kpa); 
         }
}

void loop() {
  Can0.events();
Serial.print("tps: "); Serial.print(tps);Serial.print("temp: "); Serial.print(temp); Serial.print("kpa: "); Serial.println(kpa); 

}


Result:
If I connect the teensy and the megasquirt ECU the problem is the same first value which does not change anymore.

If I plug in the teensy + UNO (mcp2551 no resistor) + megasquirt ECU = Full ok value is change!


Does this sound like an ACK problem? how to solve problem it to avoid adding the UNO on the CAN line

For the moment thank you because I was stuck !!
 
Last edited by a moderator:
it sounds like the UNO is ACKing because teensy can't, which could be a transceiver compatibility issue. Some transceivers were posted not working properly. If teensy seems to be getting values consistantly properly with the UNO attached, it means the transceiver on teensy is unable to ACK (write) to megasquirt and you need to try another transceiver
 
ok no problem do you have a link on a transceiver which is supposed to work? in 3V3 for T4
thanks
Tott
 
Hello!
I am the begginer with FlexCAN, please give me the answer, how to send message with length more then 8? In all examples msg.len is always 8.
 
Hi Gonzales. It's likely because you are using CAN and CAN always has 8 data bytes. To send more, you will just have to send multiple packets of data. Depending on your application, you might be able to use CAN FD and that will support up to 64 data bytes per package. You can read more about the differences here https://en.wikipedia.org/wiki/CAN_FD
 
a mailbox is like a hardware queue slot. each slot (mailbox) holds a CAN frame, so the MCU can read the frames from them
 
thanks, but i still dont understand how to use it.
I check example from library "mailbox_filtering_example"

Code:
for (int i = 0; i<NUM_RX_MAILBOXES; i++){
    Can0.setMB(i,RX,EXT);
  }
for (int i = NUM_RX_MAILBOXES; i<(NUM_TX_MAILBOXES + NUM_RX_MAILBOXES); i++){
    Can0.setMB(i,TX,EXT);
  }

here, i think, we assign some mailboxes for send and for recive

and what we will do here?
Code:
Can0.setMBFilter(REJECT_ALL);
  Can0.enableMBInterrupts();
  Can0.onReceive(MB0,canSniff);
  Can0.onReceive(MB1,canSniff);
  Can0.onReceive(MB2,canSniff);
  Can0.setMBFilterProcessing(MB0,0x00,0xFF);
  Can0.setMBFilterProcessing(MB1,0x03,0xFF);
  Can0.setMBFilterProcessing(MB2,0x0B,0xFF);

What is it MB0, MB1, MB2 and how to explain function setMBFilterProcessing

and one more, how can i use a large number of mailboxes in my project?

tonton81, please explaine in more detail.

Best regards
 
MB is mailbox. That is a user modified demo that was contributed but setMBFilterProcessing is an internal function to the library and not meant for user sketch. Anyways, you shouldn't start off with filtering if your just learning on it. Load up the FIFO with interrupts example and make sure your CAN bitrate is correct and you are using the proper bus in the constructor that your transceiver is connected to (CAN2?)

you can have up to 64 mailboxes total (rx and/or tx), using setMB() to configure them. By default half will be receive, other half transmit. To set the amount of mailboxes, use setMaxMB(64) to assign 64 mailboxes. You don't necessarily need that many, most people use 8 or less
 
Thanks for your answer. Of course i started with can2.0 examle, it works fine. Now i am thinking about protokol to send and recive messages more then 8 bytes. I have msg.id to identify some frames from one message, or i hoped, that MB can help me. Maybe there is a ready-made algorithm for this task?
 
the amount of mailboxes you have doesn't have anything to do with long messages, you would have to write a protocol that would take the received frames and reassemble them as theyre streaming, and split up your data to send it in 8 byte chunks.
 
SAE J2411 CANBUS @ 33k baud?

I'm using this can chip : https://www.onsemi.com/pub/Collateral/NCV7356-D.PDF

I can get it to work at 40000 baud (chip max in normal mode, 2 teensy 4.x talking to each other), but standard baud is 33000 for SAE J2411 and CAN TX pin is always high.

Do I need to set some clocks to get 33k baud to work?

I haven't tried 83.3k, as this is the SAE diagnostic high speed mode, so I might need help with that as well.
 
you can try setClock() method, older teensies ran at 16mhz osc clock i believe, t4 runs at 24mhz osc by default, you can go up to 60MHz peripheral clock if needed. I am using 60MHz accross 3 busses, 2 busses at 500kbps and one bus at 125kbps
 
Last edited:
you can try setClock() method, older teensies ran at 16mhz osc clock i believe, t4 runs at 24mhz osc by default, you can go up to 60MHz peripheral clock if needed. I am using 60MHz accross 3 busses, 2 busses at 500kbps and one bus at 125kbps

Thanks, I'll look into that.

Do you know if there is a minimum baud rate I can use for CAN?
 
Back
Top