espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
12.94k stars 7.28k forks source link

TWAI Transmit Example error. #9933

Open koulombus opened 3 days ago

koulombus commented 3 days ago

Board

ESP32 WROOM 32

Device Description

on a own board. Analyzer 2.0.sch.zip

Hardware Configuration

CAN/TWAI communication

define RX_PIN GPIO_NUM_17

define TX_PIN GPIO_NUM_16

CAN driver: SN65HVD230

image

Version

v3.0.1

IDE Name

Arduino IDE 2.X

Operating System

MacOS 14.5

Flash frequency

80MHz

PSRAM enabled

no

Upload speed

115200

Description

It is not possible for me to send data for a long time with this original sketch. It works for the first few seconds, but then no longer. With my CAN bus sniffer I can see the data being sent.

Sketch

/* ESP32 TWAI transmit example.
  This transmits a message every second.

  Connect a CAN bus transceiver to the RX/TX pins.
  For example: SN65HVD230

  The API gives other possible speeds and alerts:
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html

  created 27-06-2023 by Stephan Martin (designer2k2)
*/

#include "driver/twai.h"

// Pins used to connect to CAN bus transceiver:
#define RX_PIN 17
#define TX_PIN 16

// Interval:
#define TRANSMIT_RATE_MS 1000

#define POLLING_RATE_MS 1000

static bool driver_installed = false;

unsigned long previousMillis = 0;  // will store last time a message was send

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_NORMAL);
  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 TX alerts and Bus-Off errors
  uint32_t alerts_to_enable = TWAI_ALERT_TX_IDLE | TWAI_ALERT_TX_SUCCESS | TWAI_ALERT_TX_FAILED | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR;
  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 send_message() {
  // Send message

  // Configure message to transmit
  twai_message_t message;
  message.identifier = 0x0F6;
  message.data_length_code = 4;
  for (int i = 0; i < 4; i++) {
    message.data[i] = 0;
  }

  // Queue message for transmission
  if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
    printf("Message queued for transmission\n");
  } else {
    printf("Failed to queue message for transmission\n");
  }
}

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: %lu\n", twaistatus.bus_error_count);
  }
  if (alerts_triggered & TWAI_ALERT_TX_FAILED) {
    Serial.println("Alert: The Transmission failed.");
    Serial.printf("TX buffered: %lu\t", twaistatus.msgs_to_tx);
    Serial.printf("TX error: %lu\t", twaistatus.tx_error_counter);
    Serial.printf("TX failed: %lu\n", twaistatus.tx_failed_count);
  }
  if (alerts_triggered & TWAI_ALERT_TX_SUCCESS) {
    Serial.println("Alert: The Transmission was successful.");
    Serial.printf("TX buffered: %lu\t", twaistatus.msgs_to_tx);
  }

  // Send message
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= TRANSMIT_RATE_MS) {
    previousMillis = currentMillis;
    send_message();
  }
}

Debug Message

Driver started
CAN Alerts reconfigured
Message queued for transmission
Alert: TWAI controller has become error passive.
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 2
Alert: The Transmission failed.
TX buffered: 0  TX error: 136   TX failed: 1
Message queued for transmission
Bus error count: 3
Alert: The Transmission failed.
TX buffered: 0  TX error: 144   TX failed: 2
Message queued for transmission
Bus error count: 4
Alert: The Transmission failed.
TX buffered: 0  TX error: 152   TX failed: 3
Message queued for transmission
....
Bus error count: 16
Alert: The Transmission failed.
TX buffered: 0  TX error: 248   TX failed: 15
Message queued for transmission
Alert: The Transmission failed.
TX buffered: 0  TX error: 128   TX failed: 16
Failed to queue message for transmission
Failed to queue message for transmission
Failed to queue message for transmission
Failed to queue message for transmission
Failed to queue message for transmission
Failed to queue message for transmission`

Other Steps to Reproduce

I used another library (ACAN_ESP32 - Arduino Reference), with this I could receive data but not send it, which led me to this library.

I have checked existing issues, online documentation and the Troubleshooting Guide

me-no-dev commented 3 days ago

I suggest you also post this in the ESP-IDF repo, because it uses all their APIs. You should be able to get some help there. Let them know you are using IDF v5.1.4

aaarnas commented 3 days ago

Code works fine:

TX buffered: 0  Message queued for transmission
Alert: The Transmission was successful.
TX buffered: 0  Message queued for transmission
Alert: The Transmission was successful.
TX buffered: 0  Message queued for transmission
Alert: The Transmission was successful.

Have you connected any other device to CAN-H, CAN-L lines? There must be at least 2 devices for CAN bus to work. CAN bus sniffer does not count. It works in "listen" mode and does not influence the bus.

koulombus commented 1 day ago

@aaarnas, I wouldn't have expected that, because at the time the device is started from pre-operational to operational, this information has to be sent. At this point I basically don't know whether a device is connected, basically only one NMT is serving, which is also just listening. But I will try it!

aaarnas commented 1 day ago

I had in mind second Node, physically connected to CAN lines.

If you leave H,L lines unconnected - ESP32 puts message to TX queue but fails to transfer, because there is no one on CAN bus network to receive and acknowledge it. This is indicated as "bus error".