Skip to content

[WIP] Add hardware-in-the-loop testing for Linux - #347

Draft
LeeNX wants to merge 6 commits into
lemmingDev:masterfrom
LeeNX:leet-hil-report-size-getters
Draft

[WIP] Add hardware-in-the-loop testing for Linux#347
LeeNX wants to merge 6 commits into
lemmingDev:masterfrom
LeeNX:leet-hil-report-size-getters

Conversation

@LeeNX

@LeeNX LeeNX commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

LeeNX and others added 4 commits August 30, 2026 08:27
- BleGamepad::getHidReportSize() / getHidReportDescriptorSize(): expose the
  sizes begin() computes, so the HIL rig can assert the report descriptor
  stays inside the fixed tempHidReportDescriptor[150] buffer.
- scripts/hil.sh: build hil_runner firmware against the current working tree,
  push to the Raspberry Pi tester (192.168.101.16), run the pytest BLE-HID
  suite + latency benchmark there, pull results into ./hil-results/.
- HilTesting.md: what the rig verifies (features, ranges, GATT/DIS, battery,
  power state, polling-rate/latency) and how to run it; linked from README.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
esp32dev, v0.7.5-rc0, Raspberry Pi 3B+ tester (kernel 6.18.34, BlueZ 5.82):
single button press -> host in ~18.6 ms median (p99 ~67), 0 dropped across
200 paced presses per profile, latency flat vs HID report size (3..28 B).
The library negotiates a 48.75 ms connection interval on every profile --
the dominant latency factor and the ~20 Hz report-rate ceiling.

Charts + bench-table under docs/hil/, regenerated by `python -m hil.charts`.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rk refresh

- getHidReportDescriptor() -- the generated descriptor bytes (pairs with the
  existing size getters). Lets a test harness assert the descriptor the library
  built matches what the host received over GATT, byte for byte.
- HilTesting.md: rig repo is now github.com/LeeNX/ESP32-BLE-Gamepad-HIL;
  generic tester wording; corrected the throughput section (48.75 ms interval
  bounds latency, not paced rate -- NimBLE batches packets per connection
  event, paced input delivers 100% at 80-130 Hz); Feature/Output-report and
  HID-descriptor coverage added; refreshed baseline table + charts.
- scripts/hil.sh: per-profile progress banners + verdict roll-up, cleans stale
  bundles before build, adds the `reports` profile, requires HIL_SSH_HOST /
  HIL_SSH_USER (no baked-in host).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
All six HIL profiles (default, signed-axes, specials, minimal, maxbtn,
reports) verified green on esp32dev. Refreshed bench-table + SVGs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@lemmingDev

Copy link
Copy Markdown
Owner

only really adds 3 lines of code to one file - go ahead

LeeNX and others added 2 commits August 30, 2026 16:57
New .github/workflows/hil.yml + .github/scripts/hil_dispatch.sh: on push to
master, path-filtered PRs (Ble*.cpp/.h), a weekly cron, and workflow_dispatch,
fire a repository_dispatch (type: hil) at LeeNX/ESP32-BLE-Gamepad-HIL with the
library ref to test, then block until that rig run finishes and exit with its
conclusion. The run is correlated by workflow + event + creation time; both
repos serialise on a concurrency group so only one lands in the window. Job
summary links the rig run.

Guarded to LeeNX/ESP32-BLE-Gamepad; forks and fork PRs skip cleanly. Needs one
repo secret, HIL_DISPATCH_TOKEN (PAT for the rig repo: Contents:write +
Actions:read). HilTesting.md gains a "From CI" section documenting the wiring
and the rig-side setup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Memory usage change @ 6787737

Board flash % RAM for global variables %
esp32:esp32:esp32 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
esp32:esp32:esp32c3 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
esp32:esp32:esp32c6 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
esp32:esp32:esp32s3 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
Click for full report table
Board examples/CharacteristicsConfiguration
flash
% examples/CharacteristicsConfiguration
RAM for global variables
% examples/DrivingControllerTest
flash
% examples/DrivingControllerTest
RAM for global variables
% examples/Fightstick
flash
% examples/Fightstick
RAM for global variables
% examples/FlightControllerTest
flash
% examples/FlightControllerTest
RAM for global variables
% examples/ForcePairingMode
flash
% examples/ForcePairingMode
RAM for global variables
% examples/Gamepad
flash
% examples/Gamepad
RAM for global variables
% examples/GetPeerInfo
flash
% examples/GetPeerInfo
RAM for global variables
% examples/IndividualAxes
flash
% examples/IndividualAxes
RAM for global variables
% examples/Keypad4x4
flash
% examples/Keypad4x4
RAM for global variables
% examples/MotionController
flash
% examples/MotionController
RAM for global variables
% examples/MultipleButtons
flash
% examples/MultipleButtons
RAM for global variables
% examples/MultipleButtonsAndHats
flash
% examples/MultipleButtonsAndHats
RAM for global variables
% examples/MultipleButtonsDebounce
flash
% examples/MultipleButtonsDebounce
RAM for global variables
% examples/PotAsAxis
flash
% examples/PotAsAxis
RAM for global variables
% examples/SetBatteryLevel
flash
% examples/SetBatteryLevel
RAM for global variables
% examples/SetBatteryPowerState
flash
% examples/SetBatteryPowerState
RAM for global variables
% examples/SingleButton
flash
% examples/SingleButton
RAM for global variables
% examples/SingleButtonDebounce
flash
% examples/SingleButtonDebounce
RAM for global variables
% examples/SpecialButtons
flash
% examples/SpecialButtons
RAM for global variables
% examples/TestAll
flash
% examples/TestAll
RAM for global variables
% examples/TestFeatureReports
flash
% examples/TestFeatureReports
RAM for global variables
% examples/TestReceivingOutputReport
flash
% examples/TestReceivingOutputReport
RAM for global variables
%
esp32:esp32:esp32 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
esp32:esp32:esp32c3 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
esp32:esp32:esp32c6 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
esp32:esp32:esp32s3 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
Click for full report CSV
Board,examples/CharacteristicsConfiguration<br>flash,%,examples/CharacteristicsConfiguration<br>RAM for global variables,%,examples/DrivingControllerTest<br>flash,%,examples/DrivingControllerTest<br>RAM for global variables,%,examples/Fightstick<br>flash,%,examples/Fightstick<br>RAM for global variables,%,examples/FlightControllerTest<br>flash,%,examples/FlightControllerTest<br>RAM for global variables,%,examples/ForcePairingMode<br>flash,%,examples/ForcePairingMode<br>RAM for global variables,%,examples/Gamepad<br>flash,%,examples/Gamepad<br>RAM for global variables,%,examples/GetPeerInfo<br>flash,%,examples/GetPeerInfo<br>RAM for global variables,%,examples/IndividualAxes<br>flash,%,examples/IndividualAxes<br>RAM for global variables,%,examples/Keypad4x4<br>flash,%,examples/Keypad4x4<br>RAM for global variables,%,examples/MotionController<br>flash,%,examples/MotionController<br>RAM for global variables,%,examples/MultipleButtons<br>flash,%,examples/MultipleButtons<br>RAM for global variables,%,examples/MultipleButtonsAndHats<br>flash,%,examples/MultipleButtonsAndHats<br>RAM for global variables,%,examples/MultipleButtonsDebounce<br>flash,%,examples/MultipleButtonsDebounce<br>RAM for global variables,%,examples/PotAsAxis<br>flash,%,examples/PotAsAxis<br>RAM for global variables,%,examples/SetBatteryLevel<br>flash,%,examples/SetBatteryLevel<br>RAM for global variables,%,examples/SetBatteryPowerState<br>flash,%,examples/SetBatteryPowerState<br>RAM for global variables,%,examples/SingleButton<br>flash,%,examples/SingleButton<br>RAM for global variables,%,examples/SingleButtonDebounce<br>flash,%,examples/SingleButtonDebounce<br>RAM for global variables,%,examples/SpecialButtons<br>flash,%,examples/SpecialButtons<br>RAM for global variables,%,examples/TestAll<br>flash,%,examples/TestAll<br>RAM for global variables,%,examples/TestFeatureReports<br>flash,%,examples/TestFeatureReports<br>RAM for global variables,%,examples/TestReceivingOutputReport<br>flash,%,examples/TestReceivingOutputReport<br>RAM for global variables,%
esp32:esp32:esp32,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
esp32:esp32:esp32c3,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
esp32:esp32:esp32c6,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
esp32:esp32:esp32s3,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants