5. Projekt Elektronisches Türschloss
Stufenweise zum Projektziel:
mit Tastenfeld, Display und
RFID-TAG sowie Bluetooth-Freischaltung
5.1 Led schalten mit HC-05 Bluetooth-Modul von DSD und Smartphone-App
Als "Vor-Übung" wird hier das HC-05 Bluetooth Modul zum Schalten einer Led betrieben. Diese Übung ist universell für alle Schaltvorgänge (Relais z.B. für Garagentorsteuerungen, Kaffeemaschinen-Start, Pool-Beleuchtung ect. ) verwendbar.
Wichtig: Das HC-05 von DSD Tech kommuniziert über die serielle Schnittstelle TX0 RX0, wo gleichzeitig auch die Programmierschnittstelle (USB) betrieben wird.
!! Daher müssen beim Runterspielen des IDE-Programms auf den Mega die beiden Drähte der seriellen Schnittstelle zum HC-05 augesteckt werden !!
Nach dem erfolgreichen Programmieren wieder einstecken !!
1. Aufbau herstellen (am besten auf das kleine Zusatz-Breadboard)
2. Software auf den Mega runterspielen
3. Im Playstore die App "Arduino Bluetooth Controller" installieren (geht bei Iphones bedingt aktuell)
4. In der Suchliste das DSD Modul auswählen -> dann auf Switch drücken
5. Rechts oben bei den 3 Punkten die Werte auf 0 und 1 umstellen (andere Texte wie "auf" oder "an" werden ignoriert)
6. Das HC-05 Modul blinkt bis zum Zeitpunkt des Pairings. Sobald die App mit dem Modul kommuniziert, leuchtet die Led auf dem Modul dauerhaft (wenn sie weiterhin blinkt keine Kommunikation!!)
7. Den "Serial Monitor" in der IDE starten
8. Wird der Switch geschaltet, muss die Textausgabe zwischen "0 LED is off" und "1 LED is on" umschalten.
9. Die Led auf dem Breadboard sollte nun einschalten und ausschalten.
Statt der Led kann eine Transistorschaltstufe, ein Relais, ein Servo oder anderes Zubehört geschaltet werden (bitte auf maximal 10mA Stromentnahme aus dem MEGA-Pin achten)
Hier der Programmcode:
char blueToothVal; //Werte sollen per Bluetooth gesendet werden
char lastValue; //speichert den letzten Status der LED (on/off)
void setup(){
Serial.begin(9600); //serieller Monitor wird gestartet, Baudrate auf 9600 festgelegt
pinMode(11,OUTPUT); //PIN 11 wird als Ausgang festgelegt
}
void loop(){
blueToothVal == 0;
if(Serial.available()) //wenn Daten empfangen werden...
{
blueToothVal=Serial.read();//..sollen diese ausgelesen werden
Serial.println(blueToothVal);
}
if (blueToothVal=='1') //wenn das Bluetooth Modul eine „1“ empfängt..
{
digitalWrite(11,HIGH); //...soll die LED leuchten
if (lastValue!='1') //wenn der letzte empfangene Wert keine „1“ war...
Serial.println(F("LED is on")); //..soll auf dem Seriellen Monitor „LED is on“ angezeigt werden
lastValue=blueToothVal;
}
else if (blueToothVal=='0') //wenn das Bluetooth Modul „0“ empfängt...
{
digitalWrite(11,LOW); //..soll die LED nicht leuchten
if (lastValue!='0') //wenn der letzte empfangene Wert keine „0“ war...
Serial.println(F("LED is off")); //..soll auf dem seriellen Monitor „LED is off“ angezeigt werden
lastValue=blueToothVal;
}
}
5.2 Ein elektronisches Türschloss mit Tastenfeld
In diesem Projekt wird nun stufenweise ein elektronisches Türschloss entwickelt mit allen Erweiterungen.
Phase 1 ist die Bedienung über ein Tastenfeld und die Aktivierung eines Relais-Ausgangs sowie eine RGB Led zum Anzeigen von Status Meldungen. Zusätzlich wird über den seriellen Monitor Information ausgegeben.
-Durch Drücken der * leuchtet rote Led
-Durch Eingabe des richtiges Codes (kann eingestellt werden) + Drücken der Taste # erscheint die grüne Led und das Relais wird angesteuert.
-Durch erneutes Drücken der * Taste erscheint wieder die rote Led = Tür wieder geschlossen
-erst nach dem erneuten Drücken der *Taste lässt sich wieder ein Code eintippen
Hier der Programmcode:
#include <Keypad.h>
char P1='1';char P2='2';char P3='3';char P4='A'; // Hier werden die vier Zeichen des Passwortes eingegeben Hier: "123A"
char C1, C2, C3, C4; // Unter C1 bis C4 werden im Loop die vier eingegebenen Zeichen gespeichert
int roteLED = 43; //Die rote LED ist an Pin 12 angeschlossen
int grueneLED = 45; //Die grüne LED wird an Pin 13 angeschlossen
int Relais = 49; // Der Relais-Ausgang
int Tueroeffner_Vibration = 10; // Frequenz des Relais, simuliert das typische 50Hz Brummen eines Türöffners
//Hier wird die größe des Keypads definiert
const byte COLS = 4; //4 Spalten
const byte ROWS = 4; //4 Zeilen
int z1=0, z2, z3, z4; // Diese Variablen werden verwendet um für die einzelnen Zahlencodes die EIngabe freizuschalten. Damit wird im Sketch verhindert, dass eine einzene Codeziffer einer falschen Position zugeordnet wird.
//Die Ziffern und Zeichen des Keypads werden eingegeben:
char hexaKeys[ROWS][COLS]={
{'D','#','0','*'},
{'C','9','8','7'},
{'B','6','5','4'},
{'A','3','2','1'}
};
byte colPins[COLS] = {2,3,4,5}; //Definition der Pins für die 3 Spalten
byte rowPins[ROWS] = {6,7,8,9}; //Definition der Pins für die 4 Zeilen
char Taste; //Taste ist die Variable für die jeweils gedrückte Taste.
Keypad Tastenfeld = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //Das Keypad kann absofort mit "Tastenfeld" angesprochen werden
void setup()
{
Serial.begin(9600);
pinMode(roteLED, OUTPUT); //Die LEDs werden als Ausgang festgelegt
pinMode(grueneLED, OUTPUT);
pinMode(Relais, OUTPUT); //Pin-Deklaration als Ausgang
}
void loop()
{
//Serial.println ("Warte auf Eingabe...");
Anfang: // Dies ist eine Markierung, zu der per "goto-"Befehl gesprungen werden kann.
Taste = Tastenfeld.getKey(); //Mit Unter der Variablen pressedKey entspricht der gedrückten Taste
if (Taste) //Wenn eine Taste gedrückt wurde...
//Ab hier werden die Eingaben des Tastenfeldes verarbeitet. Zunächst die "*"Taste, da diese eine Sonderfunktion für die Verriegelung besitzt und danach die #-Taste
//nach deren Eingabe der zuvor eingegebene Code auf Richtigkeit geprüft wird.
{
if (Taste=='*') // Wenn die "*" Taste gedrückt wurde...
{
Serial.println("Tuer verriegelt");
delay(2000);
digitalWrite(Relais, LOW); //Relais AUS = Türöffner nicht aktiv
digitalWrite(roteLED, HIGH); //..die rote LED einschalten
digitalWrite(grueneLED, LOW); //..die grüne LED einschalten
z1=0; z2=1; z3=1; z4=1; // Zugang zur ersten Zeicheneingabe freischalten
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "*" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
if (Taste=='#') // Wenn die Rautetaste gedrückt wurde...
{
if (C1==P1&&C2==P2&&C3==P3&&C4==P4) //wird gepüft, ob die eingaben Codezeichen (C1 bis C4) mit den Zeichen des Passwortes (P1 bis P4) übereinstimmen.
//Falls der eingegebene Code richtig ist...
{
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
Serial.println ("Code korrekt, Schloss offen");
// Wiederhole 50 Mal die Vibration
for (int i=0; i <= 50; i++){
// Schreibe den Wert von "i" auf den LED-Pin
digitalWrite(Relais, i); //Durch Relais ein und Aus wird das typische 50Hz Brummen des Türöffners simuliert
delay(Tueroeffner_Vibration);
digitalWrite(Relais, LOW);
delay(Tueroeffner_Vibration);
}
digitalWrite(grueneLED, LOW); //..die grüne LED leuchten..
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
}
else // ist das nicht der Fall, bleibt das Schloss gesperrt
{
Serial.println ("Code falsch, Schloss gesperrt");
digitalWrite(roteLED, HIGH); // Die rote LED leuchtet
digitalWrite(grueneLED, LOW); // Die grüne LED is aus
delay(3000);
z1=0; z2=1; z3=1; z4=1; // Der Zugang für die erste Zeicheneingabe wird wieder freigeschaltet
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "#" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
}
// Ab hier werden die vier Code-positionen unter den Variablen C1 bis C4 abgespeichert.
//Damit die eingegebenen Zeichen auch an der richtigen Position des Passwortes gespeichert werden,
//wird mit den Variablen z1 bis z4 der Zugang zu den einzelnen Positinen freigegeben oder gesperrt.
if (z1==0) // Wenn das erste Zeichen noch nicht gespeichert wurde...
{
C1=Taste; //Unter der Variablen "C1" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C1);
Serial.println(" wurde gedrueckt");
z1=1; z2=0; z3=1; z4=1; // Zugang zur zweiten Zeicheneingabe freischalten
goto Anfang;
}
if (z2==0) // Wenn das zweite Zeichen noch nicht gespeichert wurde...
{
C2=Taste; //Unter der Variablen "C2" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C2);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=0; z4=1; // Zugang zur dritten Zeicheneingabe freischalten
goto Anfang;
}
if (z3==0) // Wenn das dritte Zeichen noch nicht gespeichert wurde...
{
C3=Taste; //Unter der Variablen "C3" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C3);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=0; // Zugang zur vierten Zeicheneingabe freischalten
goto Anfang;
}
if (z4==0) // Wenn das vierte Zeichen noch nicht gespeichert wurde...
{
C4=Taste; //Unter der Variablen "C4" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C4);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=1; // Zugang zur weiteren Zeicheneingabe sperren
}
}
}
5.3 Erweiterung mit TC1602 Display
Angelehnt an Übung 3.1 wird nun ein TC1602 Display erweitert - mit anderen Pin-Positionen als bei 3.1. !!
-Durch Drücken der * Taste erscheint der Text "Tür geschlossen Code + # eingebeben" und die rote Led leuchtet
-Durch Eingabe des richtiges Codes (kann eingestellt werden) + Taste # erscheint der Text "Code richtig. Tür offen", die grüne Led leuchtet und das Relais wird angesteuert.
-Durch erneutes Drücken der * Taste erscheint der Text "Tür geschlossen" und die rote Led leuchtet wieder auf = Tür wieder geschlossen
Hier der Programmcode:
#include <Keypad.h>
#include <LiquidCrystal.h> //LCD-Bibliothek laden
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird
char P1='1';char P2='2';char P3='3';char P4='A'; // Hier werden die vier Zeichen des Passwortes eingegeben Hier: "123A"
char C1, C2, C3, C4; // Unter C1 bis C4 werden im Loop die vier eingegebenen Zeichen gespeichert
int roteLED = 43; //Die rote LED ist an Pin 12 angeschlossen
int grueneLED = 45; //Die grüne LED wird an Pin 13 angeschlossen
int Relais = 49; // Der Relais-Ausgang
int Tueroeffner_Vibration = 10; // Frequenz des Relais, simuliert das typische 50Hz Brummen eines Türöffners
//Hier wird die größe des Keypads definiert
const byte COLS = 4; //4 Spalten
const byte ROWS = 4; //4 Zeilen
int z1=0, z2, z3, z4; // Diese Variablen werden verwendet um für die einzelnen Zahlencodes die EIngabe freizuschalten. Damit wird im Sketch verhindert, dass eine einzene Codeziffer einer falschen Position zugeordnet wird.
//Die Ziffern und Zeichen des Keypads werden eingegeben:
char hexaKeys[ROWS][COLS]={
{'D','#','0','*'},
{'C','9','8','7'},
{'B','6','5','4'},
{'A','3','2','1'}
};
byte colPins[COLS] = {2,3,4,5}; //Definition der Pins für die 3 Spalten
byte rowPins[ROWS] = {6,7,8,9}; //Definition der Pins für die 4 Zeilen
char Taste; //Taste ist die Variable für die jeweils gedrückte Taste.
Keypad Tastenfeld = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //Das Keypad kann absofort mit "Tastenfeld" angesprochen werden
void setup()
{
lcd.begin(16, 2); //Im Setup wird angegeben, wie viele Zeichen und Zeilen verwendet werden. Hier: 16 Zeichen in 2 Zeilen.
Serial.begin(9600);
lcd.setCursor(0, 0);
lcd.print(" Standby... ");
lcd.setCursor(0, 1);
lcd.print(" * Druecken ");
pinMode(roteLED, OUTPUT); //Die LEDs werden als Ausgang festgelegt
pinMode(grueneLED, OUTPUT);
pinMode(Relais, OUTPUT); //Pin-Deklaration als Ausgang
}
void loop()
{
Anfang: // Dies ist eine Markierung, zu der per "goto-"Befehl gesprungen werden kann.
Taste = Tastenfeld.getKey(); //Mit Unter der Variablen pressedKey entspricht der gedrückten Taste
if (Taste) //Wenn eine Taste gedrückt wurde...
//Ab hier werden die Eingaben des Tastenfeldes verarbeitet. Zunächst die "*"Taste, da diese eine Sonderfunktion für die Verriegelung besitzt und danach die #-Taste
//nach deren Eingabe der zuvor eingegebene Code auf Richtigkeit geprüft wird.
{
if (Taste=='*') // Wenn die "*" Taste gedrückt wurde...
{
Serial.println("Tuer geschlossen");
lcd.setCursor(0, 0);
lcd.print("Tuer geschlossen");
lcd.setCursor(0, 1);
lcd.print("Code + # eingeb.");
delay(2000);
digitalWrite(Relais, LOW); //Relais AUS = Türöffner nicht aktiv
digitalWrite(roteLED, HIGH); //..die rote LED einschalten
digitalWrite(grueneLED, LOW); //..die grüne LED einschalten
z1=0; z2=1; z3=1; z4=1; // Zugang zur ersten Zeicheneingabe freischalten
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "*" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
if (Taste=='#') // Wenn die Rautetaste gedrückt wurde...
{
if (C1==P1&&C2==P2&&C3==P3&&C4==P4) //wird gepüft, ob die eingaben Codezeichen (C1 bis C4) mit den Zeichen des Passwortes (P1 bis P4) übereinstimmen.
//Falls der eingegebene Code richtig ist...
{
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
Serial.println ("Code korrekt, Schloss offen");
lcd.setCursor(0, 0);
lcd.print("Code ist richtig");
lcd.setCursor(0, 1);
lcd.print(" Tuer offen ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print(" * Taste fuer ");
lcd.setCursor(0, 1);
lcd.print(" Schliessen dr. ");
// Wiederhole 50 Mal die Vibration
for (int i=0; i <= 50; i++){
// Schreibe den Wert von "i" auf den LED-Pin
digitalWrite(Relais, i); //Durch Relais ein und Aus wird das typische 50Hz Brummen des
//Türöffners simuliert
delay(Tueroeffner_Vibration);
digitalWrite(Relais, LOW);
delay(Tueroeffner_Vibration);
}
digitalWrite(grueneLED, LOW); //..die grüne LED leuchten..
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
}
else // ist das nicht der Fall, bleibt das Schloss gesperrt
{
Serial.println ("Code falsch, Schloss gesperrt");
lcd.setCursor(0, 0);
lcd.print(" Code falsch! ");
lcd.setCursor(0, 1);
lcd.print(" Tuer bleibt zu ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Erneute Eingabe ");
lcd.setCursor(0, 1);
lcd.print("* + 5Sek. warten");
digitalWrite(roteLED, HIGH); // Die rote LED leuchtet
digitalWrite(grueneLED, LOW); // Die grüne LED is aus
z1=0; z2=1; z3=1; z4=1; // Der Zugang für die erste Zeicheneingabe wird wieder freigeschaltet
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "#" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
}
// Ab hier werden die vier Code-positionen unter den Variablen C1 bis C4 abgespeichert.
//Damit die eingegebenen Zeichen auch an der richtigen Position des Passwortes gespeichert werden,
//wird mit den Variablen z1 bis z4 der Zugang zu den einzelnen Positinen freigegeben oder gesperrt.
if (z1==0) // Wenn das erste Zeichen noch nicht gespeichert wurde...
{
C1=Taste; //Unter der Variablen "C1" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C1);
Serial.println(" wurde gedrueckt");
z1=1; z2=0; z3=1; z4=1; // Zugang zur zweiten Zeicheneingabe freischalten
goto Anfang;
}
if (z2==0) // Wenn das zweite Zeichen noch nicht gespeichert wurde...
{
C2=Taste; //Unter der Variablen "C2" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C2);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=0; z4=1; // Zugang zur dritten Zeicheneingabe freischalten
goto Anfang;
}
if (z3==0) // Wenn das dritte Zeichen noch nicht gespeichert wurde...
{
C3=Taste; //Unter der Variablen "C3" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C3);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=0; // Zugang zur vierten Zeicheneingabe freischalten
goto Anfang;
}
if (z4==0) // Wenn das vierte Zeichen noch nicht gespeichert wurde...
{
C4=Taste; //Unter der Variablen "C4" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C4);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=1; // Zugang zur weiteren Zeicheneingabe sperren
}
}
}
5.4 Elektronisches Türschloss mit Code-Abfrage und
RC522 RFID-Empfänger
Die Übung 5.3 wird hier mit einem RC522 RFIF-Modul erweitert.
Über den serial Monitor wird die Kartennummer - sowohl für die weiße Karte als auch für den blauen TAG ausgegeben - bitte notieren! (ev. mit Edding direkt auf Karte/TAG schreiben)
In der Programmzeile 385 werden beide Nummern benötigt zur Abfrage.
Wenn die richtigen Karten & TAGs an den Empfänger gehalten werden, wird die Tür geöffnet. Code: " if ((code==2374150) || (code==2617530)) "
Hier der Programmcode:
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 53
#define RST_PIN 15
MFRC522 mfrc522(SS_PIN, RST_PIN);
#include <Keypad.h>
#include <LiquidCrystal.h> //LCD-Bibliothek laden
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird
char P1='1';char P2='2';char P3='3';char P4='A'; // Hier werden die vier Zeichen des Passwortes eingegeben Hier: "123A"
char C1, C2, C3, C4; // Unter C1 bis C4 werden im Loop die vier eingegebenen Zeichen gespeichert
int roteLED = 43; //Die rote LED ist an Pin 12 angeschlossen
int grueneLED = 45; //Die grüne LED wird an Pin 13 angeschlossen
int Relais = 49; // Der Relais-Ausgang
int Tueroeffner_Vibration = 10; // Frequenz des Relais, simuliert das typische 50Hz Brummen eines Türöffners
//Hier wird die größe des Keypads definiert
const byte COLS = 4; //4 Spalten
const byte ROWS = 4; //4 Zeilen
int z1=0, z2, z3, z4; // Diese Variablen werden verwendet um für die einzelnen Zahlencodes die EIngabe freizuschalten. Damit wird im Sketch verhindert, dass eine einzene Codeziffer einer falschen Position zugeordnet wird.
//Die Ziffern und Zeichen des Keypads werden eingegeben:
char hexaKeys[ROWS][COLS]={
{'D','#','0','*'},
{'C','9','8','7'},
{'B','6','5','4'},
{'A','3','2','1'}
};
byte colPins[COLS] = {2,3,4,5}; //Definition der Pins für die 3 Spalten
byte rowPins[ROWS] = {6,7,8,9}; //Definition der Pins für die 4 Zeilen
char Taste; //Taste ist die Variable für die jeweils gedrückte Taste.
Keypad Tastenfeld = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //Das Keypad kann absofort mit "Tastenfeld" angesprochen werden
void setup()
{
lcd.begin(16, 2); //Im Setup wird angegeben, wie viele Zeichen und Zeilen verwendet werden. Hier: 16 Zeichen in 2 Zeilen.
Serial.begin(9600);
lcd.setCursor(0, 0);
lcd.print(" Standby... ");
lcd.setCursor(0, 1);
lcd.print("* Druecken / TAG");
pinMode(roteLED, OUTPUT); //Die LEDs werden als Ausgang festgelegt
pinMode(grueneLED, OUTPUT);
pinMode(Relais, OUTPUT); //Pin-Deklaration als Ausgang
SPI.begin();
mfrc522.PCD_Init();
}
void loop()
{
Anfang: // Dies ist eine Markierung, zu der per "goto-"Befehl gesprungen werden kann.
Taste = Tastenfeld.getKey(); //Mit Unter der Variablen pressedKey entspricht der gedrückten Taste
if (Taste) //Wenn eine Taste gedrückt wurde...
//Ab hier werden die Eingaben des Tastenfeldes verarbeitet. Zunächst die "*"Taste, da diese eine Sonderfunktion für die Verriegelung besitzt und danach die #-Taste
//nach deren Eingabe der zuvor eingegebene Code auf Richtigkeit geprüft wird.
{
if (Taste=='*') // Wenn die "*" Taste gedrückt wurde...
{
Serial.println("Tuer geschlossen");
lcd.setCursor(0, 0);
lcd.print("Tuer geschlossen");
lcd.setCursor(0, 1);
lcd.print("Code + # eingeb.");
delay(2000);
digitalWrite(Relais, LOW); //Relais AUS = Türöffner nicht aktiv
digitalWrite(roteLED, HIGH); //..die rote LED einschalten
digitalWrite(grueneLED, LOW); //..die grüne LED einschalten
z1=0; z2=1; z3=1; z4=1; // Zugang zur ersten Zeicheneingabe freischalten
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "*" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
if (Taste=='#') // Wenn die Rautetaste gedrückt wurde...
{
if (C1==P1&&C2==P2&&C3==P3&&C4==P4) //wird gepüft, ob die eingaben Codezeichen (C1 bis C4) mit den Zeichen des Passwortes (P1 bis P4) übereinstimmen.
//Falls der eingegebene Code richtig ist...
{
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
Serial.println ("Code korrekt, Schloss offen");
lcd.setCursor(0, 0);
lcd.print("Code ist richtig");
lcd.setCursor(0, 1);
lcd.print(" Tuer offen ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print(" * Taste fuer ");
lcd.setCursor(0, 1);
lcd.print(" Schliessen dr. ");
// Wiederhole 50 Mal die Vibration
for (int i=0; i <= 50; i++){
// Schreibe den Wert von "i" auf den LED-Pin
digitalWrite(Relais, i); //Durch Relais ein und Aus wird das typische 50Hz Brummen des Türöffners simuliert
delay(Tueroeffner_Vibration);
digitalWrite(Relais, LOW);
delay(Tueroeffner_Vibration);
}
digitalWrite(grueneLED, LOW); //..die grüne LED leuchten..
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
}
else // ist das nicht der Fall, bleibt das Schloss gesperrt
{
Serial.println ("Code falsch, Schloss gesperrt");
lcd.setCursor(0, 0);
lcd.print(" Code falsch! ");
lcd.setCursor(0, 1);
lcd.print(" Tuer bleibt zu ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Erneute Eingabe ");
lcd.setCursor(0, 1);
lcd.print("* + 5Sek. warten");
digitalWrite(roteLED, HIGH); // Die rote LED leuchtet
digitalWrite(grueneLED, LOW); // Die grüne LED is aus
z1=0; z2=1; z3=1; z4=1; // Der Zugang für die erste Zeicheneingabe wird wieder freigeschaltet
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "#" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
}
// Ab hier werden die vier Code-positionen unter den Variablen C1 bis C4 abgespeichert.
//Damit die eingegebenen Zeichen auch an der richtigen Position des Passwortes gespeichert werden,
//wird mit den Variablen z1 bis z4 der Zugang zu den einzelnen Positinen freigegeben oder gesperrt.
if (z1==0) // Wenn das erste Zeichen noch nicht gespeichert wurde...
{
C1=Taste; //Unter der Variablen "C1" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C1);
Serial.println(" wurde gedrueckt");
z1=1; z2=0; z3=1; z4=1; // Zugang zur zweiten Zeicheneingabe freischalten
goto Anfang;
}
if (z2==0) // Wenn das zweite Zeichen noch nicht gespeichert wurde...
{
C2=Taste; //Unter der Variablen "C2" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C2);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=0; z4=1; // Zugang zur dritten Zeicheneingabe freischalten
goto Anfang;
}
if (z3==0) // Wenn das dritte Zeichen noch nicht gespeichert wurde...
{
C3=Taste; //Unter der Variablen "C3" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C3);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=0; // Zugang zur vierten Zeicheneingabe freischalten
goto Anfang;
}
if (z4==0) // Wenn das vierte Zeichen noch nicht gespeichert wurde...
{
C4=Taste; //Unter der Variablen "C4" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C4);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=1; // Zugang zur weiteren Zeicheneingabe sperren
}
}
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
long code=0; // Als neue Variable fügen wir „code“ hinzu, unter welcher später die UID als zusammenhängende Zahl ausgegeben wird. Statt int benutzen wir jetzt den Zahlenbereich „long“, weil sich dann eine größere Zahl speichern lässt.
for (byte i = 0; i < mfrc522.uid.size; i++)
{
code=((code+mfrc522.uid.uidByte[i])*10); // Nun werden wie auch vorher die vier Blöcke ausgelesen und in jedem Durchlauf wird der Code mit dem Faktor 10 „gestreckt“. (Eigentlich müsste man hier den Wert 1000 verwenden, jedoch würde die Zahl dann zu groß werden.
}
Serial.print("Die Kartennummer lautet:"); // Zum Schluss wird der Zahlencode (Man kann ihn nicht mehr als UID bezeichnen) ausgegeben.
Serial.println(code);
if ((code==2374150) || (code==2617530)) // Wenn der Zahlencode 2374150 oder 2617530 lautet...
{ // Programmabschniss öffnen
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
Serial.println ("TAG/KARTE richtig");
lcd.setCursor(0, 0);
lcd.print("TAG/card richtig");
lcd.setCursor(0, 1);
lcd.print(" Tuer offen ");
delay(2000);
for (int i=0; i <= 50; i++){
// Schreibe den Wert von "i" auf den LED-Pin
digitalWrite(Relais, i); //Durch Relais ein und Aus wird das typische 50Hz Brummen des Türöffners simuliert
delay(Tueroeffner_Vibration);
digitalWrite(Relais, LOW);
delay(Tueroeffner_Vibration);
}
digitalWrite(grueneLED, LOW); //..die grüne LED leuchten..
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(3000);
lcd.setCursor(0, 0);
lcd.print(" TUER wieder zu ");
lcd.setCursor(0, 1);
lcd.print(" ");
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" Standby... ");
lcd.setCursor(0, 1);
lcd.print("* Druecken / TAG");
} // Programmabschnitt schließen
}
5.5 Erweiterung der Übung 5.4 mit HC-05 Bluetooth-Modul
Die Übung 5.4 wird hier mit dem HC-05 Bluetooth Modul erweitert.
Dabei gibt es 2 Probleme:
1. Beim Programmieren des Mega-Boards muss der RXT und TXT Draht zum Bluetooth-Modul ausgesteckt werden (Pin 0 und 1), da das BT Modul die gleiche serielle Schnittstelle benutzt wie das USB-Programmierinterface.
2. Die Switch-Funktion der App stellt sich nicht selbständig auf "0" zurück, daher muss nach dem Türöffnen mit der Hand manuell in der App wieder auf "0" umgeschaltet werden. Ansonsten öffnen die Hardware immer wieder die Tür!
Hier der Programmcode:
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 53
#define RST_PIN 15
MFRC522 mfrc522(SS_PIN, RST_PIN);
#include <Keypad.h>
#include <LiquidCrystal.h> //LCD-Bibliothek laden
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird
char P1='1';char P2='2';char P3='3';char P4='A'; // Hier werden die vier Zeichen des Passwortes eingegeben Hier: "123A"
char C1, C2, C3, C4; // Unter C1 bis C4 werden im Loop die vier eingegebenen Zeichen gespeichert
int roteLED = 43; //Die rote LED ist an Pin 12 angeschlossen
int grueneLED = 45; //Die grüne LED wird an Pin 13 angeschlossen
int Relais = 49; // Der Relais-Ausgang
int Tueroeffner_Vibration = 10; // Frequenz des Relais, simuliert das typische 50Hz Brummen eines Türöffners
//Hier wird die größe des Keypads definiert
const byte COLS = 4; //4 Spalten
const byte ROWS = 4; //4 Zeilen
int z1=0, z2, z3, z4; // Diese Variablen werden verwendet um für die einzelnen Zahlencodes die EIngabe freizuschalten. Damit wird im Sketch verhindert, dass eine einzene Codeziffer einer falschen Position zugeordnet wird.
//Die Ziffern und Zeichen des Keypads werden eingegeben:
char hexaKeys[ROWS][COLS]={
{'D','#','0','*'},
{'C','9','8','7'},
{'B','6','5','4'},
{'A','3','2','1'}
};
byte colPins[COLS] = {2,3,4,5}; //Definition der Pins für die 3 Spalten
byte rowPins[ROWS] = {6,7,8,9}; //Definition der Pins für die 4 Zeilen
char Taste; //Taste ist die Variable für die jeweils gedrückte Taste.
Keypad Tastenfeld = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //Das Keypad kann absofort mit "Tastenfeld" angesprochen werden
char blueToothVal; //BT-Modul Teil Werte sollen per Bluetooth gesendet werden
char lastValue; //BT-Modul Teil speichert den letzten Status der LED (on/off)
void setup()
{
lcd.begin(16, 2); //Im Setup wird angegeben, wie viele Zeichen und Zeilen verwendet werden. Hier: 16 Zeichen in 2 Zeilen.
Serial.begin(9600);
lcd.setCursor(0, 0);
lcd.print(" Standby... ");
lcd.setCursor(0, 1);
lcd.print("*Druecken/TAG/BT");
pinMode(roteLED, OUTPUT); //Die LEDs werden als Ausgang festgelegt
pinMode(grueneLED, OUTPUT);
pinMode(Relais, OUTPUT); //Pin-Deklaration als Ausgang
SPI.begin();
mfrc522.PCD_Init();
}
void loop()
{
blueToothVal == 0;
if(Serial.available()) //wenn Daten empfangen werden...
{
blueToothVal=Serial.read();//..sollen diese ausgelesen werden
Serial.println(blueToothVal);
}
if (blueToothVal=='1') //wenn das Bluetooth Modul eine „1“ empfängt..
{
lcd.setCursor(0, 0);
lcd.print("BT APP AUF 1=AUF");
lcd.setCursor(0, 1);
lcd.print("z. auf 0 stellen");
delay(2000);
digitalWrite(grueneLED, HIGH); //...soll die LED leuchten
digitalWrite(roteLED, LOW); //...soll die LED leuchten
for (int i=0; i <= 50; i++)
{
// Schreibe den Wert von "i" auf den LED-Pin
digitalWrite(Relais, i); //Durch Relais ein und Aus wird das typische 50Hz Brummen des Türöffners simuliert
delay(Tueroeffner_Vibration);
digitalWrite(Relais, LOW);
delay(Tueroeffner_Vibration);
}
if (lastValue!='1') //wenn der letzte empfangene Wert keine „1“ war...
Serial.println(F("LED is on")); //..soll auf dem Seriellen Monitor „LED is on“ angezeigt werden
lastValue=blueToothVal;
}
else if (blueToothVal=='0') //wenn das Bluetooth Modul „0“ empfängt...
{
lcd.setCursor(0, 0);
lcd.print(" Standby... ");
lcd.setCursor(0, 1);
lcd.print("*Druecken/TAG/BT");
digitalWrite(roteLED, HIGH); //..soll die LED nicht leuchten
digitalWrite(grueneLED, LOW);
if (lastValue!='0') //wenn der letzte empfangene Wert keine „0“ war...
Serial.println(F("LED is off")); //..soll auf dem seriellen Monitor „LED is off“ angezeigt werden
lastValue=blueToothVal;
}
Anfang: // Dies ist eine Markierung, zu der per "goto-"Befehl gesprungen werden kann.
Taste = Tastenfeld.getKey(); //Mit Unter der Variablen pressedKey entspricht der gedrückten Taste
if (Taste) //Wenn eine Taste gedrückt wurde...
//Ab hier werden die Eingaben des Tastenfeldes verarbeitet. Zunächst die "*"Taste, da diese eine Sonderfunktion für die Verriegelung besitzt und danach die #-Taste
//nach deren Eingabe der zuvor eingegebene Code auf Richtigkeit geprüft wird.
{
if (Taste=='*') // Wenn die "*" Taste gedrückt wurde...
{
Serial.println("Tuer geschlossen");
lcd.setCursor(0, 0);
lcd.print("Tuer geschlossen");
lcd.setCursor(0, 1);
lcd.print("Code + # eingeb.");
delay(2000);
digitalWrite(Relais, LOW); //Relais AUS = Türöffner nicht aktiv
digitalWrite(roteLED, HIGH); //..die rote LED einschalten
digitalWrite(grueneLED, LOW); //..die grüne LED einschalten
z1=0; z2=1; z3=1; z4=1; // Zugang zur ersten Zeicheneingabe freischalten
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "*" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
if (Taste=='#') // Wenn die Rautetaste gedrückt wurde...
{
if (C1==P1&&C2==P2&&C3==P3&&C4==P4) //wird gepüft, ob die eingaben Codezeichen (C1 bis C4) mit den Zeichen des Passwortes (P1 bis P4) übereinstimmen.
//Falls der eingegebene Code richtig ist...
{
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
Serial.println ("Code korrekt, Schloss offen");
lcd.setCursor(0, 0);
lcd.print("Code ist richtig");
lcd.setCursor(0, 1);
lcd.print(" Tuer offen ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print(" * Taste fuer ");
lcd.setCursor(0, 1);
lcd.print(" Schliessen dr. ");
// Wiederhole 50 Mal die Vibration
for (int i=0; i <= 50; i++)
{
// Schreibe den Wert von "i" auf den LED-Pin
digitalWrite(Relais, i); //Durch Relais ein und Aus wird das typische 50Hz Brummen des Türöffners simuliert
delay(Tueroeffner_Vibration);
digitalWrite(Relais, LOW);
delay(Tueroeffner_Vibration);
}
digitalWrite(grueneLED, LOW); //..die grüne LED leuchten..
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
}
else // ist das nicht der Fall, bleibt das Schloss gesperrt
{
Serial.println ("Code falsch, Schloss gesperrt");
lcd.setCursor(0, 0);
lcd.print(" Code falsch! ");
lcd.setCursor(0, 1);
lcd.print(" Tuer bleibt zu ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Erneute Eingabe ");
lcd.setCursor(0, 1);
lcd.print("* + 5Sek. warten");
digitalWrite(roteLED, HIGH); // Die rote LED leuchtet
digitalWrite(grueneLED, LOW); // Die grüne LED is aus
z1=0; z2=1; z3=1; z4=1; // Der Zugang für die erste Zeicheneingabe wird wieder freigeschaltet
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "#" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
}
// Ab hier werden die vier Code-positionen unter den Variablen C1 bis C4 abgespeichert.
//Damit die eingegebenen Zeichen auch an der richtigen Position des Passwortes gespeichert werden,
//wird mit den Variablen z1 bis z4 der Zugang zu den einzelnen Positinen freigegeben oder gesperrt.
if (z1==0) // Wenn das erste Zeichen noch nicht gespeichert wurde...
{
C1=Taste; //Unter der Variablen "C1" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C1);
Serial.println(" wurde gedrueckt");
z1=1; z2=0; z3=1; z4=1; // Zugang zur zweiten Zeicheneingabe freischalten
goto Anfang;
}
if (z2==0) // Wenn das zweite Zeichen noch nicht gespeichert wurde...
{
C2=Taste; //Unter der Variablen "C2" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C2);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=0; z4=1; // Zugang zur dritten Zeicheneingabe freischalten
goto Anfang;
}
if (z3==0) // Wenn das dritte Zeichen noch nicht gespeichert wurde...
{
C3=Taste; //Unter der Variablen "C3" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C3);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=0; // Zugang zur vierten Zeicheneingabe freischalten
goto Anfang;
}
if (z4==0) // Wenn das vierte Zeichen noch nicht gespeichert wurde...
{
C4=Taste; //Unter der Variablen "C4" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C4);
Serial.println(" wurde gedrueckt");
z1=1; z2=1; z3=1; z4=1; // Zugang zur weiteren Zeicheneingabe sperren
}
}
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
long code=0; // Als neue Variable fügen wir „code“ hinzu, unter welcher später die UID als zusammenhängende Zahl ausgegeben wird. Statt int benutzen wir jetzt den Zahlenbereich „long“, weil sich dann eine größere Zahl speichern lässt.
for (byte i = 0; i < mfrc522.uid.size; i++)
{
code=((code+mfrc522.uid.uidByte[i])*10); // Nun werden wie auch vorher die vier Blöcke ausgelesen und in jedem Durchlauf wird der Code mit dem Faktor 10 „gestreckt“. (Eigentlich müsste man hier den Wert 1000 verwenden, jedoch würde die Zahl dann zu groß werden.
}
Serial.print("Die Kartennummer lautet:"); // Zum Schluss wird der Zahlencode (Man kann ihn nicht mehr als UID bezeichnen) ausgegeben.
Serial.println(code);
if ((code==370330) || (code==1844470)) // Wenn der Zahlencode 2374150 oder 2617530 lautet...
{ // Programmabschniss öffnen
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
Serial.println ("TAG/KARTE richtig");
lcd.setCursor(0, 0);
lcd.print("TAG/card richtig");
lcd.setCursor(0, 1);
lcd.print(" Tuer offen ");
delay(2000);
for (int i=0; i <= 50; i++)
{
// Schreibe den Wert von "i" auf den LED-Pin
digitalWrite(Relais, i); //Durch Relais ein und Aus wird das typische 50Hz Brummen des Türöffners simuliert
delay(Tueroeffner_Vibration);
digitalWrite(Relais, LOW);
delay(Tueroeffner_Vibration);
}
digitalWrite(grueneLED, LOW); //..die grüne LED leuchten..
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
delay(500);
digitalWrite(roteLED, HIGH); //..die rote LED nicht leuchten..
delay(3000);
lcd.setCursor(0, 0);
lcd.print(" TUER wieder zu ");
lcd.setCursor(0, 1);
lcd.print(" ");
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" Standby... ");
lcd.setCursor(0, 1);
lcd.print("*Druecken/TAG/BT");
} // Programmabschnitt schließen
}