Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Cdaprod/6b25f11bb4c9f8f5d83fd4550619d35e to your computer and use it in GitHub Desktop.
Save Cdaprod/6b25f11bb4c9f8f5d83fd4550619d35e to your computer and use it in GitHub Desktop.
This setup enables your ESP32-S3 Mini to act as a wireless Bluetooth keyboard using a USB-C keyboard. Ensure you adapt the provided code examples to fit your specific setup and environment.

Building a Wireless Bluetooth USB-C Keyboard with ESP32-S3 Mini

Creating a wireless Bluetooth USB-C keyboard using an ESP32-S3 Mini involves connecting a USB-C keyboard to an ESP32-S3 via a USB Host Shield. This project allows you to transform a wired keyboard into a wireless one, leveraging Bluetooth communication. Below is a detailed guide on how to set up and program this system.

Components Needed

  1. ESP32-S3 Mini
  2. USB Host Shield or USB Host Adapter (e.g., USB Host Shield for Arduino or a USB Host Module)
  3. USB-C Keyboard
  4. USB-C to USB-A Adapter (if necessary)
  5. Connecting wires

Setting Up the USB Host Shield

The USB Host Shield can interface with USB devices and communicate with the ESP32-S3. Below are the steps for wiring and programming.

1. Wiring the USB Host Shield to ESP32-S3

Here's how to connect the USB Host Shield to the ESP32-S3 Mini:

USB Host Shield to ESP32-S3:
USB Host Shield ESP32-S3 Mini
3.3V (VCC) 3.3V
GND GND
MOSI GPIO23
MISO GPIO19
SCK GPIO18
SS (CS) GPIO5

Ensure that the USB Host Shield is compatible with 3.3V logic levels. If it operates at 5V, you may need a level shifter.

2. Programming the ESP32-S3

You need to program the ESP32-S3 to read the USB keyboard inputs via the USB Host Shield and send these inputs over Bluetooth. Below is a simplified example of how you can achieve this:

Code Example

USB Host Keyboard Interface Example (Arduino):

#include <Usb.h>
#include <usbhub.h>
#include <hidboot.h>
#include <BluetoothSerial.h>

// USB Host Shield
USB Usb;
HIDBoot<HID_PROTOCOL_KEYBOARD> Keyboard(&Usb);

// Bluetooth Serial for ESP32
BluetoothSerial SerialBT;

// Key press handler
class KbdRptParser : public KeyboardReportParser
{
protected:
  void OnKeyDown(uint8_t mod, uint8_t key);
  void OnKeyPressed(uint8_t key);
};

KbdRptParser Kbd;

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{
  uint8_t c = OemToAscii(mod, key);

  if (c)
  {
    OnKeyPressed(c);
  }
}

void KbdRptParser::OnKeyPressed(uint8_t key)
{
  SerialBT.write(key); // Send the key press over Bluetooth
}

void setup()
{
  Serial.begin(115200);
  SerialBT.begin("ESP32_Keyboard"); // Start Bluetooth

  if (Usb.Init() == -1)
  {
    Serial.println("USB Host Shield Init Failed");
    while (1); // Halt
  }
  delay(200);
  
  Keyboard.SetReportParser(0, &Kbd);
}

void loop()
{
  Usb.Task();
}

Setting Up Bluetooth HID on ESP32

If you want to use MicroPython and ESP32’s Bluetooth capabilities, you can implement a Bluetooth HID profile. Below is a simplified version for MicroPython:

Bluetooth HID Example (MicroPython):

from machine import Pin
import time
import bluetooth

# Bluetooth HID Keyboard Report Descriptor
HID_DESCRIPTOR = bytes([
    0x05, 0x01,  # USAGE_PAGE (Generic Desktop)
    0x09, 0x06,  # USAGE (Keyboard)
    0xa1, 0x01,  # COLLECTION (Application)
    0x05, 0x07,  # USAGE_PAGE (Keyboard)
    0x19, 0xe0,  # USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,  # USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,  # LOGICAL_MINIMUM (0)
    0x25, 0x01,  # LOGICAL_MAXIMUM (1)
    0x75, 0x01,  # REPORT_SIZE (1)
    0x95, 0x08,  # REPORT_COUNT (8)
    0x81, 0x02,  # INPUT (Data,Var,Abs)
    0x95, 0x01,  # REPORT_COUNT (1)
    0x75, 0x08,  # REPORT_SIZE (8)
    0x81, 0x03,  # INPUT (Cnst,Var,Abs)
    0x95, 0x06,  # REPORT_COUNT (6)
    0x75, 0x08,  # REPORT_SIZE (8)
    0x15, 0x00,  # LOGICAL_MINIMUM (0)
    0x25, 0x65,  # LOGICAL_MAXIMUM (101)
    0x05, 0x07,  # USAGE_PAGE (Keyboard)
    0x19, 0x00,  # USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,  # USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,  # INPUT (Data,Ary,Abs)
    0xc0         # END_COLLECTION
])

# Initialize Bluetooth
ble = bluetooth.BLE()
ble.active(True)

# Set up HID service
hid = bluetooth.UUID(0x1812)
char = (bluetooth.UUID(0x2A4D), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)
service = (hid, (char,),)
ble.gatts_register_services((service,))

# Advertising function
def advertise():
    ble.gap_advertise(100, b'\x02\x01\x06\x03\x03\x12\x18')

advertise()

# Key press function
def send_key(key):
    ble.gatts_notify(0, 1, bytes([0, 0, key, 0, 0, 0, 0, 0]))

# Main loop to process key presses
while True:
    key = get_usb_key()  # Implement this to get key from USB Host Shield
    if key:
        send_key(key)
    time.sleep(0.1)

Summary

  • USB Host Shield: Use a USB Host Shield to interface with the USB-C keyboard.
  • Wiring: Connect the USB Host Shield to the ESP32-S3 using SPI connections.
  • Programming: Implement USB Host functionality to read key presses and send them over Bluetooth HID.

This setup enables your ESP32-S3 Mini to act as a wireless Bluetooth keyboard using a USB-C keyboard. Ensure you adapt the provided code examples to fit your specific setup and environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment