AustinECEStudent
Active member
Assistance with CAN FD Communication Setup in Senior Design Project Using Teensy**
I’m currently working on a Senior Design project that involves real-time motor control using a Teensy microcontroller and CAN FD communication. Here's a brief overview of the project and my setup:
Project Overview:
Our project focuses on controlling a motor via an Escon motor controller, which is interfaced with a Teensy microcontroller. The system includes a torque meter for measuring torque generated by the motor, which outputs an analog signal that is converted to digital for processing by the Teensy. The ultimate goal is to enable real-time control and monitoring of the motor through a laptop application using CAN FD (Controller Area Network Flexible Data-rate) communication.
Setup Details:
- **Teensy Microcontroller**: Acts as the main control unit, receiving signals from the motor controller and transmitting data to the laptop via CAN FD.
- **Escon Motor Controller**: Interfaces with the Teensy to control the motor based on PWM signals.
- **Torque Meter**: Measures torque and sends analog signals, which are converted and read by the Teensy.
- **CAN FD Communication**: Implemented to allow real-time data exchange between the Teensy and a laptop application. The CAN FD protocol was chosen for its high data rate, error correction capabilities, and scalability.
Code and Current Output:
I’ve used the following code to initialize the CAN FD communication and periodically send random CAN frames:
```cpp
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can0;
void setup(void) {
Serial.begin(115200); delay(400);
pinMode(2, OUTPUT); digitalWrite(2, LOW); // enable transceiver
Can0.begin();
Can0.setBaudRate(500000);
Can0.setMaxMB(16); // up to 64 max for T4, not important in FIFO mode, unless you want to use additional mailboxes with FIFO
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.onReceive(canSniff);
Can0.mailboxStatus();
}
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, HEX); Serial.print(" ");
} Serial.println();
}
void loop() {
Can0.events();
static uint32_t timeout = millis();
if ( millis() - timeout > 20 ) { // send random frame every 20ms
CAN_message_t msg;
msg.id = random(0x1,0x7FE);
for ( uint8_t i = 0; i < 8; i++ ) msg.buf = i + 1;
Can0.write(msg);
timeout = millis();
}
}
```
The output I’m currently seeing is:
- **FIFO Enabled → Interrupt Enabled**
- **FIFO Filters in use: 8**
- **Remaining Mailboxes: 8**
- **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**
- **CAN FD communication started.**
### Issue:
The output doesn’t match my expectations, especially with all the mailboxes showing as inactive. I’m unsure if this indicates a problem with the CAN FD communication setup or the way the mailboxes are configured.
Could you please provide guidance on why this might be happening and suggest any steps I can take to debug or correct the issue? Your expertise and advice would be greatly appreciated.
Also how can I make sure that CAN FD messages are actually being sent because I am not sure whats happening as I am a beginner and totally new to this protocol.
Thank you for your assistance!
I’m currently working on a Senior Design project that involves real-time motor control using a Teensy microcontroller and CAN FD communication. Here's a brief overview of the project and my setup:
Project Overview:
Our project focuses on controlling a motor via an Escon motor controller, which is interfaced with a Teensy microcontroller. The system includes a torque meter for measuring torque generated by the motor, which outputs an analog signal that is converted to digital for processing by the Teensy. The ultimate goal is to enable real-time control and monitoring of the motor through a laptop application using CAN FD (Controller Area Network Flexible Data-rate) communication.
Setup Details:
- **Teensy Microcontroller**: Acts as the main control unit, receiving signals from the motor controller and transmitting data to the laptop via CAN FD.
- **Escon Motor Controller**: Interfaces with the Teensy to control the motor based on PWM signals.
- **Torque Meter**: Measures torque and sends analog signals, which are converted and read by the Teensy.
- **CAN FD Communication**: Implemented to allow real-time data exchange between the Teensy and a laptop application. The CAN FD protocol was chosen for its high data rate, error correction capabilities, and scalability.
Code and Current Output:
I’ve used the following code to initialize the CAN FD communication and periodically send random CAN frames:
```cpp
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can0;
void setup(void) {
Serial.begin(115200); delay(400);
pinMode(2, OUTPUT); digitalWrite(2, LOW); // enable transceiver
Can0.begin();
Can0.setBaudRate(500000);
Can0.setMaxMB(16); // up to 64 max for T4, not important in FIFO mode, unless you want to use additional mailboxes with FIFO
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.onReceive(canSniff);
Can0.mailboxStatus();
}
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, HEX); Serial.print(" ");
} Serial.println();
}
void loop() {
Can0.events();
static uint32_t timeout = millis();
if ( millis() - timeout > 20 ) { // send random frame every 20ms
CAN_message_t msg;
msg.id = random(0x1,0x7FE);
for ( uint8_t i = 0; i < 8; i++ ) msg.buf = i + 1;
Can0.write(msg);
timeout = millis();
}
}
```
The output I’m currently seeing is:
- **FIFO Enabled → Interrupt Enabled**
- **FIFO Filters in use: 8**
- **Remaining Mailboxes: 8**
- **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**
- **CAN FD communication started.**
### Issue:
The output doesn’t match my expectations, especially with all the mailboxes showing as inactive. I’m unsure if this indicates a problem with the CAN FD communication setup or the way the mailboxes are configured.
Could you please provide guidance on why this might be happening and suggest any steps I can take to debug or correct the issue? Your expertise and advice would be greatly appreciated.
Also how can I make sure that CAN FD messages are actually being sent because I am not sure whats happening as I am a beginner and totally new to this protocol.
Thank you for your assistance!