Creating a virtual USB keyboard with the ESP32-S3
Introduction
The idea for this project began during a casual lunch conversation, where were wondering about how challenging it might be to build a virtual keyboard from scratch these days. That sparked my curiosity, especially since the ESP32-S3 natively supports USB OTG. I was eager to try it out for myself and see what was possible.
Choosing the Right Hardware
Before making any purchases, I watched a helpful video by Andreas Spiess that explores the different ways ESP32 controllers handle USB functionality (13-minute video: https://youtu.be/hJSBTFsOnoA?si=-KlphLdLC01w7r4N). Based on what I learned, I chose the ESP32-S3 DevKit. It comes with two USB ports and requires no soldering, making it ideal for quick experimentation.
When the board arrived, I decided to set things up using my old Windows laptop, now running Ubuntu. This way, if anything went wrong (and released the infamous magic smoke), I wouldn't risk my main machine. Plus, I prefer a setup that's easy to reproduce without specialised gear.
Installing the Arduino IDE
To keep things simple, I approached the setup as a new user would. I installed the Arduino IDE directly from the Ubuntu Software Center. However, my first attempt at compiling code resulted in a GLIBC_2.29 missing error.
After checking with ldd --version
, I discovered that my system actually had a newer version of glibc (2.39) already installed.
Troubleshooting Installation Issues
Seeking a solution, I consulted Perplexity and tried running arduino.pip install --upgrade esptool
, hoping it would resolve the issue. Unfortunately, that didn't work.
After several unsuccessful attempts to upgrade the snap versions, I decided to switch strategies. I removed the snap installation: sudo snap remove arduino
Then, I downloaded the Arduino IDE AppImage from the official documentation and installed libfuse2
as recommended.
Flashing the ESP32-S3
With the IDE up and running, I asked an LLM for an example sketch to send "Hello World!" as keyboard input to any connected computer. After selecting the appropriate port, I flashed the code, connected the second USB cable, and waited five seconds. Sure enough, the device typed "Hello World!" virtually, just as expected.
Here's the code I used:
#include <USB.h>
#include <USBHIDKeyboard.h>
USBHIDKeyboard Keyboard;
void setup() {
USB.begin();
Keyboard.begin();
delay(5000);
Keyboard.println("Hello World!");
}
void loop() {
// put your main code here, to run repeatedly:
}
Conclusion
This simple experiment opens up a world of possibilities. With an ESP32-S3, you can create your own stream deck, game controller, or even a custom keyboard—all without complex hardware modifications.
Published: 2025-06-16
Tagged: Electronics ESP32 Microcontroller USB