Making the TurboPi buttons work - GMU-ASRC/turbopi GitHub Wiki
Button Manager
We have a script that watches Button 2 on the TurboPi (the button closest to the rear of the vehicle), and allows it to do cool stuff.
Here's a quick overview of the functionality so far:
3c means click, click, click
3H means click, click, HOLD
The button in question is Button 2 unless otherwise noted.
Starting programs:
All programs started using the buttons have sudo (root) powers.
Note that, with the exception of the battery check program, buttonman will start the program and leave it running. If you're not careful, you could have more than one program running at a time...
- 1c: Start
~/program1.sh
- 2c: Start
~/program2.sh
- 5c: Start
~/program5.sh
- 6c: Start
~/program6.sh
These files should reside in the /home/pi/
directory. Here's an example of such a file that starts a python program:
#!/bin/bash
python /home/pi/milling_controller.py --startpaused
Stopping programs:
Holding the button will only stop programs if they register themselves with buttonman. See How to register a program with buttonman for more information.
- 1H: Stop all programs registered with buttonman
- 2H: Stop all programs registered with buttonman, then stop the motors, buzzer, and lights
- Flip the power switch to cut power immediately.
Wifi:
The TurboPi comes by default in direct connection AP mode, but if you follow the instructions in Disabling HiWonder TurboPi WiFi Access Point, buttonman can enable or disable this feature.
- 4c: Stop the robot's AP and restart the wifi service.
- 4H: Cut the robot's wifi connection and switch to direct connection mode (the robot starts its AP)
Other:
- 3c: Run the battery check program. 1c on either button to exit at any point.
Buttonman comes with a battery check program. It will beep/flash the single-cell average battery voltage. So 7.0 volts would be 3 flashes, a pause, then 5 flashes. The number 0 is denoted by a faster-than-usual flash. - 3H: Run the servo test program in
/home/pi/boot/hardware_test.py
. 1H on button 2 to exit as usual.
HiWonder's servo test program can be started using this sequence.
Installing buttonman.py
The boot folder needs to be placed like so: /home/pi/boot/
For instructions on how to do this, see Moving files to the TurboPi
The script needs to be installed as a service to work.
You also need to have psutil
and python-statemachine
installed.
You can do this with the following script:
cd /home/pi/boot
chmod 766 install_buttonman.sh
sudo ./install_buttonman.sh
Registering a program with buttonman
buttonman.py
will only kill processes it knows about, otherwise it could terminate important system processes.
To tell buttonman about your program and allow it to be killed, your program should create an entry in /tmp/buttonman/
The file name should be the PID of your process (usually a 3-5 digit number), and it should contain json with information on, at minimum, the pid, process name, and username of the process owner.
You don't need to worry about this for the most part; if you're using python, add these lines near the top of your file:
import sys
sys.path.append('/home/pi/boot/')
import buttonman as buttonman
buttonman.TaskManager.register_stoppable()
If your application uses motors, you may want to do some cleanup before your application gets terminated.
Otherwise, buttonman will terminate (ask nicely) or force kill your program, and the motors might keep running forever...
You may wish to wrap your application logic in a try/except block like so:
def emergency_stop():
chassis.set_velocity(0, 0, 0)
while True:
try:
main_loop()
except BaseException as err:
emergency_stop()
raise
Or perhaps you may wish to intercept the interrupt or termination signal:
def signal_handler(sig, handler):
chassis.set_velocity(0, 0, 0)
sys.exit() # exit the python script immediately
signal.signal(signal.SIGINT, signal_handler) # signal.SIGINT is for keyboard interrupts (CTRL + C)
signal.signal(signal.SIGTERM, signal_handler) # signal.SIGTERM is for terminate signals (buttonman sends these first)
If your program stops responding (i.e. gets stuck in a loop), buttonman will force-kill it after ten seconds. Kill commands can't be intercepted, so you can't run cleanup code in this case. Avoid this.