Cross-platform USB HID driver for CNC MPG pendants. Decodes button presses, jog wheel movement, and selector positions into structured Dart objects. Encodes machine state back to the pendant's LCD display.
Currently supports XHC xHB04B-family pendants — both wired (LHB04B) and wireless (WHB04B), in 4-axis and 6-axis variants.
- Device discovery — enumerates connected pendants, consolidates platform-specific HID collections into a single logical device
- Input decoding — buttons (with Fn modifier), 6-axis jog wheel, jog selector, continuous/step mode tracking
- Display output — axis coordinates, feed rate, spindle speed, coordinate space, and motion mode
- Non-blocking I/O — HID reads run in a dedicated isolate
- Cross-platform — Windows, macOS, Linux (desktop only)
- Dart SDK
>=3.10.0 <4.0.0 - A C toolchain for building the native hidapi dependency (CMake, a C compiler)
Add the dependency:
dependencies:
mpg_pendant:
git:
url: https://github.com/repentsinner/mpg_pendant.gitThe native hidapi library builds automatically via Dart's
native assets hook on
first run.
import 'package:mpg_pendant/mpg_pendant.dart';
final backend = HidapiHidBackend();
final discovery = PendantDiscovery(backend);
final pendants = discovery.findPendants();
if (pendants.isEmpty) {
print('No pendant found.');
return;
}
final conn = PendantConnection(pendants.first);
final stream = await conn.open();
conn.sendResetSequence();stream.listen((PendantState state) {
print('Button: ${state.button1}');
print('Axis: ${state.axis}, Jog: ${state.jogDelta}');
print('Jog: ${state.jogSelector}');
});conn.updateDisplay(DisplayUpdate(
axis1: 12.345,
axis2: -6.789,
axis3: 0.0,
feedRate: 1000,
spindleSpeed: 12000,
coordinateSpace: CoordinateSpace.workpiece,
));await conn.close();| Family | Models | Interface |
|---|---|---|
| XHC HB04B | LHB04B-4, LHB04B-6 | USB HID (wired) |
| XHC HB04B | WHB04B-4, WHB04B-6 | USB HID (wireless dongle) |
All variants share USB VID/PID 10CE:EB93.
Tested with: LHB04B-4 (wired, 4-axis, firmware TX:V03). Other HB04B variants use the same protocol and are expected to work but have not been verified.
The architecture supports adding new pendant families without changing the public API or device I/O layer.
-
Windows — the pendant enumerates as multiple HID collections; the driver probes to identify read vs. write endpoints automatically.
-
macOS / Linux — a single HID interface handles both directions.
-
Linux — you may need a udev rule to grant non-root access to the device. Example:
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10ce", MODE="0666"
- SPEC.md — design rationale and requirements
- Example app — terminal-based monitor that exercises all inputs and drives the display at 125 Hz
- Issue tracker
This package is a pendant driver only. It does not implement grbl, serial communication, or machine control — the consuming application handles that.