diff --git a/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino b/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino new file mode 100644 index 00000000000..e0fd8864596 --- /dev/null +++ b/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino @@ -0,0 +1,127 @@ +/* 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 from a can bus message: + -> Message received + -> Message is in Standard Format + -> ID: 604 + -> Byte: 0 = 00, 1 = 0f, 2 = 13, 3 = 02, 4 = 00, 5 = 00, 6 = 08, 7 = 00 + + Example output with alerts: + -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. + -> Bus error count: 171 + -> Alert: The RX queue is full causing a received frame to be lost. + -> RX buffered: 4 RX missed: 46 RX overrun 0 + + created 05-11-2022 by Stephan Martin (designer2k2) +*/ + +#include "driver/twai.h" + +// Pins used to connect to CAN bus transceiver: +#define RX_PIN 21 +#define TX_PIN 22 + +// Intervall: +#define POLLING_RATE_MS 1000 + +static bool driver_installed = false; + +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)TX_PIN, (gpio_num_t)RX_PIN, 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(); + + // Install TWAI driver + 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 frame receive, Bus-Off error and RX queue full states + uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | 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"); + return; + } + + // TWAI driver is now successfully installed and started + driver_installed = true; +} + +static void handle_rx_message(twai_message_t& message) { + // Process received message + if (message.extd) { + Serial.println("Message is in Extended Format"); + } else { + Serial.println("Message is in Standard Format"); + } + Serial.printf("ID: %x\nByte:", message.identifier); + if (!(message.rtr)) { + for (int i = 0; i < message.data_length_code; i++) { + Serial.printf(" %d = %02x,", i, message.data[i]); + } + Serial.println(""); + } +} + +void loop() { + if (!driver_installed) { + // Driver not installed + delay(1000); + return; + } + // Check if alert happened + uint32_t alerts_triggered; + twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS)); + twai_status_info_t twaistatus; + twai_get_status_info(&twaistatus); + + // Handle alerts + if (alerts_triggered & TWAI_ALERT_ERR_PASS) { + Serial.println("Alert: TWAI controller has become error passive."); + } + if (alerts_triggered & TWAI_ALERT_BUS_ERROR) { + Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus."); + Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count); + } + if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) { + Serial.println("Alert: The RX queue is full causing a received frame to be lost."); + Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx); + Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count); + Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count); + } + + // Check if message is received + if (alerts_triggered & TWAI_ALERT_RX_DATA) { + // One or more messages received. Handle all. + twai_message_t message; + while (twai_receive(&message, 0) == ESP_OK) { + handle_rx_message(message); + } + } +}