Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Hardware

The board is a Waveshare ESP32-S3-Zero (ESP32-S3FH4R2, 4 MB flash, 2 MB PSRAM, BLE 5.0). The full parts list, the design decisions and the build phases are in SPEC.md.

Parts

PartRole
Waveshare ESP32-S3-ZeroMCU, BLE, USB-C
VS1838B IR receiver moduleIR receiver (38 kHz)
100 Ω resistor, 100 nF capacitorsupply filter for the IR receiver
TSAL-6200 IR LED, 2N2222 transistor, 330 Ω, 33 Ω and 10 kΩ resistorsIR blaster (optional)
SS14 Schottky diode, 2× 100 kΩ resistors, 100 nF capacitorbattery input and voltage sense (optional)

Pins

SignalGPIO
IR receiver outputGPIO 1
IR blaster (transistor base, via 330 Ω)GPIO 2
Battery voltage sense (optional)GPIO 4
Status LEDonboard WS2812 (GPIO 21)
USB control linkthe USB-C port (built-in USB-Serial-JTAG)

Schematic

Schematic

The KiCad project is in hardware/. It is a schematic only: the parts have no footprints, and the ESP32-S3-Zero symbol shows only the edge header pins. The dashed boxes are the optional parts.

Wiring

The VS1838B’s pin order is OUT, GND, VCC, the same as a TSOP38238.

VS1838B pin 1 (OUT) → GPIO 1
VS1838B pin 2 (GND) → GND
VS1838B pin 3 (VCC) ──[100Ω]── 3.3V
100nF from VCC (after the 100Ω) to GND, close to the module

The 100 Ω and 100 nF filter the receiver’s supply. The IR blaster draws ~53 mA bursts at 38 kHz from the same 3.3 V rail, and that ripple would otherwise reach the receiver’s sensitive amplifier.

The optional IR blaster:

3.3V ──[33Ω]── TSAL-6200 anode (long leg)
               TSAL-6200 cathode (short leg)
                    │
               2N2222 collector
               2N2222 emitter ── GND
               2N2222 base ──[330Ω]── GPIO 2
               2N2222 base ──[10kΩ]── GND

The 10 kΩ keeps the LED off while GPIO 2 floats during reset. The transistor is drawn E-B-C (PN2222A), but the TO-92 pinout depends on the vendor: the P2N2222A, many 2N2222A and the BC337 are C-B-E. Check the datasheet of the part you have.

The optional battery:

battery + ──[SS14, anode → cathode]── "5V" pad
battery + ──[100kΩ]──┬──[100kΩ]── GND
                      ├──[100nF]── GND
                   GPIO 4
battery − ── GND

The module’s “5V” pad is wired straight to USB VBUS, with no diode. Without the Schottky, plugging in USB with a battery attached pushes 5 V into the cells, and the battery feeds the host’s USB port. The divider taps the battery side of the diode, so it reads the battery and not USB. The diode drops about 0.3 V, so use 3×AA, or expect the 3.3 V rail to sag once a LiPo falls below about 3.8 V.

The firmware’s battery-monitor feature (on by default) reads the divider once a minute and reports the charge to the TV as the Bluetooth battery level. It assumes 3×AA cells; for a LiPo, set CELL to LIPO_1S in firmware/src/battery.rs. Without a battery it reports 100%.

Status LED

The onboard RGB LED shows the Bluetooth state:

LEDMeaning
Blue, blinking (2×/s)No Bluetooth host connected; advertising
Green, steady (dim)Connected and paired to a host
Purple flashA key was sent to the host

Keys pressed while the LED is blinking blue are dropped (no flash).