EspUsbHost

repository·main·Indexed 41 days ago

https://github.com/tanakamasayuki/espusbhost

An Arduino library that enables ESP32-S2, S3, and P4 microcontrollers to act as USB Hosts. It supports various USB classes including HID, Mass Storage, MIDI, CDC, and USB Audio Class (UAC). The library provides APIs for managing USB streams, handling audio output requests, and controlling hardware-level mute and volume via Feature Units.

Tokens
187.7K
Snippets
310
Records
710
Agent score
50%

What's inside EspUsbHost

  1. Overview of EspUsbHost

    main

    EspUsbHost is an Arduino library designed for using USB Host functionality on ESP32-S3, ESP32-S2, and ESP32-P4 microcontrollers.

    Key architectural feature: USB events are processed in a background FreeRTOS task. This means you do not need to manually call any polling functions inside your loop(). Instead, you register callbacks in setup() and call begin() to start the library.

  2. Hardware Support for Mirabox N3 / Ajazz AKP03 Macro Pads

    main

    This example supports various white-label LCD macro pads (Mirabox N3, Ajazz AKP03, etc.) that share the same design but use different VID/PID combinations. Because VID/PID can vary by brand, MacroPadN3Device::begin() identifies the device by its HID interface characteristics: a claimed HID interface containing both an interrupt IN endpoint and an interrupt OUT endpoint of 1024 bytes or larger.

    Supported Hardware VID:PID:

    • STREONOR S6: 1500:3006 (Used in this example)
    • Mirabox Stream Dock N3: 6602:1000, 6602:1002, 6603:1002, 6603:1003
    • Ajazz AKP03 series: 0300:300x
    • Unbranded / White-label: 1500:3001
  3. Use EspUsbHost UsbNetwork as a USB Ethernet Host

    main

    The UsbNetwork example allows an ESP32-S3 (or other USB Host compatible Arduino-ESP32 board) to act as a USB host for CDC-NCM or CDC-ECM Ethernet adapters. It integrates the USB NIC into the lwIP stack, enabling standard Arduino networking (NetworkClient, HTTPClient) over USB without Wi-Fi.

    This is the host-side counterpart to the EspUsbDevice UsbNetwork sketch (which acts as the network device/DHCP server).

    // Example usage pattern: The sketch will automatically:
    // 1. Enumerate USB devices
    // 2. Find CDC-NCM/ECM interfaces
    // 3. Attach them to lwIP via networkAttachNetif()
    // 4. Obtain an IP address (e.g., 192.168.7.x)
    // 5. Execute HTTP GET if HTTP_TEST_URL is set
  4. Review USB class support and implementation status

    main

    EspUsbHost provides varying levels of support for different USB classes. Use the following status indicators to plan your implementation:

    • ✅ Implemented: Full or core support available (e.g., HID, USB Serial/CDC ACM, USB MIDI, HUB, CCID, Vendor-specific bulk/control).
    • 📄 Example-only (Best effort): The library does not include specific logic for these classes; instead, it provides examples using the underlying Vendor or Serial APIs (e.g., USB Graphics Adapters, USBTMC, Printers, certain HID Macro Pads).
    • 🟡 Partially implemented: Core logic exists but has known limitations (e.g., UVC/USB Camera).
    • 🔲 Experimental: Features under active development (e.g., UAC/USB Audio, MSC/Mass Storage, CDC-NCM/ECM).

    Note on USB Graphics/Display: For display devices like the AX206 or DL-1xx, the library provides examples using vendor bulk APIs, but does not include device-specific drivers. If you require high frame rates or support for other adapters, consider specialized libraries like Pico_USB_Disp.

  5. Control the ALIENTEK DP100 Power Supply via USB HID

    main

    This example demonstrates how to control the ALIENTEK DP100 (model ATK-MDP100, VID/PID 2e3c:af01) power supply using the EspUsbHost HID API. You can read device information, input/output voltage and current, temperature, and set voltage, current limits, and output ON/OFF status.

    Core Components

    • Dp100Protocol.hpp: Defines the 64-byte report frame format, CRC-16/MODBUS, and payload structures. It is independent of Arduino or USB libraries.
    • Dp100Device.hpp: Handles HID interface detection, sending interrupt OUT requests, and mapping incoming interrupt IN reports.
    • Dp100Power.hpp: Provides a high-level API for interacting with electrical units (Volts, Amperes, Celsius) and configuration settings.
    • EspUsbHostDp100Power.ino: A complete example sketch that connects to the device, displays info/settings, and periodically reads real-time measurements.
    /* Example usage pattern in EspUsbHostDp100Power.ino */
    // 1. Connect to device
    // 2. Display device info and current settings
    // 3. Periodically fetch real-time measurements
  6. Use EspUsbHostMIDI for USB MIDI I/O

    main

    EspUsbHostMIDI is a sample implementation for USB MIDI input and output. It allows an ESP32-S3 (or other Arduino-ESP32 USB Host compatible boards) to receive MIDI messages from connected USB MIDI devices (keyboards, controllers, interfaces, etc.) and send MIDI messages via serial commands.

    Core Functionality:

    • Input: All received MIDI messages are decoded and displayed on the serial monitor.
    • Output: MIDI messages can be sent to the connected device using specific serial commands.
  7. Implement ESC/POS printing with EspUsbHostPrinterEscPos

    main

    This example demonstrates how to use the EspUsbHost library to control a USB receipt printer (e.g., Xprinter XP-C58K) using the ESC/POS command language. It covers printing Japanese text (Shift-JIS), barcodes, QR codes, and using the auto-cutter.

    Key Components

    • PrinterProtocol.hpp: Defines USB Printer class requests (GET_DEVICE_ID, GET_PORT_STATUS, SOFT_RESET) and IEEE 1284 device ID parsing.
    • EscPos.hpp: A command builder for ESC/POS with range checking and real-time status handling.
    • PrinterDevice.hpp: Handles device discovery, USB interface claiming via Vendor Bulk API, and data transmission.
    • ReceiptJa.hpp: Provides Shift-JIS encoded byte arrays for Japanese receipt layouts.
    • EspUsbHostPrinterEscPos.ino: The main entry point for connecting, checking status, and printing a sample receipt.
    // Example usage pattern from EspUsbHostPrinterEscPos.ino
    // 1. Open the interface using Vendor Bulk API
    // Note: interfaceNumber is explicitly provided to allow claiming non-vendor (0x07) classes.
    // READ_ON_DEMAND is used because status is read only on request.
    // usb.vendorOpen(address, interfaceNumber, ESP_USB_HOST_VENDOR_READ_ON_DEMAND);
    
    // 2. Print a receipt (sent in a single vendorWrite call to prevent stuttering/timeouts)
    // usb.vendorWrite(receipt, length, address);
  8. Drive an ALIENTEK DP100 Power Supply via USB HID

    main

    This example demonstrates how to control an ALIENTEK DP100 digital power supply (ATK-MDP100, VID/PID 2e3c:af01) using the EspUsbHost HID API. You can read device identity, input/output voltage and current, temperatures, and set voltage/current limits or toggle the output state.

    Key Components

    • Dp100Protocol.hpp: Defines the 64-byte wire format, CRC-16/MODBUS, and read payloads.
    • Dp100Device.hpp: Handles HID interface discovery, sending requests to the interrupt OUT endpoint, and pairing them with reports from the interrupt IN endpoint.
    • Dp100Power.hpp: Provides the high-level meaning layer (volts, amps, degrees) and setpoint methods.
    • EspUsbHostDp100Power.ino: A complete Arduino sketch for connecting, printing info, setting a setpoint, and polling measurements.
    // Example usage pattern from EspUsbHostDp100Power.ino
    // Connect, print device info, set a setpoint, and poll measurements
  9. Overview of EspUsbHost USB Display (DL-1xx) Support

    main

    This specification outlines the plan to enable EspUsbHost to support USB graphics display adapters from the DL-1xx series (including DL-120, DL-160, DL-115, DL-125, DL-165, and DL-195).

    Key Goals:

    • Enable 1920x1080 resolution output from an ESP32-S3 (Full-speed OTG).
    • Provide the output as a LovyanGFX panel.
    • The intended usage pattern is to layer LGFXVirtualCanvas over the panel for drawing.
    • Success is defined by the ability to display static UI and have changes follow in a realistic timeframe (frame rate is not the primary metric).

    Architecture Strategy: To keep the core library clean, DL-1xx specific protocol logic will not be integrated into the main EspUsbHost library. Instead, the library will provide generic APIs (such as "asynchronous bulk OUT") and the DL-1xx specific implementation will reside in the examples/ directory. This follows the vendor API pattern established in vendor-api-spec.ja.md.

  10. Analyze HID report descriptors

    main

    HID devices define their data structure via a report descriptor. Use EspUsbHostHIDReportDescriptor to fetch and decode this descriptor.

    Interpreting the data:

    • Use Usage Page, Usage, Report Size, and Report Count to map bits in an input report to specific functions (e.g., button presses).
    • Private Protocols: If the Usage Page is vendor-defined (0xff00 and above), the device uses a private protocol wrapped in HID. In this case, you must treat it as a vendor-specific device (see Step 5/6 in the development guide).
  11. How CCID card identification works

    main

    The library uses two methods to identify smart cards:

    1. ATR Analysis (ccidGetCardInfo):

      • For contactless storage cards (PC/SC compliant), the reader generates a synthetic ATR containing a PC/SC RID (A0 00 00 03 06) and standard bytes. The library parses this to identify the card type and name.
      • If a card provides its own ATR (contact cards or ISO 14443-4 contactless cards), it is reported as ISO 7816 card (own ATR).
      • If the ATR contains no historical bytes, the card remains unknown.
    2. UID Estimation (ccidIdentifyCard): If ATR analysis is insufficient, the library sends a Get UID command. It estimates the type based on the identifier length:

      • 8 bytes: FeliCa (IDm), unless the first byte is 0xe0 (then it is ISO 15693).
      • 7 or 10 bytes: ISO 14443 A (NFCID1).
      • 4 bytes (starting with 0x08): ISO 14443-3 (Random NFCID1 reserved value).
      • Other 4-byte IDs: Type cannot be determined.

    Note: When using UID estimation, info.fromUid is set to true.