Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Arduino.h>
- #include <SoftwareSerial.h>
- #include <WiFiEspClient.h>
- #include <WiFiEsp.h>
- #include <WiFiEspUdp.h>
- #include <ThingsBoard.h>
- //#include <PubSubClient.h>
- #define WIFI_AP "APHere"
- #define WIFI_PASSWORD "PWDHere"
- #define DEBUG_THIS true
- #define TOKEN "TokenHere"
- #define THINGSBOARD_SERVER "DNSORHOSTHERE"
- #define DEVICE_NAME "IrrigationControl"
- #define DEVICE_VERSION "0.4"
- // Initialize the Ethernet client object
- WiFiEspClient espClient;
- ThingsBoard tb(espClient);// tb(espClient);
- //PubSubClient client(espClient);
- int status = WL_IDLE_STATUS;
- unsigned long lastSend;
- #define SOL_NUM 4
- // debugging generates more serial output
- const boolean debugging = false;
- #define TIMEOUT 5000 // mS
- // Defining Pins
- const int IO_flowsensorPin = 2; // YF‐ S201 Waterflow Sensor Input (pin2 because of interupt)
- const int IO_solenoidPins[SOL_NUM]={3,4,5,6}; // solenoids must be a series of digital pins
- const int IO_pumpPin = 7; // 12v Water Pump on any other digital pin
- const int IO_ESP8266RSTPin = 8;
- // Defining OnOffStatus to temporary deactivate solenoids without rebuilding code
- const bool solenoidtouse[SOL_NUM]={1,0,1,1};
- // Defining Times
- const unsigned int logduration = 30; // time to communicate in seconds e.g. 60*1
- const unsigned int timetowater = 1; // time to water the flowers in minutes e.g. 10min
- const unsigned int timebetweenwatering = 60*12; // time between watering in minutes e.g. 60min*12h
- // Declaring logs, flags, counters and other stuff
- volatile int flow_frequency; // Measures flow sensor pulses
- unsigned int l_hour; // Calculated litres/hour
- float l_sec = 0.0; // liters/hour this second
- unsigned long ml_total = 0; // ml total
- unsigned long ml_total_old = 0; // last value of ml total
- unsigned long Time_current;
- unsigned long Time_logLoop;
- unsigned long Time_secondLoop;
- unsigned long Time_minuteLoop;
- char outstr[15];
- unsigned long runtime=0; // seconds program totally running
- unsigned int mincounter =0;
- unsigned int startcounter =0;
- bool watering=false;
- void InitWiFi()
- {
- // initialize serial for ESP module
- //Serial3.begin(115200);
- // initialize ESP module
- WiFi.init(&Serial3);
- // check for the presence of the shield
- if (WiFi.status() == WL_NO_SHIELD)
- {
- Serial.println("[InitWifi] WiFi shield not present");
- // don't continue
- while (true)
- ;
- }
- Serial.println("[InitWifi] Connecting to AP ...");
- // attempt to connect to WiFi network
- while (status != WL_CONNECTED)
- {
- Serial.print("[InitWifi] Attempting to connect to WPA SSID: ");
- Serial.println(WIFI_AP);
- // Connect to WPA/WPA2 network
- status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
- delay(500);
- }
- Serial.println("[InitWifi] Connected to AP");
- }
- void reconnect()
- {
- // Loop until we're reconnected
- while (!tb.connected())
- {
- Serial.println("[Reconnect] Connecting to ThingsBoard node ...");
- // Attempt to connect (clientId, username, password)
- if (tb.connect(THINGSBOARD_SERVER, TOKEN))
- {
- Serial.println("[Reconnect] Connect done");
- }
- else
- {
- Serial.print("[Reconnect] Connect failed");
- //Serial.print(tb.state());
- Serial.println(" : retrying in 5 seconds]");
- // Wait 5 seconds before retrying
- delay(5000);
- }
- }
- }
- // Build bufferarray and send http-request to ESP and control return
- boolean SendCommand(String cmd, boolean powerdown=true,String function="")
- {
- //static char ESPBuffer[255]="";
- char ESPBuffer[255] = "";
- strcat(ESPBuffer,cmd.c_str());
- int i = tb.sendTelemetryJson(ESPBuffer);
- // int i =.publish("v1/devices/me/telemetry", ESPBuffer);
- if(function){
- Serial.print("["+function+"] ");
- }
- Serial.println(ESPBuffer);
- if(powerdown)
- {
- }
- delay(500);
- if (i) // timed out waiting for ack string
- return true; // ack blank or ack found
- else return false;
- }
- // Interrupt function counting turnaround of waterflow sensor
- void flow()
- {
- flow_frequency++;
- }
- // Formatting json compatible output
- char* makejson(const char *valuename, const char *type, const char *value)
- {
- char t2[3]="";
- char t3[11]="";
- static char tempchar[255];
- strcpy(tempchar, "{");
- strcat(tempchar,valuename);
- strcat(tempchar, ":");
- switch(type[0])
- {
- case 's':
- itoa(strlen(value),t2,10);
- strcat(tempchar, t2);
- strcat(tempchar, ":\"");
- strcat(tempchar, value);
- strcat(tempchar, "\",");
- break;
- case 'i':
- case 'd':
- strcat(tempchar, value);
- strcat(tempchar, ",");
- break;
- }
- strcat(tempchar, "runtime:");
- ultoa(runtime, t3, 10);
- strcat(tempchar, t3);
- strcat(tempchar, "}");
- return tempchar;
- }
- // switching load on pin with serial documentation
- void switchLoad(int pin,int status)
- {
- char tempBuff[3]="";
- char tempBuff2[11] = "";
- char tempBuff3[2]="";
- if(pin!=IO_pumpPin)
- {
- strcat(tempBuff2,"Solenoid");
- itoa(pin-IO_[0]+1,tempBuff,10);
- strcat(tempBuff2,tempBuff);
- }
- else
- {
- {strcat(tempBuff2,"Pump");}
- }
- digitalWrite(pin, status); //Switch DC ON
- itoa(status,tempBuff3,10);
- SendCommand(makejson(tempBuff2, "i", tempBuff3),false,"switchLoad");
- }
- // Waterpump on
- void water(boolean status)
- {
- switchLoad(IO_pumpPin,status);
- }
- // Solenoid on
- void solenoids(byte which)
- {
- // if any on turn off
- for(int i=0;i<SOL_NUM;i++)
- {
- if(digitalRead(IO_[i]))
- switchLoad(IO_[i],LOW);
- }
- // switch solenoid on if OnOffStatus activated
- for(int i=0;i<SOL_NUM;i++)
- {
- if(solenoidtouse[i]&&which==IO_[i])
- switchLoad(IO_[i],HIGH);
- }
- }
- // Every second, calculate and print litres/hour (if debugging)
- void calcliters()
- {
- // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
- l_hour = (flow_frequency * 60.0 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
- l_sec = flow_frequency * 1000.0 / 7.5 / 60.0; // Actual flowrate (this second) in L/hour
- ml_total = ml_total + l_sec;
- flow_frequency = 0; // Reset Counter
- }
- void setup()
- {
- // Init waterflow sensor
- pinMode(IO_, INPUT); //Sets the pin as an input
- digitalWrite(IO_, HIGH); // Optional Internal Pull-Up
- //attachInterrupt(digitalPinToInterrupt(IO_), flow, RISING); // Setup Interrupt
- sei(); // Enable interrupts
- // Init Transistors
- for(int i=0; i<SOL_NUM; i++)
- {
- pinMode(IO_[i], OUTPUT); //Sets the pin as an output
- }
- pinMode(IO_pumpPin, OUTPUT); //Sets the pin as an output
- pinMode(IO_, OUTPUT); //Sets the pin as an output
- digitalWrite(IO_,HIGH);
- // Init other stuff
- Serial.begin(9600);
- Serial.println("[Setup] Startup");
- Serial3.begin(115200);
- InitWiFi();
- lastSend = 0;
- Time_current = millis();
- Time_logLoop = Time_current;
- Time_secondLoop = Time_current;
- Time_minuteLoop = Time_current;
- if (!tb.connected())
- {
- reconnect();
- tb.sendAttributeString("Device_Name",DEVICE_NAME);
- tb.sendAttributeString("Device_Version",DEVICE_VERSION);
- SendCommand(makejson("Startup","i","1"),false,"Startup");
- }
- }
- void loop()
- {
- status = WiFi.status();
- if (status != WL_CONNECTED)
- {
- while (status != WL_CONNECTED)
- {
- Serial.print("[Loop] Attempting to connect to WPA SSID: ");
- Serial.println(WIFI_AP);
- // Connect to WPA/WPA2 network
- status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
- delay(500);
- }
- Serial.println("[Loop] Connected to AP");
- }
- if (!tb.connected())
- {
- reconnect();
- }
- Time_current = millis();
- if (Time_current >= (Time_secondLoop + 1000)) // every second do...
- {
- Time_secondLoop = Time_current; // Updates Time_secondLoop
- calcliters();
- runtime++;
- }
- if (Time_current >= (Time_minuteLoop + 1000UL*60)) // every minute do...
- {
- Time_minuteLoop= Time_current; // Updates Time_minuteLoop
- // if time to water
- if(mincounter%timebetweenwatering==0)
- {
- startcounter=mincounter;
- watering=true;
- attachInterrupt(digitalPinToInterrupt(IO_flowsensorPin), flow, RISING); // Setup Interrupt
- water(HIGH);
- }
- // if water, switch solenoids
- if(watering)
- {
- int solsum=0;
- int i=0;
- if(mincounter==(startcounter))
- solenoids(IO_[i]);
- for(;i<SOL_NUM;i++)
- {
- solsum=solsum+solenoidtouse[i];
- if(mincounter==(startcounter+solsum*timetowater))
- {
- solenoids(IO_[i+1]);
- // if all solenoids done, turn water off
- if(i+1==SOL_NUM)
- {
- water(LOW);
- detachInterrupt(digitalPinToInterrupt(IO_));
- watering=false;
- }
- }
- }
- }
- mincounter++;
- }
- if (Time_current >= (Time_logLoop + logduration * 1000UL)) // every logduration do
- {
- Time_logLoop = Time_current;
- // Log LiterTotal
- dtostrf(ml_total / 1000.0, 0, 2, outstr);
- SendCommand(makejson("LiterTotal","d",outstr),false,"loop");
- // Log LiterAVG(logduration)
- sprintf(outstr, "%d", logduration);
- char buildStr1[50]="LiterAVG(";
- char buildStr2[10]="";
- itoa(logduration, buildStr2, 10);
- strcat(buildStr1, buildStr2);
- strcat(buildStr1,")");
- dtostrf((ml_total - ml_total_old) / logduration / 1000.0 * 3600, 0, 2, outstr);
- SendCommand(makejson(buildStr1, "d", outstr),true,"loop");
- ml_total_old = ml_total;
- }
- tb.loop();
- }
RAW Paste Data