From 2d84980ebb2eb39724282aed2ea24f8c3a3e8e33 Mon Sep 17 00:00:00 2001 From: DevTown Date: Thu, 1 Nov 2018 21:15:07 +0100 Subject: [PATCH 1/4] Done some redesign from Kater --- src/HectorHardware.py | 372 +++++++++++++++++++++++++++++++++++------- 1 file changed, 315 insertions(+), 57 deletions(-) diff --git a/src/HectorHardware.py b/src/HectorHardware.py index 421c96c..971f7dd 100755 --- a/src/HectorHardware.py +++ b/src/HectorHardware.py @@ -1,247 +1,505 @@ #!/usr/bin/env python3 -# coding: utf8 + +# -*- coding: utf8 -*- + ## + # HectorHardware.py API class for Hector9000 hardware + # + # imports + from __future__ import division -devenvirement = True + + +DevEnvironment = True + + import time + import sys -import Adafruit_PCA9685 + from HectorConfig import config + + # Uncomment to enable debug output. + import logging -if not devenvirement: + + +if not DevEnvironment: + + import Adafruit_PCA9685 + import RPi.GPIO as GPIO + from hx711 import HX711 + + + logging.basicConfig(level=logging.DEBUG) + + + class HectorHardware: + + def __init__(self, cfg): + + self.config = cfg - if not devenvirement: + + if not DevEnvironment: + GPIO.setmode(GPIO.BOARD) - hx1 = cfg["hx711"]["CLK"] - hx2 = cfg["hx711"]["DAT"] - hxref = cfg["hx711"]["ref"] + + + # setup scale (HX711) + + hx1 = cfg["hx711"]["CLK"] + + hx2 = cfg["hx711"]["DAT"] + + hxref = cfg["hx711"]["ref"] + + if not DevEnvironment: + self.hx = HX711(hx1, hx2) + self.hx.set_reading_format("LSB", "MSB") + self.hx.set_reference_unit(hxref) + self.hx.reset() + self.hx.tare() + + + # setup servos (PCA9685) + + self.valveChannels = cfg["pca9685"]["valvechannels"] + + self.numValves = len(self.valveChannels) + + self.valvePositions = cfg["pca9685"]["valvepositions"] + + self.fingerChannel = cfg["pca9685"]["fingerchannel"] + + self.fingerPositions = cfg["pca9685"]["fingerpositions"] + + self.lightChannel = cfg["pca9685"]["lightchannel"] + + self.lightPositions = cfg["pca9685"]["lightpositions"] + + if not DevEnvironment: + pcafreq = cfg["pca9685"]["freq"] + self.pca = Adafruit_PCA9685.PCA9685() + self.pca.set_pwm_freq(pcafreq) - self.valveChannels = cfg["pca9685"]["valvechannels"] - self.numValves = len(self.valveChannels) - self.valvePositions = cfg["pca9685"]["valvepositions"] - self.fingerChannel = cfg["pca9685"]["fingerchannel"] - self.fingerPositions = cfg["pca9685"]["fingerpositions"] - self.lightChannel = cfg["pca9685"]["lightchannel"] - self.lightPositions = cfg["pca9685"]["lightpositions"] - - print("arm step + dir") - self.armEnable = cfg["a4988"]["ENABLE"] - self.armReset = cfg["a4988"]["RESET"] - self.armSleep = cfg["a4988"]["SLEEP"] - self.armStep = cfg["a4988"]["STEP"] - self.armDir = cfg["a4988"]["DIR"] - self.armSteps = cfg["a4988"]["numSteps"] - print("arm step %d + dir %d" % (self.armStep, self.armDir)) + + + + # setup arm stepper (A4988) + + self.armEnable = cfg["a4988"]["ENABLE"] + + self.armReset = cfg["a4988"]["RESET"] + + self.armSleep = cfg["a4988"]["SLEEP"] + + self.armStep = cfg["a4988"]["STEP"] + + self.armDir = cfg["a4988"]["DIR"] + + self.armSteps = cfg["a4988"]["numSteps"] + + print("arm step %d, dir %d" % (self.armStep, self.armDir)) + + self.arm = cfg["arm"]["SENSE"] + + if not DevEnvironment: GPIO.setup(self.armEnable, GPIO.OUT) + GPIO.output(self.armEnable, True) + GPIO.setup(self.armReset, GPIO.OUT) + GPIO.output(self.armReset, True) + GPIO.setup(self.armSleep, GPIO.OUT) + GPIO.output(self.armSleep, True) + GPIO.setup(self.armStep, GPIO.OUT) + GPIO.setup(self.armDir, GPIO.OUT) - print("done") - self.arm = cfg["arm"]["SENSE"] - if not devenvirement: GPIO.setup(self.arm, GPIO.IN) + + + # setup air pump (GPIO) + self.pump = cfg["pump"]["MOTOR"] - if not devenvirement: + + if not DevEnvironment: + GPIO.setup(self.pump, GPIO.IN) # pump off; will be turned on with GPIO.OUT (?!?) + + + print("setup done") + + + def arm_out(self): - if not devenvirement: + + if not DevEnvironment: + GPIO.output(self.armEnable, False) + print("move arm out") - if not devenvirement: + + if not DevEnvironment: + GPIO.output(self.armDir, True) + while not self.arm_pos(): - if not devenvirement: + + if not DevEnvironment: + GPIO.output(self.armStep, False) + time.sleep(.001) + GPIO.output(self.armStep, True) + time.sleep(.001) - if not devenvirement: + + if not DevEnvironment: + GPIO.output(self.armEnable, True) + print("arm is in out position") + + + def arm_in(self): + self.arm_out() - if not devenvirement: + + if not DevEnvironment: + GPIO.output(self.armEnable, False) - print("move arm in") + + print("move arm in") + + if not DevEnvironment: + GPIO.output(self.armDir, False) + for i in range(self.armSteps): + GPIO.output(self.armStep, False) + time.sleep(.001) + GPIO.output(self.armStep, True) + time.sleep(.001) + GPIO.output(self.armEnable, True) + print("arm is in in position") + + def arm_pos(self): - if not devenvirement: - pos = GPIO.input(self.arm) + + if DevEnvironment: + + print("no arm pos available") + + return 100 + + pos = GPIO.input(self.arm) + print("arm_pos: %d" % pos) - if not devenvirement: - pos = (pos != 0) - if pos: - print("arm_pos = out") - else: - print("arm_pos = in") + + pos = (pos != 0) + + if pos: + + print("arm_pos = out") + else: - pos = 100 + + print("arm_pos = in") + return pos + + def scale_readout(self): - if not devenvirement: + + if not DevEnvironment: + weight = self.hx.get_weight(5) + print("weight = %.1f" % weight) + else: + weight = 0 + return weight + + def scale_tare(self): - if not devenvirement: + + if not DevEnvironment: + self.hx.tare() + + def pump_start(self): + print("start pump") - if not devenvirement: + + if not DevEnvironment: + GPIO.setup(self.pump, GPIO.OUT) + + def pump_stop(self): + print("stop pump") - if not devenvirement: + + if not DevEnvironment: + GPIO.setup(self.pump, GPIO.IN) + + def valve_open(self, index, open=1): + if (index < 0 and index >= len(self.valveChannels) - 1): + return + if open == 0: + print("close valve no. %d" % index) + else: + print("open valve no. %d" % index) + ch = self.valveChannels[index] + pos = self.valvePositions[index][1 - open] + print("ch %d, pos %d" % (ch, pos)) - if not devenvirement: + + + if not DevEnvironment: + self.pca.set_pwm(ch, 0, pos) + + def valve_close(self, index): - if not devenvirement: + + if not DevEnvironment: + self.valve_open(index, open=0) + + def valve_dose(self, index, amount, timeout=30): + sr = 0 - if not devenvirement: + + if not DevEnvironment: + if (index < 0 and index >= len(self.valveChannels) - 1): + return + t0 = time.time() + self.scale_tare() + self.pump_start() + self.valve_open(index) + sr = self.scale_readout() + while sr < amount: + sr = self.scale_readout() + if (time.time() - t0) > timeout: + self.pump_stop() + self.valve_close(index) + return -1 + time.sleep(0.1) + self.pump_stop() + self.valve_close(index) + + else: + + print("dose channel %d, amount %d" % (index, amount)) + return sr + + def finger(self, pos=0): - if not devenvirement: + + if not DevEnvironment: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[pos]) + + def ping(self, num, retract=True): + print("ping :-)") - if not devenvirement: + + if not DevEnvironment: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) + for i in range(num): + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) + time.sleep(.15) + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[2]) + time.sleep(.15) + if retract: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) + else: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[0]) + + def cleanAndExit(self): + print("Cleaning...") - if not devenvirement: + + if not DevEnvironment: + GPIO.cleanup() + print("Bye!") + sys.exit() + + # Helper function to make setting a servo pulse width simpler. + def set_servo_pulse(self, channel, pulse): + pulse_length = 1000000 # 1,000,000 us per second + pulse_length //= 60 # 60 Hz - print('{0} us per period'.format(pulse_length)) + + print('{0} µs per period'.format(pulse_length)) + pulse_length //= 4096 # 12 bits of resolution - print('{0} us per bit'.format(pulse_length)) + + print('{0} µs per bit'.format(pulse_length)) + pulse *= 1000 + pulse //= pulse_length - if not devenvirement: + + if not DevEnvironment: + self.pca.set_pwm(channel, 0, pulse) + + + # end class HectorHardware + + if __name__ == "__main__": - if not devenvirement: + + #if not DevEnvironment: + hector = HectorHardware(config) + hector.finger(0) + hector.arm_in() + for i in range(hector.numValves): + print("close valve %d = channel %d" % (i, hector.valveChannels[i])) + hector.valve_close(hector.valveChannels[i]) + input("Bitte Glas auf die Markierung stellen") + # hector.ping(1) + hector.arm_out() + hector.valve_dose(1, 100) + hector.valve_dose(3, 20) + hector.finger(1) + hector.valve_dose(11, 100) + hector.arm_in() + hector.ping(3) + hector.finger(0) + hector.cleanAndExit() + print("done.") From f476c663ee2cde118721cd9773dba40182976a93 Mon Sep 17 00:00:00 2001 From: DevTown Date: Fri, 2 Nov 2018 13:48:16 +0100 Subject: [PATCH 2/4] More fixes from Kater --- src/HectorConfig.py | 53 +++++++++++++++++++++++++++++++++- src/HectorHardware.py | 66 +++++++++++++++++++++++++++---------------- 2 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/HectorConfig.py b/src/HectorConfig.py index c112013..a8b3f72 100644 --- a/src/HectorConfig.py +++ b/src/HectorConfig.py @@ -1,50 +1,101 @@ # hardware configuration + config = { + "hx711": { + "CLK": 29, + "DAT": 31, + "ref": 2145 # calibration yields 100 g <-> readout 214500 + }, + "pca9685": { + "freq": 60, + "valvechannels": range(12), # 0..11 + "valvepositions": [ # (open, closed) + (375, 535), # ch 0 + (375, 500), # ch 1 + (375, 535), # ch 2 + (375, 535), # ch 3 + (375, 535), # ch 4 + (375, 535), # ch 5 + (375, 250), # ch 6 + (375, 250), # ch 7 + (375, 250), # ch 8 + (375, 250), # ch 9 + (375, 250), # ch 10 + (375, 250) # ch 11 + ], + "fingerchannel": 12, + "fingerpositions": (280, 430, 450), # retracted, above bell, bell - "lightchannel": 13, + + "lightpin": 22, + + "lightpwmchannel": 13, + "lightpositions": (0, 500) + }, + "a4988": { + "ENABLE": 11, + "MS1": 13, + "MS2": 15, + "MS3": 19, + "RESET": 21, + "SLEEP": 23, + "STEP": 37, + "DIR": 33, + "numSteps": 260 + }, + "arm": { + "SENSE": 16 + }, + "pump": { + "MOTOR": 18 + }, + "ws2812": { + "DIN": 12 + } + } diff --git a/src/HectorHardware.py b/src/HectorHardware.py index 971f7dd..ae49bd6 100755 --- a/src/HectorHardware.py +++ b/src/HectorHardware.py @@ -14,7 +14,7 @@ -DevEnvironment = True +DevEnvironment = False @@ -68,11 +68,11 @@ def __init__(self, cfg): # setup scale (HX711) - hx1 = cfg["hx711"]["CLK"] + hx1 = cfg["hx711"]["CLK"] - hx2 = cfg["hx711"]["DAT"] + hx2 = cfg["hx711"]["DAT"] - hxref = cfg["hx711"]["ref"] + hxref = cfg["hx711"]["ref"] if not DevEnvironment: @@ -90,19 +90,21 @@ def __init__(self, cfg): # setup servos (PCA9685) - self.valveChannels = cfg["pca9685"]["valvechannels"] + self.valveChannels = cfg["pca9685"]["valvechannels"] - self.numValves = len(self.valveChannels) + self.numValves = len(self.valveChannels) - self.valvePositions = cfg["pca9685"]["valvepositions"] + self.valvePositions = cfg["pca9685"]["valvepositions"] - self.fingerChannel = cfg["pca9685"]["fingerchannel"] + self.fingerChannel = cfg["pca9685"]["fingerchannel"] - self.fingerPositions = cfg["pca9685"]["fingerpositions"] + self.fingerPositions = cfg["pca9685"]["fingerpositions"] - self.lightChannel = cfg["pca9685"]["lightchannel"] + self.lightPin = cfg["pca9685"]["lightpin"] - self.lightPositions = cfg["pca9685"]["lightpositions"] + self.lightChannel = cfg["pca9685"]["lightpwmchannel"] + + self.lightPositions = cfg["pca9685"]["lightpositions"] if not DevEnvironment: @@ -116,17 +118,17 @@ def __init__(self, cfg): # setup arm stepper (A4988) - self.armEnable = cfg["a4988"]["ENABLE"] + self.armEnable = cfg["a4988"]["ENABLE"] - self.armReset = cfg["a4988"]["RESET"] + self.armReset = cfg["a4988"]["RESET"] - self.armSleep = cfg["a4988"]["SLEEP"] + self.armSleep = cfg["a4988"]["SLEEP"] - self.armStep = cfg["a4988"]["STEP"] + self.armStep = cfg["a4988"]["STEP"] - self.armDir = cfg["a4988"]["DIR"] + self.armDir = cfg["a4988"]["DIR"] - self.armSteps = cfg["a4988"]["numSteps"] + self.armSteps = cfg["a4988"]["numSteps"] print("arm step %d, dir %d" % (self.armStep, self.armDir)) @@ -164,7 +166,19 @@ def __init__(self, cfg): - print("setup done") + def light_on(self): + + if not DevEnvironment: + + GPIO.output(self.lightPin, True) + + + + def light_off(self): + + if not DevEnvironment: + + GPIO.output(self.lightPin, False) @@ -210,7 +224,7 @@ def arm_in(self): GPIO.output(self.armEnable, False) - print("move arm in") + print("move arm in") if not DevEnvironment: @@ -240,19 +254,19 @@ def arm_pos(self): return 100 - pos = GPIO.input(self.arm) + pos = GPIO.input(self.arm) print("arm_pos: %d" % pos) - pos = (pos != 0) + pos = (pos != 0) - if pos: + if pos: - print("arm_pos = out") + print("arm_pos = out") - else: + else: - print("arm_pos = in") + print("arm_pos = in") return pos @@ -380,6 +394,8 @@ def valve_dose(self, index, amount, timeout=30): print("dose channel %d, amount %d" % (index, amount)) + time.sleep(3) + return sr From 3854ccf3cd64ca6a09fe4a693cc9d8436d3abcdc Mon Sep 17 00:00:00 2001 From: DevTown Date: Fri, 2 Nov 2018 18:01:49 +0100 Subject: [PATCH 3/4] Fixing lines from KAter --- src/HectorConfig.py | 52 +------ src/HectorHardware.py | 319 +++++------------------------------------- 2 files changed, 33 insertions(+), 338 deletions(-) diff --git a/src/HectorConfig.py b/src/HectorConfig.py index a8b3f72..adbfd4e 100644 --- a/src/HectorConfig.py +++ b/src/HectorConfig.py @@ -1,101 +1,51 @@ # hardware configuration - config = { - "hx711": { - "CLK": 29, - "DAT": 31, - "ref": 2145 # calibration yields 100 g <-> readout 214500 - }, - "pca9685": { - "freq": 60, - "valvechannels": range(12), # 0..11 - "valvepositions": [ # (open, closed) - (375, 535), # ch 0 - (375, 500), # ch 1 - (375, 535), # ch 2 - (375, 535), # ch 3 - (375, 535), # ch 4 - (375, 535), # ch 5 - (375, 250), # ch 6 - (375, 250), # ch 7 - (375, 250), # ch 8 - (375, 250), # ch 9 - (375, 250), # ch 10 - (375, 250) # ch 11 - ], - "fingerchannel": 12, - "fingerpositions": (280, 430, 450), # retracted, above bell, bell - "lightpin": 22, - "lightpwmchannel": 13, - "lightpositions": (0, 500) - }, - "a4988": { - "ENABLE": 11, - "MS1": 13, - "MS2": 15, - "MS3": 19, - "RESET": 21, - "SLEEP": 23, - "STEP": 37, - "DIR": 33, - "numSteps": 260 - }, - "arm": { - "SENSE": 16 - }, - "pump": { - "MOTOR": 18 - }, - "ws2812": { - "DIN": 12 - } - -} +} \ No newline at end of file diff --git a/src/HectorHardware.py b/src/HectorHardware.py index ae49bd6..2f52aa7 100755 --- a/src/HectorHardware.py +++ b/src/HectorHardware.py @@ -1,521 +1,266 @@ #!/usr/bin/env python3 - # -*- coding: utf8 -*- - ## - -# HectorHardware.py API class for Hector9000 hardware - +# HectorHardware.py API class for Hector9000 hardware # - # imports - from __future__ import division - - DevEnvironment = False - - import time - import sys - from HectorConfig import config - - # Uncomment to enable debug output. - import logging - - if not DevEnvironment: - import Adafruit_PCA9685 - import RPi.GPIO as GPIO - from hx711 import HX711 - - - logging.basicConfig(level=logging.DEBUG) - - - class HectorHardware: - - def __init__(self, cfg): - - self.config = cfg - if not DevEnvironment: - GPIO.setmode(GPIO.BOARD) - - # setup scale (HX711) - hx1 = cfg["hx711"]["CLK"] - hx2 = cfg["hx711"]["DAT"] - hxref = cfg["hx711"]["ref"] - if not DevEnvironment: - self.hx = HX711(hx1, hx2) - self.hx.set_reading_format("LSB", "MSB") - self.hx.set_reference_unit(hxref) - self.hx.reset() - self.hx.tare() - - # setup servos (PCA9685) - - self.valveChannels = cfg["pca9685"]["valvechannels"] - - self.numValves = len(self.valveChannels) - - self.valvePositions = cfg["pca9685"]["valvepositions"] - - self.fingerChannel = cfg["pca9685"]["fingerchannel"] - - self.fingerPositions = cfg["pca9685"]["fingerpositions"] - - self.lightPin = cfg["pca9685"]["lightpin"] - - self.lightChannel = cfg["pca9685"]["lightpwmchannel"] - - self.lightPositions = cfg["pca9685"]["lightpositions"] - + self.valveChannels = cfg["pca9685"]["valvechannels"] + self.numValves = len(self.valveChannels) + self.valvePositions = cfg["pca9685"]["valvepositions"] + self.fingerChannel = cfg["pca9685"]["fingerchannel"] + self.fingerPositions = cfg["pca9685"]["fingerpositions"] + self.lightPin = cfg["pca9685"]["lightpin"] + self.lightChannel = cfg["pca9685"]["lightpwmchannel"] + self.lightPositions = cfg["pca9685"]["lightpositions"] if not DevEnvironment: - pcafreq = cfg["pca9685"]["freq"] - self.pca = Adafruit_PCA9685.PCA9685() - self.pca.set_pwm_freq(pcafreq) - - # setup arm stepper (A4988) - - self.armEnable = cfg["a4988"]["ENABLE"] - - self.armReset = cfg["a4988"]["RESET"] - - self.armSleep = cfg["a4988"]["SLEEP"] - - self.armStep = cfg["a4988"]["STEP"] - - self.armDir = cfg["a4988"]["DIR"] - - self.armSteps = cfg["a4988"]["numSteps"] - + self.armEnable = cfg["a4988"]["ENABLE"] + self.armReset = cfg["a4988"]["RESET"] + self.armSleep = cfg["a4988"]["SLEEP"] + self.armStep = cfg["a4988"]["STEP"] + self.armDir = cfg["a4988"]["DIR"] + self.armSteps = cfg["a4988"]["numSteps"] print("arm step %d, dir %d" % (self.armStep, self.armDir)) - self.arm = cfg["arm"]["SENSE"] - if not DevEnvironment: - GPIO.setup(self.armEnable, GPIO.OUT) - GPIO.output(self.armEnable, True) - GPIO.setup(self.armReset, GPIO.OUT) - GPIO.output(self.armReset, True) - GPIO.setup(self.armSleep, GPIO.OUT) - GPIO.output(self.armSleep, True) - GPIO.setup(self.armStep, GPIO.OUT) - GPIO.setup(self.armDir, GPIO.OUT) - GPIO.setup(self.arm, GPIO.IN) - - # setup air pump (GPIO) - self.pump = cfg["pump"]["MOTOR"] - if not DevEnvironment: - GPIO.setup(self.pump, GPIO.IN) # pump off; will be turned on with GPIO.OUT (?!?) - - def light_on(self): - + print("turn on light") if not DevEnvironment: - GPIO.output(self.lightPin, True) - - def light_off(self): - + print("turn off light") if not DevEnvironment: - GPIO.output(self.lightPin, False) - - def arm_out(self): - if not DevEnvironment: - GPIO.output(self.armEnable, False) - print("move arm out") - if not DevEnvironment: - GPIO.output(self.armDir, True) - while not self.arm_pos(): - if not DevEnvironment: - GPIO.output(self.armStep, False) - time.sleep(.001) - GPIO.output(self.armStep, True) - time.sleep(.001) - if not DevEnvironment: - GPIO.output(self.armEnable, True) - - print("arm is in out position") - - - + print("arm is in OUT position") def arm_in(self): - self.arm_out() - if not DevEnvironment: - GPIO.output(self.armEnable, False) - - print("move arm in") - + print("move arm in") if not DevEnvironment: - GPIO.output(self.armDir, False) - for i in range(self.armSteps): - GPIO.output(self.armStep, False) - time.sleep(.001) - GPIO.output(self.armStep, True) - time.sleep(.001) - GPIO.output(self.armEnable, True) - - print("arm is in in position") - - + print("arm is in IN position") def arm_pos(self): - if DevEnvironment: - print("no arm pos available") - return 100 - - pos = GPIO.input(self.arm) - + pos = GPIO.input(self.arm) print("arm_pos: %d" % pos) - - pos = (pos != 0) - - if pos: - - print("arm_pos = out") - - else: - - print("arm_pos = in") - + pos = (pos != 0) + if pos: + print("arm_pos = out") + else: + print("arm_pos = in") return pos - - def scale_readout(self): - if not DevEnvironment: - weight = self.hx.get_weight(5) - print("weight = %.1f" % weight) - else: - weight = 0 - return weight - - def scale_tare(self): - if not DevEnvironment: - self.hx.tare() - - def pump_start(self): - print("start pump") - if not DevEnvironment: - GPIO.setup(self.pump, GPIO.OUT) - - def pump_stop(self): - print("stop pump") - if not DevEnvironment: - GPIO.setup(self.pump, GPIO.IN) - - def valve_open(self, index, open=1): - + if open == 0: + print("close valve") + else: + print("open valve") if (index < 0 and index >= len(self.valveChannels) - 1): - return - if open == 0: - print("close valve no. %d" % index) - else: - print("open valve no. %d" % index) - ch = self.valveChannels[index] - pos = self.valvePositions[index][1 - open] - print("ch %d, pos %d" % (ch, pos)) - - - if not DevEnvironment: - self.pca.set_pwm(ch, 0, pos) - - def valve_close(self, index): - if not DevEnvironment: - self.valve_open(index, open=0) - - def valve_dose(self, index, amount, timeout=30): - + print("dose channel %d, amount %d" % (index, amount)) sr = 0 - if not DevEnvironment: - if (index < 0 and index >= len(self.valveChannels) - 1): - return - t0 = time.time() - self.scale_tare() - self.pump_start() - self.valve_open(index) - sr = self.scale_readout() - while sr < amount: - sr = self.scale_readout() - if (time.time() - t0) > timeout: - self.pump_stop() - self.valve_close(index) - return -1 - time.sleep(0.1) - self.pump_stop() - self.valve_close(index) - else: - - print("dose channel %d, amount %d" % (index, amount)) - time.sleep(3) - return sr - - def finger(self, pos=0): - if not DevEnvironment: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[pos]) - - def ping(self, num, retract=True): - print("ping :-)") - if not DevEnvironment: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) - for i in range(num): - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) - time.sleep(.15) - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[2]) - time.sleep(.15) - if retract: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) - else: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[0]) - - def cleanAndExit(self): - print("Cleaning...") - if not DevEnvironment: - GPIO.cleanup() - print("Bye!") - sys.exit() - - # Helper function to make setting a servo pulse width simpler. - def set_servo_pulse(self, channel, pulse): - pulse_length = 1000000 # 1,000,000 us per second - pulse_length //= 60 # 60 Hz - print('{0} µs per period'.format(pulse_length)) - pulse_length //= 4096 # 12 bits of resolution - print('{0} µs per bit'.format(pulse_length)) - pulse *= 1000 - pulse //= pulse_length - if not DevEnvironment: - self.pca.set_pwm(channel, 0, pulse) - - - # end class HectorHardware - - if __name__ == "__main__": - #if not DevEnvironment: - hector = HectorHardware(config) - hector.finger(0) - hector.arm_in() - for i in range(hector.numValves): - print("close valve %d = channel %d" % (i, hector.valveChannels[i])) - hector.valve_close(hector.valveChannels[i]) - input("Bitte Glas auf die Markierung stellen") - # hector.ping(1) - hector.arm_out() - hector.valve_dose(1, 100) - hector.valve_dose(3, 20) - hector.finger(1) - hector.valve_dose(11, 100) - hector.arm_in() - hector.ping(3) - hector.finger(0) - hector.cleanAndExit() - - print("done.") + print("done.") \ No newline at end of file From 437e03087c5d6941b143daf678339ea64e5ada52 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 9 Jan 2019 18:51:47 +0100 Subject: [PATCH 4/4] current state after 35C3 maiden trip --- .gitignore | 4 + src/ConfigureScreen.py | 12 +- src/HectorConfig.py | 18 +- src/HectorHardware.py | 529 ++++++++++++++++++++--------------------- src/MainPanel.py | 36 ++- src/NeoPixel.py | 128 ++++++++++ src/adjustValves.py | 19 ++ src/clean.py | 40 ++++ src/database.py | 15 ++ src/drinks.py | 108 +++++++-- src/hx711.py | 0 src/main.py | 2 +- src/neo | 2 + src/servo_config.json | 26 +- src/valveclose.py | 30 +++ src/valveopen.py | 30 +++ src/windowconf | 0 17 files changed, 680 insertions(+), 319 deletions(-) mode change 100755 => 100644 src/HectorHardware.py mode change 100755 => 100644 src/MainPanel.py create mode 100644 src/NeoPixel.py create mode 100644 src/adjustValves.py create mode 100644 src/clean.py mode change 100755 => 100644 src/drinks.py mode change 100755 => 100644 src/hx711.py mode change 100755 => 100644 src/main.py create mode 100644 src/neo mode change 100755 => 100644 src/servo_config.json create mode 100644 src/valveclose.py create mode 100644 src/valveopen.py mode change 100755 => 100644 src/windowconf diff --git a/.gitignore b/.gitignore index 32800a5..76e8c9a 100755 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,7 @@ modules.xml *.pyc *.db + +src/log + +src/nohup\.out diff --git a/src/ConfigureScreen.py b/src/ConfigureScreen.py index aff0721..4418f15 100644 --- a/src/ConfigureScreen.py +++ b/src/ConfigureScreen.py @@ -21,14 +21,18 @@ def exit(self): Label(text='Do you realy want to close Hector9000 ? \nThere will be no more drinks ....')) root.add_widget(root2) - content = Button(text='OK', font_size=60, size_hint_y=0.15) - root.add_widget(content) + buttOK = Button(text='OK', font_size=60, size_hint_y=0.15) + root.add_widget(buttOK) + + buttCancel = Button(text='Cancel', font_size=60, size_hint_y=0.15) + root.add_widget(buttCancel) popup = Popup(title='WAIT !!!', content=root, auto_dismiss=False) - content.bind(on_press=popup.dismiss) - popup.bind(on_dismiss=self.shutdown) + buttOK.bind(on_press=self.shutdown) + buttCancel.bind(on_press=popup.dismiss) + #popup.bind(on_dismiss=self.shutdown) popup.open() def shutdown(self, instance): diff --git a/src/HectorConfig.py b/src/HectorConfig.py index adbfd4e..496507f 100644 --- a/src/HectorConfig.py +++ b/src/HectorConfig.py @@ -10,16 +10,16 @@ "valvechannels": range(12), # 0..11 "valvepositions": [ # (open, closed) (375, 535), # ch 0 - (375, 500), # ch 1 - (375, 535), # ch 2 - (375, 535), # ch 3 - (375, 535), # ch 4 - (375, 535), # ch 5 - (375, 250), # ch 6 + (375, 510), # ch 1 + (375, 515), # ch 2 + (375, 515), # ch 3 + (375, 520), # ch 4 + (375, 520), # ch 5 + (375, 235), # ch 6 (375, 250), # ch 7 (375, 250), # ch 8 - (375, 250), # ch 9 - (375, 250), # ch 10 + (375, 240), # ch 9 + (375, 235), # ch 10 (375, 250) # ch 11 ], "fingerchannel": 12, @@ -48,4 +48,4 @@ "ws2812": { "DIN": 12 } -} \ No newline at end of file +} diff --git a/src/HectorHardware.py b/src/HectorHardware.py old mode 100755 new mode 100644 index 2f52aa7..5531ae0 --- a/src/HectorHardware.py +++ b/src/HectorHardware.py @@ -1,266 +1,263 @@ -#!/usr/bin/env python3 -# -*- coding: utf8 -*- -## -# HectorHardware.py API class for Hector9000 hardware -# -# imports -from __future__ import division - -DevEnvironment = False - -import time -import sys -from HectorConfig import config - -# Uncomment to enable debug output. -import logging - -if not DevEnvironment: - import Adafruit_PCA9685 - import RPi.GPIO as GPIO - from hx711 import HX711 - - -logging.basicConfig(level=logging.DEBUG) - - -class HectorHardware: - - def __init__(self, cfg): - - self.config = cfg - if not DevEnvironment: - GPIO.setmode(GPIO.BOARD) - - # setup scale (HX711) - hx1 = cfg["hx711"]["CLK"] - hx2 = cfg["hx711"]["DAT"] - hxref = cfg["hx711"]["ref"] - if not DevEnvironment: - self.hx = HX711(hx1, hx2) - self.hx.set_reading_format("LSB", "MSB") - self.hx.set_reference_unit(hxref) - self.hx.reset() - self.hx.tare() - - # setup servos (PCA9685) - self.valveChannels = cfg["pca9685"]["valvechannels"] - self.numValves = len(self.valveChannels) - self.valvePositions = cfg["pca9685"]["valvepositions"] - self.fingerChannel = cfg["pca9685"]["fingerchannel"] - self.fingerPositions = cfg["pca9685"]["fingerpositions"] - self.lightPin = cfg["pca9685"]["lightpin"] - self.lightChannel = cfg["pca9685"]["lightpwmchannel"] - self.lightPositions = cfg["pca9685"]["lightpositions"] - if not DevEnvironment: - pcafreq = cfg["pca9685"]["freq"] - self.pca = Adafruit_PCA9685.PCA9685() - self.pca.set_pwm_freq(pcafreq) - - # setup arm stepper (A4988) - self.armEnable = cfg["a4988"]["ENABLE"] - self.armReset = cfg["a4988"]["RESET"] - self.armSleep = cfg["a4988"]["SLEEP"] - self.armStep = cfg["a4988"]["STEP"] - self.armDir = cfg["a4988"]["DIR"] - self.armSteps = cfg["a4988"]["numSteps"] - print("arm step %d, dir %d" % (self.armStep, self.armDir)) - self.arm = cfg["arm"]["SENSE"] - if not DevEnvironment: - GPIO.setup(self.armEnable, GPIO.OUT) - GPIO.output(self.armEnable, True) - GPIO.setup(self.armReset, GPIO.OUT) - GPIO.output(self.armReset, True) - GPIO.setup(self.armSleep, GPIO.OUT) - GPIO.output(self.armSleep, True) - GPIO.setup(self.armStep, GPIO.OUT) - GPIO.setup(self.armDir, GPIO.OUT) - GPIO.setup(self.arm, GPIO.IN) - - # setup air pump (GPIO) - self.pump = cfg["pump"]["MOTOR"] - if not DevEnvironment: - GPIO.setup(self.pump, GPIO.IN) # pump off; will be turned on with GPIO.OUT (?!?) - - def light_on(self): - print("turn on light") - if not DevEnvironment: - GPIO.output(self.lightPin, True) - - def light_off(self): - print("turn off light") - if not DevEnvironment: - GPIO.output(self.lightPin, False) - - def arm_out(self): - if not DevEnvironment: - GPIO.output(self.armEnable, False) - print("move arm out") - if not DevEnvironment: - GPIO.output(self.armDir, True) - while not self.arm_pos(): - if not DevEnvironment: - GPIO.output(self.armStep, False) - time.sleep(.001) - GPIO.output(self.armStep, True) - time.sleep(.001) - if not DevEnvironment: - GPIO.output(self.armEnable, True) - print("arm is in OUT position") - - - def arm_in(self): - self.arm_out() - if not DevEnvironment: - GPIO.output(self.armEnable, False) - print("move arm in") - if not DevEnvironment: - GPIO.output(self.armDir, False) - for i in range(self.armSteps): - GPIO.output(self.armStep, False) - time.sleep(.001) - GPIO.output(self.armStep, True) - time.sleep(.001) - GPIO.output(self.armEnable, True) - print("arm is in IN position") - - def arm_pos(self): - if DevEnvironment: - print("no arm pos available") - return 100 - pos = GPIO.input(self.arm) - print("arm_pos: %d" % pos) - pos = (pos != 0) - if pos: - print("arm_pos = out") - else: - print("arm_pos = in") - return pos - - def scale_readout(self): - if not DevEnvironment: - weight = self.hx.get_weight(5) - print("weight = %.1f" % weight) - else: - weight = 0 - return weight - - def scale_tare(self): - if not DevEnvironment: - self.hx.tare() - - def pump_start(self): - print("start pump") - if not DevEnvironment: - GPIO.setup(self.pump, GPIO.OUT) - - def pump_stop(self): - print("stop pump") - if not DevEnvironment: - GPIO.setup(self.pump, GPIO.IN) - - def valve_open(self, index, open=1): - if open == 0: - print("close valve") - else: - print("open valve") - if (index < 0 and index >= len(self.valveChannels) - 1): - return - if open == 0: - print("close valve no. %d" % index) - else: - print("open valve no. %d" % index) - ch = self.valveChannels[index] - pos = self.valvePositions[index][1 - open] - print("ch %d, pos %d" % (ch, pos)) - if not DevEnvironment: - self.pca.set_pwm(ch, 0, pos) - - def valve_close(self, index): - if not DevEnvironment: - self.valve_open(index, open=0) - - def valve_dose(self, index, amount, timeout=30): - print("dose channel %d, amount %d" % (index, amount)) - sr = 0 - if not DevEnvironment: - if (index < 0 and index >= len(self.valveChannels) - 1): - return - t0 = time.time() - self.scale_tare() - self.pump_start() - self.valve_open(index) - sr = self.scale_readout() - while sr < amount: - sr = self.scale_readout() - if (time.time() - t0) > timeout: - self.pump_stop() - self.valve_close(index) - return -1 - time.sleep(0.1) - self.pump_stop() - self.valve_close(index) - else: - time.sleep(3) - return sr - - def finger(self, pos=0): - if not DevEnvironment: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[pos]) - - def ping(self, num, retract=True): - print("ping :-)") - if not DevEnvironment: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) - for i in range(num): - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) - time.sleep(.15) - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[2]) - time.sleep(.15) - if retract: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) - else: - self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[0]) - - def cleanAndExit(self): - print("Cleaning...") - if not DevEnvironment: - GPIO.cleanup() - print("Bye!") - sys.exit() - - # Helper function to make setting a servo pulse width simpler. - def set_servo_pulse(self, channel, pulse): - pulse_length = 1000000 # 1,000,000 us per second - pulse_length //= 60 # 60 Hz - print('{0} µs per period'.format(pulse_length)) - pulse_length //= 4096 # 12 bits of resolution - print('{0} µs per bit'.format(pulse_length)) - pulse *= 1000 - pulse //= pulse_length - if not DevEnvironment: - self.pca.set_pwm(channel, 0, pulse) - - -# end class HectorHardware - -if __name__ == "__main__": - #if not DevEnvironment: - hector = HectorHardware(config) - hector.finger(0) - hector.arm_in() - for i in range(hector.numValves): - print("close valve %d = channel %d" % (i, hector.valveChannels[i])) - hector.valve_close(hector.valveChannels[i]) - input("Bitte Glas auf die Markierung stellen") - # hector.ping(1) - hector.arm_out() - hector.valve_dose(1, 100) - hector.valve_dose(3, 20) - hector.finger(1) - hector.valve_dose(11, 100) - hector.arm_in() - hector.ping(3) - hector.finger(0) - hector.cleanAndExit() - print("done.") \ No newline at end of file +#!/usr/bin/env python3 +# coding: utf8 +## +# HectorHardware.py API class for Hector9000 hardware +# +# imports +from __future__ import division + +devEnvironment = False + +import time +import sys +import Adafruit_PCA9685 +from HectorConfig import config + +# Uncomment to enable debug output. +import logging + +if not devEnvironment: + import RPi.GPIO as GPIO + from hx711 import HX711 + + +logging.basicConfig(level=logging.DEBUG) + + +class HectorHardware: + + def __init__(self, cfg): + + self.config = cfg + if not devEnvironment: + GPIO.setmode(GPIO.BOARD) + + hx1 = cfg["hx711"]["CLK"] + hx2 = cfg["hx711"]["DAT"] + hxref = cfg["hx711"]["ref"] + self.hx = HX711(hx1, hx2) + self.hx.set_reading_format("LSB", "MSB") + self.hx.set_reference_unit(hxref) + self.hx.reset() + self.hx.tare() + + pcafreq = cfg["pca9685"]["freq"] + self.pca = Adafruit_PCA9685.PCA9685() + self.pca.set_pwm_freq(pcafreq) + self.valveChannels = cfg["pca9685"]["valvechannels"] + self.numValves = len(self.valveChannels) + self.valvePositions = cfg["pca9685"]["valvepositions"] + self.fingerChannel = cfg["pca9685"]["fingerchannel"] + self.fingerPositions = cfg["pca9685"]["fingerpositions"] + self.lightPin = cfg["pca9685"]["lightpin"] + self.lightChannel = cfg["pca9685"]["lightpwmchannel"] + self.lightPositions = cfg["pca9685"]["lightpositions"] + + print("arm step + dir") + self.armEnable = cfg["a4988"]["ENABLE"] + self.armReset = cfg["a4988"]["RESET"] + self.armSleep = cfg["a4988"]["SLEEP"] + self.armStep = cfg["a4988"]["STEP"] + self.armDir = cfg["a4988"]["DIR"] + self.armSteps = cfg["a4988"]["numSteps"] + print("arm step %d + dir %d" % (self.armStep, self.armDir)) + + GPIO.setup(self.lightPin, GPIO.OUT) + GPIO.output(self.lightPin, False) + GPIO.setup(self.armEnable, GPIO.OUT) + GPIO.output(self.armEnable, True) + GPIO.setup(self.armReset, GPIO.OUT) + GPIO.output(self.armReset, True) + GPIO.setup(self.armSleep, GPIO.OUT) + GPIO.output(self.armSleep, True) + GPIO.setup(self.armStep, GPIO.OUT) + GPIO.setup(self.armDir, GPIO.OUT) + print("done") + + self.arm = cfg["arm"]["SENSE"] + if not devEnvironment: + GPIO.setup(self.arm, GPIO.IN) + + self.pump = cfg["pump"]["MOTOR"] + if not devEnvironment: + GPIO.setup(self.pump, GPIO.IN) # pump off; will be turned on with GPIO.OUT (?!?) + + def light_on(self): + if not devEnvironment: + GPIO.output(self.lightPin, True) + + def light_off(self): + if not devEnvironment: + GPIO.output(self.lightPin, False) + + def arm_out(self): + if not devEnvironment: + GPIO.output(self.armEnable, False) + print("move arm out") + if not devEnvironment: + GPIO.output(self.armDir, True) + while not self.arm_pos(): + if not devEnvironment: + GPIO.output(self.armStep, False) + time.sleep(.001) + GPIO.output(self.armStep, True) + time.sleep(.001) + if not devEnvironment: + GPIO.output(self.armEnable, True) + print("arm is in out position") + + + def arm_in(self): + self.arm_out() + if not devEnvironment: + GPIO.output(self.armEnable, False) + print("move arm in") + GPIO.output(self.armDir, False) + for i in range(self.armSteps): + GPIO.output(self.armStep, False) + time.sleep(.001) + GPIO.output(self.armStep, True) + time.sleep(.001) + GPIO.output(self.armEnable, True) + print("arm is in in position") + + def arm_pos(self): + if not devEnvironment: + pos = GPIO.input(self.arm) + print("arm_pos: %d" % pos) + if not devEnvironment: + pos = (pos != 0) + if pos: + print("arm_pos = out") + else: + print("arm_pos = in") + else: + pos = 100 + return pos + + def scale_readout(self): + if not devEnvironment: + weight = self.hx.get_weight(5) + print("weight = %.1f" % weight) + else: + weight = 0 + return weight + + def scale_tare(self): + if not devEnvironment: + self.hx.tare() + + def pump_start(self): + print("start pump") + if not devEnvironment: + GPIO.setup(self.pump, GPIO.OUT) + + def pump_stop(self): + print("stop pump") + if not devEnvironment: + GPIO.setup(self.pump, GPIO.IN) + + def valve_open(self, index, open=1): + if (index < 0 and index >= len(self.valveChannels) - 1): + return + if open == 0: + print("close valve no. %d" % index) + else: + print("open valve no. %d" % index) + ch = self.valveChannels[index] + pos = self.valvePositions[index][1 - open] + print("ch %d, pos %d" % (ch, pos)) + + if not devEnvironment: + self.pca.set_pwm(ch, 0, pos) + + def valve_close(self, index): + if not devEnvironment: + self.valve_open(index, open=0) + + def valve_dose(self, index, amount, timeout=30): + sr = 0 + if not devEnvironment: + if (index < 0 and index >= len(self.valveChannels) - 1): + return + t0 = time.time() + self.scale_tare() + self.pump_start() + self.valve_open(index) + sr = self.scale_readout() + while sr < amount: + sr = self.scale_readout() + if (time.time() - t0) > timeout: + self.pump_stop() + self.valve_close(index) + return -1 + time.sleep(0.1) + self.pump_stop() + self.valve_close(index) + return sr + + def finger(self, pos=0): + if not devEnvironment: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[pos]) + + def ping(self, num, retract=True): + print("ping :-)") + if not devEnvironment: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) + for i in range(num): + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) + time.sleep(.15) + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[2]) + time.sleep(.15) + if retract: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[1]) + else: + self.pca.set_pwm(self.fingerChannel, 0, self.fingerPositions[0]) + + def cleanAndExit(self): + print("Cleaning...") + if not devEnvironment: + GPIO.cleanup() + print("Bye!") + sys.exit() + + # Helper function to make setting a servo pulse width simpler. + def set_servo_pulse(self, channel, pulse): + pulse_length = 1000000 # 1,000,000 us per second + pulse_length //= 60 # 60 Hz + print('{0} us per period'.format(pulse_length)) + pulse_length //= 4096 # 12 bits of resolution + print('{0} us per bit'.format(pulse_length)) + pulse *= 1000 + pulse //= pulse_length + if not devEnvironment: + self.pca.set_pwm(channel, 0, pulse) + + +# end class HectorHardware + +if __name__ == "__main__": + if not devEnvironment: + hector = HectorHardware(config) + hector.ping(int(sys.argv[1])) + hector.finger(0) +if __name__ == "XX__main__": + if not devEnvironment: + hector = HectorHardware(config) + hector.finger(0) + hector.arm_in() + for i in range(hector.numValves): + print("close valve %d = channel %d" % (i, hector.valveChannels[i])) + hector.valve_close(hector.valveChannels[i]) + input("Bitte Glas auf die Markierung stellen") + # hector.ping(1) + hector.arm_out() + hector.valve_dose(1, 100) + hector.valve_dose(3, 20) + hector.finger(1) + hector.valve_dose(11, 100) + hector.arm_in() + hector.ping(3) + hector.finger(0) + hector.cleanAndExit() + print("done.") diff --git a/src/MainPanel.py b/src/MainPanel.py old mode 100755 new mode 100644 index 3df144b..38fc33b --- a/src/MainPanel.py +++ b/src/MainPanel.py @@ -72,7 +72,12 @@ def fillButtons(self, drinks): count = 0 while count < countDrinksOnScreen: self.buttonText[count] = drinks[count]['name'] - self.buttonColor[count] = [1, 0, 0, 1] if self.isalcoholic(drinks[count]) else [0, 1, 0, 1] + if self.buttonText[count].startswith("..."): + self.buttonColor[count] = [.3, .3, .3, 1] + elif self.isalcoholic(drinks[count]): + self.buttonColor[count] = [1, 0, 0, 1] + else: # non-alcoholic + self.buttonColor[count] = [0, 1, 0, 1] count += 1 while count < 8: @@ -90,25 +95,34 @@ def choiceDrink(self, *args): root2 = BoxLayout() root2.add_widget(Image(source='img/empty-glass.png')) root2.add_widget( - Label(text='Please be shoure ,\n that a Glas \nwith min 400ml \nstands under the extruder.')) + Label(text='Please be sure\n that a glass \nwith min 200 ml \nis placed onto the black fixture.', font_size='30sp')) root.add_widget(root2) - content = Button(text='OK', font_size=60, size_hint_y=0.15) - root.add_widget(content) + contentOK = Button(text='OK', font_size=60, size_hint_y=0.15) + root.add_widget(contentOK) + + contentCancel = Button(text='Cancel', font_size=60, size_hint_y=0.15) + root.add_widget(contentCancel) popup = Popup(title='LOOK HERE !!!', content=root, auto_dismiss=False) def closeme(button): popup.dismiss() - Clock.schedule_once(partial(self.doGiveDrink, args[0]), .5) + Clock.schedule_once(partial(self.doGiveDrink, args[0]), .01) + + contentOK.bind(on_press=closeme) + + def cancelme(button): + popup.dismiss() + + contentCancel.bind(on_press=cancelme) - content.bind(on_press=closeme) popup.open() def doGiveDrink(self, drink, intervaltime): root = BoxLayout(orientation='vertical') - content = Label(text='Take a break \nYour \n\n' + self.drinkOnScreen[drink]["name"]+'\n\nwill be mixed.') + content = Label(text='Take a break -- \nYour \n\n' + self.drinkOnScreen[drink]["name"]+'\n\nwill be mixed.', font_size='40sp') root.add_widget(content) popup = Popup(title='Life, the Universe, and Everything. There is an answer.', content=root, auto_dismiss=False) @@ -117,18 +131,22 @@ def makeDrink(parentwindow): drinks = self.drinkOnScreen[drink] hector = HectorHardware(config) + hector.light_on() + time.sleep(1) hector.arm_out() for ingridient in drinks["recipe"]: hector.valve_dose(pumpList[ingridient[0]], ingridient[1]) - time.sleep(1) + time.sleep(.1) print("IndexPumpe: ", pumpList[ingridient[0]]) - print("Incredence: ", ingridient[0]) + print("Ingredient: ", ingridient[0]) print("Output in ml: ", ingridient[1]) self.db.countUpIngredient(ingridient[0],ingridient[1]) + time.sleep(1) self.db.countUpDrink(drinks["name"]) hector.arm_in() + hector.light_off() hector.finger(1) hector.ping(3) hector.finger(0) diff --git a/src/NeoPixel.py b/src/NeoPixel.py new file mode 100644 index 0000000..8cd907b --- /dev/null +++ b/src/NeoPixel.py @@ -0,0 +1,128 @@ + +import time, board, neopixel + +PORT = board.D18 +NUM = 15 +NUMBASE = 5 + +pixels = neopixel.NeoPixel(PORT, NUM) + +cols = [ + (255, 0, 0), + (255, 63, 0), + (255, 120, 0), + (0, 255, 0), + (0, 255, 255), + (0, 0, 255), + (255, 0, 255) + ] +col_neutral = (80,80,30) + +NUMCOLS = len(cols) + +def mode1(): + while True: + for i in range(NUMCOLS): + pixels.fill(cols[i]) + time.sleep(4) + +def mode2(): + + while True: + pixels.fill((0,0,0)) + time.sleep(.05) + pixels.fill((255,255,255)) + time.sleep(.05) + +def modeClean(): + + while True: + pixels.fill((255,255,255)) + time.sleep(.5) + pixels.fill((255,255,0)) + time.sleep(.5) + +def mode3(): + for i in range(NUMBASE): + pixels[i] = (0,0,255) + while True: + for c in range(NUMCOLS): + for i in range(NUM-NUMBASE): + pixels[NUMBASE+i] = cols[c] + #pixels[(NUMBASE+i-1) % NUM] = (0,0,0) + time.sleep(.1) + for i in range(NUMBASE): + pixels[i] = (0,0,255) + +# The number of NeoPixels +num_pixels = NUM + +# The order of the pixel colors - RGB or GRB. Some NeoPixels have red and green reversed! +# For RGBW NeoPixels, simply change the ORDER to RGBW or GRBW. +ORDER = neopixel.GRB + +#pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.2, auto_write=False, pixel_order=ORDER) + + +def wheel(pos): + # Input a value 0 to 255 to get a color value. + # The colours are a transition r - g - b - back to r. + if pos < 0 or pos > 255: + r = g = b = 0 + elif pos < 85: + r = int(pos * 3) + g = int(255 - pos*3) + b = 0 + elif pos < 170: + pos -= 85 + r = int(255 - pos*3) + g = 0 + b = int(pos*3) + else: + pos -= 170 + r = 0 + g = int(pos*3) + b = int(255 - pos*3) + return (r, g, b) if ORDER == neopixel.RGB or ORDER == neopixel.GRB else (r, g, b, 0) + + +def rainbow_cycle(wait): + for j in range(255): + for i in range(NUM-NUMBASE): + pixel_index = (i * 256 // num_pixels) + j + #pixels[NUMBASE+i] = wheel((int(-pixel_index * 20 / 256) + 55) & 255) + pixels[NUMBASE+i] = wheel(int(pixel_index) & 255) + for j in range(NUMBASE): + pixels[j] = pixels[NUMBASE] + pixels.show() + time.sleep(wait) + + +def mode4(): + while True: + if False: + # Comment this line out if you have RGBW/GRBW NeoPixels + pixels.fill((255, 0, 0)) + # Uncomment this line if you have RGBW/GRBW NeoPixels + # pixels.fill((255, 0, 0, 0)) + pixels.show() + time.sleep(1) + + # Comment this line out if you have RGBW/GRBW NeoPixels + pixels.fill((0, 255, 0)) + # Uncomment this line if you have RGBW/GRBW NeoPixels + # pixels.fill((0, 255, 0, 0)) + pixels.show() + time.sleep(1) + + # Comment this line out if you have RGBW/GRBW NeoPixels + pixels.fill((0, 0, 255)) + # Uncomment this line if you have RGBW/GRBW NeoPixels + # pixels.fill((0, 0, 255, 0)) + pixels.show() + time.sleep(1) + + rainbow_cycle(0.001) # rainbow cycle with 1ms delay per step + + +modeClean() diff --git a/src/adjustValves.py b/src/adjustValves.py new file mode 100644 index 0000000..ecdb60e --- /dev/null +++ b/src/adjustValves.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 + +import sys +from HectorConfig import config +from HectorHardware import HectorHardware + +h = HectorHardware(config) + +while True: + vnum = int(input("Bitte Ventilnr. eingeben (0..11); Ende mit -1: ")) + if vnum == -1: + sys.exit() + cpos = h.valvePositions[vnum][1] + print("Ventil %d wird geschlossen, Servoposition = %d" % (vnum, cpos)) + while cpos != -1: + h.pca.set_pwm(vnum, 0, cpos) + cpos = int(input("Bitte neue Servoposition eingeben:")) + + diff --git a/src/clean.py b/src/clean.py new file mode 100644 index 0000000..915bccc --- /dev/null +++ b/src/clean.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +import sys, time +from HectorConfig import config +from HectorHardware import HectorHardware + +hardware = True + +if hardware: + h = HectorHardware(config) + +print("REINIGUNG") +print("") + +if hardware: + h.light_on() + time.sleep(1) + h.arm_out() + +if True: + vlist = sys.argv[1:] + valves = [] + print("Die folgenden Kanäle werden jetzt gereinigt:") + for v in vlist: + if v == "": + continue + i = int(v) + print(" %d" % i) + valves.append(i) +if hardware: + h.pump_start() + while True: + for vnum in valves: + print("Ventil %d wird geöffnet, Ende mit " % (vnum,)) + h.valve_open(vnum) + time.sleep(10) + h.valve_close(vnum) + + + diff --git a/src/database.py b/src/database.py index ba15249..9a66e9c 100644 --- a/src/database.py +++ b/src/database.py @@ -1,5 +1,6 @@ import sqlite3 as lite import datetime +from time import * class Database: @@ -31,3 +32,17 @@ def countUpIngredient(self, ingredient, ml): def __del__(self): self.con.commit() self.con.close() + +# when called directly, read out database and generate a log +if __name__ == "__main__": + db = Database("h9k") + db.cur.execute("SELECT * FROM DrinksLog WHERE date > '2018-12-11' ORDER BY date ASC") + #db.cur.execute("SELECT * FROM DrinksLog ORDER BY date ASC") + res = db.cur.fetchall() + #print("%d entries" % len(res)) + for l in res: + number, name, tstampstr = l + tstamp = mktime(strptime(tstampstr.split(".")[0], "%Y-%m-%d %H:%M:%S")) + tstamp += (14*24*3600 + 10*3600 + 8*60 + 28) + print("%30s: %s" % (strftime("%a %Y-%m-%d %H:%M:%S", localtime(tstamp)), name)) + diff --git a/src/drinks.py b/src/drinks.py old mode 100755 new mode 100644 index 1ab93f8..af00662 --- a/src/drinks.py +++ b/src/drinks.py @@ -2,38 +2,112 @@ drink_list = [ { - "name": "Gin \n& \nTonic", + "name": "...under\nconstruction", "recipe": [ - ("gin", 50), - ("tonic", 150) -] + ] }, { "name": "Virgin Sunrise", "recipe": [ - ("oj", 150), - ("gren", 15) + ("oj", 160), + ("gren", 8) + ] + }, { + "name": "Exotic", + "recipe": [ + ("oj", 90), + ("pineapple", 60), + ("mango", 30), + ("curacao", 16) + #("cocos", 16) + ] + }, { + "name": "PineMate", + "recipe": [ + ("mate", 100), + ("pineapple", 75), + ("curacao", 16) + #("cocos", 20) + ] + }, { + "name": "Happy", + "recipe": [ + ("mate", 100), + ("mango", 50), + ("lemonjuice", 20) + ] + }, { + "name": "...under\nconstruction", + "recipe": [ + ] + }, { + "name": "...under\nconstruction", + "recipe": [ + ] + }, { + "name": "...under\nconstruction", + "recipe": [ + ] + }, { + "name": "...under\nconstruction", + "recipe": [ + ] + }, { + "name": "...under\nconstruction", + "recipe": [ + ] + }, { + "name": "...under\nconstruction", + "recipe": [ + ] + }, { + "name": "Bo", + "recipe": [ + ("oj", 120), + ("bacardi", 40) + ] + }, { + "name": "Bs", + "recipe": [ + ("oj", 120), + ("bacardi", 40), + ("gren", 8) + ] + }, { + "name": "Ts 0 (1:6)", + "recipe": [ + ("bacardi", 20), + ("mate", 120) ] }, { - "name": "Tequila Sunrise", + "name": "Ts 1", "recipe": [ - ("tequila", 50), - ("oj", 150), - ("gren", 15) - ] } + ("bacardi", 40), + ("mate", 300) + ] + }, { + "name": "...under\nconstruction", + "recipe": [ + ] + } ] # "NAME":("NICENAME", ISWITHALCOHOL) ingredients = { - "gin": ("Gin", True), + "gren": ("Grenadine", False), + "cocos": ("Cocos", False), + "lemonjuice": ("Lemon Juice", False), + "bacardi": ("Bacardi", True), "rum": ("Rum", True), "vodka": ("Vodka", True), - "tequila": ("Tequila", True), - "tonic": ("Tonic Water", False), - "coke": ("Coke", False), + "gin": ("Gin", True), + "curacao": ("Blue Curacao", False), + "mango": ("Mango", False), + "pineapple": ("Pineapple", False), + "tequila": ("tequila", False), + "cola": ("Cola", False), "oj": ("Orange Juice", False), - "gren": ("Orange Juice", False), - "mmix": ("Margarita Mix", True) + "mate": ("Mate", False), } diff --git a/src/hx711.py b/src/hx711.py old mode 100755 new mode 100644 diff --git a/src/main.py b/src/main.py old mode 100755 new mode 100644 index 3751a4f..5b67ee0 --- a/src/main.py +++ b/src/main.py @@ -5,7 +5,7 @@ from MainPanel import MainPanel from ConfigureScreen import Configure -Config.set('graphics', 'fullscreen', '0') # 'auto' -> Fullscreen | '0' -> NormalMode +Config.set('graphics', 'fullscreen', 'auto') # 'auto' -> Fullscreen | '0' -> NormalMode class MyScreenManager(ScreenManager): diff --git a/src/neo b/src/neo new file mode 100644 index 0000000..cb02682 --- /dev/null +++ b/src/neo @@ -0,0 +1,2 @@ +#!/bin/sh +sudo python3 NeoPixel.py diff --git a/src/servo_config.json b/src/servo_config.json old mode 100755 new mode 100644 index 15f57b1..30f6c3b --- a/src/servo_config.json +++ b/src/servo_config.json @@ -2,61 +2,61 @@ "pump_1": { "name": "Pump 1", "channel": 0, - "value": "gin" + "value": "gren" }, "pump_2": { "name": "Pump 2", "channel": 1, - "value": "tonic" + "value": "cocos" }, "pump_3": { "name": "Pump 3", "channel": 2, - "value": "oj" + "value": "lemonjuice" }, "pump_4": { "name": "Pump 4", "channel": 3, - "value": "coke" + "value": "rum" }, "pump_5": { "name": "Pump 5", "channel": 4, - "value": "tequila" + "value": "vodka" }, "pump_6": { "name": "Pump 6", "channel": 5, - "value": "gren" + "value": "000_gin" }, "pump_7": { "name": "Pump 7", "channel": 6, - "value": null + "value": "curacao" }, "pump_8": { "name": "Pump 8", "channel": 7, - "value": null + "value": "mango" }, "pump_9": { "name": "Pump 9", "channel": 8, - "value": null + "value": "pineapple" }, "pump_10": { "name": "Pump 10", "channel": 9, - "value": null + "value": "mate" }, "pump_11": { "name": "Pump 11", "channel": 10, - "value": null + "value": "bacardi" }, "pump_12": { "name": "Pump 12", "channel": 11, - "value": null + "value": "oj" } -} \ No newline at end of file +} diff --git a/src/valveclose.py b/src/valveclose.py new file mode 100644 index 0000000..4d51fcd --- /dev/null +++ b/src/valveclose.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +import sys, time +from HectorConfig import config +from HectorHardware import HectorHardware + +hardware = True + +if hardware: + h = HectorHardware(config) + +print("VENTILE SCHLIESSEN") +print("") + +if hardware: + h.light_on() + time.sleep(1) + h.arm_in() + + h.pump_stop() + for vnum in range(12): + print("Ventil %d wird geschlossen" % (vnum,)) + time.sleep(1) + h.valve_close(vnum) + +h.light_off() + +print("fertig.") + + diff --git a/src/valveopen.py b/src/valveopen.py new file mode 100644 index 0000000..4451d13 --- /dev/null +++ b/src/valveopen.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +import sys, time +from HectorConfig import config +from HectorHardware import HectorHardware + +hardware = True + +if hardware: + h = HectorHardware(config) + +print("VENTILE ÖFFNEN") +print("") + +if hardware: + h.light_on() + time.sleep(1) + h.arm_in() + + h.pump_stop() + for vnum in range(12): + print("Ventil %d wird geöffnet" % (vnum,)) + time.sleep(1) + h.valve_open(vnum) + +h.light_off() + +print("fertig.") + + diff --git a/src/windowconf b/src/windowconf old mode 100755 new mode 100644