Site Information

 Loading... Please wait...

ESP32, ESP32-S2 - Serial Port, Native USB Access using Arduino IDE

Posted by Wilfried Voss on

The test setup, as shown in the image, represents the hardware of a new project that requires reading CAN (Controller Area Network) data frames, combining them with real-time information plus GPS position, and storing the result onto an SD card. This post will focus on the ESP32 communicating with the GPS module delivering NMEA 0183 serial data per UART at 9600 baud. 

Since we use the Arduino IDE to program the ESP32, we are using the Serial class, representing the standard approach. Thus, any experienced programmer wouldn't expect any significant problems but think again when it comes to time-sensitive applications. After all, a slow serial rate of 9600 baud may impact the performance. First of all, it is mandatory to reserve a sufficient buffer to store the serial data when the program is busy with other tasks. Secondly, there are some flaws in the ESP32's adaptation of the HardwareSerial class, which came unexpectedly and caused delays during the development process. 

Assigning the Receive Buffer Size

In our project, we assign the serial TX and RX pins and use the HardwareSerial class, as demonstrated in the below shown code. For more information on the use of HardwareSerial, see

In the setup() function, we install a serial buffer of 1024 bytes, which is sufficient to store the full NMEA 0183 serial data string. As noted in the code, the standard Arduino CPU utilizes a 64-byte buffer, while the ESP32 comes with 256 bytes. That size can be increased by using Serial.setRxBufferSize. All this will take care of the serial buffer design. 

The Problem with Serial.readBytes()

The code in the loop() section shows our initial approach to catching the data using the Serial.readBytes() function. However, we encountered a problem with this method, i.e., the function always returns MAX_STRLEN, regardless of the actual number of bytes received. This is most probably a bug in the ESP32's HardwareSerial library for the Arduino IDE. It is therefore highly recommended not to use this function. 

There are a few alternatives to accomplish the functionality. The following code section demonstrates our version: 

ESP32-S2 - Native USB

The reason for using the S2 version of the ESP32 was the need for a high-speed serial connection, namely the ESP32-S2's native USB, which is faster than any other serial connection on the processor. 

We did some time-consuming research on accessing the native USB port. Unfortunately, we found a tremendous amount of misleading information, probably published immediately after the release of the S2 version. In the meantime, however, the situation has improved, and things are much simpler than explained in the original resources. 

First of all, you need to update the Arduino IDE's Board Manager as described here:

The code turned out to be pretty simple, as demonstrated below, but please be aware that this is only a demo sample which should not be used "as is."

espBerry - ESP32 Development Board with Dual Isolated CAN Bus HAT

espBerry - ESP32 Development Board with Dual Isolated CAN Bus HAT

The espBerry DevBoard combines the ESP32-DevKitC development board with any Raspberry Pi HAT by connecting to the onboard RPi-compatible 40-pin GPIO header. 

The Dual Channel CAN Bus expansion HAT, designed for the Raspberry Pi, supports the full CAN2.0 Standard, and it features multi onboard protection circuits, high anti-interference capability, and reliable operation. As a result, it suits applications such as automotive devices or industrial automation.

The HAT is well documented, and there are multiple code samples using the C programming language under the Arduino IDE.