Im ersten Teil haben wir unsere verbauten Teile vorgestellt. Im zweiten Teil ging es um die Vorbereitung und im dritten Teil um die Programmiersprache. Und jetzt ist es endlich so weit. Im vorerst letzten Teil unserer DIY Alarmanlage geben wir dir einen Einblick in unseren Code. Wir erklären ihn möglichst detailliert und bieten den kompletten Code mit Pin-Tabelle am Ende des Beitrags kostenfrei zum Download an.
Anforderungen an das System
Beginnen wir mit der Auflistung aller Anforderungen und Voraussetzungen an das System. Der Ursprung des ganzen Projektes war die automatische Schubladenschließanlage. Wir haben etwas größer geträumt, dezent übertrieben und einen hohen Anspruch an viel Automation entwickelt.
- Automatisches Abschließen der Schubladen beim Starten des Motors.
- Hinweis bei offenen Fenstern und Türen zum Fahrtbeginn
- Ein- und Abschalten der Druckwasserpumpe zur Sicherheit vor unerwartetem Leck
- Ein- und Abschalten des Warmwasserboilers zum Stromsparen
- Ein- und Abschalten von weiteren Geräten wie der Außenbeleuchtung
- Abgespeckter Alarm für Nächte im Van (warnt beim unerlaubtem Öffnen von Türen)
- Vollständige Alarmanlage mit Sirene und SMS Benachrichtigung
Wir erklären unseren Code
Okay, jetzt kommt der anstrengende Teil unserer Blog-Serie … Der Code! Wir gehen Abschnittweise gemeinsam durch den Code und versuchen dabei möglichst nichts auszulassen.
Einbinden externer Sketches
In der allerersten Zeile unseres Programmes binden wir eine externe Datei mit ein. Die “pitches.h” Datei haben wir im Internet gefunden und vereinfacht die Tonausgabe unseres Piepers.
#include "pitches.h"
Variablen definieren
Direkt im Anschluss werden sämtliche unserer benötigten Variablen definiert. Dabei wird der Variablentyp, ein Name und ggf. auch gleich ein vorausgewählter Wert bestimmt. Versuche die Namen der Variablen so zu wählen, dass du den Nutzen der Variable wiedererkennst. Eine kurze Beschreibung als Kommentar kann manchmal auch helfen.
//DEFINE VARIABLES -----------------------------------------------------
int redValue; int greenValue; int blueValue;
word ledcolor = "white";
word alarm = "aus";
word scharf = "aus"; //aus, home, away
bool scharftasterbefore;
bool homescharftasterbefore;
long int magnetkontakte;
long int magnetkontaktebefore;
bool lock;
bool lockcurrent;
bool lockpol = LOW;
long int lockcount;
long int locktime = 120;
bool locktasterbefore;
bool pump = false;
bool pumptasterbefore;
bool boiler = false;
bool boilertasterbefore;
bool outdoorlight = false;
bool outdoorlighttasterbefore;
bool motordplusbefore = LOW;
long myTimer = 0;
long scharfstellentimer = 30000; //Dauer des Scharfstellens
long voralarmtimer = 15000; //Dauer des Voralarms
long alarmtimer = 5000; //Dauer des Alarms bis Vollalarm
long vollalarmtimer = 30000; //Dauer des Vollalarmes
long pausealarmtimer = 30000; //Dauer des Pausealarmes
long homevoralarmtimer = 8000; //Dauer des Voralarms
long homealarmtimer = 30000; //Dauer des Alarms
Variablen für Pinbelegung definieren
Wie im vorherigen Teil beschrieben werden hier die Pin-Nummern am Arduino mit Namen assoziiert. So können wir im späteren Code einfach auf die Schnittstellen zu den Geräten zugreifen, ohne ständig die Pin-Nummer heraussuchen zu müssen. Ein weiterer Vorteil ist der, dass wir so nur eine Codezeile ändern müssen, sollten wir ein Gerät an einen anderen Pin anschließen.
//DEFINE PINS ----------------------------------------------------------
#define BLUE 6
#define GREEN 5
#define RED 7
#define HOMESCHARFTASTER 8
#define OUTDOORTASTER 32
#define WASSERTASTER 10
#define WASSERLED 9
#define BOILERTASTER 3
#define BOILERLED 4
#define VENT 26 //Magnetkontakt
#define SCHIEBETUER 27 //Magnetkontakt
#define HECKTUER 28 //Magnetkontakt
#define DACHFENSTER 29 //Magnetkontakt
#define KUECHEFENSTER 31 //Magnetkontakt
#define MOTORDPLUS 47 //Motor D+ Signal über Relay
#define RFID 38 //Signal von 2. Arduino für akzeptierte RFID Karte
#define RELAY1 25 //Waterpump
#define RELAY2 24 //Outdoorlight-schiebetür
#define RELAY3 23 //Locker Open
#define RELAY4 22 //Locker Close
#define RELAY5 45 //Sirene
#define RELAY6 44 //Router
#define RELAY7 43 //
#define RELAY8 42 //Boiler
#define BUZZERACTIVE 16 //Buzzer und Beeper
#define BUZZERPASSIVE 15 //Buzzer für Vollalarm
Pins als Ein- oder Ausgänge definieren
Im Setup-Teil des Sketches werden sämtliche benutzte Pins aktiviert und mit dem korrekten pinMode assoziiert. So weiß der Arduino, welcher Pin ein Eingang und welcher ein Ausgang ist. Auch haben wir hier die serielle Schnittstelle aktiviert, damit wir ggf. ein paar Daten am Computer auslesen können.
void setup()
{
Serial.begin(9600);
pinMode(HOMESCHARFTASTER, INPUT);
pinMode(BLUE, OUTPUT);
digitalWrite(BLUE, HIGH);
pinMode(GREEN, OUTPUT);
digitalWrite(GREEN, HIGH);
pinMode(RED, OUTPUT);
digitalWrite(RED, HIGH);
pinMode(RELAY1, OUTPUT);
digitalWrite(RELAY1, HIGH);
pinMode(RELAY2, OUTPUT);
digitalWrite(RELAY2, HIGH);
pinMode(RELAY3, OUTPUT);
digitalWrite(RELAY3, HIGH);
pinMode(RELAY4, OUTPUT);
digitalWrite(RELAY4, HIGH);
pinMode(RELAY5, OUTPUT);
digitalWrite(RELAY5, HIGH);
pinMode(RELAY6, OUTPUT);
digitalWrite(RELAY6, HIGH);
pinMode(RELAY7, OUTPUT);
digitalWrite(RELAY7, HIGH);
pinMode(RELAY8, OUTPUT);
digitalWrite(RELAY8, HIGH);
pinMode(VENT, INPUT_PULLUP);
pinMode(SCHIEBETUER, INPUT_PULLUP);
pinMode(HECKTUER, INPUT_PULLUP);
pinMode(DACHFENSTER, INPUT_PULLUP);
pinMode(KUECHEFENSTER, INPUT_PULLUP);
pinMode(OUTDOORTASTER, INPUT_PULLUP);
pinMode(WASSERTASTER, INPUT_PULLUP);
pinMode(WASSERLED, OUTPUT);
pinMode(BOILERTASTER, INPUT_PULLUP);
pinMode(BOILERLED, OUTPUT);
pinMode(MOTORDPLUS, INPUT_PULLUP);
pinMode(RFID, INPUT_PULLUP);
pinMode (BUZZERACTIVE,OUTPUT);
pinMode (BUZZERPASSIVE,OUTPUT);
digitalWrite(BUZZERPASSIVE, HIGH);
}
Eingänge auslesen
Am Anfang des Loop-Scripts haben wir sämtliche Eingänge ausgelesen und die dafür passenden Variablen beschrieben. Dadurch können nach dem Auslesen die Variablen durch ein paar Automationen überschrieben werden. Der Reihenfolge nach werden die Codezeilen von oben nach unten ausgelesen, weshalb der wichtigste Teil, der alles überschreiben soll, kurz vor dem Schreiben der Ausgänge platziert werden sollte.
Einen Taster auslesen
Beginnen wir mit dem Taster für die Außen- / Umgebungsbeleuchtung. Über unserer Schiebetür befindet sich ein Taster, der zwei Leuchten außerhalb unseres Vans schaltet. Beim Betätigen des Tasters wird ein einfacher Toggle-Befehl x = !x; ausgeführt, der den Wert in der Variable outdoorlight mit dem gegenteiligen Wert überschreibt. Die if-Abfrage für die Taster haben wir im dritten Teil erklärt.
// main loop
void loop()
{
//BASIC CODE ---------------------------------------------------------
//Toggle AußenlichtRelay-Value (outdoorlight) on Button-Push
if (digitalRead(OUTDOORTASTER) != outdoorlighttasterbefore) {
delay(10);
if (digitalRead(OUTDOORTASTER) == LOW) {
outdoorlight = !outdoorlight;
} outdoorlighttasterbefore = digitalRead(OUTDOORTASTER);
}
Taster in Relation zueinander auslesen
Lesen wir als Nächstes die Werte der Taster für die Wasserpumpe und den Warmwasserboiler aus. Hier verfahren wir nach dem gleichen Prinzip, wiederum ist hier noch eine kleine Sicherheitsmaßnahme mit einprogrammiert. Wird die Pumpe ausgeschaltet, schaltet sich der Boiler mit ab. Wenn der Boiler eingeschaltet wird, die Pumpe jedoch noch aus ist, wird neben dem Boiler auch die Pumpe eingeschaltet.
//Toggle WaterRelay-Value (pump) on Button-Push
if (digitalRead(WASSERTASTER) != pumptasterbefore) {
delay(10);
if (digitalRead(WASSERTASTER) == LOW) {
if (pump == true) { pump = false; boiler = false; }
else { pump = true; }
} pumptasterbefore = digitalRead(WASSERTASTER);
}
//Toggle BoilerRelay-Value (boiler) on Button-Push
if (digitalRead(BOILERTASTER) != boilertasterbefore) {
delay(10);
if (digitalRead(BOILERTASTER) == LOW) {
if (boiler == false) { boiler = true; pump = true; }
else { boiler = false; }
} boilertasterbefore = digitalRead(BOILERTASTER);
}
Motorsignal auswerten
Kommen wir nun zur Motorerkennung. Wie im dritten Teil bereits erklärt, haben wir das Zündungsplus an dem Arduino angeschlossen. Wenn der Wert des Eingangs sich ändert, wird eine Abfrage gestartet, die den Wert ausliest. Ist der Motor gestartet, wird die Variable lock mit true und die Variablen pump, boiler und outdoorlight mit false überschrieben, was den Schubladenmechanismus zuschließen bzw. die Geräte ausschalten lässt.
Sollte die Variable magnetkontakte ungleich 100 sein, ertönt außerdem ein Ton, der dem Fahrer mitteilt, dass hinten noch ein Fenster geöffnet ist! Ist die Alarmanlage als home scharf bzw. aktiviert, wird diese ebenfalls abgeschaltet. Sollte währenddessen bereits die Sirene angegangen sein, wird diese abgeschaltet und es ertönt lediglich ein kurzer leiser Hinweiston. Die Variable magnetkontakte, sowie das System hinter der Alarmanlage wird gleich erklärt.
Wird der Motor abgeschaltet, wird lediglich die Variable lock auf false gesetzt, was dem Schließmechanismus den Befehl gibt, die Schubladen zu entriegeln.
//Engine Start with D+ Relay
if (digitalRead(MOTORDPLUS) != motordplusbefore)
{
delay(10);
if (digitalRead(MOTORDPLUS) == LOW)
{
lock = true;
pump = false;
boiler = false;
outdoorlight = false;
if(magnetkontakte != 100)
{
tone(BUZZERACTIVE, NOTE_C7, 8000);
}
if(scharf == "home")
{
scharf = "aus";
alarm = "aus";
tone(BUZZERACTIVE, NOTE_C5, 200);
digitalWrite(BUZZERPASSIVE, HIGH);
digitalWrite(RELAY5, HIGH); //SIRENE
}
}
if (digitalRead(MOTORDPLUS) == HIGH)
{
lock = false;
}
motordplusbefore = digitalRead(MOTORDPLUS);
}
Ein Taster mit mehreren Nutzen
Der RGB-Taster funktioniert im Stillstand als HOME-Alarm Taster (wird mit der Alarmanlage erklärt). Während der Fahrt, bzw. während der Motor läuft, ändert sich seine Funktion und er lässt die abgeschlossenen Schubladen entriegeln und wieder verriegeln. So können wir mit laufendem Motor etwas aus den Schubladen holen, ohne immer den Motor abschalten zu müssen.
//Toggle Lock on Button-Push, because Engine is running
if(digitalRead(HOMESCHARFTASTER) != homescharftasterbefore && digitalRead(MOTORDPLUS) == LOW)
{
if(digitalRead(HOMESCHARFTASTER)==HIGH)
{
lock = !lock;
delay(10);
}
homescharftasterbefore = digitalRead(HOMESCHARFTASTER);
}
Unsere Alarmanlage
Unsere Alarmanlage besteht aus mehreren Teilen. Zum einen gibt es drei Modi der Scharfschaltung also der Variable scharf: off, home und away. Je nach Scharfschaltung wird ein anderer Alarm ausgelöst. Auch wird der Alarm nicht direkt im Vollalarm loskreischen, sondern baut sich langsam auf (Voralarm), um bei einem Fehlalarm nicht direkt die Nachbarschaft zu beschallen.
Magnetkontakte auslesen
Ausgelöst wird der Alarm durch mehrere Magnetkontakte, die im Van verteilt angebracht sind. Um alle Kontakte / Eingänge in einer Variable unterzubringen haben wir uns für einen numerischen Inhalt entschieden, der im normalen Zustand immer den Wert 100 beinhaltet. Wenn ein Fenster oder eine Tür geöffnet wird, wird der Wert um 1 subtrahiert, woran man schnell erkennt, ob und wie viele Kontakte geöffnet sind.
//Magnetkontakte auslesen und Variable um je 1 subtrahieren
magnetkontakte = 100; //Zurücksetzen auf Ausgangswert (100)
if (digitalRead(VENT) == HIGH) { magnetkontakte--; }
if (digitalRead(SCHIEBETUER) == HIGH) { magnetkontakte--; }
if (digitalRead(HECKTUER) == HIGH) { magnetkontakte--; }
if (digitalRead(DACHFENSTER) == HIGH) { magnetkontakte--; }
if (digitalRead(KUECHEFENSTER) == HIGH) { magnetkontakte--; }
Schärfen der Alarmanlage
Zuallererst müssen wir die Alarmanlage scharf stellen und somit aktivieren. Dafür haben wir eine eigene Variable. Die Variable namens scharf ist eine word-Variable und kann die Werte aus, away oder home beinhalten.
Der Alarmanlagenmodus aus ist selbstverständlich eine deaktivierte Alarmanlage. Der Modus home ist für uns zur extra Sicherheit, wenn wir selbst uns im Van Aufenthalten und der away Modus ist dafür da, wenn wir den Van verlassen.
Scharfschalten (HOME)
Wenn der Motor abgeschaltet ist, ist unser RGB-Taster für das Schärfen und Entschärfen des HOME-Alarms zuständig. Wenn die Alarmanlage abgeschaltet ist und der Taster betätigt wurde, wird die Variable scharf mit dem Wert home überschrieben. Die Variable magnetkontaktebefore speichert den aktuellen Zustand des Vans und ein Ton bestätigt die Aktivierung des Alarmes.
Durch ein erneutes drücken des RGB-Tasters wird der Alarm wieder entschärft also die variable scharf mit dem wert aus überschrieben. Die Abschaltung wird auch hier durch einen Ton bestätigt, die Sirene wird mit aus überschrieben und sämtliche Töne abgeschaltet.
Die Variable alarm wird neben der Scharfschaltung genutzt, um den Alarmfortschritt wiederzugeben. Ist die Variable alarm auf aus, ist das System zwar scharf geschaltet, wiederum ist der Alarm nicht ausgelöst. In beiden Fällen der Scharfschaltung und Entschärfung wird die Variable mit aus überschrieben.
//Toggle Scharf-Value (scharf) on Button-Push to HOME or OFF
//if not set to AWAY when engine is off
if(digitalRead(HOMESCHARFTASTER) != homescharftasterbefore && digitalRead(MOTORDPLUS) == HIGH)
{
if(digitalRead(HOMESCHARFTASTER)==HIGH)
{
if(scharf == "aus")
{
scharf = "home";
alarm = "aus";
magnetkontaktebefore = magnetkontakte;
tone(BUZZERACTIVE, NOTE_C6, 200);
}
else if(scharf != "away")
{
scharf = "aus";
alarm = "aus";
digitalWrite(BUZZERPASSIVE, HIGH);
digitalWrite(RELAY5, HIGH); //SIRENE
tone(BUZZERACTIVE, NOTE_C5, 200);
}
delay(10);
}
homescharftasterbefore = digitalRead(HOMESCHARFTASTER);
}
Scharfschalten (AWAY)
Wenn wir den Van für eine längere Zeit verlassen, haben wir einen weiteren Modus, den wir gesondert aktivieren können. Mit einem versteckten RFID-Scanner bekommen wir ein Signal, das wir zum Schärfen und Entschärfen des away-Alarmes nutzen.
Ähnlich wie bei der Scharfschaltung des Home-Alarmes wird hier die Variable scharf auf away gesetzt. Da wir nach der Scharfschaltung gemütlich alles abschließen und den Van verlassen wollen, wird der Alarm erst nach einer kurzen Pause aktiviert. Gelöst haben wir das mit der Variable alarm, die vorerst mit scharfstellen beschrieben wird und es beginnt ein Timer zu laufen, der die Scharfschaltung verzögert.
Da dieser Alarm-Modus die Schubladen verriegelt, werden sie beim Entschärfen wieder geöffnet.
//Toggle Scharf-Value (scharf) on RFID-Scan to AWAY or OFF
if(digitalRead(RFID) != scharftasterbefore)
{
if(digitalRead(RFID)==HIGH)
{
if(scharf != "aus")
{
scharf = "aus";
alarm = "aus";
lock = false;
tone(BUZZERACTIVE, NOTE_C5, 500);
digitalWrite(BUZZERPASSIVE, HIGH);
digitalWrite(RELAY5, HIGH); //SIRENE
digitalWrite(RELAY6, HIGH); // Router OFF
}
else
{
scharf = "away";
myTimer = millis();
alarm = "scharfstellen";
tone(BUZZERACTIVE, NOTE_C6, 500);
}
delay(10);
}
scharftasterbefore=digitalRead(RFID);
}
Alarmstufen bei geschärfter Alarmanlage
Wenn die Alarmanlage scharf geschaltet ist und die Tür geöffnet wird, soll verständlicherweise direkt mitgeteilt werden, dass dieser Van extra gesichert ist. Damit nicht jedes Mal direkt die volle Ladung an Schall uns entgegen dröhnt, wenn wir selbst den Wagen öffnen, haben wir einen Voralarm in mehreren Stufen eingebaut. So werden wir kurz darauf hingewiesen, dass der Alarm aktiviert ist und bekommen ein paar Sekunden Zeit, diesen zu deaktivieren.
Je nach Alarmmodus bzw. Scharfschaltung wird ein anderer Alarm ausgelöst. Die Sirene wird beispielsweise nur im away-Modus mit aktiviert, während der home-Modus uns lediglich aufwecken und den Einbrecher erschrecken soll. Ebenso benötigen wir keine SMS-Benachrichtigung, wenn wir uns selbst im Van aufhalten.
Alarmmodus AUS
Ist die Alarmanlage entschärft, also die Variable scharf mit aus beschrieben, wird die Variable alarm auf aus zurückgesetzt. Außerdem wird im ausgeschalteten Zustand die LED des RGB-Tasters mit einem neuen Nutzen beauftragt. Wenn sämtliche Magnetkontakte und somit alle Türen und Fenster geschlossen sind, färbt sie sich Grün ein. Sollte ein Magnetkontakt offen sein, färbt sich die LED Cyan. So können wir schnell checken, ob noch etwas offen ist, bevor wir losfahren.
//ALARMSYSTEM --------------------------------------------------------
//ALARMSYSTEM --- System ist Entschärft ---------------------
if (scharf == "aus")
{
alarm = "aus";
if (magnetkontakte == 100) {
ledcolor = "green";
}
if (magnetkontakte < 100) {
ledcolor = "cyan";
}
}
Alarmmodus // Warten
Wenn die Variable alarm auf scharfstellen steht, wird die ledcolor auf activate gestellt, was ein rotes Blinken ausführt. Wenn der gestartete Timer die vordefinierte Zeit der Variable scharfstellentimer erreicht hat, wird der Wert der Variable alarm mit aus überschrieben und das System ist scharfgestellt. Das wird mit einen kurzen Hinweiston ebenfalls bestätigt.
//ALARMSYSTEM --- System stellt scharf ----------------------
if (alarm == "scharfstellen")
{
if (millis() < scharfstellentimer + myTimer) {
ledcolor = "activate";
} else {
magnetkontaktebefore = magnetkontakte;
alarm = "aus";
tone(BUZZERACTIVE, NOTE_C7, 500);
}
}
Alarmmodus HOME
Der Alarmmodus home ist im Gegensatz zum away direkt scharf. Wenn die Variable alarm auf aus steht, wird die ledcolor in einem angenehmen orange, bzw. in yellow eingefärbt, wenn noch ein Magnetkontakt offen ist. Der Wert der magnetkontakte wird ständig geprüft und mit dem magnetkontaktebefore verglichen. Wenn ein Fenster geschlossen wird, aktualisieren sich lediglich beide Variablen. Wenn ein Fenster hingegen geöffnet wird, wird ein Hinweiston abgespielt und die Variable alarm auf voralarm gestellt.
Im voralarm passiert erstmal nichts, da dieser lediglich eine kurze Pause zum Abschalten beinhaltet. Wenn die Zeit homevoralarmtimer wiederum abgelaufen ist, ertönt ein neuer Hinweiston und wir gehen über zum alarm. Solange der homealarmtimer nicht abgelaufen ist, ertönt weiterhin der Ton aus dem BUZZERACTIVE und wird stoßweise mit dem lauteren BUZZERPASSIVE unterstützt.
//ALARMSYSTEM --- System scharf als HOME --------------------
if (scharf == "home" && alarm != "scharfstellen")
{
if (alarm == "aus")
{
if (magnetkontakte == 100) {
ledcolor = "orange";
}
if (magnetkontakte != 100) {
ledcolor = "yellow";
}
if (magnetkontakte > magnetkontaktebefore) {
magnetkontaktebefore = magnetkontakte;
}
if (magnetkontakte < magnetkontaktebefore) {
alarm = "voralarm";
myTimer = millis();
tone(BUZZERACTIVE, NOTE_C6, 3000);
}
}
if (alarm == "voralarm")
{
if (millis() < homevoralarmtimer + myTimer) {
ledcolor = "activate";
} else {
alarm = "alarm";
myTimer = millis();
tone(BUZZERACTIVE, NOTE_C8, homealarmtimer);
}
}
if (alarm == "alarm")
{
if (millis() < homealarmtimer + myTimer) {
ledcolor = "alarm";
if (millis() % 1000 > 250)
{
digitalWrite(BUZZERPASSIVE, LOW);
}
else
{
digitalWrite(BUZZERPASSIVE, HIGH);
}
}
else
{
digitalWrite(BUZZERPASSIVE, HIGH);
}
}
}
Alarmmodus AWAY
Wenn der away-Modus aktiviert und scharfgestellt ist, wird im normalen Zustand (aus) die ledcolor mit red überschrieben. Ansonsten ist es das Gleiche wie beim home-Modus. Die magnetkontakte werden so lange geprüft, bis sich etwas öffnet und die Variable alarm wird mit voralarm beschrieben. Auch hier wird wieder ein Timer gestartet und ein Hinweiston wird abgespielt.
Bis der voralarmtimer abgelaufen ist, blinkt die LED abwechselnd rot und blau (activate). Wenn die Pause abgelaufen ist, wird die Variable alarm auf alarm gestellt und der Hinweiston wird aggressiver abgespielt, bis der alarmtimer abläuft.
Zu guter Letzt kommt der Vollalarm, der stoßweise den BUZZERPASSIVE, und das Relais der Sirene dazuschaltet. Außerdem wird das Relais zu unserem Router geschaltet, was das Signal einer SMS-Benachrichtigung freigibt. Abwechselnd wird zwischen vollalarm und pause gewechselt, wobei wir uns dazu entschlossen haben keine Pause zu machen, sondern hier der Sirene Dauerfeuer zu geben.
Neben der lärmenden Alarmanlage werden beim Scharf schalten des away-Modus auch die Schubladen verriegelt und die Variablen pump, boiler und outdoorlight auf false geschaltet.
//ALARMSYSTEM --- System scharf als AWAY --------------------
if (scharf == "away" && alarm != "scharfstellen")
{
if (alarm == "aus")
{
if (magnetkontakte == magnetkontaktebefore) {
ledcolor = "red";
}
if (magnetkontakte > magnetkontaktebefore) {
magnetkontaktebefore = magnetkontakte;
}
if (magnetkontakte < magnetkontaktebefore) {
alarm = "voralarm";
myTimer = millis();
tone(BUZZERACTIVE, NOTE_C7, 3000);
}
}
if (alarm == "voralarm")
{
if (millis() < voralarmtimer + myTimer) {
ledcolor = "activate";
} else {
alarm = "alarm";
myTimer = millis();
tone(BUZZERACTIVE, NOTE_C8, 3000);
}
}
if (alarm == "alarm")
{
if (millis() < alarmtimer + myTimer) {
ledcolor = "activate";
} else {
alarm = "vollalarm";
myTimer = millis();
tone(BUZZERACTIVE, NOTE_C8, vollalarmtimer);
}
}
if (alarm == "vollalarm")
{
ledcolor = "alarm";
digitalWrite(RELAY6, LOW); // Router ON
if (millis() < vollalarmtimer + myTimer)
{
if (millis() % 1000 > 250) { digitalWrite(BUZZERPASSIVE, LOW); }
else { digitalWrite(BUZZERPASSIVE, HIGH); }
if (millis() % 1000 > 500) { digitalWrite(RELAY5, LOW); }
else { digitalWrite(RELAY5, HIGH); } //SIRENE beepen
}
else
{
alarm = "pause";
myTimer = millis();
tone(BUZZERACTIVE, NOTE_C7, pausealarmtimer);
}
}
if (alarm == "pause")
{
if (millis() < pausealarmtimer + myTimer) {
ledcolor = "alarm";
digitalWrite(RELAY5, LOW); //Sirene an
if (millis() % 1000 > 250)
{ digitalWrite(BUZZERPASSIVE, LOW); }
else { digitalWrite(BUZZERPASSIVE, HIGH); }
}
else {
alarm = "vollalarm";
myTimer = millis();
tone(BUZZERACTIVE, NOTE_C8, vollalarmtimer);
}
}
lock = true;
pump = false;
boiler = false;
outdoorlight = false;
}
Farben für RGB-Taster definieren
Der RGB-Taster hat drei integrierte LEDs (Rot, Grün, Blau). Gemischt kann er auch die Farben Lila, Cyan, Gelb, Orange und Weiß leuchten lassen. Diese Farben haben wir oben mit der Variable ledcolor definiert und wandeln hier die Werte in die richtige Farbkombination der einzelnen LEDs um.
//Define LED Colour
if (ledcolor == "red") {
redValue = 0;
greenValue = 255;
blueValue = 255;
}
if (ledcolor == "green") {
redValue = 255;
greenValue = 0;
blueValue = 255;
}
if (ledcolor == "blue") {
redValue = 255;
greenValue = 255;
blueValue = 0;
}
if (ledcolor == "purple") {
redValue = 100;
greenValue = 255;
blueValue = 50;
}
if (ledcolor == "cyan") {
redValue = 255;
greenValue = 200;
blueValue = 0;
}
if (ledcolor == "yellow") {
redValue = 120;
greenValue = 50;
blueValue = 255;
}
if (ledcolor == "orange") {
redValue = 50;
greenValue = 20;
blueValue = 255;
}
if (ledcolor == "white") {
redValue = 150;
greenValue = 70;
blueValue = 0;
}
Neben den Farben haben wir die Werte off, activate und alarm deflariert. off schaltet alle LEDs aus, activate lässt den Taster Rot blinken und alarm beinhaltet ein schnelles Blinken zwischen den Farben Rot und Blau.
if (ledcolor == "off") {
redValue = 255;
greenValue = 255;
blueValue = 255;
}
if (ledcolor == "activate") {
if (millis() % 1000 > 500) {
redValue = 0;
greenValue = 255;
blueValue = 255;
} else {
redValue = 255;
greenValue = 255;
blueValue = 255;
}
}
if (ledcolor == "alarm") {
if (millis() % 400 > 200) {
redValue = 0;
greenValue = 255;
blueValue = 255;
} else {
redValue = 255;
greenValue = 255;
blueValue = 0;
}
}
Abschließend wird die rote, grüne und blaue LED im Taster mit dem jeweiligen Wert beschrieben.
//Write 3-Colour Status LED
analogWrite(RED, redValue);
analogWrite(GREEN, greenValue);
analogWrite(BLUE, blueValue);
Ausgänge mit Variablen schalten
Das Ende unseres Skripts beinhaltet das Schreiben und Schalten der Ausgänge. Die Variablen lock, pump, boiler und outdoorlight werden in if-Abfragen ausgelesen und die dazugehörigen Ausgänge passend zum Wert der Variable geschaltet.
Die Außenbeleuchtung wird recht simpel nur durch true und false mit HIGH und LOW geschaltet.
//WRITE OUTPUT -------------------------------------------------------
//Write Outdoorlight at Relay 2
if (outdoorlight == true)
{digitalWrite(RELAY2, LOW);}
else
{digitalWrite(RELAY2, HIGH);}
Die Ausgänge der Pumpe und des Warmwasserboilers sind aneinander gekoppelt. Diese Abhängigkeit wird beim Auslesen der Taster bereits aufgegriffen. Sollte wiederum ein Fehler aufgetreten sein und die Pumpe abgeschaltet sein, wird das vor dem Schalten überprüft und ggf. auch der Boiler ausgeschaltet.
//Check Water & Boiler
if (pump == false && boiler == true) {boiler = false; }
//Write Boiler at Relay 8
if (boiler == true)
{digitalWrite(RELAY8, LOW); digitalWrite(BOILERLED, HIGH);}
else
{digitalWrite(RELAY8, HIGH); digitalWrite(BOILERLED, LOW);}
//Write Wasserpumpe at Relay 1
if (pump == true) {
digitalWrite(RELAY1, LOW);
digitalWrite(WASSERLED, HIGH);
} else {
digitalWrite(RELAY1, HIGH);
digitalWrite(WASSERLED, LOW);
}
Zu guter Letzt schreiben wir die Motoren der Schubladen. Den Code haben wir im dritten Teil schon unter die Lupe genommen. Einen Unterschied haben wir jedoch noch eingebaut. Anstelle der vorgeschriebenen HIGH und LOW Werte haben wir die Variable lockpol mit einem der Werte beschrieben. Falls die Motoren versehentlich falsch herum am Relais angeschlossen wurden, können wir die Polarität so mit nur einer Codezeile umkehren. Bedenke aber, dass im neutralen Zustand dann immer plus auf den Kabeln liegt und nicht mehr minus und die Relais ständig eingeschaltet sind.
//Write lock (Schließanlage) mit automatischer Abschaltung
if (lock != lockcurrent) {
lockcurrent = lock;
lockcount = 0;
}
if (lock == true && lockcount < locktime) {
lockcount++;
digitalWrite(RELAY3, lockpol);
digitalWrite(RELAY4, !lockpol);
}
else if (lock == false && lockcount < locktime) {
lockcount++;
digitalWrite(RELAY3, !lockpol);
digitalWrite(RELAY4, lockpol);
}
else {
digitalWrite(RELAY3, !lockpol);
digitalWrite(RELAY4, !lockpol);
}
Unser vollständiger Code mit Pin-Tabelle
Hinter dem Code und den Blogposts steckt viel Arbeit und Hirnschmalz. Nichtsdestotrotz haben wir uns dazu entschlossen, alles mit euch kostenfrei zu teilen. Wir würden uns sehr freuen, wenn wir ein paar von euch dazu motivieren konnten, auch ein paar Automatisierungen mit einem Mikrocontroller im Haus oder sogar dem Van selbst zu bauen. Unseren kompletten Code, mit der Pin-Tabelle kannst du hier kostenlos herunterladen. Natürlich würden wir uns dennoch über eine kleine finanzielle Spende freuen.
Wie geht es weiter?
Aktuell hängt der Arduino noch etwas unfertig mitten im Kabelsalat und ungeschützt im Van herum. Funktionieren tut das System zwar einwandfrei, aber wirklich schön ist die verbaute Hardware noch nicht. Zusammen mit einem Kumpel möchten wir eine Box entwickeln und 3D-Drucken, um den Arduino fest im Van zu verschrauben und ihn zum einen vor umherfallenden Dingen im Schrank und zum anderen auch vor Vandalismus zu schützen. Auch sollen alle umliegenden Module mit in der Box verstaut werden, um so den Kabelsalat etwas ordentlicher zu machen.
Als Schließanlage für unsere Schubladen, als Steuereinheit für unsere Geräte, sowie als Alarmanlage funktioniert das System aktuell echt TOP, wiederum spinnt aktuell unser Router noch etwas und ein Taster klemmt manchmal etwas. Aber das sind halt die spannenden Downsides, wenn man etwas komplett selber macht, dafür war die Entwicklung um so spannender.
Also seid gespannt. Das hier war erst der erste Teil und somit das erste Update über unser kleines (Riesen-) Projekt. Wir sind selbst schon sehr gespannt, was wir noch so schaffen werden. Mut und Durchhaltevermögen haben wir jedenfalls noch ein bisschen (auch wenn das ein paar mal echt am Schwanken war, z. B. als aus Versehen der Computer den kompletten Code mitsamt Backup und Notizen gelöscht hat 🥲). Aber den Aufwand hast du ja jetzt nicht mehr.
Vielen lieben Dank, dass du bis hier hin durchgehalten hast und wir freuen uns mal von dir und deinem Projekt zu hören.
Viele Grüße,
Hanna & Dorian