I spent my career trying to write reasonably efficient and fast code in firmware, device drivers and system level utilities. I'm afraid I just couldn't stomach adding a polling loop on top of the polling loop (every .2 seconds) that I discovered at the core of halui.
So I've done an end-run around the problem, which works nicely.
My mill runs from a Raspberry Pi, connected via a Mesa ethernet card. It occurred to me that if HAL could twiddle an actual gpio pin, then I could easily read that, and hook it up to action. And of course if there's one thing the RPi has, it's plenty of gpio.
So I loaded hal_gpio, and hooked up a couple of output pins:
loadrt hal_gpio outputs=GPIO16,GPIO20
addf hal_gpio.write servo-thread
net external-estop-off \
estop-latch.0.fault-out => hal_gpio.GPIO16-out
net coolant-mist => hal_gpio.GPIO20-out
Those pins were chosen because they were eacy immediately adjacent to another unused pin. Gpio 16 is next to 19, and 20 is next to 26. I jumpered those two pairs.
Then I wrote a short script using gpiomon to watch pins 19 and 26 for transitions.
#!/bin/bash
estop=19
vacuum=26
switch()
{
echo Turning $1 $2 # e.g. "Turning vacuum on"
wget -q -O /dev/null http://service:9901/event:cnc-mill-$1-$2 &
}
while read pinevent
do
echo got $pinevent # this will be "19-1", "19-0", "26-1", or "26-0"
case $pinevent in
$estop-1)
switch spindle off
;;
$vacuum-0)
switch vacuum off
;;
$vacuum-1)
switch vacuum on
;;
esac
done < <( gpiomon --line-buffered --format="%o-%e" gpiochip0 19 26)
This works perfectly.
While I'm pleased to have found this solution, it sure seems silly to have had to consume 4 gpio pins in order to do it.
Thanks for all your suggestions!
paul