Verified via hid_discover caps and live data dump. Throttle responds on axis 3 (HID usage 0x33 = Rx), not axis 5 or 6.
STK Library
A C23 library for reading EdgeTX radio joystick (HID) input on Windows. Reads raw HID input reports to access 4 analog axes and 24 buttons.
Wired for test-driven development using Unity and CMock.
All dependencies are fetched automatically via CMake FetchContent — no
manual installation required beyond the tools listed below.
Requirements
| Tool | Purpose |
|---|---|
| CMake >= 3.21 | Build system |
| Ninja | Build backend |
| C23 compiler | GCC 14+, Clang 18+ |
| Ruby >= 3.0 | CMock mock generation |
| gcovr >= 6.0 | Coverage reports — optional (uv tool install gcovr) |
Build
Configure:
cmake -S . -B build -G Ninja
Build:
ninja -C build
Test
Full Unity output with colors:
ninja -C build check
CTest summary only:
ninja -C build test
check builds all suites and runs CTest with --output-on-failure,
so assertion-level detail appears on any failure without running
binaries by hand.
Coverage
Configure with coverage instrumentation:
cmake -S . -B build-cov -G Ninja -DENABLE_COVERAGE=ON
Generate the HTML report:
ninja -C build-cov coverage
Open build-cov/coverage/index.html in a browser to view results.
Only stk/ source files are measured. Unity, CMock, and generated
mock files are excluded. Requires GCC or Clang with gcov support, and
gcovr on PATH.
Windows note: requires GCC (e.g.
scoop install gcc) or a Clang build that includes compiler-rt. A custom Clang without compiler-rt will fail at link time.
Run
Windows:
./build/main.exe
API
#include <stk/stk.h>
// Open with default VID/PID
stk_config_t config = {
.vendor_id = STK_DEFAULT_VID,
.product_id = STK_DEFAULT_PID,
};
if (stk_open(&config) != 0) {
// handle error
}
// Read state (non-blocking)
stk_state_t state;
stk_read(&state);
// Named accessors for the 4 active axes
int16_t rx = stk_right_x(&state);
int16_t ry = stk_right_y(&state);
int16_t throttle = stk_throttle(&state);
int16_t lx = stk_left_x(&state);
// Raw axes array (indices 0-7, only 1/2/3/4 active)
// state.axes[0..7] — values in range STK_AXIS_MIN..MAX (0..2047)
// AETR layout: axes 1/2 = right stick, 3 = throttle, 4 = left X (rudder)
// Button check
if (stk_button_pressed(&state, 3)) {
// switch 4 is on
}
// Close the device
stk_close();
Radio Profile
EdgeTX radio (VID:PID 1209:4F54) HID input report:
| Field | Size | Details |
|---|---|---|
| Axes | 4 x 16-bit | Range 0-2047 (HID usage 0x30-0x37, indices 1/2/3/4) |
| Buttons | 24 bits | Switches, rockers, paddles |
| Total | 20 bytes | No report ID |
Axis 1 = right X (aileron), 2 = right Y (elevator), 3 = throttle, 4 = left X (rudder). This matches the AETR stick layout.
Current Status
- Build system (CMake + Ninja)
- Raw HID device enumeration and opening
- Reading 4 axes and 24 buttons
- Linux support
- macOS support