Closed Strangistra closed 1 year ago
Please set the Log output to Verbose and run the application. You can report here the serial console output.
The documentation about TWAI for IDF 4.4 (used with Arduino Core 4.4) is here: https://docs.espressif.com/projects/esp-idf/en/v4.4.4/esp32s2/api-reference/peripherals/twai.html
There is information about TWAI peripheral in the S2 TRM in the chapter 29: https://www.espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf
A few projects that use Canbus with ESP32... it may help.
https://github.com/MagnusThome/RejsaCAN-ESP32 https://github.com/miwagner/ESP32-Arduino-CAN
Related issues: https://github.com/espressif/arduino-esp32/issues/3921 https://forum.arduino.cc/t/esp32-waveshare-sn65hvd230-can/1089185/2
I don't understand what is not working. I don't know if it's a software or hardware issue.
I don't have such hardware... sorry for not helping further.
Hi SuGlider Sorry for the late reply but all this information does not solve my problem. I tested the ESP32-S2 with an MCP2515 module with SPI interface and this solution works fine. In fact I don't understand either why the SN65HVD230 module doesn't work. After several researches I found that many people give up the can bus on ESP32 after the passage in TWAI library. In CAN library formerly used on the first ESP32 it worked perfectly but not with the new models.
This is the case with your mentioned issue #3921
if you run the TWAI example, does it output CAN frames to Serial? Or what does it output?
You will have to change the Bitrate to fit:
(i made this example and here is my working setup with a SN65HVD230 : https://github.com/espressif/arduino-esp32/pull/7430#issuecomment-1320452191
any updates @Strangistra?
/Hello everyone. I will come back to give you news of my investigations concerning this subject. After buying the Adafruit CAN Pal which never arrived I acquired these modules: TECNOIOT 5pcs MCP2551 High Speed Can Protocol Controller Bus Interface Module
I then made the following connection:
I defined the RX and TX pins in the "pins_arduino.h" file located in the following path C:\Users\XXXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.9\variants\lolin_s2_mini
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
// Default USB Settings
#define USB_VID 0x303a
#define USB_PID 0x80C2
#define USB_MANUFACTURER "WEMOS.CC"
#define USB_PRODUCT "LOLIN-S2-MINI"
#define USB_SERIAL "0"
// Default USB FirmwareMSC Settings
#define USB_FW_MSC_VENDOR_ID "ESP32-S2" //max 8 chars
#define USB_FW_MSC_PRODUCT_ID "Firmware MSC" //max 16 chars
#define USB_FW_MSC_PRODUCT_REVISION "1.23" //max 4 chars
#define USB_FW_MSC_VOLUME_NAME "S2-Firmware" //max 11 chars
#define USB_FW_MSC_SERIAL_NUMBER 0x00000000
#define EXTERNAL_NUM_INTERRUPTS 46
#define NUM_DIGITAL_PINS 48
#define NUM_ANALOG_INPUTS 20
#define analogInputToDigitalPin(p) (((p)<20)?(analogChannelToDigitalPin(p)):-1)
#define digitalPinToInterrupt(p) (((p)<48)?(p):-1)
#define digitalPinHasPWM(p) (p < 46)
static const uint8_t LED_BUILTIN = 15;
#define BUILTIN_LED LED_BUILTIN // backward compatibility
static const uint8_t TX = 39;
static const uint8_t RX = 40;
static const uint8_t SDA = 8;
static const uint8_t SCL = 18;
static const uint8_t SS = 34;
static const uint8_t MOSI = 35;
static const uint8_t MISO = 37;
static const uint8_t SCK = 36;
static const uint8_t A0 = 1;
static const uint8_t A1 = 2;
static const uint8_t A2 = 3;
static const uint8_t A3 = 4;
static const uint8_t A4 = 5;
static const uint8_t A5 = 6;
static const uint8_t A6 = 7;
static const uint8_t A7 = 8;
static const uint8_t A8 = 9;
static const uint8_t A9 = 10;
static const uint8_t A10 = 11;
static const uint8_t A11 = 12;
static const uint8_t A12 = 13;
static const uint8_t A13 = 14;
static const uint8_t A14 = 15;
static const uint8_t A15 = 16;
static const uint8_t A16 = 17;
static const uint8_t A17 = 18;
static const uint8_t A18 = 19;
static const uint8_t A19 = 20;
static const uint8_t T1 = 1;
static const uint8_t T2 = 2;
static const uint8_t T3 = 3;
static const uint8_t T4 = 4;
static const uint8_t T5 = 5;
static const uint8_t T6 = 6;
static const uint8_t T7 = 7;
static const uint8_t T8 = 8;
static const uint8_t T9 = 9;
static const uint8_t T10 = 10;
static const uint8_t T11 = 11;
static const uint8_t T12 = 12;
static const uint8_t T13 = 13;
static const uint8_t T14 = 14;
static const uint8_t DAC1 = 17;
static const uint8_t DAC2 = 18;
#endif /* Pins_Arduino_h */
I then downloaded the original code of the ESP32 from canbus namely the example "ESP32 TWAI receive example" available in the ESP32 examples:
/* 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 40
#define TX_PIN 39
// Intervall:
#define POLLING_RATE_MS 1000
static bool driver_installed = false;
void setup() {
delay (1000);
// 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_125KBITS(); //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);
}
}
}
After testing the code on the car... miraculously I received the frames from the canbus.
Conclusion :
the configuration of the outputs of the RX and TX pins works well on the ESP32 S2 mini Lolin board I do not know if all of my old SN65HVD230 canbus cards were fakes or if the card is not compatible with this type of material in any case they did not work for me MCP2551 based canbus modules work perfectly and finally, the TWAI example of the ESP32 actually also works in order to acquire the frames of a car I hope that all of this information will be useful to someone else who finds themselves in the same situation as me.
See you soon for new experiences
One request... Can you wrap the code in 3x backticks instead of 1? Also the 3 backticks are not in-line, so need their own line in your post. Like this:
Une demande... Pouvez-vous envelopper le code en 3x backticks au lieu de 1 ? De plus, les 3 backticks ne sont pas en ligne, vous avez donc besoin de leur propre ligne dans votre message. Comme ça:
Modifiactions done
Board
ESP32 S2 mini Lolin / Wemos
Device Description
A mini wifi cards based on ESP32-S2FN4R2.
Hardware Configuration
In order to recover the canbus signal with an ESP32, it is advisable to use a transceiver of the type SN65HVD230 Can Board Connecting MCUs 1 to be placed at the level of the TX and RX pins of the board
Version
v2.0.8
IDE Name
IDE Arduino
Operating System
Windows 10
Flash frequency
40
PSRAM enabled
yes
Upload speed
115200
Description
Good morning I am trying to retrieve information from the comfort canbus in 125kbit from a car using an ESP32 LOLIN S2 MINI + SN65HVD230 transceiver
Here is what I have already done:
I managed to read data from the car and find the correct frame id from canbus which I should use in my code. But the problem is that I managed this with a CANBed board from Seeed Studio CAN bus development kit for Arduino (ATmega32U4 with MCP2515 and MCP2551)
This board is based on an ATmega32U4 with the Arduino Leonardo bootloader coupled to an MCP2515 CAN bus controller and MCP2551 CAN bus transceiver
I used this code to retrieve the AC information I needed and it works perfectly
include // https://github.com/autowp/arduino-mcp2515 + https://github.com/watterott/Arduino-Libs/tree/master/digitalWriteFast
///////////////////// // Configuration // /////////////////////
define CS_PIN_CAN0 17
define SERIAL_SPEED 115200
define CAN_SPEED CAN_125KBPS // Entertainment CAN bus - Low speed
define CAN_FREQ MCP_16MHZ // Switch to 8MHZ if you have a 8Mhz module
//////////////////// // Initialization // ////////////////////
MCP2515 CAN0(CS_PIN_CAN0); // CAN-BUS Shield N°1
//////////////////// // Variables // ////////////////////
String LeftTemp; String RightTemp;
// CAN-BUS Messages struct can_frame canMsgRcv;
void setup() {
CAN0.reset(); CAN0.setBitrate(CAN_SPEED, CAN_FREQ); while (CAN0.setNormalMode() != MCP2515::ERROR_OK) { delay(100); } }
void loop() {
// Receive CAN messages from the car if (CAN0.readMessage( & canMsgRcv) == MCP2515::ERROR_OK) { int id = canMsgRcv.can_id; int len = canMsgRcv.can_dlc;
} }
include "driver/gpio.h"
include "driver/twai.h"
//#define ACCEPT_ID 0x036 //11 bit standard format ID;if not define any ID,accept all IDs.
ifdef ACCEPT_ID
define MASK_ID ~(0x7FF << 21) //32 bit standard format ID,but only care for the frist 11 bits.
define TWAI_FILTER_CONFIG() {.acceptance_code = (ACCEPT_ID << 21),.acceptance_mask = MASK_ID,.single_filter = true};
endif
// Pins used to connect to CAN bus transceiver:
define RX_PIN 2
define TX_PIN 1
// Intervall:
define POLLING_RATE_MS 10
void setup() { // put your setup code here, to run once: delay (5000); Serial.begin(115200); twai_init(); }
void loop() { // put your main code here, to run repeatedly: twai_receive(); }
void twai_init() { //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_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_125KBITS();
ifdef ACCEPT_ID
twai_filter_config_t f_config = TWAI_FILTER_CONFIG();
else
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
endif
//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; } }
void twai_receive() { //Wait for message to be received twai_message_t message; if (twai_receive(&message, pdMS_TO_TICKS(POLLING_RATE_MS)) == ESP_OK) { // Serial.println("Message received"); Serial.println("ID DATA----------->"); Serial.print(message.identifier, HEX); if (!(message.rtr)) { for (int i = 0; i < message.data_length_code; i++) { Serial.print(" "); Serial.print(message.data[i], HEX); } } Serial.println(" "); } else { Serial.println("Failed to receive message"); return; } }
Other Steps to Reproduce
I carried out other tests by now defining in input TX = 39 and RX = 37 as defined in my original code.
Here is the wiring used. Connecting the TX pin to the RX pin
Conclusion, it also works so the TX / RX serial link pins are well configurable.
Another remark noted, obviously the serial link does not work on the TX and RX pins if the baud exceeds 100,000. So with a baud of 115,200 it does not work.
Last observation, the definition of the RX / TX pins in the pins_arduino.h file does not change anything in this code. The definition of pins in the "SoftwareSerial" object takes precedence over the definition of pins in the pins_arduino.h file
I have checked existing issues, online documentation and the Troubleshooting Guide