//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 //<--- "threshold" muss ggf. veraendert werden
#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]
, ‘you can’t use my two-sided ‘unsafety’ razor, you’ll have to use the scrotum razor.”I was telling a few of my bellydancing class about it and realised I was getting some pretty nervous looks…and finally one said, u.8;Um…*whydoesCraighaveascrot2mrazor*?”“Oooohhhhh…1didn’t I mention his vasectomy? Ooops….it was a one-off, people!!”
Em thÃch bà i nà y quá.Và thÃch mô hình qua ‘cái nắm tay’. Sau khi cÆ¡m có thịt, bé có áo ấm sẽ là ‘cái cần câu cho vùng ca.1&82#7;oHy vá»ng chÆ°Æ¡ng trình nhân lên mãi….