I have decided that Charlie needs some kind of battery monitor because the power curve of the new Li-Ion batteries doesn’t match the firmware anymore so there’s no on-robot warning of an impending power crash.
I have thrown together a short script based on a script you gave me:
#!/usr/bin/python3
# print GoPiGo3 battery and 5v voltages
import easygopigo3
from time import sleep
from statistics import mean
import os
# import runLog
#DIODE_DROP=0.7 # YMMV
DIODE_DROP=0.6 # YMMV
egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
# for testing
volt = 10.50
try:
while True:
x = []
for i in [1,2,3]:
sleep(.005)
x += [egpg.volt()+DIODE_DROP]
out = "{:.2f}".format(mean(x))
# for testing
out = "{:.2f}".format(volt)
if (float(out) <= 9.75):
f = open("/home/pi/Desktop/EMERGENCY_SHUTDOWN.txt", "a")
f.write("Emergency Commanded Shutdown at " + out + " volts!\n")
f.close()
os.system("sudo shutdown -h now")
elif (float(out) <= 10.00):
f = open("/home/pi/Desktop/POWER_WARNING.txt", "a")
f.write("Current battery voltage " + out + " volts!\n")
f.close()
egpg.left_eye_color = (80, 0, 0)
egpg.right_eye_color = (80, 0, 0)
egpg.open_eyes()
# for testing
print("Battery voltage:", out, "volts")
volt -= 0.05
sleep(2)
# end While
except KeyboardInterrupt:
print("exiting")
# end program
The idea is, as you know, to periodically monitor the battery’s voltage and command a safe shutdown when it gets too low.
I don’t want to mess with the antenna LED, so I use the eyes.
At the warning voltage, (10.00 volts), it drops a warning file on the desktop and turns the eyes a bright red. At the trigger voltage, (9.75), it drops a shutdown message file on the desktop and then commands an immediate formal shutdown.
Questions:
-
Is 9.75 a good voltage to shut down on? (I remember something like that.)
-
How often should this run? Every minute? Every five minutes?
-
How do you run yours? A “at restart” cron-job that loops? A periodic cron-job? As a startup service?
- If you run it as a service, how do you get it to repeat? A sleep statement? Does the service autostart periodically?
- If it runs as a periodic job, either as an autostarting service or as a cron-job, how do you keep each instantiation of easygopigo from killing your robot’s wheel speed settings?
=========
Update:
Here’s the current version:
#!/usr/bin/python3
# print GoPiGo3 battery and 5v voltages
import easygopigo3
from time import sleep
from statistics import mean
import os
# import sys
# import runLog
#DIODE_DROP=0.7 # YMMV
DIODE_DROP=0.6 # YMMV
egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
# for testing
# volt = 10.50
try:
while True:
# Create a new "canary file" each execution cycle to verify it's running.
f = open("/home/pi/Desktop/battery_monitor_running", "w")
f.write("Battery Monitor is running\n")
f.close()
x = []
for i in [1,2,3]:
sleep(.005)
x += [egpg.volt()+DIODE_DROP]
out = "{:.2f}".format(mean(x))
# for testing
# out = "{:.2f}".format(volt)
if (float(out) <= 9.75):
f = open("/home/pi/Desktop/EMERGENCY_SHUTDOWN.txt", "a")
f.write("Emergency Commanded Shutdown at " + out + " volts!\n")
f.close()
# sys.exit(0)
os.system("sudo shutdown -h now")
elif (float(out) <= 10.00):
f = open("/home/pi/Desktop/POWER_WARNING.txt", "a")
f.write("Current battery voltage " + out + " volts!\n")
f.close()
egpg.left_eye_color = (80, 0, 0)
egpg.right_eye_color = (80, 0, 0)
egpg.open_eyes()
# for testing
# print("Battery voltage:", out, "volts")
# volt -= 0.05
sleep(60)
# end While
except KeyboardInterrupt:
print("exiting")
# end program
I have it set to run as a “on startup” (@reboot) cron job with a 60 second sleep, so it starts once and then runs continuously until I either shut down or it triggers.
For the time being, I have it drop a “canary” file each time it runs so that I can verify that it’s actually running. If I delete the file, it should return within 60 seconds.
Currently running on battery to exhaustion, to see if it actually grabs the system before the battery dies.
Any ideas or improvements would be appreciated.
Thanks!