Da wir nun endlich den Prüfungsaufbau vollständig modifizieren können, beseitigen wir die größte Schwachstelle des Systems:
Die Trennung des induktiven und kapazitiven Sensors!!!
Das alte Modell
Ablauf:
- Der Zylinder m1 blockiert die Rutsche
- Wenn ein Würfel am kapazitiven Sensor „s_rutsche“ (blau) ankommt, wird m1 eingefahren und der Würfel rutscht herunter
- Der Würfel erreicht den induktiven Sensor „s_metall“ (silber)
- Auswertung findest statt: Handelt es sich um ein Metallwürfel, bekommt man ein 1 Signal, bei einem Plastikwürfel eine 0.
Schwachstelle: Woher sollte man nun wissen, ob der Würfel überhaupt unter dem Sensor „s_metall“ liegt, sich auf der Rutsche verkeilte oder gar nicht los rutschte? GING NICHT!
Abhilfe: Man ließ eine Zeit ablaufen. Nach Ablauf musste entweder eine 1 an „s_metall“ stehen oder es wurde vermutet, dass es sich um einen Plastikwürfel handelt…
Das NEUE Modell
ENDLICH bekommen wir die Sensorwerte parallel! Dies bedeutet nun folgenden Ablauf:
- Der Zylinder „m1“ ist immer eingefahren
- Ein Würfel kann frei die Rampe herunterrutschen
- Sensor „s_rutsche“ (blau) bekommt ein 1 Signal, fährt Zylinder „m1“ aus und sperrt weitere Würfel
- In genau diesem Moment, wenn „s_rutsche“ eine 1 hat, können wir den Sensor „s_metall“ verlässlich auswerten! Hat dieser jetzt eine 1, ist es Metall und bei einer 0 ganz sicher Plastik!
Der Vorgang der Sortierung hat sich zum alten Modell nicht geändert, aber der Quelltext für diese Änderung!
class AutomatikSeri(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 als Wert >0 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.io.h_start.value = True # Automatikbetrieb auf virtuellem Device setzen self.rpi.io.aktivauto.value = True # Automatisch Grundstellung herstellen funccatalog.band.grundstellung() funccatalog.zylinder.grundstellung() while not self.evt_ende.is_set(): # Warten, bis ein Wuerfel am Sensor s_rutsche erkannt wird ec = self.rpi.io.s_rutsche.wait( exitevent=self.evt_ende, okvalue=True ) if ec > 0: break # Zylinder m1 ausfahren funccatalog.zylinder.set_m1(True) # Kleines delay für den Metallsensor ec = self.rpi.io.s_metall.wait( exitevent=self.evt_ende, okvalue=True, timeout=100 ) if ec > 0: print("kunststoff erkannt") self.metall = False else: print("metall erkannt") self.metall = True # Prüfen ob Magazine voll sind if self.checkmagazinvoll(): self.aufhaldefahren() # Zylinder m1 einfahren funccatalog.zylinder.set_m1(False) continue print("motor los") funccatalog.band.set_lahm_rechts() # Warten bis Würfel bei Magazin 1 angekommen ist ec = self.rpi.io.s_magazin1.wait( exitevent=self.evt_ende, timeout=7000 ) if ec <= 0 and self.metall: # Warten bis Würfel bei Magazin 2 angekommen ist ec = self.rpi.io.s_magazin2.wait( exitevent=self.evt_ende, timeout=3000 ) print("motor aus") funccatalog.band.grundstellung() if ec == 1: # exitevent ausgelöst break elif ec == 2: # timeout überschritten funccatalog.anlage.stoerung = True break # Auf Motorstopp warten ec = self.rpi.io.fu_motoran.wait( exitevent=self.evt_ende, timeout=1000 ) if ec == 1: # exitevent ausgelöst break elif ec == 2: # timeout überschritten funccatalog.anlage.stoerung = True break if self.metall: # Zylinder m3 ausfahren und warten auf Endlage print("auswerfen") funccatalog.zylinder.set_m3(True) ec = self.rpi.io.m_m3_ausgefahren.wait(exitevent=self.evt_ende) if ec > 0: break # Magazinzähler Metall erhöhen self.rpi.io.magazin2.value += 1 # Zylinder m3 einfahren funccatalog.zylinder.set_m3(False) else: # Zylinder m2 ausfahren und warten auf Endlage print("auswerfen") funccatalog.zylinder.set_m2(True) ec = self.rpi.io.m_m2_ausgefahren.wait(exitevent=self.evt_ende) if ec > 0: break # Magazinzähler Kunststoff erhöhen self.rpi.io.magazin1.value += 1 # Zylinder m2 einfahren funccatalog.zylinder.set_m2(False) # Zylinder m1 einfahren funccatalog.zylinder.set_m1(False) # Grundstellung einnehmen funccatalog.band.grundstellung() if self.evt_ende.is_set(): funccatalog.zylinder.grundstellung() # Lampen ausschalten self.rpi.io.h_start.value = False # Automatikbetrieb auf virtuellem Device zurücknehmen self.rpi.io.aktivauto.value = False def aufhaldefahren(self): """Faehrt Wuerfel auf die Halde.""" print("magazin voll - auswerfen") funccatalog.band.set_schnell_rechts() self.evt_ende.wait(3) funccatalog.band.grundstellung() def checkmagazinvoll(self): """Prueft ob eines der Magazine voll ist. @return True, wenn eines der Magazine voll ist""" return ( self.metall and self.rpi.io.warn_mag2full.value or not self.metall and self.rpi.io.warn_mag1full.value ) def stop(self): """Beendet den Automatikbetrieb.""" self.evt_ende.set()