Arduino im Smart Home – HowTo Teil 4: Status-LED per UDP ansteuern

Loxone im Einsatz? Dann schau dir unseren LoxKurs an und profitiere von unserem Wissen!

In den ersten drei¬†Artikeln der Serie Arduino im Smart Home¬†wurden nach einer kurzen Einf√ľhrung in die Thematik sowohl digitale als auch analoge Messwerte √ľber einen¬†Arduino Uno erfasst und per¬†UDP-Protokoll mithilfe eines Ethernet Shield an die netzwerkseitig angebundene Smart-Home-Zentrale Loxone gesendet. Daneben lassen sich √ľber das Arduino-Board aber nicht nur Sensorwerte erfassen, sondern auch¬†Aktoren¬†steuern, wobei¬†hierf√ľr¬†mehrere M√∂glichkeiten¬†zur Verf√ľgung stehen.

Zu diesem Zweck sendet die Smart-Home-Zentrale Loxone (oder FHEM) eine UDP-Nachricht an den Arduino, welcher eine dort angeschlossene LED-Diode ansteuert. Umgesetzt wird das Ganze √ľber eine¬†LED-Leuchtdiode, welche den aktuellen Verbindungsstatus¬†der angebundenen Smart-Home-Zentrale signalisiert. Eine¬†leuchtende LED gibt so schnell Auskunft dar√ľber, dass¬†eine funktionst√ľchtige¬†Netzwerkverbindung zwischen Arduino und Zentrale hergestellt ist. Wie das im Detail funktioniert und welcher entscheidende¬†Zusatznutzen in Kombination mit der¬†Arduino-Programmlogik¬†entsteht, wird in nachfolgendem Artikel erl√§utert.

Signal-LED per Arduino schalten

Zur Anzeige des aktuellen Onlinestatus der Smart-Home-Zentrale wird eine gr√ľne LED-Leuchtdiode an Pin 4 des Arduino angeschlossen, welcher nicht nur als¬†digitaler Eingang, sondern wie in diesem Anwendungsfall, auch als digitaler Ausgang¬†genutzt werden kann.

LED-Leuchtdiode

Da die hier verwendete gr√ľne LED-Leuchtiode nativ f√ľr eine Spannung von 3,7 V ausgelegt ist, der Arduino jedoch eine Versorgungsspannung von 5 V¬†aufweist, wird¬†die LED in Reihe mit einem 100 Ohm Widerstand geschaltet,¬†um ein Durchbrennen zu vermeiden. Der Widerstand ist so berechnet, dass er die¬†√ľbersch√ľssige Spannung schluckt und diese in W√§rme umwandelt, wodurch die LED nur noch die ben√∂tigte Betriebsspannung erh√§lt.

Wer eine andersfarbige LED (wei√ü, gelb, blau) aus einem Funduino Lernset (Affiliate-Link) verwenden m√∂chte, kann¬†ebenfalls einen 100 Ohm Widerstand als Spannungsteiler nutzen, im Fall der roten LED muss jedoch ein 200 Ohm Widerstand eingesetzt¬†werden, da die rote LED f√ľr¬†2,1 V konzipiert¬†wurde.

LED-Leuchtdioden

¬†LED-gest√ľtzter¬†Onlineverbindungsstatus

Damit der Onlineverbindungsstatus zuverlässig ermittelt werden kann, nutzt das nachfolgende Szenario zwei zusammenspielende Sende- und Empfangsbenachrichtigungen.

Konzept Onlineverbindungsstatus

Der Arduino sendet in regelm√§√üigen Abst√§nden¬†per UDP-Nachricht ein Lebenszeichen in Form von¬†„Ping“ an den¬†Smart-Home-Server. Sobald der Smart-Home-Server (in diesem Beispiel Loxone) die Nachricht empf√§ngt, sendet¬†er zwei¬†direkt aufeinanderfolgende“Pong“-R√ľckantworten mit dem Inhalt „000“ und „001“¬†an den Arduino zur√ľck. Sobald diese Nachrichten dort eingeht, wird die gr√ľne LED geschaltet. Empf√§ngt der Arduino in einem festgelegten¬†Zeitraum keine R√ľckantwort (Timeout),¬†wird die LED ausgeschaltet. Mehr Details dazu dann direkt in der Erl√§uterung zum Arduino-Programm.

Benötigte Komponenten

F√ľr die Ansteuerung einer Signal-LED zur Anzeige des Onlineverbindungsstatus der angebundenen Smart-Home-Zentral werden einige¬†Komponenten ben√∂tigt, welche (wie beim vorangegangen Szenario auch) f√ľr unter 30 Euro erh√§ltlich sind:

Wer die vorangegangenen Szenarien¬†(HowTo Teil 2¬†und HowTo Teil 3)¬†als Ausgangspunkt nutzt, ben√∂tigt f√ľr das folgende Setup lediglich die beiden¬†letztgenannten Komponenten aus obiger Liste, die mit weniger als einem Euro zu Buche schlagen und bspw. bereits¬†im Lernset¬†Funduino UNO 8 (Affiliate-Link) enthalten sind.

Vorbereitung der Hardware

Das bereits f√ľr die vorherigen Szenarien eingesetzte¬†Breadboard wird mit einer gr√ľnen LED-Leuchtdiode und einem 100 Ohm Widerstand erweitert, welche in Reihe geschaltet werden. Da der elektrische Strom nur in einer¬†Richtung durch die LED flie√üt, muss auf die korrekte Polarisation geachtet werden. Der l√§ngere Kontakt¬†der LED-Leuchtdiode (in der Zeichnung mit dem abgeknickten rechten Beinchen symbolisiert) wird gew√∂hnlich an VCC (+5 V)¬†(in diesem Fall am Pin 4 des Arduino-Boards) und der k√ľrzere Kontakt¬†√ľber den benachbarten Widerstand an¬†GND (Ground)¬†angeschlossen.

Steckplatinenskizze Status-LED

Die Installation¬†f√ľllt sich¬†dabei weiter¬†mit Leben, wobei das Ganze durch den Einsatz des Breadboards dennoch √ľberraschend √ľbersichtlich bleibt.

Arduino Board LED

Wie man unschwer erkennen kann, ist sogar noch gen√ľgend Platz auf dem Breadboard f√ľr sp√§tere Erweiterungen. Langsam wird es aber dennoch¬†Zeit f√ľr einen neuen Satz¬†Drahtbr√ľcken (Affiliate-Link), damit es k√ľnftig keine Engp√§sse bei der prototypischen¬†Verkabelung gibt.

Arduino Board Bewegungsmelder Fotowiderstand LED

Erstellung des Arduino-Programmcodes

Genutzt wird die bereits in HowTo Teil 3 erstellte Programmlogik, welche teilweise etwas verbessert wurde und nun erweitert wird.

Der komplette Sketch kann nachfolgend auch direkt als Arduino-Datei heruntergeladen werden:  sketch_onlinestatus_led.ino (1800 Downloads)

Teil 1 – Grundeinstellungen und Variablendeklaration

Da eine schnelle Response-Zeit z.B. beim Bewegungsmelder oder einem Tastendruck erzielt¬†werden soll, ist es notwendig, dass¬†der Arduino-Programmcode mehrmals pro Sekunde durchlaufen¬†wird. Damit man die Timings f√ľr verschiedene Intervallabfragen ad√§quat¬†umsetzen kann, wird die Variable „Programmfrequenz“ eingef√ľhrt, die mit einem Wert von 50 (Hz) f√ľr den¬†Anwendungsfall passend erscheint. Die angegebene Variable wirkt sich¬†dabei ma√ügeblich¬†auf das¬†am Ende des loop-Teils angegebene¬†Delay „delay(1000/Programmfrequenz);“ aus, wodurch dem Arduino pro Programmdurchlauf¬†eine Zwangspause von 20 ms (1000/50) auferlegt wird, was in der Konsequenz einer Programmfrequenz von 50 Hz entspricht.

√úber die Variable „OnlinestatusCheckEachSekOnline“ wird angegeben, in welchem zeitlichen Abstand ein „Ping“-Impuls vom Arduino versendet wird. Testweise ist dieser Wert auf 10 Sekunden gesetzt, k√ľnftig soll er den Wert 60 tragen, so dass der Onlinestatus jede Minute abgefragt werden kann. Dieser Wert wird dabei situationsbedingt¬†nur dann verwendet, sofern¬†der vorausgegangene¬†Onlinecheck erfolgreich¬†war und eine R√ľckantwort eingegangen ist. War der letzte Check negativ (keine R√ľckantwort vom Empf√§nger), wird stattdessen der Wert der Variablen „OnlinestatusCheckEachSekOffline“ verwendet. Der Hintergrund ist, dass der Arduino nach einer Verbindungstrennung¬†in k√ľrzeren¬†Intervallen¬†ein „Ping“-Signal aussenden soll, damit der Status schneller¬†korrigiert wird, sobald die Verbindung wieder steht.¬†Vermutlich kann dieser Wert auch langfristig mit¬†2 (Sekunden)¬†besetzt¬†werden.

Die Variable „OnlinestatusCheckTimeoutSek“ gibt an, wieviele Sekunden¬†vom Aussenden der „Ping“-Nachricht bis zur „Pong“-Antwort der Zentrale maximal vergehen d√ľrfen, bis der Status von „Online“ auf „Offline“ wechselt.¬†Mit den hier angegebenen Werten kam es bei ersten Tests zwischen¬†Arduino und Loxone im Schnitt √ľber mehrere Stunden hinweg zu keinen¬†Paketverlusten, was f√ľr die Testumgebung¬†ein gutes Setting darstellt. Im sp√§teren Dauerbetrieb sollte¬†der Wert auf mehrere¬†Sekunden erh√∂ht werden, um einen gr√∂√üeren¬†Puffer einzubauen.

Danach folgen weitere Variablen, die unter anderem auch zur Berechnung bzw. Umrechnung der in Sekunden angegebenen Parameterwerte in¬†die Laufzeitumgebung des Arduino genutzt werden. So wird aus dem in Sekunden angegebenen Wert „OnlinestatusCheckEachSekOnline“ (10) durch die Multiplizierung mit der angegebenen¬†„Programmfrequenz“ (50) die im weiteren Programmcode verwendete Variable „OnlinestatusCheckOnline“ (10 x 50 = 500) gebildet,¬†sodass durch die noch folgende¬†Logik im loop-Teil nur bei jedem 500. Programmdurchlauf (also alle 10 Sekunden) ein Ping-Signal ausgesendet¬†wird.

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

// PIN Settings
#define Bewegungsmelder 2
#define OnlinestatusLED 4

// Variable Declaration
int Programmfrequenz = 50; // loop-Durchlauf pro Sekunde (ca.)

int HelligkeitssensordIdleSek = 2; // Minimale Pause zwischen zwei Helligkeitbenachrichtigungen in Sek
int HelligkeitssensorSchwellwert = 10; // Schwellwert fuer Helligkeitsbenachrichtigungen (empfohlen 5-20)

int OnlinestatusCheckEachSekOnline = 10; // Ping in Sek wenn letzter Status Online war
int OnlinestatusCheckEachSekOffline = 2; // Ping in Sek wenn letzter Status Offline war
int OnlinestatusCheckTimeoutSek = 1; // Status auf Offline setzen wenn Rueckmeldung nicht innerhalb x Sek

char BewegungsmelderState = 0;
int Helligkeitssensor = 0;
int HelligkeitssensorCounter = 0;
int HelligkeitssensorObergrenze = 0;
int HelligkeitssensorUntergrenze = 0;
char msg[25];
int HelligkeitssensordIdle = HelligkeitssensordIdleSek * Programmfrequenz;
int OnlinestatusSendCounter = 0;
int OnlinestatusReceiveCounter = 0;
char OnlinestatusLoxone = 0;
int OnlinestatusCheckOnline = OnlinestatusCheckEachSekOnline * Programmfrequenz;
int OnlinestatusCheckOffline = OnlinestatusCheckEachSekOffline * Programmfrequenz;
int OnlinestatusCheckTimeout = (OnlinestatusCheckTimeoutSek + OnlinestatusCheckEachSekOnline) * Programmfrequenz;

// Network Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 3, 19);
IPAddress gateway(192, 168, 3, 1);
IPAddress subnet(255, 255, 255, 0);

// Local UDP port to listen on
unsigned int localPort = 7002;

// Recipient IP
IPAddress RecipientIP(192, 168, 3, 11);

// Recipient UDP Port
unsigned int RecipientPort = 7001;

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

// An EthernetUDP instance to send and receive packets over UDP
EthernetUDP Udp;

Teil 2 – Setup

Im¬†Setup-Teil wird im¬†Vergleich zum vorhergehenden Szenario lediglich die neu verwendete gr√ľne Status-LED an Pin 4¬†als „pinMode“ mit dem Attribut „OUTPUT“¬†definiert.

void setup()
{
 // for debug only
 Serial.begin(9600);

 // start Ethernet
 Ethernet.begin(mac,ip);

 // Start UDP
 Udp.begin(localPort);

 // Bewegungsmelder
 pinMode(Bewegungsmelder, INPUT);

 //OnlinestatusLED
 pinMode(OnlinestatusLED, OUTPUT); // LED an Pin4

 // send UDP Ready
 sendUDP("UDP Ready");
}

Teil 3 – Programmablauf (loop)

Der nun recht umfangreiche loop-Teil k√ľmmert sich nun um das Aussenden und Empfangen der UDP-Mitteilungen sowie deren Auswertung.

Zuerst werden zwei if-Bedingungen f√ľr das situationsbezogene zeitliche¬†Versenden der „Ping“-Nachricht definiert. Die erste if-Abfrage wird getriggert, sobald¬†der in jedem loop-Durchlauf um den Wert 1 erh√∂hte Z√§hler „OnlinestatusSendCounter“ mit dem oben durch den Nutzer festgelegten¬†„OnlinestatusCheckOnline“ √ľbereinstimmt und weiterhin der Wert von¬†„OnlinestatusReceiveCounter“, welcher die Zeit seit dem letzten Versenden der Ping-Nachricht berechnet, nicht mit dem vom Nutzer angegebenen bzw. berechneten Wert von¬†„OnlinestatusCheckTimeout“ √ľbereinstimmt. Die zweite Abfrage ist f√ľr den Fall gedacht, dass die letzte Ping-Anfrage im Nirvana gelandet ist.¬†In diesem Fall¬†ist der Unterscheid zur vorherigen if-Abfrage, dass nun „OnlinestatusReceiveCounter“ und¬†„OnlinestatusCheckTimeout“ √ľbereinstimmen. Sobald eine der if-Bedignungen erf√ľllt ist, wird der „Ping“ ausgesendet und der Durchz√§hlwert von „OnlinestatusSendCounter“ resettet.

Nachdem die Ping-Nachricht beim Empf√§nger eintrifft,¬†werden zwei kurz hintereinander getaktete¬†„Pong“-R√ľckmeldungen von der Smart-Home-Zentrale mit den Werten¬†„000“ und „001“ in Richtung Arduino zur√ľckgesendet (Details dazu weiter unten im Programmcode). Beim Eintreffen der ersten Nachricht (000) wird der Wert von „OnlinestatusReceiveCounter“ auf 0 zur√ľckgesetzt und bei der zweiten Nachricht (000) der Statuswert „OnlinestatusLoxone“ auf 1 gesetzt. Weiterhin wird die installierte gr√ľne LED an Pin 4 mit der Anweisung „digitalWrite(OnlinestatusLED, HIGH);“ mit Strom versorgt.

Dieser „Umweg“ mit zwei¬†Nachrichten erschien¬†notwendig, da der UDP-Empfangspuffer des Arduino nur einmal kurz die Variable „OnlineStatusReceiveCounter“ resetten soll. W√ľrde der Empfangspuffer, der durch die erste Nachricht mit „000“ gef√ľllt¬†ist, direkt im Anschluss nicht mit dem Wert „001“ √ľberschrieben werden, w√ľrde bei jedem neuen Programmdurchlauf weiterhin „000“ im Puffer stehenbleiben, so dass immer wieder der Variablenwert von „OnlineStatusReceiveCounter“ zur√ľckgesetzt werden w√ľrde¬†und dieser nicht¬†mehr hochz√§hlen k√∂nnte, sofern nicht zuf√§llig eine anderslautende¬†eingehende UDP-Nachricht den UDP-Puffer¬†√ľberschreibt. Vermutlich l√§sst sich dieser eher unsaubere¬†Workaround¬†auch viel eleganter l√∂sen, jedoch mangelt es mir derzeitig an dem daf√ľr notwendigen Hintergrundwissen.

Mit¬†„if (OnlinestatusReceiveCounter < OnlinestatusCheckTimeout)“ wird weiterhin gepr√ľft, ob der Z√§hler „OnlinestatusreceiverCounter“ kleiner ist als der hinterlegte Timeout durch „OnlinestatusCheckTimeout“. Sofern das der Fall ist, wird der Wert von „OnlinestatusReceiverCounter“ um 1 erh√∂ht. Dadurch wird erreicht, dass das Hochz√§hlen automatisch gestoppt wird, sobald der Timeout stattfindet.

Sobald der Timeout einmal erreicht ist¬†(letzte if-Abfrage des Loops), wird der Status von „OnlinestatusLoxone“ auf 0 gesetzt und die LED mit dem Befehl „digitalWrite(OnlinestatusLED, LOW);“ ausgeschaltet.

Wer das Ganze nicht sofort durchblickt, knappt sich am besten eine Tasse Kaffee und spielt die einzelnen Punkte des Loops noch einmal gedanklich durch. Es hat auch einige Zeit gedauert und Nerven gekostet, bis dieser Lösungsweg in der vorliegenden Form zuverlässig lief. Wer Verbesserungen zum Code einbringen möchte, kann gerne die Kommentarfunktion nutzen. Ich bin mit C und UDP-Empfangspuffern nicht wirklich fit, vermutlich lässt sich das Ganze noch viel eleganter umsetzen.

void loop()
{

 checkUDP();

 // Bewegungsmelder (Send)
 if (digitalRead(Bewegungsmelder) == LOW && BewegungsmelderState != 0)
 {
  sendUDP("WZ.Bewegungsmelder: 0");
  BewegungsmelderState = 0;
 }

 if (digitalRead(Bewegungsmelder) == HIGH && BewegungsmelderState != 1)
 {
  sendUDP("WZ.Bewegungsmelder: 1");
  BewegungsmelderState = 1;
 }

 // Helligkeitssensor (Send)
 Helligkeitssensor=analogRead(A0);

 HelligkeitssensorCounter = HelligkeitssensorCounter + 1;

 if (Helligkeitssensor >= HelligkeitssensorObergrenze || Helligkeitssensor <= HelligkeitssensorUntergrenze)
 {

  if (HelligkeitssensorCounter >= HelligkeitssensordIdle)
  {
   sprintf(msg, "WZ.Helligkeitssensor: %d", Helligkeitssensor);
   Serial.println(msg);
   sendUDP(msg);

   HelligkeitssensorObergrenze = Helligkeitssensor + HelligkeitssensorSchwellwert;
   HelligkeitssensorUntergrenze = Helligkeitssensor - HelligkeitssensorSchwellwert;
   HelligkeitssensorCounter = 0;
  }
 }

 // Onlinestatus-Ping (Send)
 OnlinestatusSendCounter = OnlinestatusSendCounter + 1;

 if (OnlinestatusSendCounter == OnlinestatusCheckOnline && OnlinestatusReceiveCounter != OnlinestatusCheckTimeout)
 {
  Serial.println("SendUDP: Ping");
  sendUDP("Ping");
  OnlinestatusSendCounter = 0;
 }

 if (OnlinestatusSendCounter == OnlinestatusCheckOffline && OnlinestatusReceiveCounter == OnlinestatusCheckTimeout)
 {
  Serial.println("SendUDP: Ping");
  sendUDP("Ping");
  OnlinestatusSendCounter = 0;
 }

 // Onlinestatus-Pong (Receive)
 if (!strcmp(packetBuffer, "000"))
 {
  OnlinestatusReceiveCounter = 0;
 }

 if (!strcmp(packetBuffer, "001"))
 {
  OnlinestatusLoxone = 1;
  digitalWrite(OnlinestatusLED, HIGH);
 }

 if (OnlinestatusReceiveCounter < OnlinestatusCheckTimeout)
 {
  OnlinestatusReceiveCounter = OnlinestatusReceiveCounter + 1;
 }

 if (OnlinestatusReceiveCounter == OnlinestatusCheckTimeout)
 {
  OnlinestatusLoxone = 0;
  digitalWrite(OnlinestatusLED, LOW);
 }

delay(1000/Programmfrequenz);
}

Teil 4 – UDP-Sendefunktion

Die¬†Sendefunktion f√ľr die UDP-Nachrichten bleibt im Vergleich zum vorangegangenen Szenario unver√§ndert.

// Function to send UDP packets
void sendUDP(String text)
{
 Udp.beginPacket(RecipientIP, RecipientPort);
 // Udp.write("Test");
 Udp.print(text);
 Udp.endPacket();
}

Teil 5 – UDP-Empfangsfunktion

Die Empfangsfunktion¬†f√ľr die UDP-Nachrichten ist der Gegenpart zur der soeben in Teil 4 angesprochenen¬†Sendefunktion und wird abschlie√üend¬†deklariert. Wer m√∂chte, kann den auskommentierten Teil am Ende der Funktion f√ľr Testzwecke aktivieren, damit¬†beim Empfang einer neuen eingehenden UDP-Nachricht der Wert „ACK“ an den Sender zur√ľck√ľbermittelt¬†wird.

// Function to check for new incoming UDP packets
void checkUDP()
{
 // if there's data available, read a packet
 int packetSize = Udp.parsePacket();
 if(packetSize)
 {
  // read the packet into packetBufffer
  Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);

  // For debug only
  // Write packetBuffer to serial
  Serial.print("ReceiveUDP: ");
  Serial.println(packetBuffer);

  // send "ACK" as reply
  //Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  //Udp.write("ACK");
  //Udp.endPacket();
 }
}

Einrichtung des Smart-Home-Servers

In der¬†Loxone-Config werden nun ebenfalls zwei Komponenten ben√∂tigt. Zum einen der¬†„Virtueller UDP Eingang Befehl“, welcher die Nachricht des Arduino mit dem Wert „Ping“ entgegennimmt und zum anderen der¬†„Virtuellen Ausgang Befehl“, welcher die beiden Nachrichten „000“ und „001“ in Richtung Arduino zur√ľcksendet.

In Eingangsrichtung wird der bereits im HowTo Teil 2¬†eingef√ľhrte¬†„Virtuelle Eingang“ namens „WZ.Arduino“ mit dem Empfangsport „7001“ genutzt. Ihm untergliedert wird nun¬†der¬†„Virtuelle Eingang Befehl“ namens „Ping“, welcher mit der Option „Als Digitaleingang verwenden“ angelegt wird. Die¬†„Befehlserkennung“ lautet dabei schlicht „Ping“.

Loxone Config Anwesenheitsstatus Ping

Der Gegenpart ist der „Virtueller Ausgang“ mit der¬†„Adresse“ „/dev/udp/192.168.3.19/7002“. Hier werden¬†die zugewiesene IP des Arduino „192.168.3.19“ und dessen UDP-Port „7002“ angegeben, damit die Pakete auch zum¬†Empf√§nger gelangen.

Loxone Config Virtueller Ausgang UDP

Ihm unterstellt wird der „Virtuelle Ausgang Befehl“ namens „Pong“, der im Falle von¬†„Befehl bei Ein“¬†den Wert¬†„000“ und im Falle von „Befehl bei Aus“ den Wert „001“ kurz nacheinender¬†zur√ľck an den Arduino √ľbertr√§gt.

Loxone Config Anwesenheitsstatus Pong

Da der UDP-Empfangspuffer des Arduino eher rudiment√§rer Natur¬†ist, sollte er grunds√§tzlich nur mit Stringwerten gef√ľttert werden, die alle die selbe L√§nge (in diesem Fall die¬†L√§nge von 3 Zeichen) aufweisen.

Anfangs hatte ich bspw. abwechselnd „Pong“ und¬†„Reset“ zur√ľckgesendet.¬†Sobald jedoch der neu eintreffende Wert „Pong“ den bereits im UDP-Empfangspuffer stehenden Wert „Reset“ √ľberschreiben sollte, stand pl√∂tzlich „Pongt“ im Puffer, da sich die Strings in der L√§nge unterscheiden und anscheinend ein kurzer¬†String einen bereits¬†im Puffer¬†befindlichen l√§ngeren String nicht komplett √ľberschreibt. Eine wichtige Erkenntnis, die auf jeden Fall ber√ľcksichtigt¬†werden muss, um nicht in unn√∂tige Probleme zu laufen.

Ein zus√§tzlicher virtueller „Treppenlichtschalter“, welcher am „Ping“-Signal angeschlossen ist,¬†gibt auf Seiten von Loxone schlie√ülich noch Aufschluss √ľber den aktuellen¬†„Onlinestatus“ des Arduino. Ein Treppenlichtschalter¬†bietet sich dabei gerade f√ľr Tests an, da durch¬†seinen „Sanduhreffekt“ sehr schnell deutlich wird, wann der letzte „Ping“ erfolgt ist und wie lange es noch bis zum potenziellen Timeout dauert. Die Ausschaltzeit wurde dabei testweise auf 11 Sekunden (nur eine Sekunde h√∂her als die Standard-Ping-Zeit des Arduino) gesetzt. Dieser sollte jedoch k√ľnftig hochgesetzt¬†werden, um das Timeout¬†sinnvollerweise zu erh√∂hen.

Loxone iPhone App Onlinestatus

Aus meinem täglichen Leben

Urspr√ľnglich wollte ich nur kurz beschreiben, wie eine UDP-Nachricht an den Arduino gesendet und eine einfache LED mithilfe des Befehls¬†„digitalWrite(OnlinestatusLED, HIGH);“¬†geschaltet werden kann. Da ich jedoch schon von Anfang an eine zuverl√§ssige M√∂glichkeit gesucht habe, um schnell pr√ľfen zu k√∂nnen, ob aktuell¬†ein Datenaustausch zwischen Arduino und Smart-Home-Zentrale m√∂glich ist, habe ich kurzerhand obiges Szenario umgesetzt. Nichtsahnend, dass die Umsetzung doch etwas l√§nger dauert und mehr logische Abfragen ben√∂tigt, als urspr√ľnglich erwartet. Gerade der UDP-Empfangspuffer hat mir dabei etwas Kummer bereitet.¬†Bis auf diese Tatsache, dass¬†aktuell eine¬†„doppelte R√ľckmeldung“ vom Arduino erwartet wird, finde ich das Gesamtkonzept jedoch schon recht rund.

Zuk√ľnftig l√§sst sich der Onlinestatus auch noch f√ľr viel spannendere Dinge nutzen als „nur“ den aktuellen Verbindungsstatus¬†per LED zu kontrollieren. Dadurch, dass k√ľnftig bspw. auch Verbraucher √ľber Relais am Arduino per¬†Smart-Home-Zentrale geschaltet werden sollen¬†(HowTo folgt im n√§chsten Blogpost), l√§sst sich der Onlinestatus gerade auch f√ľr¬†situationsbedingte Schaltvorg√§nge in Abh√§ngigkeit der Netzwerkverf√ľgbarkeit¬†nutzen.

Besteht eine Verbindung zwischen Arduino und Smart-Home-Server (Loxone oder FHEM), leitet ein am Arduino angeschlossener Taster den Tastendruck regulär an Loxone weiter. Dort wird der Befehl ausgewertet und der am Arduino betriebene Aktor (z.B. Beleuchtung) erst dann geschaltet, sofern es die Zentral zulässt (z.B. bei geringer Helligkeit).

Besteht jedoch gerade keine Verbindung zur Zentrale, kann der Tastendruck des Arduino per Fallback √ľber die¬†Programmregel „wenn Onlinestatus = 0“¬†den Aktor direkt schalten. Dadurch wird die aus meiner Sicht derzeit noch gr√∂√üte Schwachstelle vieler¬†zentraler L√∂sungen auf smarte Weise umgangen¬†, die auf dem¬†Konzept¬†einer Smart-Home-Zentrale basieren (dazu geh√∂rt gerade auch Loxone).

Ein an¬†der Smart-Home-Zentrale angebundener¬†Arduino, welcher als ein solches „Gateway“ eingesetzt wird, kann¬†auf diese Weise mit einer Grundintelligenz¬†ausgestattet werden, die trotz tempor√§rer¬†Nichtverf√ľgbarkeit der Zentrale zumindest rudiment√§re Aktionen¬†(Licht an, Rollos hoch) umsetzen kann.

Konzept Onlineverbindungsstatus Standard Fallback

Ein spannendes Zusatzfeature, welches ich bisher noch gar nicht auf dem Schirm hatte und das aus meiner Sicht einen wertvollen Zusatznutzen generiert, auch wenn die Infrastruktur so konzipiert ist, dass die Zentrale dauerhaft erreichbar ist. Manchmal ist sie es, egal ob gewollt (Neustart, Update) oder nicht (Fehlkonfiguration, Absturz, Stromausfall, Austausch) doch einmal nicht. Was hältst du von dieser durch den Arduino ermöglichten Fallback-Lösung? Stimme einfach ab und hinterlasse einen Kommentar.

[poll id=“18″]

Weiter geht es in der Blogserie mit HowTo Teil 5: 24 V LED-Spot per Schaltrelais ansteuern.

Affiliate-Links

[easyazon_image align=“none“ height=“76″ identifier=“B00OEIMCIW“ locale=“DE“ src=“https://www.meintechblog.de/wordpress/wp-content/uploads/2015/06/51cJci1hCCL.SL1102.jpg“ tag=“meintechblog-150622-21″ width=“110″][easyazon_image align=“none“ height=“110″ identifier=“B00PL70PA2″ locale=“DE“ src=“https://www.meintechblog.de/wordpress/wp-content/uploads/2015/06/517P2BCdff7L.SL1101.jpg“ tag=“meintechblog-150622-21″ width=“110″][easyazon_image align=“none“ height=“110″ identifier=“B00HD4U60A“ locale=“DE“ src=“https://www.meintechblog.de/wordpress/wp-content/uploads/2015/06/31vUbit25XL.SL1101.jpg“ tag=“meintechblog-150622-21″ width=“110″][easyazon_image align=“none“ height=“88″ identifier=“B00IYSV8EM“ locale=“DE“ src=“http://ecx.images-amazon.com/images/I/51EzGOkQ4kL.jpg“ tag=“meintechblog-150622-21″ width=“110″]

Loxone im Einsatz? Dann schau dir unseren LoxKurs an und profitiere von unserem Wissen!

Verpasse keine Inhalte mehr! Trage dich in den Newsletter ein und folge uns auf Facebook.

Was ist ein Affiliate-Link? Wenn du auf einen Affiliate-Link klickst und √ľber diesen Link einkaufst, bekomme ich vom betreffenden Online-Shop oder Anbieter eine Provision, was mich u.A. bei den laufenden Kosten den Blogs unterst√ľtzt. F√ľr dich ver√§ndert sich der Preis nicht.

Jörg

hat meintechblog.de ins Leben gerufen, um seine Technikbegeisterung und Erkenntnisse zu teilen. Er veröffentlicht regelmäßig Howtos in den Bereichen Smart Home und Home Entertainment. Mehr Infos

Ein Gedanke zu „Arduino im Smart Home – HowTo Teil 4: Status-LED per UDP ansteuern“

  1. Hi Jörg,

    mal wieder ein super Beitrag! Wegen deinem Problem mit dem Empfangspuffer: Die einfachste Lösung ist hier, am Beginn der Funktion checkUDP den Puffer komplett zu leeren.

    for(int i=0; i < UDP_TX_PACKET_MAX_SIZE; i++){
    packetBuffer[i] = 0;
    }

    Gr√ľ√üe
    Gary

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert