Skip to content
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

ESP32 S2 mini Lolin / Wemos car canbus #8199

Closed
1 task done
Strangistra opened this issue May 12, 2023 · 12 comments
Closed
1 task done

ESP32 S2 mini Lolin / Wemos car canbus #8199

Strangistra opened this issue May 12, 2023 · 12 comments
Labels
Resolution: Awaiting response Waiting for response of author Status: Community help needed Issue need help from any member from the Community. Type: Question Only question

Comments

@Strangistra
Copy link

Strangistra commented May 12, 2023

Board

ESP32 S2 mini Lolin / Wemos

Device Description

A mini wifi cards based on ESP32-S2FN4R2.
image

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:

/////////////////////
//    Libraries    //
/////////////////////
#include <SPI.h>
#include <Wire.h>

#include <mcp2515.h> // 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() {

    // Initalize Serial for debug
    Serial.begin(SERIAL_SPEED);

    // CAN-BUS from car
    Serial.print("Initialization CAN0");
    
  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;

    if (id == 464){

     char tmp[3];

        snprintf(tmp, 3, "%02X", canMsgRcv.data[5]);
        LeftTemp = String (tmp);
        Serial.print("LeftTemp = ");  
        Serial.println(LeftTemp);
        Serial.println(tmp);       

        snprintf(tmp, 3, "%02X", canMsgRcv.data[6]);       
        RightTemp = String (tmp);
        Serial.print("RightTemp = ");        
        Serial.println(RightTemp);
        Serial.println(tmp);    

       Serial.println();
    }

   } 
}
  • In order to recover the canbus signal from the car, it is advisable to use a trancreicever of the SN65HVD230 Can Board Connecting MCUs type to be placed at the level of the TX and RX pins of the card

  • So I bought the necessary components and made this assembly:
    image

  • I then loaded the code for ESP32 which allows to process the canbus signal renamed TWAI

  • It obviously didn't work

  • By putting a delay of 5000 ms at the start of void setup() I have the initialization messages which go up correctly:
    --- Driver installed
    --- Driver started
    --- CAN Alerts reconfigured

  • Then I have the error message "Failed to receive message" which loops

I don't understand what is not working. I don't know if it's a software or hardware issue.

Sketch

#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;
  }
}

Debug Message

Compilation OK

Other Steps to Reproduce

  • I tested SoftwareSerial communication by putting TX on pin 1 and RX on pin 2 and it worked.
  • I tested this with the following code which reads in the serial monitor the message sent by TX.
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 1); // RX, TX

void setup()
{
  delay (5000);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Native USB only
  }

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}
  • By entering a text in the console then "ENTER", when I connect RX and TX then I have the message that is displayed on the serial console.
  • If I unplug the connection between RX and TX then I have nothing coming up in the console.
  • Conclusion, there is indeed a serial link via TX and RX on an ESP32-S2 Lolin min

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
    image

  • 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

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@Strangistra Strangistra added the Status: Awaiting triage Issue is waiting for triage label May 12, 2023
@mrengineer7777 mrengineer7777 added Type: Question Only question Status: Community help needed Issue need help from any member from the Community. and removed Status: Awaiting triage Issue is waiting for triage labels May 12, 2023
@SuGlider
Copy link
Collaborator

Please set the Log output to Verbose and run the application. You can report here the serial console output.

@SuGlider
Copy link
Collaborator

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

@SuGlider
Copy link
Collaborator

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

@SuGlider
Copy link
Collaborator

@SuGlider
Copy link
Collaborator

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.

@Strangistra
Copy link
Author

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.

@Strangistra
Copy link
Author

This is the case with your mentioned issue #3921

@designer2k2
Copy link
Contributor

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:

https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino

(i made this example and here is my working setup with a SN65HVD230 : #7430 (comment)

@VojtechBartoska
Copy link
Collaborator

any updates @Strangistra?

@VojtechBartoska VojtechBartoska added the Resolution: Awaiting response Waiting for response of author label Aug 18, 2023
@Strangistra
Copy link
Author

Strangistra commented Aug 18, 2023

/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
image

I then made the following connection:
image

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:
image

/* 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

@TD-er
Copy link
Contributor

TD-er commented Aug 19, 2023

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:
image

@Strangistra
Copy link
Author

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: image

Modifiactions done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Awaiting response Waiting for response of author Status: Community help needed Issue need help from any member from the Community. Type: Question Only question
Projects
None yet
Development

No branches or pull requests

6 participants