Security Door mit LCD, Keypad und Servomotor

In diesem Projekt zeigen wir eine Möglichkeit einer Schaltung für eine Sicherheitstür mit wenigen Bauteilen. Diese Tür kann z.B. in einer Sicherheitsbox zur Aufbewahrung wichtiger Dokumente eingesetzt werden.

Unser Aufbau wird die Sicherheitsbox durch Eingabe eines alphanumerischen Codes öffnen. Dieser Code wird vier Zeichen lang sein. Wir werden einen LCD-Bildschirm verwenden, um die Zahlen anzuzeigen, wie sie auf der 4x4-Matrix-Tastatur betätigt werden. Außerdem werden wir eine Bestätigung anzeigen, je nachdem, ob der Code richtig oder falsch eingegeben wurde. Für den Schließmechanismus der Tür werden wir einen Servomotor verwenden. Außerdem werden wir zwei LEDs installieren. Eine rote LED, die anzeigt, dass die Tür geschlossen und verriegelt und eine weitere grüne LED, die anzeigt, dass die Tür geöffnet ist. Über die Tastatur können wir auswählen, ob das Display ein- oder ausgeschaltet bleiben soll.

Wie Sie später im Video sehen können, werden wir die Vorderseite dieses Projekts entfernen, um zu sehen, wie sich das Verriegelungssystem für das Türschloss bewegt. Dies ist ein einfaches Projekt mit nur wenigen Komponenten, aber wir können viel damit anfangen. Beginnen wir mit den benötigten Materialien und der Software.

Benötigte Materialien:

1

Mikrocontroller Board mit ATmega328P

1

MG90S Micro Servomotor

alternativ

SG90 Micro Servo Motor 9G

2

330 Ohm Widerstände

1

HD44780 2004 LCD Display Bundle 4x20 Zeichen mit I2C Schnittstelle

1

MB 102 Breadboard Kit - 830 Breadboard, Netzteil Adapter 3,3V 5V, 65Stk Steckbrücken

1

Rote LED

1

Grüne LED

1

4x4 Matrix Array Keypad Tastenfeld

Benötigte Software

  • Arduino IDE
  • Liquid Crystal I2C Library (über Bibliotheksverwalter)
  • Keypad Library (von Chris-A; über Bibliotheksverwalter)
  • Servo Library (integriert)
  • Security Door Sketch

Schaltung und Beschreibung der Funktionsweise

Der Schaltplan ist wie in der Abbildung unten dargestellt:

Wie in der Schaltung zu sehen ist, werden der Servomotor und das LCD-Display mit separaten 5V versorgt, so dass der Mikrocontroller entlastet ist.

Jetzt werden wir die anderen Komponenten anschließen. Wir beginnen mit der 4x4-Matrix-Tastatur, die wir von Pin D2 bis Pin D9 des Mikrocontrollers anschließen. Wir sollten vermeiden, die Pins D0 und D1 des Mikrocontrollers zu verwenden. Da wir die I2C-Kommunikation mit dem Bildschirm benutzen werden, stört das die Tastatursignale. Für die grüne und rote LED verwenden wir die Pins D10 bzw. D11 und den Servomotor schließen wir an Pin D12 des Mikrocontrollers an. An der jeweiligen Anode der LEDs und dem Mikrocontroller verwenden wir die 330-Ohm Vorwiderstände.

Wie bereits erwähnt, verwenden wir für die Kommunikation des LCD-Bildschirms den I2C-Bus, der, wie Sie in der Dokumentation des Mikrocontrollers nachlesen können, die Pins A4 und A5 verwendet, an die wir die Pins SDA und SCL des I2C-Adaptermoduls des LCD-Bildschirms anschließen. Es ist sehr wichtig, den GND-Pin des Netzteilmoduls mit dem GND des Mikrocontrollers zu verbinden, um Kommunikationsfehler zu vermeiden. Zum Schluss schließen wir die 5 V-DC-Stromversorgung an.

Im Sketch ist der Code 2255 als Schlüssel zum Öffnen des Tresors voreingestellt. Dieser Schlüssel kann so konfiguriert werden, dass er einen Code mit mehreren Zahlen enthält. Normalerweise ist der Bildschirm nicht beleuchtet. Um die Beleuchtung zu aktivieren, müssen Sie das Symbol # drücken, die Meldung "enter the key" erscheint und die eingegebenen Zahlen erscheinen auf dem Bildschirm. Wenn die vier Ziffern den richtigen Code ergeben, wird dies auf dem Display angezeigt, der Stellmotor bewegt sich und die grüne LED leuchtet auf, um anzuzeigen, dass die Tür geöffnet ist. Um die Tür zu schließen, drücken Sie das *-Symbol auf der Tastatur, die Türstifte verriegeln und die rote LED blinkt, um anzuzeigen, dass die Tür geschlossen ist. Wenn Sie bei der Eingabe der Schlüsselzahlen einen Fehler machen, können Sie die eingegebenen Zahlen durch Drücken der Taste * löschen.

Beschreibung des Quellcodes

Das erste, was immer zu Beginn eines Sketches gemacht werden muss, ist das Hinzufügen der notwendigen Bibliotheken, um die Komponenten unserer Projekte verwenden zu können. In diesem Fall müssen wir die Bibliothek für den LCD-Bildschirm inkludieren. In diesem Fall verwenden wir die LiquidCrystal Bibliothek mit dem Zusatz „_I2C“. Außerdem binden wir Keypad.h und Servo.h für die Kommunikation mit dem Keypad und dem Servo ein.

#include <LiquidCrystal_I2C.h>		          // LCD display library.
#include <Wire.h>                                 // I2C comunications library
#include <Servo.h>			          // Servo motor library.
#include <Keypad.h>			          // 4x4 matrix keyboard library.

Danach folgt die Konfiguration für die benötigten Module. Wir beginnen mit der Instanziierung eines Objekts unseres LCD-Bildschirms. Die Argumente (Parameter), die wir angeben müssen, sind: die I2C-Adresse unseres Moduls, die Anzahl der Spalten unseres Bildschirms und die Anzahl der Zeilen.

LiquidCrystal_I2C lcd(0x27,20,4);

Wir beginnen dann mit der Deklaration der notwendigen Variablen unseres Projekts, das sind: die Zeichenpositionsvariable für den Vergleich unserer konfigurierten Taste mit der über die Tastatur eingegebenen Taste, die Position des ersten Zeichens der zu tippenden Taste auf dem LCD-Bildschirm, die Statusvariable (nicht korrekt = 0 und korrekt = 1) unserer Taste und die Variable für den Status der Hintergrundbeleuchtung unseres LCD-Bildschirms.

LiquidCrystal_I2C lcd(0x27,20,4);	          // LCD display object implementation.
int key_position_numbers = 0;                     // Variable for position of the opening code numbers.
int cursor_position = 8;                          // Variable for initial position of the first number of the opening code on LCD.
int status_key_number = 0;                        // Variable for opening code numbers correct (1), wrong (0).
int lcd_light = 0;                                // Variable for LCD backlight ON (1), OFF (0)

Um den Servomotor verwenden zu können, instanziieren wir ein Objekt dieses Servomotors und definieren eine Variable, um die Achs-Positionen speichern. Der Typ der Variable ist Integer, da wir ganzzahlige Gradzahlen verwenden werden.

Servo servo_lock;			          // Servo motor object implementation
int servo_position = 0;			          // Variable servo motor position definition
Das Modul, das noch konfiguriert werden muss, ist die 4x4-Folientastatur. Das ist ein wenig aufwändiger. Für die Anzahl der Zeilen und Spalten definieren wir zwei Konstanten, denen wir 4 Zeilen und 4 Spalten zuweisen.
const byte rows = 4;     		          // Number of keyboard rows
const byte columns = 4;    		          // Number of keyboard columns
Dann müssen wir zwei Arrays erstellen, um die Mikrocontroller-Pins zu definieren, mit denen die Zeilen und Spalten der Tastatur verbunden sind. Noch einmal an dieser Stelle der Hinweis, dass die Pins D0 und D1 durch die Verwendung der I2C-Schnittstelle blockiert sind.
byte rows_pins[] = {9,8,7,6};   	          // Microcontroller pins connecting the keyboard rows.
byte columns_pins[] = {5,4,3,2};   	          // Microcontroller pins connecting the keyboard columns.

Als Nächstes haben wir eine Matrix (mehrdimensionales Array) mit der Anzahl der Zeilen und Spalten konfiguriert. Das Array spiegelt das Tastaturlayout wider. Wenn man eine Zeilen- und Spaltennummer auswählt und sie kreuzt, erhält man eine Taste. Denken Sie daran, dass die Koordinaten in der Programmierung bei 0 (Null) beginnen. Wenn wir also Zeile 2 und Spalte 1 auswählen, erhalten wir die Taste 8.

char keys [rows] [columns] = {		         // Matrix with the positions of the keys on the keyboard.
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
};

Mit allen zuvor konfigurierten Parametern können wir nun ein Objekt für unsere Tastatur implementieren. Wir nennen das Objekt myKeyboard. Als Argumente erhält es die Matrix mit dem Layout der Tasten, die Variablen der Mikrocontroller-Pins, an die die Zeilen und Spalten angeschlossen sind, und die Variablen mit der Anzahl der Zeilen und Spalten, die unsere Tastatur hat.

Keypad myKeyboard = Keypad(makeKeymap(keys), rows_pins, columns_pins, rows, columns);	

Um den Öffnungscode des Tresors zu definieren, konfigurieren wir ein Array mit der Länge der gewünschten Zeichen, diese Zahl steht zwischen eckigen Klammern, in unserem Fall hat sie eine Länge von 4 Zeichen. Innerhalb des Arrays schreiben wir die gewünschten Zeichen zwischen einfachen Anführungszeichen und durch Kommata getrennt, in diesem Projekt ist der Code 2255.

char opening_code[4] = {'2','2','5','5'};

Die letzte Konfiguration, die noch festgelegt werden muss, sind die Pins D10 und D11 des Mikrocontrollers, an die wir die grüne bzw. rote LED anschließen werden.

int green_led = 10;
int red_led = 11;
Nachdem wir die Komponenten und Module unserer Schaltung konfiguriert haben, müssen wir die Initialisierung oder den Anfangszustand programmieren, wenn wir die Spannung anschließen oder den Mikrocontroller zurücksetzen. Dies geschieht in der setup()-Methode des Sketches. Wir beginnen mit der Initialisierung unseres LCD-Bildschirms und ohne Beleuchtung in der Anfangskonfiguration.
lcd.init();
lcd.noBacklight();	

Nach der Initialisierung des Bildschirms folgen die LEDs. In den ersten beiden Zeilen konfigurieren wir diese Pins als Ausgang. Die nächsten beiden Zeilen sind der Anfangszustand der LEDs, da die Tür geschlossen und verriegelt ist, konfigurieren wir den Ausgang des roten LED-Pins auf High-Pegel, so dass die LED leuchtet. Der Pin der grünen LED ist mit LOW-Pegel konfiguriert und damit aus.

pinMode(green_led,OUTPUT);		    // Configuration of the microcontroller pin to the green LED pin as output.
pinMode(red_led, OUTPUT);		    // Configuration of the microcontroller pin to the red LED pin as output.
digitalWrite(red_led,HIGH);  		    // Initial status of red LED on.
digitalWrite(green_led, LOW);  		    // Initial status of green LED off.
Jetzt müssen wir den Servomotor in der Ausgangsposition initialisieren. Dazu werden wir als erstes dem Mikrocontroller den Pin mitteilen, an den wir das Signal zum Servomotor anschließen, es ist Pin D12. Wir müssen auch den Wert in Grad der Position senden, in der er sich befinden soll, wenn der Mikrocontroller initialisiert wird. In diesem Fall sind das 90 Grad. Dieser Wert hängt von der Position ab, in der wir den Servomotor in der Tür installieren.
servo_lock.attach(12);
servo_lock.write(90);	

Die folgenden Zeilen des Codes sind die Meldungen, die auf dem Bildschirm erscheinen werden. Wie bereits erwähnt, beginnen die Programmierkoordinaten bei 0 und nicht bei 1, so dass die erste Zeile angibt, dass der Cursor in der ersten Zeile und der ersten Spalte des Bildschirms platziert wird. In der nächsten Zeile geben wir die Meldung an, die angezeigt werden soll. Die weiteren Zeilen sind ähnlich, nur dass wir in der vierten Zeile den Cursor an die Position cursor_position setzen. Es wird dann aber nichts weiter angezeigt, da diese Zeile dazu dient, die eingegebenen Zeichen einzublenden.

lcd.setCursor(0,0); 			          // Cursor position at the 0 position of the first row of the LCD display.
lcd.print("  Safe deposit box  ");	          // Text to be displayed in the first row.
lcd.setCursor(0,1);			          // Cursor position at the 0 position of the second row of the LCD display.
lcd.print("    AZ-Delivery     ");	          // Text to be displayed in the second row.
lcd.setCursor(0,2);   			          // Cursor position at position 0 of the third row of the LCD.
lcd.print(" Enter code to open "); 	          // Text to be displayed in the third row.
lcd.setCursor(cursor_position,3); 	          // Cursor position at position 8 of the fourth row of the LCD.

Die nächste Methode, die wir programmieren müssen, ist loop(). Der Block, der ständig läuft. Wenn wir diese Methode betrachten können wir sehen, dass es 4 Bedingungen gibt. Eine wird ausgeführt, wenn die *-Taste gedrückt wird (Zeichen löschen), eine aktiviert den Servomotor für die Verriegelung und zwei andere Bedingungen werden ausgeführt, wenn die #-Taste gedrückt wird (Hintergrundbeleuchtung des Displays). Erläutern wir die loop()-Zeilen.

Die erste und sehr wichtige Zeile ist die Deklaration einer Variablen vom Typ "Zeichen", um den Wert der gedrückten Taste zu speichern.

char keystroke = myKeyboard.getKey();	

Die erste Bedingung wird ausgeführt, wenn die zuvor deklarierte Variable nicht leer ist. Wenn diese Variable irgendwelche Daten enthält, prüft die folgende Bedingung, ob die gedrückten Tasten nicht die Zeichenlöschtaste oder die Taste zum Aktivieren der Hintergrundbeleuchtung sind und ob der korrekte Öffnungscode nicht abgeschlossen ist. Dann wird das gedrückte Zeichen auf den Bildschirm geschrieben und der Cursor an die nächste Position gesetzt.

    char keystroke = myKeyboard.getKey();
    if (keystroke != 0) {
	if (keystroke != '#' && keystroke != '*' && status_key_number == 0) {
    	    lcd.print(keystroke);
    	    cursor_position++;

Wenn der Vergleich ergibt, dass vier Zeichen eingegeben wurden und dem hinterlegten Code entsprechen, wird die nachfolgende Bedingung ausgeführt. Damit wird zunächst die Position des Cursors in der ersten Position der dritten Zeile des Bildschirms festgelegt und die Meldung "Gültiger Code" ausgegeben. Dann wird die Position cursor_position in der vierten Zeile verwendet und gesetzt. Der Variablen status_key_number wird eine 1 zugwiesen. Das bedeutet, dass der eingegebene Code korrekt ist. Der Zustand der LEDs wird geändert, die grüne LED leuchtet. Dann läuft eine Schleife, so dass sich der Servomotor in einer langsamen Bewegung von der 90-Grad-Position in die 180-Grad-Position bewegt und die Türstifte entriegelt.

if (key_position_numbers == 4) {
      lcd.setCursor (0,2);
      lcd.print ("     Valid code     ");
      lcd.setCursor(cursor_position,3);
      status_key_number = 1;
      digitalWrite(red_led,LOW);
      digitalWrite(green_led, HIGH);

      for (servo_position = 90; servo_position <= 180; servo_position += 1) {
            servo_lock.write(servo_position);
            delay(15);
      } 
}

Wenn der Vergleich eine Fehleingabe ergibt und die Cursorposition für die Zeicheneingabe mehr als vier Positionen beträgt, wird die Position in cursor_position geändert. Als erstes wird der Cursor-Positionsvariable der Wert 8 zugewiesen, die folgende Variable key_position_numbers ist die Position der Vergleichszeichen unserer Taste und wird auf 0 gesetzt, um sie "zurückzusetzen". Als Nächstes müssen wir die eingeführten Zeichen bereinigen. Dazu platzieren wir den Cursor auf dem LCD-Bildschirm an der Position des Wertes der Variablen cursor_position, der wir zuvor 8 in der vierten Zeile zugewiesen haben, schreiben vier Leerzeichen und platzieren den Cursor wieder an der vorherigen Position (cursor_position). Damit ist die Zeile gelöscht.

If (cursor_position > 11) {
   cursor_position = 8;
   key_position_numbers = 0;
   lcd.setCursor(cursor_position,3);
   lcd.print("    ");
   lcd.setCursor(cursor_position,3);

Die nächste Bedingung prüft den Zustand der Variablen unserer Taste, der wir zu Beginn des Sketches den Wert 0 zugewiesen haben. In Zeile 3 unseres LCDs wird die Meldung "Falscher Code" für 4 Sekunden anzeigt, dann wieder die Meldung "Enter code to open". Anschließend wird der Cursor in Zeile 4 an der Position cursor_position positioniert. In diesem Fall wieder 8.

If (status_key_number == 0) {
      lcd.setCursor (0,2);
      lcd.print ("     Wrong code     ");
      delay(4000);
      lcd.setCursor (0,2);
      lcd.print (" Enter code to open ");
      lcd.setCursor(cursor_position,3);
}

Nun werden wir die Hintergrundbeleuchtung des LCD-Bildschirms programmieren, wofür wir ebenfalls Bedingungen verwenden werden. Wir haben eine Variable (lcd_light) für den Zustand der Hintergrundbeleuchtung des Bildschirms deklariert. Wenn diese 0 ist, ist der Bildschirm ausgeschaltet und wenn sie 1 ist, ist er beleuchtet. In der ersten Bedingung der LCD-Hintergrundbeleuchtung, wenn wir die #-Taste drücken und die Variable den Wert 0 hat, wird der Bildschirm beleuchtet. Wir setzen die Variable auf 1, um den Bildschirm eingeschaltet zu halten. Dann löschen wir den Inhalt der press-Variable, indem wir ihr den Wert 0 geben, so dass zu key ohne Drücken gewechselt wird. Auf diese Weise wird der Mikrocontroller dann auf das Drücken einer Taste warten.

if (keystroke == '#' && lcd_light==0) {
      lcd.backlight();
      lcd_light=1;
      keystroke =0;
}
Wenn dagegen beim Drücken der Taste # die Variable lcd_light den Wert 1 hat, bedeutet dies, dass der Bildschirm beleuchtet ist. Dann wird die folgende Bedingung ausgeführt, die die Hintergrundbeleuchtung des Bildschirms ausschaltet und den Wert 0 in der Variable lcd_light speichert.
if (keystroke == '#' && lcd_light==1) {
        lcd.noBacklight();
        lcd_light=0;
}

Es bleibt nur noch die Funktionalität der *-Taste, mit der wir die Tür verriegeln und die Nummern des Öffnungsschlüssels löschen können. In der if-Anweisung wird zuerst die Anzahl der eingegebenen Zeichen gelöscht. Die Cursorposition wird wieder auf 8 gesetzt. Der Zustand der Öffnung-Variable wird als nicht korrekt eingestellt. Auf dem LCD-Bildschirm positionieren wir den Cursor dann in der dritten Zeile, so dass der Text, der zur Eingabe des Öffnungscodes auffordert, angezeigt wird. Danach positionieren wir den Cursor an der Stelle, an der der Code eingegeben wurde und löschen alle Zeichen. Schließlich lassen wir die rote LED aufleuchten und das Servo bewegt sich, um die Türstifte zu verriegeln, wenn sie vorher nicht geschlossen war. Ich erkläre kurz, warum wir die Schleife innerhalb einer Bedingung programmiert haben. Wie Sie in der Bedingung sehen können, stehen als Schleifenparameter die Positionen des Servomotors 180 und 90.

Wenn wir die Bedingung nicht einfügen würden, würde sich der Servomotor, auch wenn er sich in der Position von 90 Grad befindet, auf 180 Grad bewegen und dann auf die 90 Grad. Wir haben programmiert, dass die Schleife ausgeführt wird, wenn sich der Stellmotor in einer Position von mehr als 99 Grad befindet, d.h. wenn die Tür offen ist, während die Schleife ausgeführt wird. Wenn die Tür schon geschlossen und verriegelt ist, beträgt die Servoposition 90 Grad. Dann werden nur die Zeichen auf dem Display gelöscht.

if (keystroke == '*') {
      key_position_numbers = 0;
      cursor_position = 8;
      status_key_number = 0;
      key_position_numbers = 0;
      lcd.setCursor(0,2);
      lcd.print(" Enter code to open ");
      
      lcd.setCursor(cursor_position,3);
      lcd.print("    ");
      lcd.setCursor(cursor_position,3);
      
      digitalWrite(red_led,HIGH);
      digitalWrite(green_led, LOW);

      if (servo_position >= 99) {
            for (servo_position = 180; servo_position >= 90; servo_position -= 1) {
                  servo_lock.write(servo_position);
                  delay(15);
            }
      }
}

Kompletter Quellcode als Download

Ich hoffe, dass Ihnen dieses Projekt gefällt, es Ihnen Spaß macht und Sie es nützlich finden.

 

 

DisplaysFür arduinoProjekte für anfänger

Leave a comment

All comments are moderated before being published