Unser heutiger Blog-Beitrag basiert auf einem Projekt welches wir erst kürzlich im Rahmen eines Workshops mit einer Schulklasse erstellt haben.
Dabei geht es vor allem darum mit vorhandenen Bauteilen und den verfügbaren Bibliotheken und Beispielen aus verschiedenen Quellen ein funktionierendes Gerät zu bauen, und zu programmieren.
Für die Realisierung benötigen wir folgende Bauteile:
AZ-Delivery Nano V3
AZ-Delivery Breadboard
AZ-Delivery Steckbrücken m/m
AZ-Delivery 4x4 Matrix Keypad
AZ-Delivery Buzzer Modul Passiv
AZ-Delivery Bewegungsmelder Modul
AZ-Delivery 0,96 Zoll I2C OLED Display
Pinbelegung:
Nano V3 |
Keypad Modul 4x4 |
Oled Display |
Buzzer |
Bewegungsmelder |
D2 |
1 |
|
|
|
D3 |
2 |
|
|
|
D4 |
3 |
|
|
|
D5 |
4 |
|
|
|
D6 |
5 |
|
|
|
D7 |
6 |
|
|
|
D8 |
7 |
|
|
|
D9 |
8 |
|
|
|
3V3 |
|
VCC |
|
|
GND |
|
GND |
- |
GND |
A4 |
|
SDA |
|
|
A5 |
|
SCL |
|
|
D11 |
|
|
S |
|
5V |
|
|
|
VCC |
D10 |
|
|
|
mitte |
Schritt 1: Keypad einrichten
Pins 1-8 von Keypad verbinden mit Pins D2 - D9 am Nano
Sketch -> Bibliothek einbinden -> Bibliotheken verwalten
Suchen nach "keypad"
Keypad by Mark Stanley, Alexander Brevig
Intallieren
Datei -> Beispiele -> Keypad -> HelloKeypad
Anpassen: ROWS und COLS jeweils 4
A, B, C und D hinzufügen
Einstellungen überprüfen unter "Werkzeuge":
Board: Arduino Nano
Prozessor: ATmega 328P(old bootloader)
Port: COM port auswählen
Seriellen Monitor öffnen, Baudrate auf 9600 einstellen.
#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
Serial.begin(9600);
}
void loop(){
char key = keypad.getKey();
if (key){
Serial.println(key);
}
}
Hochladen & Testen
Datei -> Speichern unter -> HelloKeypad
Schritt 2: Display einrichten
Pins wie folgt verbinden:
Display Nano V3
GND GND
VCC 3V3
SCL A5
SDA A4
Wir nehmen die Bibliothek SSD1306Ascii und erweitern unseren code wie folgt:
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
im void setup()
Wire.begin();
Wire.setClock(400000L);
#if RST_PIN >= 0
oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
oled.set2X(); // doppelte größe der Schrift
Nun erstellen wir eine Funktion die das Zeichen auf unser Display ausgibt:
void print2oled(char oledText){
oled.setFont(System5x7);
oled.clear();
oled.println(oledText);
delay(500);
}
Und rufen diese Funktion im loop() auf:
if (key){
Serial.println(key);
print2oled(key);
}
Ergebnis: Beim drücken der Taste erscheint die gedrückte Taste im Display.
Nächster Schritt: wir lesen den IR-Sensor aus
Anschließen:
IR Sensor Nano V3
VCC 5V
Mitte D10
GND GND
Wir fügen dem Code folgendes hinzu:
pinmode(10, INPUT); // Pin D10 wird als INPUT genutzt
bool detected = false; // wurde bewegung erfasst?
und machen eine funktion die den Sensor abfragt:
void checkPIR(){
if digitalread(PIR){
detected = true;
Serial.println("Bewegung erfasst");
}
else {
detected = false;
Serial.println("keine Bewegung");
}
Den Buzzer für den Alarmton schließen wir wie folgt an:
Buzzer Nano V3
- GND
S D11
Wir fügen folgendes zum Sketch hinzu:
int speaker = 11; // Digital Pin 11
pinMode(speaker, OUTPUT);
und die folgende Funktion, um zu testen ob der Buzzer geht:
void speakerTest(){
tone(speaker, 600, 500);
delay(100);
tone(speaker, 700, 100);
delay(100);
tone(speaker, 800, 750);
delay(200);
}
Nun sind alle benötigten Sensoren und Module soweit funktionsfähig und ansprechbar/auslesbar.
Wir speichern den Sketch mittels "Datei" -> "Speichern unter" als Alarmanlage
Hier der komplette Quellcode von der Alarmanlage mit allen Funktionen:
#include <Keypad.h> #include <Wire.h> #include "SSD1306Ascii.h" #include "SSD1306AsciiWire.h" #define I2C_ADDRESS 0x3C #define RST_PIN -1 #define PIR 10 bool detected = false; // wurde bewegung erfasst? bool armed = false; // ist der Alarm scharf geschaltet? SSD1306AsciiWire oled; const byte ROWS = 4; //four rows const byte COLS = 4; //three columns char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); int speaker = 11; // Digital Pin 11 char* pinCode = "1337"; // Set the required PIN code. int currentPosition = 0; // Keeps track of the position of the code entered. void setup(){ Serial.begin(9600); Wire.begin(); Wire.setClock(400000L); #if RST_PIN >= 0 oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); #else // RST_PIN >= 0 oled.begin(&Adafruit128x64, I2C_ADDRESS); #endif // RST_PIN >= 0 oled.set2X(); // doppelte größe der Schrift pinMode(10, INPUT); pinMode(speaker, OUTPUT); speakerTest(); } void loop(){ char key = keypad.getKey(); checkPIR(); int l; if (key){ beep(); Serial.println(key); print2oled(key); if (int(key) != 0) { // Check to see if there is a value present. for (l=0; l<=currentPosition; ++l) { } if (key == pinCode[currentPosition]) // If the value is correct, increase he code position by one. { ++currentPosition; if (currentPosition == 4) // If all four parts of the code are correct, unlock the door. { oled.clear(); unlockDoor(); currentPosition = 0; } } else { invalidCode(); // If any parts of the code are wrong, do not open the door. currentPosition = 0; } } } if (armed){ // alarmanlage scharf? if (detected){ playAlarm(); } } } void print2oled(char oledText){ oled.setFont(fixed_bold10x15); oled.print(oledText); delay(500); } void checkPIR(){ if (digitalRead(PIR)){ detected = true; Serial.println("Bewegung erfasst"); delay(50); } else { detected = false; //Serial.println("keine Bewegung"); delay(50); } } void speakerTest(){ tone(speaker, 600, 50); delay(100); tone(speaker, 700, 50); delay(100); tone(speaker, 800, 200); delay(200); } void beep(){ tone(speaker, 2000, 100); } void beepOK(){ tone(speaker, 3000, 50); delay(50); tone(speaker, 3300, 50); } void invalidCode() { oled.clear(); oled.println("Fehler"); tone(speaker, 300,150); delay(250); tone(speaker, 220, 300); delay(1000); oled.clear(); } void unlockDoor() { if (armed){ armed=false; Serial.println("Alarm deaktiviert"); oled.setFont(fixed_bold10x15); oled.clear(); oled.println("Aus"); delay(1000); oled.clear(); } else{ armed=true; Serial.println("Alarm aktiviert!"); oled.setFont(fixed_bold10x15); oled.clear(); oled.println("aktiv!"); delay(1000); oled.clear(); } tone(speaker, 1000, 50); delay(50); tone(speaker, 1200, 50); delay(60); tone(speaker, 1300, 50); delay(50); tone(speaker, 1000, 50); delay(60); tone(speaker, 1200, 50); delay(50); tone(speaker, 1300, 50); delay(60); tone(speaker, 1000, 50); delay(50); tone(speaker, 1200, 50); delay(60); tone(speaker, 1300, 100); delay(50); } void playAlarm(){ Serial.println("Alarm! Alarm! Alarm!"); tone(speaker, 2000, 400); delay(500); tone(speaker, 2000, 400); delay(500); tone(speaker, 2000, 400); delay(500); tone(speaker, 2000, 400); delay(500); oled.setFont(fixed_bold10x15); oled.clear(); oled.println(" Alarm!!!"); }
1 Kommentar
Rolando
Le istruzioni del programma si scrivono in inglese: per esempio #include , non Filo.h. Tralascio tutti gli altri errori ; ci sarebbe da scriverci un romanzo,
Die Programmanweisungen sind in englischer Sprache verfasst: Zum Beispiel #include , nicht Filo.h. Ich lasse alle anderen Fehler weg; Es würde einen Roman geben, über den man schreiben könnte.
Scusami se nella traduzione in tedesco ci sono degli errori…
Entschuldigung, wenn die deutsche Übersetzung fehlerhaft ist …
Firmato: un principiante