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

Use Serial0 as the default UART in USB-CDC mode #4869

Closed
wants to merge 2 commits into from

Conversation

spectrumjade
Copy link
Contributor

What does this implement/fix?

This change fixes an error that occurs with a default configuration on ESP32 devices that have USB-CDC support (like ESP32-S2 and ESP32-C3). If you bootstrap one of these devices (esphome seems to default to Arduino rather than ESP-IDF) and try to configure them to use UART for something, you'll see the following error at compile time (in my case, this is with an ESP32-S2):

src/esphome/components/uart/uart_component_esp32_arduino.cpp: In member function 'virtual void esphome::uart::ESP32ArduinoUARTComponent::setup()':
src/esphome/components/uart/uart_component_esp32_arduino.cpp:91:25: error: cannot convert 'USBCDC*' to 'HardwareSerial*' in assignment
     this->hw_serial_ = &Serial;
                         ^~~~~~
*** [/data/downstairs-airgradient/.pioenvs/downstairs-airgradient/src/esphome/components/uart/uart_component_esp32_arduino.cpp.o] Error 1

A workaround that has arisen within the community is to disable USB-CDC with a PlatformIO build flag, however this has the effect of breaking hardware logging over USB which is very useful to have:

esphome:
  name: "esp32-s2-device"
  platformio_options: 
    board_build.extra_flags:
      - "-DARDUINO_USB_CDC_ON_BOOT=0"

It seems like the root cause here is that, when USB-CDC mode is enabled, the Serial device points to an instance of USBCDC or HWCDC rather than HardwareSerial. This is great for the logger, which accepts anything that extends the Stream base class (which both USBCDC and HWCDC do), however the UART component expects instances of HardwareSerial explicitly - which is appropriate since CDC serial is probably not useful for UART components anyway.

In USB-CDC mode, it's necessary to reference Serial0 rather than Serial to access UART0 - note the following code from the Arduino HardwareSerial library:

#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
#if !ARDUINO_USB_MODE
#include "USB.h"
#include "USBCDC.h"
#endif
extern HardwareSerial Serial0;
#else
extern HardwareSerial Serial;
#endif

This change updates the UART component code to reference Serial0 if ARDUINO_USB_CDC_ON_BOOT is true. This allows the code to compile and run as expected. We unfortunately can't always use Serial0 because it isn't defined as such outside of USB-CDC mode.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Other

Test Environment

  • ESP32
  • ESP32 IDF
  • ESP8266
  • RP2040

Checklist:

  • The code change is tested and works locally.
  • Tests have been added to verify that the new code works (under tests/ folder).

If user exposed functionality or configuration variables are added/changed:

@probot-esphome
Copy link

Hey there @esphome/core, mind taking a look at this pull request as it has been labeled with an integration (uart) you are listed as a code owner for? Thanks!
(message by CodeOwnersMention)

@kroimon
Copy link
Contributor

kroimon commented May 21, 2023

👍 This also matches the documentation:

To use the UART as serial output, you can use Serial0.print("Hello World!"); instead of Serial.print("Hello World!"); which will be printed using USB CDC.

However, this probably needs coordination with #4853.

@spectrumjade spectrumjade mentioned this pull request May 21, 2023
13 tasks
@jesserockz
Copy link
Member

Related: #4658

@Mrten
Copy link

Mrten commented Aug 11, 2023

would probably fix issues/3988

Copy link
Contributor

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. Thank you for your contributions.

@github-actions github-actions bot added the stale label Nov 10, 2023
@github-actions github-actions bot closed this Nov 17, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Nov 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants