ESP32 S3 as USB host with TinyUSB?

I’m trying to program an esp32-s3-n16r8 using platformio to serve as USB OTG host to connect a keyboard to it. The esp32 should then display the pressed key on the serial monitor.

Unfortunately, I struggle to get platformio.ini and libraries (e.g. TinyUSB) etc right to get it to compile/work. Does someone have a minimal example for this?

@maxgerhardt Would you by any chance happen to know?

I actually would not recommend to use TinyUSB for that, because you have to do quite a bit of work to parse the keyboard HID packet structure.

See the examples:

I found this library instead:

This is building on top of the official ESP-IDF library from Espressif: “USB Host HID (Human Interface Device) Driver” (docs, repo). They have an example

https://github.com/esp32beans/ESP32_USB_Host_HID/blob/e5cc02275155ddfa8a3d087a8094a865b5d07b17/examples/hid_host_example/hid_host_example.ino

That is compilable for an ESP32-S3 and can detect connected keyboards and mice.

I compiled this sketch in PlatformIO with the latest Arduino-ESP32 3.3.1 core thanks to the PIO Arduino platform onto my ESP32-S3-DevkitC-N16R8 board.

This board conveniently has 2 USB-C ports, one going to a USB-to-UART chip and then to the UART port of the ESP32S3 (labeled “COM”), and one going straight to the native ESP32S3 USB pins (labeled “USB”). I found its schematics here.

On my board specifically, I had to connect a solder pad with solder so that the “USB” port provides +5V to the connected keyboard.

That pad was labeled “USB-OTG” and bypasses a diode to allow the 5V rail (as provided from the “COM” USB-C port) to be directly connected to the “USB” USB-C port, powering the keyboard.

This also makes it that you absolutely cannot plug both the “USB” and “COM” port into the computer at the same time, since they would be backfeeding each other. You would need to remove the solder link to be able to use the ESP32S3 board in USB device mode again.

While I was at it, I also soldered the solder jumper pad for “IN-OUT”

This makes the pin labeled “5V” on the header of the board actually output 5V directly, and not only accept 5V as input to the power the board. This is also useful of you don’t want to solder the “USB-OTG” jumper so you can grab the needed 5V from that pin and somehow (with USB breakout boards) put it on the USB-A conncetor to power your USB device.

Then, I connected a USB-C to USB-A OTG adapter to the “USB” USB-C port and plugged my (german) keyboard in. It detected the keyboard successfully and everything I typed on the keyboard showed up in the serial monitor (which assumed a US QWERTY layout..)


Tested keyboard: ISY IKE 1000

3 Likes

I also uploaded the code to

1 Like

Ah, I actually found out that it also compiles with the official platform = espressif32@6.12.0, so there’s no need to bring in the PIOArduino platform.

I’ve updated the repo to only use the official platform (uses Arduino-ESP32 v2.0.17), while giving you the option for PIO Arduino in the commented out section. See https://github.com/maxgerhardt/esp32s3-usb-host-keyboard/blob/main/platformio.ini.

@sivar2311 's board definition for the S3 N16R8 board worked nicely.

FYI, USB Host using Adafruit TinyUSB on ESP32S3 doesn’t seem to be possible with the regular Arduino framework right now:

Their TinyUSB config file also hardcodes that for USB hosts, a MAX3421 external USB SPI chip is used.

Thanks a lot @maxgerhardt for your fast reply and amazing help! I tried with espressif32@6.12.0 and it compiles nicely and works!

Ultimately, I would like to use the ESP32-S3 to read in a diy HID gamepad (rahter than Keyboard) based on Seeeduino Xiao using TinyUSB, but I saw that I can use the “generic” for it, like in another example in that repo. :slight_smile:

1 Like

Thank you @maxgerhardt. I’ve been searching for an explanation for those bridging solder pads. And thanks for the repo examples.

1 Like