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.
Teensy Flexcan Canbus mailboxes
-
- Posts: 656
- Joined: Sat Oct 05, 2019 6:50 pm
- Location: Northern California, USA
- Been thanked: 1 time
- Contact:
Re: Teensy Flexcan Canbus mailboxes
This stuff is pretty complicated! I ended up using setCallback for this purpose.
And the function that the callback calls back to:
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
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);
Code: Select all
void handleChademoCan(CAN_FRAME * frame) {
chademo.handleCANFrame(frame);
}
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
-
- Posts: 474
- Joined: Thu Jul 04, 2019 6:35 pm
- Location: Somerset, UK
- Has thanked: 43 times
- Been thanked: 107 times
Re: Teensy Flexcan Canbus mailboxes
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.
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.
-
- Posts: 656
- Joined: Sat Oct 05, 2019 6:50 pm
- Location: Northern California, USA
- Been thanked: 1 time
- Contact:
Re: Teensy Flexcan Canbus mailboxes
Exactly.
I'm using the version straight from the Teensy installer, which I think is Paul Stoffregen's work.
I'm using the version straight from the Teensy installer, which I think is Paul Stoffregen's work.
-
- Posts: 110
- Joined: Sun Aug 30, 2020 3:28 pm
- Location: United States, Michigan
- Been thanked: 4 times
- Contact:
Re: Teensy Flexcan Canbus mailboxes
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.
- rstevens81
- Posts: 353
- Joined: Sun Dec 22, 2019 10:36 am
- Location: Bristol, UK
- Has thanked: 23 times
- Been thanked: 92 times
Re: Teensy Flexcan Canbus mailboxes
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
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
Which rule does everyone forget
-
- Posts: 474
- Joined: Thu Jul 04, 2019 6:35 pm
- Location: Somerset, UK
- Has thanked: 43 times
- Been thanked: 107 times
Re: Teensy Flexcan Canbus mailboxes
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.
Then on message recieve I use the following to use the data from a specific can ID
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.
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();
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]);
}
}
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.