Connect an XHC WHB04B pendant to a GRBL-based CNC controller using a RaspberryPi Zero
TODO
- Clean this up and add some text about how all this is supposed to work
- Document the code
- Add tests
- Provide pictures and documentation for the HW
Notes
-
Button Interpretation:
- Reset: issue a soft reset to the Controller
- using '^X' realtime command
- Stop: stop everything and leave it in position
- using '!' realtime command
- Start/Pause: toggle between cycle start and resume
- using '~' realtime command
- Feed+/-: adjust feed rate while program is running
- Spindle+/-: adjust spindle speed while program is running
- M-Home: stop and home all three axes in machine coordinate space
- set to machine coordinate space
- Safe-Z: retract spindle to top of Z axis travel (home Z axis only)
- W-Home: stop and home all three axes in workpiece coordinate space
- S-on/off: toggle spindle on/off
- Probe-Z: run probing cycle
- Continuous: set into continuous movement mode
- selected axis will move in direction of jog wheel movement (i.e., cw or ccw)
- movement will stop whenever wheel movement stops
- movement is done at the rate given by the increment knob setting
- i.e., a percentage of max movement rate
- movement is independent of speed at which the jog wheel is rotated
- Step: set into step movement mode
- selected axis will move in direction of jog wheel movement
- movement is in increments given by the increment knob setting
- Macro-[1-11]: defined by yaml in button config file
- Reset: issue a soft reset to the Controller
-
Adding more increments to the incr knob in step mode: 10.0, 50.0, 100.0
- ignoring/not implementing the 'Lead' setting
-
Reset
- Pendant comes out of power-up in RESET mode
- it remembers the last coordinate line values it was given and displays "RESET"
- remains in this state until overwritten
- comes up with selected axis as given by axis knob
- could have changed during power down
- it remembers the last coordinate line values it was given and displays "RESET"
- can change coordinate lines on the display while in reset mode
- reset sequence on power-up
- set RESET flag
- wait for motion mode button to be pressed
- ignore all other inputs
- clear RESET flag
- the pendant remains in the previous coordinate space at startup
- must get the current coordinates and space from the Controller and update the display on reset
- pendant emits current state of knobs (and buttons/jog wheel) on power-up
- not doing anything with it right now
- sometimes emits a null data packet -- i.e., all zeros (key1, key2, incr, axis, jog)
- sometimes first thing after powerup is a null packet
- pendant looks like it continues emitting packets until it is reset
- Pendant comes out of power-up in RESET mode
-
Display
- pendant automatically displays the value of the axis knob with an asterix next to a coordinate line
- host is not able to set the selection marker
- top display line is the status line RF bars icon, battery level icon, and mode word
- mode word starts as "RESET" until motion mode mode is set
- after motion mode is selected, the mode word becomes either "CONT" or "STP"
- the value following the mode word is dependent on the mode
- for "STP" the value is a floating point number
- for "CONT" the value is a percentage
- the value following the mode word is dependent on the mode
- the display format is specific to the motion mode
- e.g., "STP: 1.0", "CONT: 30%"
- both MPG and PCT motion modes display "XX%", where 'XX' is given by the incr knob setting
- no text associated with these modes -- just 'XX%'
- if axis knob is in "off" state, can't update the display
- don't send display packets if that's the case -- drop commands and log warnings
- if power on with axis "off", emits axis off (0x06) and state of incr knob
- could suppress this in this object
- doesn't automatically update the display if axis is Off
- the display automatically updates CONT/STEP mode values based on knob positions
- the coordinate lines display the current machine position
- X, Y, Z or A, B, C coordinates if in Machine coordinate system
- X1, Y1, Z1 or A1, B1, C1 coordinates if in Work coordinate system
- the currently selected coordinate (i.e., the one where motion will occur) is (automatically) indicated on the display with an asterix
- pendant automatically displays the value of the axis knob with an asterix next to a coordinate line
-
Input
- this object emits the (lightly parsed) basic events from the pendant
- puts them into an internal queue, provide method to pull from this input queue
- the action logic (e.g., in the main code body) will pull from this queue via methods
- an input thread handles device events, does the pre-processing, and queues the output
- outputs from the pendant include: key1, key2, axis, incr, and jog
- any number of these can be null in a packet
- there's also a header, seed, and checksum in each packet
- these values are not currently being used by this code
- the header is checked but the checksum is currently not
- have to figure out what the seed does and how the checksum works
- button-down events have a key value, then button up events are signified by 0x0 value
- e.g., pressing a single key results in reports with key1=0x??, then key1=0x00 when it is released
- e.g., button down will give the keyName, button up returns 'Noop'
- key1 is the first key pressed, key2 is the second key pressed while key1 is held
- this means any key can be a modifier -- but only "Fn" is so marked
- key values are between 0x00 (nothing pressed) and 0x10
- 0x01 starts in upper left ("Reset") and raster left-right, top-down
- "Continuous" = 0x0e, "Step" = 0x0f, last key is "Macro-10" = 0x10
- when the axis knob is in the "off" position, no jog deltas are sent
- in this case, axis == 0x06 and jog == 0x00 (there's not axis to apply the jog to)
- all button and knob values are small integers -- except incr "Lead" == 155
- the pendent emits NOP packets when the axis knob is not set to "Off" and the jog wheel is not moving
- the pendent continuously sends a jog value of 0
- the input tuple contains:
- the (possibly empty) name of a pressed key,
- the current setting of the axis knob, the current setting of the increment knob,
- and the jog wheel delta
- if no key was pressed, then the key name will be None.
- if the axis knob is set to "Off" a None is given for the axis value,
- otherwise, the axis character is given as a string -- e.g, "X", or "A".
- the increment knob returns either:
- a float (that corresponds to the increment to be moved by with each click of the jog wheel when in "STEP" mode)
- or an integer (that corresponds to the percentage of the maximum speed at which it can move).
- reports current axis and incr knob settings
- axis: 0x06="off"
- incr: 0x0e=0.001/2%, 0x0d=0.02/5% ...
- this object emits the (lightly parsed) basic events from the pendant
-
notes
- always have to click some button after power-on of Pendant
- otherwise, don't know when you just turned on the Pendant
- assume that the app is always running and the Pendant gets turned on/off at random times
- also, if the Pendant is on when the app starts, then need to hit the button again
- use Fn(RESET) to get Pendant out of reset mode
- use Fn(STOP) to exit app
- need to interrogate the Controller to get the current values for the Coordinates
- just do this by periodically asking the Controller for status ('?')
- status inputs are demuxed onto another channel
- the -4 pendant only has four values (0x11-0x14), other two values for the -6
- this application should interpret the final three positions of the incr knob as: 10, 50, 100?
- the input from the pendant and the pendant's display are logically independent
- it may take some time for the controller to receive inputs from the pendant and send back results that then are sent to the pendant's display
- everything should converge to a consistent state quickly
- other controllers have MPG and CONT/STEP buttons
- mine has CONT and STEP buttons
- this means that it only understands two modes
- this is why I've never seen "MPG" or "PCT" displays
- mine has CONT and STEP buttons
- doesn't update 'F:<>' display when in STEP mode, does in CONT mode
- pendant remembers the coordinates and other state between power cycles
- but comes up with RESET flag set -- must clear it to go on
- always have to click some button after power-on of Pendant
-
install udev rules for RF dongle and reload udevd
- sudo cp ./99-xhc-whb04b-4.rules /etc/udev/rules.d/
- sudo udevadm control --reload-rules
- sudo udevadm trigger
-
info on the xhc-whb04b-6