Beitrag zum Kalenderwettbewerb 2015 von Leander Hackmann: Jeder hat Topfpflanzen. Sie verschönern unseren Alltag, benötigen jedoch auch häufig unsere Aufmerksamkeit in Form von Pflege. Um den besten Standort herauszufinden und das regelmäßige Giessen nicht zu vergessen, habe ich folgende Anwendung mit dem Iot-Board entworfen und umgesetzt: ein Datenlogger für Licht und Feuchtigkeit.
Download des Programms Das Programm
//Blumenwaechter für das NanoESP-Board //2016 von Leander H. //Misst alle 30min. Feuchtigkeit und Helligkeit //Mit Druck auf Taster kann ein Nullpunkt in der Messung als markanter Punkt gesetzt werden# //Es werden zwei Channels auf Thingspeak.com verwendet (API-Keys in "LightKEY und "MoistureKEY") //Über "threshold" kann der Pegel zur Warnung eingestellt werden //Code und Idee von Leander H. -- Funktionen von Fabian Kainka #include SoftwareSerial.h> #include Time.h> //Setup-Bereich #define SSID "[SSID]" #define PASSWORD "[Passwort]" #define LightKEY "[API-KEY]" #define MoistureKEY "[API-KEY]" #define threshold 400 // #define DEBUG true #define LED_WLAN 13 SoftwareSerial esp8266(11, 12); // RX, TX int ledGreen = 5; int ledYellow = 4; int ledRed = 3; int sensorPower = 2; int moistSensor = 2; String lastminute; const byte thingPost[] PROGMEM = { 80, 79, 83, 84, 32, 42, 85, 82, 76, 42, 32, 72, 84, 84, 80, 47, 49, 46, 49, 10, 72, 111, 115, 116, 58, 32, 97, 112, 105, 46, 116, 104, 105, 110, 103, 115, 112, 101, 97, 107, 46, 99, 111, 109, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 99, 108, 111, 115, 101, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 120, 45, 119, 119, 119, 45, 102, 111, 114, 109, 45, 117, 114, 108, 101, 110, 99, 111, 100, 101, 100, 10, 67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32, 42, 76, 69, 78, 42, 10, 10, 42, 65, 80, 80, 69, 78, 68, 42, 10 }; void setup() { pinMode(ledGreen, OUTPUT); pinMode(ledYellow, OUTPUT); pinMode(ledRed, OUTPUT); pinMode(sensorPower, OUTPUT); Serial.begin(19200); esp8266.begin(19200); while(!espConfig()){ //Failsafe für WLAN delay(200); } digitalWrite(LED_WLAN, HIGH); while(!getTime("chronic.herokuapp.com", "/utc/in+one+hours") == false){ //Failsafe für Zeitsynchro delay(200); } sendThingPost(LightKEY, analogRead(A0)); //Erste Übermittlung digitalWrite(sensorPower, HIGH); delay(200); int tmp = analogRead(A2); sendThingPost(MoistureKEY, tmp); digitalWrite(sensorPower, LOW); if(tmp threshold){ digitalWrite(ledRed, HIGH); digitalWrite(ledGreen, LOW); }else{ digitalWrite(ledRed, LOW); digitalWrite(ledGreen, HIGH); } } void loop() { String shour, sminute, ssecond; if (hour() 9) shour = "0" + String(hour()); else shour = String(hour()); // adjust for 0-9 if (minute() 9) sminute = "0" + String(minute()); else sminute = String(minute()); if (second() 9) ssecond = "0" + String(second()); else ssecond = String(second()); //debug(shour + ":" + sminute + ":" + ssecond); if(sminute == "0" || sminute == "30"){ //Wird zur halben und vollen Stunde ausgeführt if(sminute != lastminute){ digitalWrite(ledYellow, HIGH); if(sendThingPost(LightKEY, analogRead(A0) == false)){ while(sendThingPost(LightKEY, analogRead(A0) == false)){ sendThingPost(LightKEY, analogRead(A0)); delay(200); } } digitalWrite(ledYellow, LOW); delay(500); digitalWrite(ledYellow, HIGH); digitalWrite(sensorPower, HIGH); delay(100); if(sendThingPost(MoistureKEY, analogRead(A2) == false)){ while(sendThingPost(MoistureKEY, analogRead(A2) == false)){ sendThingPost(MoistureKEY, analogRead(A2)); delay(200); } } digitalWrite(sensorPower, LOW); digitalWrite(ledYellow, LOW); digitalWrite(sensorPower, HIGH); delay(100); int tmp = analogRead(A2); digitalWrite(sensorPower, LOW); if(tmp threshold){ digitalWrite(ledRed, HIGH); digitalWrite(ledGreen, LOW); }else{ digitalWrite(ledRed, LOW); digitalWrite(ledGreen, HIGH); } lastminute = sminute; } } if(analogRead(A1) > 500){ //Button zum Setzen eines Nullpunktes digitalWrite(ledYellow, HIGH); sendThingPost(LightKEY, 0); digitalWrite(ledYellow, LOW); delay(500); digitalWrite(ledYellow, HIGH); sendThingPost(MoistureKEY, 0); digitalWrite(ledYellow, LOW); delay(1000); } } //Verwendete Funktionen von Fabian Kainka folgen ab hier: //-----------------------------------------ThingsSpeak Functions------------------------------------ boolean sendThingPost(String key, int value) { boolean succes = true; String Host = "api.thingspeak.com"; String msg = "field1=" + String(value); succes &= sendCom("AT+CIPSTART="TCP","" + Host + "",80", "OK"); String postRequest = createThingPost("/update", key, msg); if (sendCom("AT+CIPSEND=" + String(postRequest.length()), ">")) { esp8266.print(postRequest); esp8266.find("SEND OK"); if (!esp8266.find("CLOSED")) succes &= sendCom("AT+CIPCLOSE", "OK"); } else { succes = false; } return succes; } String createThingPost(String url, String key, String msg) { String xBuffer; for (int i = 0; i sizeof(thingPost); i++) { char myChar = pgm_read_byte_near(thingPost + i); xBuffer += myChar; } String append = "api_key=" + key + "&" + msg; xBuffer.replace("*URL*", url); xBuffer.replace("*LEN*", String( append.length())); xBuffer.replace("*APPEND*", append); return xBuffer; } String createThingGet(String url, String key) { String xBuffer; for (int i = 0; i sizeof(thingPost); i++) { char myChar = pgm_read_byte_near(thingPost + i); xBuffer += myChar; } String append = "api_key=" + key; xBuffer.replace("POST", "GET"); xBuffer.replace("*URL*", url); xBuffer.replace("*LEN*", String( append.length())); xBuffer.replace("*APPEND*", append); return xBuffer; } String createThingGet(String url, String key, String msg) { String xBuffer; for (int i = 0; i sizeof(thingPost); i++) { char myChar = pgm_read_byte_near(thingPost + i); xBuffer += myChar; } String append = "api_key=" + key + "&" + msg; xBuffer.replace("POST", "GET"); xBuffer.replace("*URL*", url); xBuffer.replace("*LEN*", String( append.length())); xBuffer.replace("*APPEND*", append); return xBuffer; } String getTCP(String Host, String Subpage) { boolean succes = true; succes &= sendCom("AT+CIPSTART="TCP","" + Host + "",80", "OK"); String getRequest = "GET " + Subpage + " HTTP/1.1rnHost:" + Host + "rnrn"; succes &= sendCom("AT+CIPSEND=" + String(getRequest.length() + 2), ">"); return sendCom(getRequest); } boolean getTime(String Host, String Subpage) { boolean succes = true; int xyear, xmonth, xday, xhour, xminute, xsecond; //lokal variables succes &= sendCom("AT+CIPSTART="TCP","" + Host + "",80", "OK"); String getRequest = "GET " + Subpage + " HTTP/1.1rnHost:" + Host + "rn"; succes &= sendCom("AT+CIPSEND=" + String(getRequest.length() + 2), ">"); esp8266.println(getRequest); if (esp8266.find("+IPD")) { if (esp8266.find("rnrn")) { xyear = esp8266.parseInt(); xmonth = esp8266.parseInt(); xday = esp8266.parseInt(); xhour = esp8266.parseInt(); xminute = esp8266.parseInt(); xsecond = esp8266.parseInt(); if (xday 0) xday *= -1; //Because of date seperator - parseInt detects negativ integer if (xmonth 0) xmonth *= -1; //Because of date seperator - parseInt detects negativ integer setTime(xhour, xminute, xsecond, xday, xmonth, xyear); sendCom("AT+CIPCLOSE", "OK"); return true; } else return false; } else return false; } //-----------------------------------------Config ESP8266------------------------------------ boolean espConfig() { boolean succes = true; esp8266.setTimeout(5000); succes &= sendCom("AT+RST", "ready"); esp8266.setTimeout(1000); if (configStation(SSID, PASSWORD)) { succes &= true; debug("WLAN Connected"); debug("My IP is:"); debug(sendCom("AT+CIFSR")); } else { succes &= false; } //shorter Timeout for faster wrong UPD-Comands handling succes &= sendCom("AT+CIPMODE=0", "OK"); //So rum scheit wichtig! succes &= sendCom("AT+CIPMUX=0", "OK"); return succes; } boolean configTCPServer() { boolean succes = true; succes &= (sendCom("AT+CIPMUX=1", "OK")); succes &= (sendCom("AT+CIPSERVER=1,80", "OK")); return succes; } boolean configTCPClient() { boolean succes = true; succes &= (sendCom("AT+CIPMUX=0", "OK")); //succes &= (sendCom("AT+CIPSERVER=1,80", "OK")); return succes; } boolean configStation(String vSSID, String vPASSWORT) { boolean succes = true; succes &= (sendCom("AT+CWMODE=1", "OK")); esp8266.setTimeout(20000); succes &= (sendCom("AT+CWJAP="" + String(vSSID) + "","" + String(vPASSWORT) + """, "OK")); esp8266.setTimeout(1000); return succes; } boolean configAP() { boolean succes = true; succes &= (sendCom("AT+CWMODE=2", "OK")); succes &= (sendCom("AT+CWSAP="NanoESP","",5,0", "OK")); return succes; } boolean configUDP() { boolean succes = true; succes &= (sendCom("AT+CIPMODE=0", "OK")); succes &= (sendCom("AT+CIPMUX=0", "OK")); succes &= sendCom("AT+CIPSTART="UDP","192.168.255.255",90,91,2", "OK"); //Importand Boradcast...Reconnect IP return succes; } //-----------------------------------------------Controll ESP----------------------------------------------------- boolean sendUDP(String Msg) { boolean succes = true; succes &= sendCom("AT+CIPSEND=" + String(Msg.length() + 2), ">"); //+","192.168.4.2",90", ">"); if (succes) { succes &= sendCom(Msg, "OK"); } return succes; } boolean sendCom(String command, char respond[]) { esp8266.println(command); if (esp8266.findUntil(respond, "ERROR")) { return true; } else { debug("ESP SEND ERROR: " + command); return false; } } String sendCom(String command) { esp8266.println(command); return esp8266.readString(); } //-------------------------------------------------Debug Functions------------------------------------------------------ void serialDebug() { while (true) { if (esp8266.available()) Serial.write(esp8266.read()); if (Serial.available()) esp8266.write(Serial.read()); } } void debug(String Msg) { if (DEBUG) { Serial.println(Msg); } } [collapse]
...