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()