/* IT-Syndikat Open device Firmware for the wooden Device with two fat buttons Network Requirements: * Ethernet port on Router * DHCP enabled on Router * Unique MAC Address for Arduino Additional Credits: Example sketches from Arduino team, Ethernet by Adrian McEwen Based on the Ethernet to Thingspeak exaple by Hans Scharler */ #include #include #include "APIKey.h" #include "TimerOne.h" // Must be unique on local network byte mac[] = {0xD4, 0xBA, 0xD9, 0x9A, 0x7C, 0x95}; // Initialize Arduino Ethernet Client EthernetClient client; // Twitter response variables #define SERVER_DOMAIN "spaceapi.it-syndikat.org" // URL // Specific variables // Status int hsopen; int ethernetstatus; int ledtimer = 0; const int ledspan = 100; int pingtimer = -1; const int pingspan = 250; int checktimer = 0; const int checkspan = 1000; int update = 0; // debug options boolean debug = true; // LED and Switch pins const int glight = 5; const int rlight = 6; const int topen = 2; const int tclose = 3; const int beeper = A5; #define MODE_OPEN_STATE 0 #define MODE_PING_STATE 1 void setLeds() { if (pingtimer >= 0) { if (hsopen) { // If space is not closed, beep three times with // beep if ((pingtimer > 220) && ((pingtimer / 5) % 2 == 1)) { digitalWrite(beeper, HIGH); } else { digitalWrite(beeper, LOW); } } else { // if closed, beep once // beep if ((pingtimer > 240) && ((pingtimer / 5) % 2 == 1)) { digitalWrite(beeper, HIGH); } else { digitalWrite(beeper, LOW); } } // blink like crazy if ((pingtimer / 2) % 2 == 1) { analogWrite(rlight, 255); analogWrite(glight, 255); } else { analogWrite(rlight, 0); analogWrite(glight, 0); } pingtimer--; } else { switch (ethernetstatus) { case 0: { // ethernet fail // blink red if (ledtimer < (ledspan / 2)) { analogWrite(rlight, 255); } else { analogWrite(rlight, 0); } analogWrite(glight, 0); break; } case -1: { // ethernet unknown // fade green if (ledtimer < (ledspan / 2)) { analogWrite(glight, (255 / (ledspan / 2) * ledtimer)); // fade up } else { analogWrite(glight, 255 - (255 / (ledspan / 2) * (ledtimer - (ledspan / 2)))); // fade down } analogWrite(rlight, 0); break; } case 1: { // ethernet ok switch (hsopen) { case 0: { // closed // red analogWrite(rlight, 255); analogWrite(glight, 0); break; } case 1: { // open // green analogWrite(rlight, 0); analogWrite(glight, 255); break; } case 2: { // wait // fade red and green if (ledtimer < (ledspan / 2)) { int tmp = (255 / (ledspan / 2) * ledtimer); analogWrite(glight, tmp); // fade up analogWrite(rlight, tmp); // fade up } else { int tmp = 255 - (255 / (ledspan / 2) * (ledtimer - (ledspan / 2))); analogWrite(glight, tmp); // fade down analogWrite(rlight, tmp); // fade down } break; } case -1: { // unknown // fade red if (ledtimer < (ledspan / 2)) { analogWrite(rlight, (255 / (ledspan / 2) * ledtimer)); // fade up } else { analogWrite(rlight, 255 - (255 / (ledspan / 2) * (ledtimer - (ledspan / 2)))); // fade down } analogWrite(glight, 0); break; } } break; } } ledtimer++; if (ledtimer >= ledspan) { ledtimer = 0; } } checktimer++; if (checktimer >= checkspan) { checktimer = 0; update = 1; } } void setEth(int statuss) { ethernetstatus = statuss; if (debug) { Serial.println("Setting eth "); Serial.println(statuss); } setLeds(); } void setRoom(int statuss) { hsopen = statuss; if (debug) { Serial.print("Setting room "); Serial.println(statuss); } setLeds(); } void startEthernet() { client.stop(); if (debug) { Serial.println("Connecting Arduino to network..."); Serial.println(); } setEth(-1); delay(1000); // Connect to network amd obtain an IP address using DHCP if (Ethernet.begin(mac) == 0) { if (debug) { Serial.println("DHCP Failed, reset Arduino to try again"); Serial.println(); } setEth(0); } else { if (debug) { Serial.println("Arduino connected to network using DHCP"); Serial.println(); } setEth(1); } if (debug) { Serial.println("DONE"); Serial.println(); } delay(1000); } // reads out the status returned by the server and sets the LED's appropriately. // the mode is defied by the intended call: void readServerStatus(int mode) { char lastsign = '0'; boolean readStatus = false; String currentLine = ""; // string to hold the text from server while (client.connected()) { if (client.available()) { // read incoming bytes: char inChar = client.read(); // add incoming byte to end of line: currentLine += inChar; if (debug) { Serial.print(inChar); } // if you get a newline, clear the line: if (inChar == '\n') { currentLine = ""; if (lastsign == '\n') { // /r/n /r/n is the end of a header readStatus = true; // start to parse the content of the line if (debug) { Serial.println("##END OF HEADER##"); } } } if (readStatus) { if (currentLine.startsWith("true", 0)) { if (debug) { Serial.println(""); } switch (mode) { case MODE_OPEN_STATE: setRoom(1); break; case MODE_PING_STATE: if (debug) { Serial.println("Wink Wink"); } pingtimer = pingspan; break; } // close the connection to the server: client.stop(); return; } if (currentLine.startsWith("false", 0)) { if (debug) { Serial.println(""); } switch (mode) { case MODE_OPEN_STATE: setRoom(0); break; case MODE_PING_STATE: if (debug) { Serial.println("No Wink"); } break; } // close the connection to the server: client.stop(); return; } } if (inChar != '\r') { // removes /r so we dan test if the header end with // two newlines, hacky but works. lastsign = inChar; } } } setRoom(-1); client.stop(); } void TriggerServerReq(String req, int mode) { // attempt to connect, and wait a millisecond: if (debug) { Serial.println("connecting to server... Status req"); } if (client.connect(SERVER_DOMAIN, 80)) { if (debug) { Serial.println("making HTTP request: " + req); } // make HTTP request to server: client.println(req + " HTTP/1.1"); client.println("HOST: " SERVER_DOMAIN); client.println("Connection: close"); client.println(); readServerStatus(mode); } else { if (debug) { Serial.println("Not connected..."); } } // note the time of this connect attempt: } void RequestState() { TriggerServerReq("GET /api/status-s.php", MODE_OPEN_STATE); } // Status LED pins void setup() { pinMode(glight, OUTPUT); pinMode(rlight, OUTPUT); pinMode(beeper, OUTPUT); digitalWrite(beeper, LOW); // Buttons with pullup resistor pinMode(topen, INPUT); pinMode(tclose, INPUT); digitalWrite(topen, HIGH); digitalWrite(tclose, HIGH); // Start Serial for debugging on the Serial Monitor if (debug) { Serial.begin(9600); } // Start Ethernet on Arduino setEth(-1); setRoom(2); Timer1.initialize(20000); // 50 mal die Sekunde Timer1.attachInterrupt(setLeds); startEthernet(); delay(1000); // Get current Status RequestState(); } void readButtons() { if ((digitalRead(topen) == LOW) && (hsopen != 1)) { // startEthernet(); setRoom(2); TriggerServerReq("POST /api/update.php?open=true&apikey=" UPDATE_API_KEY, MODE_OPEN_STATE); } if ((digitalRead(tclose) == LOW) && (hsopen != 0)) { // startEthernet(); setRoom(2); TriggerServerReq("POST /api/update.php?open=false&apikey=" UPDATE_API_KEY, MODE_OPEN_STATE); } } void RequestPing() { TriggerServerReq("POST /api/ping-get.php?apikey=" PING_GET_API_KEY, MODE_PING_STATE); } void launchUpdate() { if (update == 1) { RequestPing(); RequestState(); update = 0; } } void loop() { readButtons(); launchUpdate(); }