Teensy Flexcan Canbus mailboxes

Post Reply
LRBen
Posts: 471
Joined: Thu Jul 04, 2019 6:35 pm
Location: Somerset, UK
Has thanked: 42 times
Been thanked: 99 times

Teensy Flexcan Canbus mailboxes

Post by LRBen »

Ok i've been working on this for a few days now but I just can't get my head around Flexcan mail boxes.

I can setup the mailboxes, and set masks so that each mailbox will only read a certain can ID. But then how do I retrieve that data?

Does anyone have a fairly simple arduino/teensy flexcan script that does this? I can't find any examples and I have been reading the documentation for flexcan over and over, it just isn't clicking yet.

My setup only uses one canbus message ID right now, so I can read that just fine. But a single message canbus system is pretty useless and I will need more for the BMS at least.
Isaac96
Posts: 656
Joined: Sat Oct 05, 2019 6:50 pm
Location: Northern California, USA
Been thanked: 1 time
Contact:

Re: Teensy Flexcan Canbus mailboxes

Post by Isaac96 »

This stuff is pretty complicated! I ended up using setCallback for this purpose.

Code: Select all

  Can1.setRXFilter(0, 0x520, 0x7f0, false);//filter for ISA - this accepts 520 through 52F

  Can1.setRXFilter(1, 0, 0, false);
  Can1.setCallback(1, handleChademoCan);
And the function that the callback calls back to:

Code: Select all

void handleChademoCan(CAN_FRAME * frame) {
  chademo.handleCANFrame(frame);
}
Just passing the message along since it doesn't like calling objects, functions work nicely though.

I haven't tested this extensively but it worked well for having ISA and Chademo on the same bus with completely different message handlers.

Check out the 'rx_singlebus_withobjects' example in FlexCAN -- it shows a bit of the mailbox system and has a function to process any received frame. The important part here is that it tells you which mailbox it's from -- so you could, depending on which mailbox you're using, call one of many functions according to the mailbox ID.

Hope this makes sense, it's what I know from using the library a good bit.

-Isaac
LRBen
Posts: 471
Joined: Thu Jul 04, 2019 6:35 pm
Location: Somerset, UK
Has thanked: 42 times
Been thanked: 99 times

Re: Teensy Flexcan Canbus mailboxes

Post by LRBen »

Thanks for the information. So if I understand your first code correctly, you are setting a filter for 0x520, 0x7f0 on mailbox 0, and letting everything through on mailbox 1? Then you are forwarding Mailbox 1 on.

I've managed to make sense of 'rx_singlebus_withobjects' this time around, so I'm ahead of where I was before. But still can't quite figure out the filtering bit.

What version of flexcan are you using as I can't get any form of setFilter or setRXFilter to work. I'm using the Collin80 fork.
Isaac96
Posts: 656
Joined: Sat Oct 05, 2019 6:50 pm
Location: Northern California, USA
Been thanked: 1 time
Contact:

Re: Teensy Flexcan Canbus mailboxes

Post by Isaac96 »

Exactly.

I'm using the version straight from the Teensy installer, which I think is Paul Stoffregen's work.
collin80
Posts: 110
Joined: Sun Aug 30, 2020 3:28 pm
Location: United States, Michigan
Been thanked: 4 times
Contact:

Re: Teensy Flexcan Canbus mailboxes

Post by collin80 »

Isaac96 wrote: Wed Aug 04, 2021 9:21 pm Exactly.

I'm using the version straight from the Teensy installer, which I think is Paul Stoffregen's work.
Here's the story:

A long time ago I added to the FlexCAN driver by Pawelsky. This was for the Teensy 3.5/3.6 boards and it was... OK. It worked. It was included with the Teensy installer for years, still is. It's more or less compatible with all my other CAN drivers for other boards (ESP32, Arduino Due) so you can write CAN code for one board and then compile it on a bunch of other boards even boards with different processors.

Along came Tony Brewer and he did a much better job of supporting the FlexCAN hardware and making a nice driver. His is probably more complicated to use but it makes better use of the FlexCAN hardware and has a CAN-FD version for the Teensy 4.0/4.1 hardware. So, the Teensy installer also has a FlexCAN_T4 driver. Tony maintains that one and it's essentially 100% different from the one I wrote.

It is more or less user preference for which one to use. If you need CANFD you'll need his version. If you have other code you wrote that conforms to my API then it'd be easier to use my version. If you don't have legacy code you're probably better off using his version. I'm building a board with a Teensy micromod module on it and I'm probably going to use his library instead of trying to port mine over to CAN-FD on the newer Teensy 4.1 hardware. But, maybe not. I might modify the FlexCAN library I helped write. But, I have not done so yet so your best luck with Teensy 4/4.1 hardware is to use FlexCAN_T4.
User avatar
rstevens81
Posts: 349
Joined: Sun Dec 22, 2019 10:36 am
Location: Bristol, UK
Has thanked: 21 times
Been thanked: 91 times

Re: Teensy Flexcan Canbus mailboxes

Post by rstevens81 »

There is also the acan library

https://github.com/pierremolinaro

Which has flavours for teensy 3, teensy 4, esp32 & mcp2515, which is also worth a look 😁
Rule 1 of EV Club is don't buy a rust bucket....
Which rule does everyone forget 🤪
LRBen
Posts: 471
Joined: Thu Jul 04, 2019 6:35 pm
Location: Somerset, UK
Has thanked: 42 times
Been thanked: 99 times

Re: Teensy Flexcan Canbus mailboxes

Post by LRBen »

Ok I think I figured this out. I think my main problem was a complete lack of coding knowledge. Ended up using Flexcan_T4.

I use the following to filter Can ids into mail boxes. Right now I am only using one mail box, but it is ready for when I need to add more canbus messages.

Code: Select all

void setup() {
Can0.begin();
Serial.begin(115200); delay(400);
  Can0.setBaudRate(500000);
  Can0.setMaxMB(NUM_TX_MAILBOXES + NUM_RX_MAILBOXES);
  for (int i = 0; i<NUM_RX_MAILBOXES; i++){
    Can0.setMB(i,RX,STD);
  }
  for (int i = NUM_RX_MAILBOXES; i<(NUM_TX_MAILBOXES + NUM_RX_MAILBOXES); i++){
    Can0.setMB(i,TX,STD);
  }
  Can0.setMBFilter(REJECT_ALL);
  Can0.enableMBInterrupts();
  Can0.setMBFilterProcessing(MB0,0x3FF, 0xFF);
  //Can0.setMBFilterProcessing(MB1,0x400, 0xFF);
  //Can0.setMBFilterProcessing(MB2,0x0B,0xFF);
  Can0.enhanceFilter(MB0);
  //Can0.enhanceFilter(MB1);
  Can0.onReceive(MB0,canSniff1);
  //Can0.onReceive(MB1,canSniff2);
  //Can0.onReceive(MB2,canSniff);
  Can0.mailboxStatus();
Then on message recieve I use the following to use the data from a specific can ID

Code: Select all

void canSniff1(const CAN_message_t &msg) {
 if (msg.id == 0x3FF)
  {
  HVbus = msg.buf[5];
  Batvolt = msg.buf[6];
  rpmraw = (( msg.buf[4] << 8) | msg.buf[3]);
  
}
}
It's probably pretty janky but it seems to work for now. Thanks for all your input!

During this I discovered what functions do, which is helping allot! Also noticed some timer functions look useful as well. So instead of throwing everything into the loop I can now break things up into functions and call those functions in the loop instead. With some functions being slowed down by the Metro timer, because I don't need to be checking the coolant temperature thousands of times a second for example.
Post Reply