Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
| zutrittskontrolle_tor_und_anmeldung_zna [2019/06/25 16:19] – student | zutrittskontrolle_tor_und_anmeldung_zna [2023/07/03 10:16] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| + | ---- | ||
| + | ===== Zutrittskontrolle Tor und Anmeldung ZNA ===== | ||
| + | |||
| + | ====== Kurzbeschreibung ====== | ||
| + | |||
| + | Als Projekt haben wir uns die Alltagssituation in einer Notaufnahme vorgenommen. Es kommt ein Rettungswagen, | ||
| + | In der Einfahrt selber hängt ein Touchbildschirm, | ||
| + | |||
| + | ===== Screenshots Touchscreen ===== | ||
| + | |||
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | |||
| + | |||
| + | ====== Aufbau ====== | ||
| + | |||
| + | Die Torsteuerung wird über einen 12V und einen 5V Akku versorgt. Der Motor ist über eine H-Brücke angeschlossen, | ||
| + | Die Zutrittskontrolle wird mit einem RFID USB Reader geregelt. | ||
| + | Die Anmeldung wird mit vor definierten Felder auf einem Touchbildschirm durchgeführt. Nach der Auswahl werden passende Emails versendet. | ||
| + | |||
| + | ==== Bauteile ==== | ||
| + | |||
| + | * Drehspiegelkennleuchte (Gelb) | ||
| + | * Raspberry Pi 3 | ||
| + | * Raspberry Pi Touchdisplay | ||
| + | * [[nfc-shield|RFID-Leser]] | ||
| + | * 2 RFID-Karten | ||
| + | * Akku für 5v Stromversorgung | ||
| + | * Akku für 12v Stromversorgung | ||
| + | * [[dc-motor|DC-Motor]] | ||
| + | * 2 Taster | ||
| + | * [[h-bruecke|H-Brücke]] | ||
| + | * 2 Transistoren | ||
| + | |||
| + | ==== Fritzing-Schaltung ==== | ||
| + | |||
| + | |||
| + | {{: | ||
| + | |||
| + | ==== Flussdiagramme ==== | ||
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ===== Code-Ausschnitte: | ||
| + | |||
| + | Besteht aus 2 Teilen: | ||
| + | |||
| + | Python als Programmiersprache | ||
| + | |||
| + | <file python Anmeldung_ZNA.py> | ||
| + | #programm fuer Anmeldung | ||
| + | #zeigt Email Account und fuellt ihn mit Werten. Einfach aus dem Netz genommen | ||
| + | import smtplib | ||
| + | from email.MIMEMultipart import MIMEMultipart | ||
| + | from email.MIMEText import MIMEText | ||
| + | |||
| + | senderEmail = " | ||
| + | empfangsEmail = " | ||
| + | msg = MIMEMultipart() | ||
| + | msg[' | ||
| + | msg[' | ||
| + | |||
| + | #Programm welches die Anmeldung angibt | ||
| + | import time | ||
| + | |||
| + | def anmeldung(): | ||
| + | stopp2() | ||
| + | start() | ||
| + | def triage(): | ||
| + | #setzt Triage auf NORMAL, also auf drückbar | ||
| + | bAdd2.config(state=NORMAL) | ||
| + | bAdd6.config(state=NORMAL) | ||
| + | bAdd7.config(state=NORMAL) | ||
| + | bAdd8.config(state=NORMAL) | ||
| + | bAdd9.config(state=NORMAL) | ||
| + | def mail(): | ||
| + | #mail wird abgeschickt. Code aus dem Netz | ||
| + | msg.attach(MIMEText(emailText, | ||
| + | server = smtplib.SMTP(' | ||
| + | server.starttls() | ||
| + | server.login(senderEmail, | ||
| + | text = msg.as_string() | ||
| + | server.sendmail(senderEmail, | ||
| + | server.quit() | ||
| + | def chir(): | ||
| + | # | ||
| + | #setzt die variable anmeldung global | ||
| + | global anmeldung | ||
| + | anmeldung = " | ||
| + | triage() | ||
| + | #setzt Fachgebiete auf DISABLED, also auf nicht drückbat | ||
| + | bAdd3.config(state=DISABLED) | ||
| + | bAdd4.config(state=DISABLED) | ||
| + | |||
| + | def inn(): | ||
| + | # | ||
| + | global anmeldung | ||
| + | anmeldung = " | ||
| + | triage() | ||
| + | #setzt Fachgebiete auf DISABLED, also auf nicht drückbat | ||
| + | bAdd1.config(state=DISABLED) | ||
| + | bAdd4.config(state=DISABLED) | ||
| + | |||
| + | def neur(): | ||
| + | # | ||
| + | global anmeldung | ||
| + | anmeldung = " | ||
| + | triage() | ||
| + | #setzt Fachgebiete auf DISABLED, also auf nicht drückbat | ||
| + | bAdd3.config(state=DISABLED) | ||
| + | bAdd1.config(state=DISABLED) | ||
| + | |||
| + | def rot(): | ||
| + | #Methode Triage SOFORT | ||
| + | #setzt den Betreff | ||
| + | msg[' | ||
| + | #setzt variable emailText auf global | ||
| + | global emailText | ||
| + | #setzt den Emailtext | ||
| + | emailText = " | ||
| + | #methoden werden aufgerufen | ||
| + | mail() | ||
| + | stopp() | ||
| + | gross() | ||
| + | |||
| + | def gelb(): | ||
| + | # | ||
| + | msg[' | ||
| + | global emailText | ||
| + | emailText = ' | ||
| + | mail() | ||
| + | stopp() | ||
| + | gross() | ||
| + | | ||
| + | def schwarz(): | ||
| + | # | ||
| + | msg[' | ||
| + | global emailText | ||
| + | emailText = ' | ||
| + | mail() | ||
| + | stopp() | ||
| + | gross() | ||
| + | | ||
| + | def gruen(): | ||
| + | #Methode Triage NORMAL | ||
| + | msg[' | ||
| + | global emailText | ||
| + | emailText = ' | ||
| + | mail() | ||
| + | stopp() | ||
| + | gross() | ||
| + | |||
| + | def pink(): | ||
| + | #Methode Triage NICHT DRINGEND | ||
| + | msg[' | ||
| + | global emailText | ||
| + | emailText = ' | ||
| + | mail() | ||
| + | stopp() | ||
| + | gross() | ||
| + | |||
| + | def start2(): | ||
| + | #methode um Fenster mit Anmeldeknopf zu oeffnen | ||
| + | global fenster2 | ||
| + | #fenster wird erstellt | ||
| + | fenster2 = Tk() | ||
| + | # | ||
| + | fenster2.title(" | ||
| + | # | ||
| + | fenster2.geometry(' | ||
| + | # | ||
| + | w=Label(master=fenster2, | ||
| + | w.pack() | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd1= Button(master=fenster2, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd1.pack(fill=X, | ||
| + | #button und label wird eingefuegt | ||
| + | fenster2.mainloop() | ||
| + | | ||
| + | def stopp2(): | ||
| + | #methode um Fenster mit Anmeldeknopf zu minimieren | ||
| + | fenster2.geometry(' | ||
| + | | ||
| + | def gross(): | ||
| + | #methode um Fenster mit Anmeldeknopf auf Anfangsgroesse zu setzten, also zu maximieren | ||
| + | fenster2.geometry(' | ||
| + | | ||
| + | def stopp(): | ||
| + | #fenster mit Triage wird geschlossen | ||
| + | fenster.destroy() | ||
| + | | ||
| + | def reset(): | ||
| + | #fenster1 schliesst. fenster2 wird vergroesert. | ||
| + | stopp() | ||
| + | gross() | ||
| + | | ||
| + | def start(): | ||
| + | global fenster | ||
| + | fenster = Tk() | ||
| + | fenster.title(" | ||
| + | #Geometry vom Fenster wird eingestellt | ||
| + | fenster.geometry(' | ||
| + | #label wird erstellt, der auf der Fensterleiste steht | ||
| + | w=Label(master=fenster, | ||
| + | global bAdd1 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd1= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd1.pack(fill=X, | ||
| + | global bAdd2 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd2= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd2.pack(fill=X, | ||
| + | global bAdd3 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd3= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd3.pack(fill=X, | ||
| + | global bAdd4 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd4= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd4.pack(fill=X, | ||
| + | global bAdd6 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd6= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd6.pack(fill=X, | ||
| + | global bAdd7 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd7= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd7.pack(fill=X, | ||
| + | global bAdd8 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd8= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd8.pack(fill=X, | ||
| + | global bAdd9 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd9= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd9.pack(fill=X, | ||
| + | global bAdd10 | ||
| + | #button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll) | ||
| + | bAdd10= Button(master=fenster, | ||
| + | #button wird in der groesse angepasst und auf der x achse komplett gefuellt | ||
| + | bAdd10.pack(fill=X, | ||
| + | fenster.mainloop() | ||
| + | | ||
| + | from Tkinter import * | ||
| + | import tkMessageBox | ||
| + | |||
| + | start2() | ||
| + | |||
| + | </ | ||
| + | |||
| + | <file python Torsteuerung.py> | ||
| + | import RPi.GPIO as GPIO | ||
| + | import time | ||
| + | import serial | ||
| + | import string | ||
| + | GPIO.setwarnings(False) | ||
| + | |||
| + | GPIO.setmode(GPIO.BOARD) | ||
| + | #Code für NFC Reader, aus WEB (Brads´s Rasberry Pi Blog) | ||
| + | serial = serial.Serial("/ | ||
| + | |||
| + | code = '' | ||
| + | |||
| + | # GPIO 17 und 27 als Ausgang fuer den Motor setzen | ||
| + | GPIO.setup(11, | ||
| + | GPIO.setup (13, GPIO.OUT) | ||
| + | |||
| + | # GPIO 20 und 21 als Eingang festlegen um die zwei Taster abzufragen | ||
| + | GPIO.setup(16, | ||
| + | GPIO.setup(18, | ||
| + | |||
| + | # GPIO 20 und 21 als Eingang festlegen um die zwei Taster abzufragen | ||
| + | GPIO.setup(38, | ||
| + | GPIO.setup(40, | ||
| + | |||
| + | def torzu(): | ||
| + | GPIO.output(11, | ||
| + | GPIO.output(13, | ||
| + | | ||
| + | def torauf(): | ||
| + | GPIO.output(11, | ||
| + | GPIO.output(13, | ||
| + | | ||
| + | def lampeaus(): | ||
| + | GPIO.output(16, | ||
| + | GPIO.output(18, | ||
| + | | ||
| + | def lampean(): | ||
| + | GPIO.output(16, | ||
| + | GPIO.output(18, | ||
| + | | ||
| + | def motoraus(): | ||
| + | GPIO.output(11, | ||
| + | GPIO.output(13, | ||
| + | |||
| + | #Try-Block: Versucht es solange bis über str+c abgebrochen wird | ||
| + | try: | ||
| + | while 1: | ||
| + | motoraus() | ||
| + | #hier liest er den code von der NFC Karte ein | ||
| + | data = serial.read() | ||
| + | #wenn karte die richtige nummer hat | ||
| + | if data == ' | ||
| + | print(code) | ||
| + | #wenn kein Taster gedrückt ist | ||
| + | if GPIO.input(40) == GPIO.LOW and GPIO.input(38) == GPIO.LOW: | ||
| + | lampean() | ||
| + | torzu() | ||
| + | #wenn es laenger als 5 durchlaeufe braucht. Stoppt motor und lampe | ||
| + | i = 0 | ||
| + | while i<5: | ||
| + | |||
| + | # 1 oder 0 von GPIO 40. 0 wenn nicht gedrückt 1 gedrückt | ||
| + | y = GPIO.input(40) | ||
| + | print y | ||
| + | time.sleep(2) | ||
| + | |||
| + | if y == 1: | ||
| + | # wenn einer der Taster geschlossen ist, soll der Motor und Lampe anhalten | ||
| + | motoraus() | ||
| + | lampeaus() | ||
| + | print(" | ||
| + | i = 6 | ||
| + | | ||
| + | i= i+1 | ||
| + | | ||
| + | |||
| + | | ||
| + | elif (string.find(code, | ||
| + | #Taster zu ist gedrückt und Karte ist richtig | ||
| + | lampean() | ||
| + | time.sleep(1) | ||
| + | print(" | ||
| + | torauf() | ||
| + | |||
| + | i = 0 | ||
| + | while i<5: | ||
| + | |||
| + | x = GPIO.input(38) | ||
| + | print x | ||
| + | time.sleep(2) | ||
| + | |||
| + | if x == GPIO.HIGH: | ||
| + | |||
| + | # wenn einer der Taster geschlossen ist, soll der Motor und Lampe anhalten | ||
| + | motoraus() | ||
| + | lampeaus() | ||
| + | print(" | ||
| + | time.sleep(5) | ||
| + | i = 6 | ||
| + | | ||
| + | i= i+1 | ||
| + | |||
| + | elif GPIO.input(38) == GPIO.HIGH and string.find(code, | ||
| + | #Taster auf ist gedrückt und Karte ist richtig | ||
| + | lampean() | ||
| + | time.sleep(1) | ||
| + | print(" | ||
| + | torzu() | ||
| + | |||
| + | i = 0 | ||
| + | while i<5: | ||
| + | |||
| + | y = GPIO.input(40) | ||
| + | print y | ||
| + | time.sleep(2) | ||
| + | |||
| + | if y == 1: | ||
| + | # wenn einer der Taster geschlossen ist, soll der Motor und Lampe anhalten | ||
| + | tor == 1 | ||
| + | motoraus() | ||
| + | lampeaus() | ||
| + | print(" | ||
| + | time.sleep(5) | ||
| + | i = 6 | ||
| + | | ||
| + | i= i+1 | ||
| + | |||
| + | else: | ||
| + | #wenn falsche Taste grdrückt | ||
| + | print(" | ||
| + | code = '' | ||
| + | else: | ||
| + | #else von der NFC Karte | ||
| + | code = code + data | ||
| + | | ||
| + | |||
| + | except KeyboardInterrupt: | ||
| + | pass | ||
| + | GPIO.output(11, | ||
| + | GPIO.output(13, | ||
| + | GPIO.output(16, | ||
| + | GPIO.output(18, | ||
| + | GPIO.cleanup() # | ||
| + | print(" | ||
| + | |||
| + | </ | ||
| + | |||
| + | ====== GPIO Portbelegungen ====== | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ---- | ||
| + | 17 GPIO Out (DC-Motor) - 11 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | 20 GPIO In (Taster 1, grün) - 38 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | 21 GPIO In (Taster 2, orange) - 40 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | 22 GPIO Out - 15 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | 23 GPIO Out - 16 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | 24 GPIO Out - 18 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | 27 GPIO Out (DC-Motor) - 13 | ||
| + | |||
| + | ---- | ||