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 | ||
+ | |||
+ | ---- |