|  | 
|  | 1 | +/* ESP32 TWAI receive example. | 
|  | 2 | +  Receive messages and sends them over serial. | 
|  | 3 | +
 | 
|  | 4 | +  Connect a CAN bus transceiver to the RX/TX pins. | 
|  | 5 | +  For example: SN65HVD230 | 
|  | 6 | +
 | 
|  | 7 | +  TWAI_MODE_LISTEN_ONLY is used so that the TWAI controller will not influence the bus. | 
|  | 8 | +
 | 
|  | 9 | +  The API gives other possible speeds and alerts: | 
|  | 10 | +  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html | 
|  | 11 | +
 | 
|  | 12 | +  Example output from a can bus message: | 
|  | 13 | +  -> Message received | 
|  | 14 | +  -> Message is in Standard Format | 
|  | 15 | +  -> ID: 604 | 
|  | 16 | +  -> Byte: 0 = 00, 1 = 0f, 2 = 13, 3 = 02, 4 = 00, 5 = 00, 6 = 08, 7 = 00 | 
|  | 17 | +
 | 
|  | 18 | +  Example output with alerts: | 
|  | 19 | +  -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. | 
|  | 20 | +  -> Bus error count: 171 | 
|  | 21 | +  -> Alert: The RX queue is full causing a received frame to be lost. | 
|  | 22 | +  -> RX buffered: 4  RX missed: 46 RX overrun 0 | 
|  | 23 | +
 | 
|  | 24 | +  created 05-11-2022 by Stephan Martin (designer2k2) | 
|  | 25 | +*/ | 
|  | 26 | + | 
|  | 27 | +#include "driver/twai.h" | 
|  | 28 | + | 
|  | 29 | +// Pins used to connect to CAN bus transceiver: | 
|  | 30 | +#define RX_PIN 21 | 
|  | 31 | +#define TX_PIN 22 | 
|  | 32 | + | 
|  | 33 | +// Intervall: | 
|  | 34 | +#define POLLING_RATE_MS 1000 | 
|  | 35 | + | 
|  | 36 | +static bool driver_installed = false; | 
|  | 37 | + | 
|  | 38 | +void setup() { | 
|  | 39 | +  // Start Serial: | 
|  | 40 | +  Serial.begin(115200); | 
|  | 41 | + | 
|  | 42 | +  // Initialize configuration structures using macro initializers | 
|  | 43 | +  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_LISTEN_ONLY); | 
|  | 44 | +  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();  //Look in the api-reference for other speed sets. | 
|  | 45 | +  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); | 
|  | 46 | + | 
|  | 47 | +  // Install TWAI driver | 
|  | 48 | +  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) { | 
|  | 49 | +    Serial.println("Driver installed"); | 
|  | 50 | +  } else { | 
|  | 51 | +    Serial.println("Failed to install driver"); | 
|  | 52 | +    return; | 
|  | 53 | +  } | 
|  | 54 | + | 
|  | 55 | +  // Start TWAI driver | 
|  | 56 | +  if (twai_start() == ESP_OK) { | 
|  | 57 | +    Serial.println("Driver started"); | 
|  | 58 | +  } else { | 
|  | 59 | +    Serial.println("Failed to start driver"); | 
|  | 60 | +    return; | 
|  | 61 | +  } | 
|  | 62 | + | 
|  | 63 | +  // Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states | 
|  | 64 | +  uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL; | 
|  | 65 | +  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) { | 
|  | 66 | +    Serial.println("CAN Alerts reconfigured"); | 
|  | 67 | +  } else { | 
|  | 68 | +    Serial.println("Failed to reconfigure alerts"); | 
|  | 69 | +    return; | 
|  | 70 | +  } | 
|  | 71 | + | 
|  | 72 | +  // TWAI driver is now successfully installed and started | 
|  | 73 | +  driver_installed = true; | 
|  | 74 | +} | 
|  | 75 | + | 
|  | 76 | +static void handle_rx_message(twai_message_t& message) { | 
|  | 77 | +  // Process received message | 
|  | 78 | +  if (message.extd) { | 
|  | 79 | +    Serial.println("Message is in Extended Format"); | 
|  | 80 | +  } else { | 
|  | 81 | +    Serial.println("Message is in Standard Format"); | 
|  | 82 | +  } | 
|  | 83 | +  Serial.printf("ID: %x\nByte:", message.identifier); | 
|  | 84 | +  if (!(message.rtr)) { | 
|  | 85 | +    for (int i = 0; i < message.data_length_code; i++) { | 
|  | 86 | +      Serial.printf(" %d = %02x,", i, message.data[i]); | 
|  | 87 | +    } | 
|  | 88 | +    Serial.println(""); | 
|  | 89 | +  } | 
|  | 90 | +} | 
|  | 91 | + | 
|  | 92 | +void loop() { | 
|  | 93 | +  if (!driver_installed) { | 
|  | 94 | +    // Driver not installed | 
|  | 95 | +    Serial.println("TWAI driver not installed!"); | 
|  | 96 | +    return; | 
|  | 97 | +  } | 
|  | 98 | +  // Check if alert happened | 
|  | 99 | +  uint32_t alerts_triggered; | 
|  | 100 | +  twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS)); | 
|  | 101 | +  twai_status_info_t twaistatus; | 
|  | 102 | +  twai_get_status_info(&twaistatus); | 
|  | 103 | + | 
|  | 104 | +  // Handle alerts | 
|  | 105 | +  if (alerts_triggered & TWAI_ALERT_ERR_PASS) { | 
|  | 106 | +    Serial.println("Alert: TWAI controller has become error passive."); | 
|  | 107 | +  } | 
|  | 108 | +  if (alerts_triggered & TWAI_ALERT_BUS_ERROR) { | 
|  | 109 | +    Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus."); | 
|  | 110 | +    Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count); | 
|  | 111 | +  } | 
|  | 112 | +  if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) { | 
|  | 113 | +    Serial.println("Alert: The RX queue is full causing a received frame to be lost."); | 
|  | 114 | +    Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx); | 
|  | 115 | +    Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count); | 
|  | 116 | +    Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count); | 
|  | 117 | +  } | 
|  | 118 | + | 
|  | 119 | +  // Check if message is received | 
|  | 120 | +  if (alerts_triggered & TWAI_ALERT_RX_DATA) { | 
|  | 121 | +    // One or more messages received. Handle all. | 
|  | 122 | +    twai_message_t message; | 
|  | 123 | +    while (twai_receive(&message, 0) == ESP_OK) { | 
|  | 124 | +      handle_rx_message(message); | 
|  | 125 | +    } | 
|  | 126 | +  } | 
|  | 127 | +} | 
0 commit comments