NALS: Network-Attached-LED-Stripe (Teil 3)

Die Codes haben wir, also können wir nun mit der Programmierung des Senders beginnen.

Was muss der nochmal alles können?

Der Arduino muss mit dem Netzwerk verbunden sein. Wir haben uns dabei für eine pseudo dynamisch IP Adresse entschieden, damit wir flexibler sind. Pseudo dynamisch deswegen, weil es eine feste Zuweisung der IP zu dem Gerät gibt (Konfig im DHCP Server). Eine feste IP benötigen wir, da wir den Arduino zwecks Befehlsübermittlung ansprechen möchten. Wichtig zu wissen ist dabei: Man kann dem Arduino durchaus eine feste IP vergeben. Da findet ihr viele Beispiele im Netz.

Ein mini Webserver muss auf dem Arduino lauschen, damit wir über einen einfachen URL-Aufruf Befehle übermitteln können.

Ein Infrarot Sender (Diode) wird angesteuert um die Infrarot Signale an den LED Empfänger zu schicken.

Der Sketch

Der Sketch für unsere Steuerung sieht aus wie folgt. Die Codes, CMD_LEN (bspw. 32bit) und das Protokoll muss ggf. angepasst werden.


#include "WebServer.h"
#include "SPI.h"
#include "Ethernet.h"
#include "IRremote.h"

IRsend light;

enum {
 RED = 0xFF9867,
 GREEN = 0xFFD827,
 YELLOW = 0xFF38C7,
 ON = 0xFFB04F,
 OFF = 0xFFF807,
 CMD_LEN = 32
};

// CHANGE THIS TO YOUR OWN UNIQUE VALUE
byte mac[] = {
 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

// blink var
int blinker = 0;

// DHCP Start
EthernetClient client;

// Webserver
WebServer webserver("/lights", 80);

// declare Commands to be executed
void redCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
 blinker = 0;
 light.sendNEC(ON, CMD_LEN);
 light.sendNEC(RED, CMD_LEN);
 server.print("<html><body>red</body></html>");
}
void greenCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
 blinker = 0;
 light.sendNEC(ON, CMD_LEN);
 light.sendNEC(GREEN, CMD_LEN);
 server.print("<html><body>green</body></html>");
}
void yellowCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
 blinker = 0;
 light.sendNEC(ON, CMD_LEN);
 light.sendNEC(YELLOW, CMD_LEN);
 server.print("<html><body>gelb</body></html>");
}
void offCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
 blinker = 0;
 light.sendNEC(OFF, CMD_LEN);
 server.print("<html><body>alles aus</body></html>");
}
void blinkCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
 blinker = 1;
 server.print("<html><body>blink</body></html>");
}

void setup() {
 // Open serial communications and wait for port to open:
 Serial.begin(9600);

// start the Ethernet connection:
 if (Ethernet.begin(mac) == 0) {
 Serial.println("Failed to configure Ethernet using DHCP");
 // no point in carrying on, so do nothing forevermore:
 for(;;)
 ;
 }

 Serial.print("My IP: ");
 print_ip();
 webserver.addCommand("red", redCmd);
 webserver.addCommand("green", greenCmd);
 webserver.addCommand("yellow", yellowCmd);
 webserver.addCommand("blink", blinkCmd);
 webserver.addCommand("off", offCmd);
 webserver.begin();
}

void loop()
{
 long milliseconds = millis();
 /*Serial.print(milliseconds);
 Serial.println(); */
 if ( milliseconds > 1100 && milliseconds < 1200 ) {
 Serial.print("Doing DHCP renew...");
 Serial.println();
 int status = Ethernet.maintain();
 delay(100);
 /*
 returns:
 0: nothing happened
 1: renew failed
 2: renew success
 3: rebind fail
 4: rebind success
 */
 if(status){
 Serial.print(millis(), DEC);
 Serial.println(" A renew or rebind event happened while maintaining the dhcp lease");
 Serial.print(status, DEC);
 Serial.println(" was the returned status");
 Serial.print("IP address after renew/rebind:");
 print_ip();
 }
 }
 // process incoming connections one at a time forever
 webserver.processConnection();
 if ( blinker == 1 ) {
 light.sendNEC(ON, CMD_LEN);
 light.sendNEC(RED, CMD_LEN);
 delay(1000);
 light.sendNEC(OFF, CMD_LEN);
 delay(1000);
 }
}

void print_ip(){
 for (byte thisByte = 0; thisByte < 4; thisByte++) {
 // print the value of each byte of the IP address:
 Serial.print(Ethernet.localIP()[thisByte], DEC);
 Serial.print(".");
 }
 Serial.println();
}

Libraries

Wie schon in Teil 2 benötigen wir für diesen Sketch ein weiteres Library – das webduino. Webduino stellt Funktionen bereit, mit denen sich recht einfach ein “Webserver” realisieren lässt.

Den webduino findet ihr hier.

Upload ….

Schaltplan

Der Schaltplan ist auch hier wieder relativ einfach … den 100Ohm Widerstand nicht vergessen ;-)

Fertig? IP vergeben?

Das sollte es nun eigentlich gewesen sein. Wenigstens von der Hardware her.

Wir haben dem Ding eine Hülle spendiert :-)

Habt ihr eine DHCP Adresse? Der Arduino schreibt die Adresse beim Start in die Serielle Konsole.

Geht ein Ping? Dann sollte das ganze funktionieren.

Nu los!

Über den URL Aufruf http://<euer Arduino/lights/red sollte nun das entsprechende Signal an den Empfänger des LED Stripes geschickt werden. Probiert das mal aus. Achtung! Es gibt eine Stolperfalle mit dem Chrome Browser. Dieser ruft Seiten schon im Hintergrund auf, wenn nur die URL in der History angezeigt wird. Das kann verwirren, da der Status der LED sich schon ändert bevor ihr sie wirklich aufgerufen habt. Ich habe ab dann immer mit curl auf der CLI getestet ;-)

Für ein Script bietet sich curl entsprechend genauso an. Wie in diesem Beispiel:


...

case $STATUS in
 0)
 LED="green"
 ;;
 1)
 LED="orange"
 ;;
 2)
 LED="red"
 ;;
 3)
 LED="blink"
 ;;
 esac

#echo "would set to $STATUS / $LED"
 curl -s --connect-timeout 1 "http://10.10.199.186/lights/$LED" >/dev/null 2>&1

Ich hoffe ich hab nicht allzu viel vergessen. Bei Fragen oder Fehlern einfach melden ;-)

Quellen:

https://github.com/shirriff/Arduino-IRremote

http://www.dpunkt.de/leseproben/3692/5%20Universalfernbedienung.pdf

Hinterlasse eine Antwort

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

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>