# HID Reporter

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/132/845/medium800/hacks_hidrep-1740.jpg?1727828471)

Are you into weird USB keyboards you dug out of the basement of a mysterious research lab? Nice! Do some keys act funny and send confusing messages to your host computer? Now you can find out&nbsp;_exactly_ what your USB keyboard is saying with the HID Reporter.&nbsp;

Plug your keyboard into the USB Host FeatherWing and the hex codes for up to six keys are displayed on the built-in TFT screen whenever a key is pressed.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/846/medium800/hacks_hidrep-1746.jpg?1727828515)

## Parts
### Adafruit ESP32-S2 TFT Feather - 4MB Flash, 2MB PSRAM, STEMMA QT

[Adafruit ESP32-S2 TFT Feather - 4MB Flash, 2MB PSRAM, STEMMA QT](https://www.adafruit.com/product/5300)
We've got a new machine here at Adafruit, it can uncover your deepest desires. Don't believe me? I'll turn it on right now to prove it to you! What, you want unlimited mozzarella sticks? OK well, that's not something we can provide. But we can provide your...

In Stock
[Buy Now](https://www.adafruit.com/product/5300)
[Related Guides to the Product](https://learn.adafruit.com/products/5300/guides)
![Adafruit ESP32-S2 TFT Feather powered on by a USB- C power source displaying the product tittle in a red, yellow, green, white and blue. ](https://cdn-shop.adafruit.com/640x480/5300-06.jpg)

### Adafruit USB Host FeatherWing with MAX3421E

[Adafruit USB Host FeatherWing with MAX3421E](https://www.adafruit.com/product/5858)
Lots of microcontrollers these days have USB ports on them, to program or debug, act like a keyboard or disk drive, or simply&nbsp;send data between a computer and your firmware. But did you know that you can also add a USB Host port? That means that your microcontroller project can have a...

In Stock
[Buy Now](https://www.adafruit.com/product/5858)
[Related Guides to the Product](https://learn.adafruit.com/products/5858/guides)
![Video of a Black woman's green-manicured hand plugging in a USB TrinKey board into a USB Host FeatherWing assembled on a Doubler below an Adafruit TFT microcontroller board.](https://cdn-shop.adafruit.com/product-videos/640x480/5858-05.jpg)

### FeatherWing Doubler - Prototyping Add-on For All Feather Boards

[FeatherWing Doubler - Prototyping Add-on For All Feather Boards](https://www.adafruit.com/product/2890)
This is the **FeatherWing Doubler** - a prototyping add-on and more for all Feather boards. This is similar to our [FeatherWing Proto](https://www.adafruit.com/products/2884) except there are two! The magic of the Doubler comes when stacking a Feather and another...

In Stock
[Buy Now](https://www.adafruit.com/product/2890)
[Related Guides to the Product](https://learn.adafruit.com/products/2890/guides)
![Double prototyping feather wing PCB with socket headers installed](https://cdn-shop.adafruit.com/640x480/2890-01.jpg)

# HID Reporter

## Assemble the HID Reporter

## Solder the Headers
### Feather Headers

Solder the male headers under the Feather as shown.

[This guide](https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/assembly) has more info on soldering header pins onto the Feather board.

![hacks_hidrep-1718.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/819/medium640/hacks_hidrep-1718.jpg?1727821522)

![hacks_hidrep-1717.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/820/medium640/hacks_hidrep-1717.jpg?1727821716)

### FeatherWing Headers

Solder the male headers under the FeatherWing as shown.

![hacks_hidrep-2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/821/medium640/hacks_hidrep-2.jpg?1727821734)

![hacks_hidrep-1715.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/822/medium640/hacks_hidrep-1715.jpg?1727821755)

### FeatherWing Doubler

Solder the female headers into the FeatherWing doubler as shown.&nbsp;

[This page](https://learn.adafruit.com/featherwing-proto-and-doubler/assembly) has info on soldering headers into doublers.

![hacks_hidrep-1713.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/817/medium640/hacks_hidrep-1713.jpg?1727821313)

## Plug 'em In

Plug the Feather and FeatherWing into the doubler as shown.

![hacks_hidrep-1711.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/823/medium640/hacks_hidrep-1711.jpg?1727821855)

![](https://cdn-learn.adafruit.com/assets/assets/000/132/827/medium800/hacks_hidrep-1722.jpg?1727821909)

# HID Reporter

## Arduino IDE Setup

Warning: 

The first thing you will need to do is to download the latest release of the Arduino IDE. You will need to&nbsp;be using&nbsp; **version 1.8** &nbsp;or higher for this guide

[Arduino IDE Download](http://www.arduino.cc/en/Main/Software)
To use the ESP32-S2/S3 with Arduino, you'll need to follow the steps below for your operating system. You can also [check out the Espressif Arduino repository for the most up to date details on how to install it](https://github.com/espressif/arduino-esp32#using-through-arduino-ide).

After you have downloaded and installed **&nbsp;the latest version of Arduino IDE** , you will need to start the IDE&nbsp;and navigate to&nbsp;the&nbsp; **Preferences** &nbsp;menu. You can access it from the&nbsp; **File** &nbsp;menu in&nbsp;_Windows_&nbsp;or&nbsp;_Linux_, or the&nbsp; **Arduino** &nbsp;menu on&nbsp;_OS X_.

![](https://cdn-learn.adafruit.com/assets/assets/000/101/639/medium800/esp32_s2_arduino_ide_setup_flora_prefs.png?1618870383)

A dialog will pop up just like the one shown below.

![](https://cdn-learn.adafruit.com/assets/assets/000/101/640/medium800/esp32_s2_arduino_ide_setup_flora_Screen_Shot_2015-05-07_at_9.07.21_AM.png?1618870405)

We will be adding a URL to the new&nbsp; **Additional Boards Manager URLs** &nbsp;option. The list of URLs is comma separated, and&nbsp;_you will only have to add each&nbsp;URL once._&nbsp;New Adafruit boards and updates to existing boards&nbsp;will automatically be picked up&nbsp;by the Board Manager each time&nbsp;it is opened. The URLs point to index files that the Board Manager uses to build the list of available & installed boards.

To find the most up to date list of URLs you can&nbsp;add, you can visit the list of&nbsp;[third party board URLs on the Arduino IDE wiki](https://github.com/arduino/Arduino/wiki/Unofficial-list-of-3rd-party-boards-support-urls#list-of-3rd-party-boards-support-urls). We will only need to add one URL to the IDE in this example, but&nbsp;_ **you can add multiple URLS by separating them with commas** _. Copy and paste the link below into the&nbsp; **Additional Boards Manager URLs** &nbsp;option in the Arduino IDE preferences.

`https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json`

![](https://cdn-learn.adafruit.com/assets/assets/000/125/110/medium800/esp32_s2_s3_arduino_ide_setup_Screenshot_2023-10-12_at_11.05.03_AM.png?1697133995)

If you're an advanced hacker and want the 'bleeding edge' release that may have fixes (or bugs!) you can check out the dev url instead:

`https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json`

If you have multiple boards you want to support, say ESP8266 and Adafruit, have both URLs in the text box separated by a comma (,)

Once done click&nbsp; **OK** &nbsp;to save the new preference settings.

The next step is to actually install the Board Support Package (BSP). Go to the **Tools → Board → Board Manager** &nbsp;submenu. A dialog should come up with various BSPs. Search for **esp32**. Choose the latest version, which may be later than the version shown in the screenshot below.

![](https://cdn-learn.adafruit.com/assets/assets/000/107/162/medium800/esp32_s2_arduino_ide_setup_Screen_Shot_2021-12-09_at_9.58.40_AM.png?1639072797)

Click the **Install** button and wait for it to finish. Once it is finished, you can close the dialog.

In the **Tools → Board** submenu you should see **ESP32 Arduino** and in that dropdown it should contain the ESP32 boards along with all the latest ESP32-S2/S3 boards.

# HID Reporter

## Code the HID Reporter

Warning: An issue was introduced in version 3.2.0 of the ESP32 Arduino board support package that causes [MAX3421E examples to not compile](https://github.com/adafruit/Adafruit_TinyUSB_Arduino/issues/513). To compile the code for this project, downgrade to a previous version of the board support package (ex. 3.1.3).

The code below reads keypresses from a USB keyboard plugged into the USB Host FeatherWing and displays the corresponding keycodes on the TFT display of the Feather ESP32-S2.

First, install the necessary libraries in the Arduino IDE:

- **Adafruit GFX Library**
- **Adafruit ST7789 TFT Library**
- **TinyUSB for Adafruit ESP32-S2**

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/HID_Reporter/USB_Host_HID_Reporter/USB_Host_HID_Reporter.ino

This code initializes the Feather ESP32-S2's TFT screen, mounts a USB HID device (keyboard), and displays any keycodes received from the device.

## Code Explainer

### Include Libraries

- **`usbh_helper.h`** : This header contains helper functions and configurations to interface with the USB Host controller and handle HID (Human Interface Devices) like a keyboard.
- **`Adafruit_GFX` and `Adafruit_ST7789`** : These libraries are used to control the TFT display. `Adafruit_GFX` provides generic graphics functions, while `Adafruit_ST7789` is specific to the ST7789 TFT driver used by the Feather ESP32-S2 TFT.
- **Fonts** : Two different fonts (`FreeMono18pt7b` and `FreeMono12pt7b`) are used for displaying text on the TFT screen in different sizes.

```auto
#include "usbh_helper.h"
#include &lt;Adafruit_GFX.h&gt;
#include &lt;Adafruit_ST7789.h&gt;
#include &lt;Fonts/FreeMono18pt7b.h&gt;
#include &lt;Fonts/FreeMono12pt7b.h&gt;
```

### Initialize Display

This line initializes the TFT object, specifying the control pins: `TFT_CS` (chip select), `TFT_DC` (data/command), and `TFT_RST` (reset). These pins are defined in `usbh_helper.h` based on the hardware configuration of the Feather ESP32-S2 TFT.

`Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);`

### Setup

- **`Serial.begin(115200)`**: Initializes serial communication at 115200 baud, useful for debugging via the serial monitor.
- **`pinMode` and `digitalWrite`** : These lines control the TFT's backlight and power. The backlight is turned on by setting `TFT_BACKLITE` to HIGH, and the I2C power (which powers the screen) is enabled by setting `TFT_I2C_POWER` to HIGH.
- **`tft.init(135, 240)`**: Initializes the TFT display with a resolution of 135x240 pixels.
- **`tft.setRotation(3)`**: Rotates the display to the correct orientation.
- **`tft.fillScreen(ST77XX_BLACK)`**: Clears the screen by filling it with black.
- **Text Setup** : The display is prepared to print "HIDreporter" at the top of the screen using a green color and a specific font.
- **`USBHost.begin(1)`**: Initializes the USB Host on the first port (port 1). This is necessary to allow the Feather ESP32-S2 to act as a USB host and handle devices like keyboards.
- **`Serial.println`** : Outputs a message to the serial monitor indicating that the HID reporter has started.

```auto
void setup() {
  Serial.begin(115200);
  pinMode(TFT_BACKLITE, OUTPUT);
  digitalWrite(TFT_BACKLITE, HIGH);

  pinMode(TFT_I2C_POWER, OUTPUT);
  digitalWrite(TFT_I2C_POWER, HIGH);
  delay(10);
  
  tft.init(135, 240);
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);
  
  tft.setFont(&amp;FreeMono18pt7b);
  tft.setCursor(0, 20);
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(1);
  tft.println("HIDreporter");

  USBHost.begin(1);
  Serial.println("TinyUSB HID Device Reporter");
}
```

### Main Loop

- **`USBHost.task()`**: Continuously runs the USB Host task, which manages communication with connected USB devices (e.g., keyboards). It handles detection, setup, and communication with the device.
- **`Serial.flush()`**: Ensures all serial output has been transmitted. This is mainly used for debugging purposes.

```auto
void loop() {
  USBHost.task();
  Serial.flush();
}
```

### HID Callbacks

These functions are defined as **extern "C"** since they're invoked by the USB host stack when certain events (like mounting or unmounting a USB device) occur.

#### HID Device Mounted

- This function is called when a USB HID device (e.g., a keyboard) is mounted (connected to the USB Host).
- **`tuh_vid_pid_get`** : Retrieves the Vendor ID (VID) and Product ID (PID) of the connected USB device and displays this information on the TFT screen and serial monitor.
- **`tft.fillRect`** : Clears a portion of the screen to make room for new text.
- **`tuh_hid_receive_report`** : Requests to receive a report from the HID device. A report contains data from the device (e.g., key presses from the keyboard).

```auto
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) {
  uint16_t vid, pid;
  tuh_vid_pid_get(dev_addr, &amp;vid, &amp;pid);

  tft.fillRect(0, 34, 240, 80, ST77XX_BLACK);
  tft.setFont(&amp;FreeMono12pt7b);
  tft.setCursor(0, 50);
  tft.printf("VID=%04x,PID=%04x\r\n", vid, pid);
  
  if (!tuh_hid_receive_report(dev_addr, instance)) {
    Serial.printf("Error: cannot request to receive report\r\n");
  }
}
```

#### HID Device Unmounted

- This function is called when a USB HID device is unmounted (disconnected).
- It clears part of the screen and displays the message "-- unmounted --" in yellow to indicate that the device is no longer connected.

```auto
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
  tft.fillRect(0, 34, 240, 140, ST77XX_BLACK);
  tft.setFont(&amp;FreeMono12pt7b);
  tft.setTextColor(ST77XX_YELLOW);
  tft.setCursor(0, 50);
  tft.printf("--  unmounted  --");
  tft.setTextColor(ST77XX_GREEN);
}
```

#### HID Report Received

- This function is invoked when a new report (keycode) is received from the connected HID device.
- It loops through the bytes in the report and prints the hexadecimal values on both the TFT display and the serial monitor.
- **`tuh_hid_receive_report`** is called again at the end to continuously request new reports from the HID device.

```auto
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
  tft.fillRect(0, 64, 240, 80, ST77XX_BLACK);
  tft.setCursor(0, 88);
  tft.setFont(&amp;FreeMono18pt7b);

  for (uint16_t i = 0; i &lt; len; i++) {
    tft.printf("%02X ", report[i]);
  }
  
  if (!tuh_hid_receive_report(dev_addr, instance)) {
    Serial.printf("Error: cannot request to receive report\r\n");
  }
}
```

# HID Reporter

## Use the HID Reporter

![](https://cdn-learn.adafruit.com/assets/assets/000/132/856/medium800thumb/hacks_hidrep_dem01.jpg?1727829846)

## Power the System

You can power the system via the Feather's USB-C port or through a LiPo battery.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/847/medium800/hacks_hidrep-1724.jpg?1727828700)

## Attach the USB Keyboard

Plug a USB keyboard into the USB-A port of the USB Host FeatherWing. The keyboard's USB Vendor ID and Product ID will be displayed.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/848/medium800/hacks_hidrep-1734.jpg?1727828734)

![](https://cdn-learn.adafruit.com/assets/assets/000/132/849/medium800/hacks_hidrep-1725.jpg?1727828754)

When the keyboard is unplugged, a message will appear to let you know :)

![](https://cdn-learn.adafruit.com/assets/assets/000/132/853/medium800/hacks_hidrep-1731.jpg?1727829234)

You can plug in a different keyboard and continue testing. Note the different VID and PID.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/854/medium800/hacks_hidrep-1744.jpg?1727829285)

![](https://cdn-learn.adafruit.com/assets/assets/000/132/855/medium800/hacks_hidrep-1746.jpg?1727829307)

## View Keycodes

Once the setup is running, press keys on the USB keyboard. The corresponding keycodes will be displayed on the TFT screen in hexadecimal format.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/850/medium800/hacks_hidrep-1738.jpg?1727828824)

![](https://cdn-learn.adafruit.com/assets/assets/000/132/851/medium800/hacks_hidrep-1729.jpg?1727828844)

![](https://cdn-learn.adafruit.com/assets/assets/000/132/852/medium800/hacks_hidrep-1730.jpg?1727829106)

## Troubleshooting

If the keyboard is plugged in but doesn't appear to connect, press the Rest button on the Feather (or FeatherWing, they're the same pin).

Some keyboards with integrated USB hubs won't show up properly, such as the official Raspberry Pi keyboard, for this reason.


## Featured Products

### Adafruit ESP32-S2 TFT Feather - 4MB Flash, 2MB PSRAM, STEMMA QT

[Adafruit ESP32-S2 TFT Feather - 4MB Flash, 2MB PSRAM, STEMMA QT](https://www.adafruit.com/product/5300)
We've got a new machine here at Adafruit, it can uncover your deepest desires. Don't believe me? I'll turn it on right now to prove it to you! What, you want unlimited mozzarella sticks? OK well, that's not something we can provide. But we can provide your...

In Stock
[Buy Now](https://www.adafruit.com/product/5300)
[Related Guides to the Product](https://learn.adafruit.com/products/5300/guides)
### Adafruit USB Host FeatherWing with MAX3421E

[Adafruit USB Host FeatherWing with MAX3421E](https://www.adafruit.com/product/5858)
Lots of microcontrollers these days have USB ports on them, to program or debug, act like a keyboard or disk drive, or simply&nbsp;send data between a computer and your firmware. But did you know that you can also add a USB Host port? That means that your microcontroller project can have a...

In Stock
[Buy Now](https://www.adafruit.com/product/5858)
[Related Guides to the Product](https://learn.adafruit.com/products/5858/guides)
### FeatherWing Doubler - Prototyping Add-on For All Feather Boards

[FeatherWing Doubler - Prototyping Add-on For All Feather Boards](https://www.adafruit.com/product/2890)
This is the **FeatherWing Doubler** - a prototyping add-on and more for all Feather boards. This is similar to our [FeatherWing Proto](https://www.adafruit.com/products/2884) except there are two! The magic of the Doubler comes when stacking a Feather and another...

In Stock
[Buy Now](https://www.adafruit.com/product/2890)
[Related Guides to the Product](https://learn.adafruit.com/products/2890/guides)

## Related Guides

- [Adafruit ESP32-S2 TFT Feather](https://learn.adafruit.com/adafruit-esp32-s2-tft-feather.md)
- [Adafruit USB Host FeatherWing with MAX3421E](https://learn.adafruit.com/adafruit-usb-host-featherwing-with-max3421e.md)
- [RPi Stock Alert Alarm](https://learn.adafruit.com/rpi-stock-alert-alarm.md)
- [ESPHole Ad Blocker](https://learn.adafruit.com/esphole-ad-blocker.md)
- [MIDI Melody Maker](https://learn.adafruit.com/midi-melody-maker.md)
- [Homefruit FeatherWing Tester](https://learn.adafruit.com/homefruit-featherwing-tester.md)
- [Adafruit IO Basics: Digital Output](https://learn.adafruit.com/adafruit-io-basics-digital-output.md)
- [Air Quality Sensor 3D Printed Enclosure](https://learn.adafruit.com/air-quality-sensor-silo-house.md)
- [CircuitPython displayio Setup for TFT FeatherWings](https://learn.adafruit.com/using-circuitpython-displayio-with-a-tft-featherwing.md)
- [MIDI Laser Harp with Time of Flight Distance Sensors](https://learn.adafruit.com/midi-laser-harp-time-of-flight-sensors.md)
- [Getting Started with Microsoft Azure and CircuitPython](https://learn.adafruit.com/getting-started-with-microsoft-azure-and-circuitpython.md)
- [Adafruit CAN Bus FeatherWing](https://learn.adafruit.com/adafruit-can-bus-featherwing.md)
- [32x32 Square Pixel Art Animation Display](https://learn.adafruit.com/32x32-square-pixel-display.md)
- [File Glider](https://learn.adafruit.com/file-glider.md)
- [MIDI for Makers](https://learn.adafruit.com/midi-for-makers.md)
- [Animatronic Cosplay Wings](https://learn.adafruit.com/animatronic-cosplay-wings.md)
