----
===== Zutrittskontrolle Tor und Anmeldung ZNA =====
====== Kurzbeschreibung ======
Als Projekt haben wir uns die Alltagssituation in einer Notaufnahme vorgenommen. Es kommt ein Rettungswagen, welcher einen Patienten abliefern möchte. Das Tor für die Einfahrt ist mittels RFID-Karte gesichert. Einmaliges scannen öffnet dieses Tor und erneutes scannen, schließt es wieder. Eine dazu geschaltete Kennleuchte warnt vor der Bewegung des Tors.
In der Einfahrt selber hängt ein Touchbildschirm, welcher dem Personal dazu dient den Patienten anzumelden. Dort ist es möglich die Fachrichtung, also chirurgisch..., auszuwählen und daraufhin die Triage zu wählen, also wie schwer der Patient verletzt ist. Anschließend wird die Notaufnahme über eine Email mit den Informationen informiert.
===== Screenshots Touchscreen =====
{{:anmeldung1.png?400|}}
{{:anmeldung2-auswahl.png?400|}}
====== Aufbau ======
Die Torsteuerung wird über einen 12V und einen 5V Akku versorgt. Der Motor ist über eine H-Brücke angeschlossen, welche das öffnen und schließen ermöglicht. Die Kennleuchte ist über die Steckplatte angeschlossen und wird durch einen Widerstand komplett ausgeschaltet. Der in der Lampe befindliche Drehmotor wird wie die Lampe mit 5V versorgt. Die Ansteuerung von Lampe und Motor läuft über GPIOS und einen Transistor.
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 ====
{{:raspberry1_steckplatine.jpg?600|}}
==== Flussdiagramme ====
{{:bildschirmfoto_2019-06-25_um_13.31.03.png?400|}}
{{:bildschirmfoto_2019-06-25_um_13.31.52.png?400|}}
===== Code-Ausschnitte: =====
Besteht aus 2 Teilen:
Python als Programmiersprache
#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 = "einfahrtRD@gmail.com" #mit dieser mail wird gesendet
empfangsEmail = "personalKrankenhaus@gmail.com" #empfangene MailAdresse
msg = MIMEMultipart()
msg['From'] = senderEmail
msg['To'] = empfangsEmail
#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, 'html'))
server = smtplib.SMTP('smtp.googlemail.com', 587) # Die Server Daten
server.starttls()
server.login(senderEmail, "###HIERISTDASKENNWORT###") # Das Passwort
text = msg.as_string()
server.sendmail(senderEmail, empfangsEmail, text)
server.quit()
def chir():
#methode chirurgische Anmeldung
#setzt die variable anmeldung global
global anmeldung
anmeldung = "Chirurgisch"
triage()
#setzt Fachgebiete auf DISABLED, also auf nicht drückbat
bAdd3.config(state=DISABLED)
bAdd4.config(state=DISABLED)
def inn():
#methode internistische Anmeldung
global anmeldung
anmeldung = "Internistisch"
triage()
#setzt Fachgebiete auf DISABLED, also auf nicht drückbat
bAdd1.config(state=DISABLED)
bAdd4.config(state=DISABLED)
def neur():
#methode neurologische Anmeldung
global anmeldung
anmeldung = "Neurologisch"
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['Subject'] = 'Triage SOFORT. Fachrichtung ' + anmeldung
#setzt variable emailText auf global
global emailText
#setzt den Emailtext
emailText = "Achtung neue Anmeldung. SOFORT und " + anmeldung + " " + time.strftime("%d.%m.%Y %H:%M:%S")
#methoden werden aufgerufen
mail()
stopp()
gross()
def gelb():
#Methode Triage SEHR DRINGEND
msg['Subject'] = 'Achtung neue Anmeldung. Triage SEHR DRINGEND. Fachrichtung ' + anmeldung
global emailText
emailText = 'Achtung neue Anmeldung. Triage SEHR DRINGEND. Fachrichtung ' + anmeldung +" " + time.strftime("%d.%m.%Y %H:%M:%S")
mail()
stopp()
gross()
def schwarz():
#Methode Triage DRINGEND
msg['Subject'] = 'Achtung neue Anmeldung. Triage DRINGEND. Fachrichtung ' + anmeldung
global emailText
emailText = 'Achtung neue Anmeldung. Triage DRINGEND. Fachrichtung ' + anmeldung +" " + time.strftime("%d.%m.%Y %H:%M:%S")
mail()
stopp()
gross()
def gruen():
#Methode Triage NORMAL
msg['Subject'] = 'Achtung neue Anmeldung. Triage NORMAL. Fachrichtung ' + anmeldung
global emailText
emailText = 'Achtung neue Anmeldung. Triage NORMAL. Fachrichtung ' + anmeldung +"" + time.strftime("%d.%m.%Y %H:%M:%S")
mail()
stopp()
gross()
def pink():
#Methode Triage NICHT DRINGEND
msg['Subject'] = 'Achtung neue Anmeldung. Triage NICHT DRINGEND. Fachrichtung ' + anmeldung
global emailText
emailText = 'Achtung neue Anmeldung. Triage NICHT DRINGEND. Fachrichtung ' +" " + anmeldung + time.strftime("%d.%m.%Y %H:%M:%S")
mail()
stopp()
gross()
def start2():
#methode um Fenster mit Anmeldeknopf zu oeffnen
global fenster2
#fenster wird erstellt
fenster2 = Tk()
#fenstertitel wird geaendert
fenster2.title("Anmeldung starten")
#fenstergroesse wird eingestellt
fenster2.geometry('800x480')
#willkommenstext wird beschrieben
w=Label(master=fenster2,text='Wenn Programm wieder in dieses Fenster zurueckspringt, dann ist der Pat. erfolgreich angemldet', fg='red')
w.pack()
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd1= Button(master=fenster2,text='Anmeldung starten', command = anmeldung)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd1.pack(fill=X, ipady=20)
#button und label wird eingefuegt
fenster2.mainloop()
def stopp2():
#methode um Fenster mit Anmeldeknopf zu minimieren
fenster2.geometry('0x0')
def gross():
#methode um Fenster mit Anmeldeknopf auf Anfangsgroesse zu setzten, also zu maximieren
fenster2.geometry('800x480')
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("Anmeldung ZNA")
#Geometry vom Fenster wird eingestellt
fenster.geometry('800x480')
#label wird erstellt, der auf der Fensterleiste steht
w=Label(master=fenster,text='Anmeldung Zentrale Notaufnahme HSNR')
global bAdd1
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd1= Button(master=fenster,text='chirurgisch', command = chir)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd1.pack(fill=X, ipady=10)
global bAdd2
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd2= Button(master=fenster,text='Sofort',state=DISABLED,bg="red", command = rot)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd2.pack(fill=X, ipady=10)
global bAdd3
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd3= Button(master=fenster,text='internistisch', command = inn)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd3.pack(fill=X, ipady=10)
global bAdd4
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd4= Button(master=fenster, text='neurologisch', command = neur)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd4.pack(fill=X, ipady=10)
global bAdd6
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd6= Button(master=fenster,text= 'Sehr Dringend TEST',state=DISABLED,bg="orange", command = gelb)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd6.pack(fill=X, ipady=10)
global bAdd7
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd7= Button(master=fenster, text='Dringend',state=DISABLED, bg="yellow", command = gruen)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd7.pack(fill=X, ipady=10)
global bAdd8
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd8= Button(master=fenster, text='Normal',state=DISABLED,bg="green", fg='white', command = schwarz)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd8.pack(fill=X, ipady=10)
global bAdd9
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd9= Button(master=fenster, text='Nicht Dringend',state=DISABLED,bg="pink", command = pink)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd9.pack(fill=X, ipady=10)
global bAdd10
#button wird erstellt (auf welchem Fenster, name, methode die ausgefuehrt werden soll)
bAdd10= Button(master=fenster, text='RESET',bg="blue", fg='white', command = reset)
#button wird in der groesse angepasst und auf der x achse komplett gefuellt
bAdd10.pack(fill=X, ipady=10)
fenster.mainloop()
from Tkinter import *
import tkMessageBox
start2()
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("/dev/ttyUSB0", baudrate=9600)
code = ''
# GPIO 17 und 27 als Ausgang fuer den Motor setzen
GPIO.setup(11, GPIO.OUT)
GPIO.setup (13, GPIO.OUT)
# GPIO 20 und 21 als Eingang festlegen um die zwei Taster abzufragen
GPIO.setup(16, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)
# GPIO 20 und 21 als Eingang festlegen um die zwei Taster abzufragen
GPIO.setup(38, GPIO.IN)
GPIO.setup(40, GPIO.IN)
def torzu():
GPIO.output(11, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
def torauf():
GPIO.output(11, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
def lampeaus():
GPIO.output(16, GPIO.LOW)
GPIO.output(18, GPIO.LOW)
def lampean():
GPIO.output(16, GPIO.HIGH)
GPIO.output(18, GPIO.HIGH)
def motoraus():
GPIO.output(11, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
#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 == '\r':
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("Motor wurde an Position gestoppt")
i = 6
i= i+1
elif (string.find(code, '55000840736E') != -1 and GPIO.input(40) == GPIO.HIGH):
#Taster zu ist gedrückt und Karte ist richtig
lampean()
time.sleep(1)
print("Tor geht auf")
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("Motor wurde an Position gestoppt")
time.sleep(5)
i = 6
i= i+1
elif GPIO.input(38) == GPIO.HIGH and string.find(code, '55000840736E') != -1 :
#Taster auf ist gedrückt und Karte ist richtig
lampean()
time.sleep(1)
print("Tor geht zu")
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("Motor wurde an Position gestoppt")
time.sleep(5)
i = 6
i= i+1
else:
#wenn falsche Taste grdrückt
print("Falsche taste gedrueckt")
code = ''
else:
#else von der NFC Karte
code = code + data
except KeyboardInterrupt: #Hier folgt, was passieren soll, wenn strg-c gedrueckt wird
pass
GPIO.output(11, GPIO.LOW) #GPIOs stromlos schalten
GPIO.output(13, GPIO.LOW)
GPIO.output(16, GPIO.LOW)
GPIO.output(18, GPIO.LOW)
GPIO.cleanup() #GPIO-Belegungen loeschen
print("Programm unterbrochen")
====== 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
----