In unserem Thread für die Automatik sehen wir nun ein interessantes Konzept. Wir „warten“ im Quellcode auf Sensoren, die auslösen. Der Quellcode blockiert an den jeweiligen Stellen und kann über bestimmte Bedingungen, Ereignisse oder threading.Events() fortgesetzt werden.
Die Ablauflogik ist in der run() Funktion, welche durchgehend ausgeführt wird, wenn der Thread läuft. Der Thread wird durch die Eventfunktion def evt_start(self): aus unserem vorherigen Beitrag gestartet.
Für den kapazitiven Sensor „s_metall“ wird zu Beginn des Threads ein Event Registriert, welches unseren „Merker“ self.metall auf True setzt. Dieser wird in der run() Funktion ausgewertet.
class Automatik(Thread):
"""Thread fuer den Automatikbetrieb."""
def __init__(self, rpi):
"""Instanziiert den Automatik-Thread."""
super().__init__()
self.evt_ende = Event()
self.daemon = True
self.rpi = rpi
self.metall = False
def run(self):
"""Wird durchgehend ausgefuehrt, wenn Anlage im Automatikbetrieb.
Diese Funktion lauft durchgehend und Regelt die Ablaeufe fuer den
Automatikbetrieb. Die wait() Funktionen bekommen immer das Exit-Event
self.evt_ende uebergeben, damit diese beim Beenden vom Automatikbetrieb
abgebrochen werden. Da dann ein False zurueckgegeben wird, brechen wir
die Verarbeitung an der Stelle ab. Die while-Schleife wird dann
verlassen.
Ungewoehnlich ist evtl. das sich das Programm DAUERHAFT in dieser
Schleife aufhaelt. Die automatische Prozessbildaktualisierung von
RevPiModIO synchronisiert im Hinterhund staendig unsere Inputs und
Outputs. Und ein Blockieren des Programms verhindern wir damit, dass
diese Funktion als Thread ausgefuehrt wird.
"""
# Lampe h_start Einschalten
self.rpi.devices["do02"]["h_start"] = True
# Automatisch Grundstellung herstellen
funccatalog.band.grundstellung()
funccatalog.zylinder.grundstellung()
self.rpi.devices["do02"]["h_automatik"] = True
self.rpi.devices["di02"].reg_event(
"s_metall", self.set_metall, edge=revpimodio.RISING
)
while not self.evt_ende.is_set():
# Warten, bis ein Wuerfel am Sensor s_rutsche erkannt wird
ec = self.rpi.devices.wait(
"di02", "s_rutsche", exitevent=self.evt_ende, okvalue=True
)
if ec > 0:
break
# Zylinder m1 einfahren
funccatalog.zylinder.set_m1(False)
# Metallmerker reset
self.metall = False
# Warten bis Endlage m1 erreicht ist
ec = self.rpi.devices.wait(
"di02", "m_m1_eingefahren", exitevent=self.evt_ende
)
if ec > 0:
break
# Warten damit Würfel zum Metallsensor rutschen kann
self.evt_ende.wait(2)
# Zylinder m1 ausfahren
funccatalog.zylinder.set_m1(True)
# Prüfen ob Magazine voll sind
if self.checkmagazinvoll():
self.aufhaldefahren()
continue
print("motor los")
funccatalog.band.set_lahm_rechts(True)
if self.metall:
# Warten bis Würfel bei Magazin 2 angekommen ist
ec = self.rpi.devices.wait(
"di02", "s_magazin2",
exitevent=self.evt_ende,
timeout=7000
)
print("motor aus")
funccatalog.band.set_lahm_rechts(False)
if ec == 1:
# exitevent ausgelöst
break
if ec == 2:
# timeout überschritten
continue
self.evt_ende.wait(0.5)
# Zylinder m3 ausfahren und warten auf Endlage
print("auswerfen")
funccatalog.zylinder.set_m3(True)
ec = self.rpi.devices.wait(
"di02", "m_m3_ausgefahren", exitevent=self.evt_ende
)
if ec > 0:
break
# Magazinzähler Metall erhöhen
funccatalog.anlage.magazin2 += 1
# Zylinder m3 einfahren
funccatalog.zylinder.set_m3(False)
else:
print("kunststoff erkannt")
# Warten bis Würfel bei Magazin 1 angekommen ist
ec = self.rpi.devices.wait(
"di02", "s_magazin1",
exitevent=self.evt_ende,
timeout=10000
)
print("motor aus")
funccatalog.band.set_lahm_rechts(False)
if ec == 1:
# exitevent ausgelöst
break
if ec == 2:
# timeout überschritten
continue
self.evt_ende.wait(0.5)
# Zylinder m2 ausfahren und warten auf Endlage
print("auswerfen")
funccatalog.zylinder.set_m2(True)
ec = self.rpi.devices.wait(
"di02", "m_m2_ausgefahren", exitevent=self.evt_ende
)
if ec > 0:
break
# Magazinzähler Kunststoff erhöhen
funccatalog.anlage.magazin1 += 1
# Zylinder m2 einfahren
funccatalog.zylinder.set_m2(False)
self.rpi.devices["do02"]["h_automatik"] = False
self.rpi.devices["di02"].unreg_event(
"s_metall", self.set_metall, edge=revpimodio.RISING
)
# Lampe h_start Ausschalten
self.rpi.devices["do02"]["h_start"] = False
def aufhaldefahren(self):
"""Faehrt Wuerfel auf die Halde."""
print("magazin voll - auswerfen")
funccatalog.band.set_schnell_rechts(True)
self.evt_ende.wait(4)
funccatalog.band.set_schnell_rechts(False)
def checkmagazinvoll(self):
"""Prueft ob eines der Magazine voll ist.
@return True, wenn eines der Magazine voll ist"""
return (
self.metall
and funccatalog.anlage.magazin2 >= funccatalog.anlage.magazin2max
or not self.metall
and funccatalog.anlage.magazin1 >= funccatalog.anlage.magazin1max
)
def set_metall(self, ioname, iovalue):
"""Eventfunktion loest aus, wenn Metallsensor gesetzt wird."""
print("metall erkannt")
self.metall = True
# Im Event Prüfen
if self.checkmagazinvoll():
# Nur auf Halde fahren, wenn noch nicht gemacht
if not self.rpi.devices["do01"]["q_schnell_rechts"]:
self.aufhaldefahren()
def stop(self):
"""Beendet den Automatikbetrieb."""
self.evt_ende.set()
funccatalog.band.grundstellung()
funccatalog.zylinder.grundstellung()
