-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Add TWAI receive example #7430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add TWAI receive example #7430
Conversation
Example showing how to receive messages using the TWAI interface and a CAN transceiver.
use pdMS_TO_TICKS for twai_read_alerts, format specifier on hex byte info, and dedicated if´s instead of else if on alerts to show multiple errors.
I do not have the required hardware to properly test it. All I can confirm is that it compiles and isn't crashing. |
@designer2k2 Hi, we're watching this and we will include it in upcoming release 2.0.6., release date will be in the 1st half of December. |
Hello @Dazza0, if you will have some time please help with review of this. We would like to include this in next release. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@designer2k2 Thanks for the contribution. Left some comments about how to use the TWAI alerts more effectively.
Hello @Dazza0, I will incorporate your requests by tomorrow |
Hello @Dazza0, please take a look if the changes are ok like this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more nitpick. Could you squash your commits before we merge? The example and TWAI driver usage LGTM otherwise.
Reading the twai status help to understand why certain alerts happen Update as requested - capitals for macros - using TWAI_ALERT_RX_DATA for polling - parsing in static function - (shortened output to speed up output) move function above loop, define before use
@Dazza0 i am lost with the squash topic, the github gui only allowed me to squash the last 3. Any way thats possible to do on your end? Or give me a hint how i can resolve the error above? |
@designer2k2 I think I see where the issue is. It seems like the issue might be coming from this commit. It seems updates from upstream Alternatively:
|
yes there i clicked on the "Update branch" Button in the Gui, that was not good. Could you create the branch/PR for me? Its not clear to me on how to do that. |
This commit addes an example showing how to receive messages using the TWAI driver interface and a CAN transceiver. Specifically, the example demonstrates: - How to configure and install the TWAI drvier - How to poll for TWAI events (i.e., alerts) using twai_read_alerts() - How to handle the various events (such as TWAI_ALERT_RX_DATA) Closes espressif#7430
@designer2k2 Squashing commits can be done by us when we will merge this so don't worry about that. Update: I just see it's already done by @Dazza0. :) |
This commit addes an example showing how to receive messages using the TWAI driver interface and a CAN transceiver. Specifically, the example demonstrates: - How to configure and install the TWAI drvier - How to poll for TWAI events (i.e., alerts) using twai_read_alerts() - How to handle the various events (such as TWAI_ALERT_RX_DATA) Closes espressif#7430
This commit addes an example showing how to receive messages using the TWAI driver interface and a CAN transceiver. Specifically, the example demonstrates: - How to configure and install the TWAI drvier - How to poll for TWAI events (i.e., alerts) using twai_read_alerts() - How to handle the various events (such as TWAI_ALERT_RX_DATA) Closes espressif#7430
This commit addes an example showing how to receive messages using the TWAI driver interface and a CAN transceiver. Specifically, the example demonstrates: - How to configure and install the TWAI drvier - How to poll for TWAI events (i.e., alerts) using twai_read_alerts() - How to handle the various events (such as TWAI_ALERT_RX_DATA) Closes espressif#7430
In order to filter out and accept only specific message IDs, the statement "twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();" has to be replaced with the appropriate "acceptance code and the acceptance mask". This is not well explained in the Espressif documentation. Has anyone managed to successfully code this information to limit the message IDs seen by an Arduino C++ application? If so, please share that part of your code. Thank you! |
Please refer to https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html#acceptance-filter |
Thanks for responding to my question. However, I have read this particular section of the specs 17 times and still don't know how to code the masks and filters. There are several examples on the the Espressif forum and Github, but none that fully explains how to code Arduino C++ that accepts two or more IDs. The examples show shift-left (<<) by various amounts (<<3, <<5, <<21). There is no indication in the documentation that there is more than one acceptance filter (One indication implies there are a possible of up to 8 filters, while the Espressif documentation implies there is only one filter that can be used in single or dual mode (that would allow 2 acceptance codes). If there is the possibility to use more than two filters in single filter mode, then I can add more IDs later. The code I have accumulated, based on various sources, is shown below. If you could adjust this code so it accepts only IDs 743 and 7DF, it would be very much appreciated. /* ESP32 TWAI receive example.
Receive messages and sends them over serial.
Connect a CAN bus transceiver to the RX/TX pins.
For example: SN65HVD230
TWAI_MODE_LISTEN_ONLY is used so that the TWAI controller will not influence the bus.
The API gives other possible speeds and alerts:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html
Example output:
-> Message received
-> Message is in Standard Format
-> ID is 604
-> Byte 0 = 0 Byte 1 = f Byte 2 = 13 Byte 3 = 2 Byte 4 = 0 Byte 5 = 0 Byte 6 = 8 Byte 7 = 0
created 05-11-2022 by Stephan Martin (designer2k2)
*/
#include "driver/twai.h"
//Pins used to connect to CAN bus transceiver:
#define rxPin 4
#define txPin 5
#define CAN_PWM_ADDR 0x743 // address of PWM message from ECU (unsolicited)
unsigned char rxBuf[8]; // read buffer
byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xFE}; // write buffer
void setup() {
// Start Serial:
Serial.begin(115200);
//Initialize configuration structures using macro initializers
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)txPin, (gpio_num_t)rxPin, TWAI_MODE_LISTEN_ONLY);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS(); //Look in the api-reference for other speed sets.
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
// Configure acceptance code and mask for ID 0x743
f_config.acceptance_code = 0x743 << 5; // acceptance code for ID 743
f_config.acceptance_mask = 0x743 << 5; // Mask with 11 bits set to 1 for full acceptance
f_config.single_filter = true; // single filter if "1", dual filter if "0"
// Configure acceptance code and mask for ID 0x7DF
f_config.acceptance_code |= 0x7DF << 5; // Use bitwise OR to add the new acceptance code
/* //Install TWAI driver (ChatGPT code) ***********************************************************
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
Serial.println("Driver installed");
} else {
Serial.println("Failed to install driver");
return;
}
*/
//Start TWAI driver
if (twai_start() == ESP_OK) {
Serial.println("Driver started");
} else {
Serial.println("Failed to start driver");
return;
}
//Reconfigure alerts to detect Bus-Off error and RX queue full states
uint32_t alerts_to_enable = TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
Serial.println("CAN Alerts reconfigured");
} else {
Serial.println("Failed to reconfigure alerts");
}
}
void loop()
{ //Check if alert happened
uint32_t alerts_triggered;
twai_read_alerts(&alerts_triggered, 1);
if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
Serial.println("Alert: TWAI controller has become error passive.");
} else if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
} else if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
}
//Wait for message to be received:
twai_message_t message;
if (twai_receive(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
Serial.println("Message received");
twai_message_t message;
} else {
Serial.println("No message received");
return;
}
//Process received message
if (message.extd) {
Serial.println("Message is in Extended Format");
} else {
Serial.println("Message is in Standard Format");
}
Serial.printf("ID is %x\n", message.identifier);
if (!(message.rtr))
{
if (message.identifier = CAN_PWM_ADDR)
{ for (int i = 0; i < 8; i++)
{ Serial.printf("Byte %d = %x ", i, message.data[i]);
rxBuf[i] = message.data[i];
}
Serial.println("");
// put application logic here to process the received message ID 743
}
}
} |
Description of Change
Example showing how to receive messages using the TWAI interface and a CAN transceiver.
It also uses the alerts to show how to set them up and react to them.
It is based on the samples shown in the api: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html
Tests scenarios
I used an esp32-c3-devkit (ESP32-D0WDQ6) with a SN65HVD230 CAN transceiver.
This was attached between 2 Arduino Nano´s with a MCP2515/MCP2562 CAN interface, whereby they replayed a recording from a quite busy CAN bus.
This replay was then observed by the ESP32 and send with this example to the host.