Guest User

Irrigation Valve Control

a guest
May 17th, 2019
164
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <Arduino.h>
  2. #include <SoftwareSerial.h>
  3. #include <WiFiEspClient.h>
  4. #include <WiFiEsp.h>
  5. #include <WiFiEspUdp.h>
  6. #include <ThingsBoard.h>
  7. //#include <PubSubClient.h>
  8.  
  9. #define WIFI_AP "APHere"
  10. #define WIFI_PASSWORD "PWDHere"
  11. #define DEBUG_THIS true
  12.  
  13. #define TOKEN "TokenHere"
  14. #define THINGSBOARD_SERVER "DNSORHOSTHERE"
  15.  
  16. #define DEVICE_NAME "IrrigationControl"
  17. #define DEVICE_VERSION "0.4"
  18.  
  19. // Initialize the Ethernet client object
  20. WiFiEspClient espClient;
  21. ThingsBoard tb(espClient);// tb(espClient);
  22. //PubSubClient client(espClient);
  23.  
  24. int status = WL_IDLE_STATUS;
  25. unsigned long lastSend;
  26.  
  27. #define SOL_NUM 4
  28. // debugging generates more serial output
  29. const boolean debugging = false;
  30.  
  31. #define TIMEOUT 5000 // mS
  32.  
  33. // Defining Pins
  34. const int IO_flowsensorPin = 2;   // YF‐ S201 Waterflow Sensor Input (pin2 because of interupt)
  35. const int IO_solenoidPins[SOL_NUM]={3,4,5,6}; // solenoids must be a series of digital pins
  36. const int IO_pumpPin = 7; // 12v Water Pump on any other digital pin
  37. const int IO_ESP8266RSTPin = 8;
  38.  
  39. // Defining OnOffStatus to temporary deactivate solenoids without rebuilding code
  40. const bool solenoidtouse[SOL_NUM]={1,0,1,1};
  41.  
  42. // Defining Times
  43. const unsigned int logduration = 30; // time to communicate in seconds e.g. 60*1
  44. const unsigned int timetowater = 1; // time to water the flowers in minutes e.g. 10min
  45. const unsigned int timebetweenwatering = 60*12; // time between watering in minutes e.g. 60min*12h
  46.  
  47. // Declaring logs, flags, counters and other stuff
  48. volatile int flow_frequency; // Measures flow sensor pulses
  49. unsigned int l_hour;         // Calculated litres/hour
  50. float l_sec = 0.0; // liters/hour this second
  51. unsigned long ml_total = 0; // ml total
  52. unsigned long ml_total_old = 0; // last value of ml total
  53. unsigned long Time_current;
  54. unsigned long Time_logLoop;
  55. unsigned long Time_secondLoop;
  56. unsigned long Time_minuteLoop;
  57. char outstr[15];
  58. unsigned long runtime=0; // seconds program totally running
  59. unsigned int mincounter =0;
  60. unsigned int startcounter =0;
  61. bool watering=false;
  62.  
  63. void InitWiFi()
  64. {
  65.   // initialize serial for ESP module
  66.   //Serial3.begin(115200);
  67.     // initialize ESP module
  68.   WiFi.init(&Serial3);
  69.   // check for the presence of the shield
  70.   if (WiFi.status() == WL_NO_SHIELD)
  71.   {
  72.     Serial.println("[InitWifi] WiFi shield not present");
  73.     // don't continue
  74.     while (true)
  75.       ;
  76.   }
  77.  
  78.   Serial.println("[InitWifi] Connecting to AP ...");
  79.   // attempt to connect to WiFi network
  80.   while (status != WL_CONNECTED)
  81.   {
  82.     Serial.print("[InitWifi] Attempting to connect to WPA SSID: ");
  83.     Serial.println(WIFI_AP);
  84.     // Connect to WPA/WPA2 network
  85.     status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
  86.     delay(500);
  87.   }
  88.   Serial.println("[InitWifi] Connected to AP");
  89. }
  90.  
  91. void reconnect()
  92. {
  93.   // Loop until we're reconnected
  94.   while (!tb.connected())
  95.   {
  96.     Serial.println("[Reconnect] Connecting to ThingsBoard node ...");
  97.     // Attempt to connect (clientId, username, password)
  98.     if (tb.connect(THINGSBOARD_SERVER, TOKEN))
  99.     {
  100.       Serial.println("[Reconnect] Connect done");
  101.     }
  102.     else
  103.     {
  104.       Serial.print("[Reconnect] Connect failed");
  105.       //Serial.print(tb.state());
  106.       Serial.println(" : retrying in 5 seconds]");
  107.       // Wait 5 seconds before retrying
  108.       delay(5000);
  109.     }
  110.   }
  111. }
  112.  
  113. // Build bufferarray and send http-request to ESP and control return
  114. boolean SendCommand(String cmd, boolean powerdown=true,String function="")
  115. {
  116.   //static char ESPBuffer[255]="";
  117.   char ESPBuffer[255] = "";
  118.   strcat(ESPBuffer,cmd.c_str());
  119.   int i = tb.sendTelemetryJson(ESPBuffer);
  120.   // int i =.publish("v1/devices/me/telemetry", ESPBuffer);
  121.   if(function){
  122.     Serial.print("["+function+"] ");
  123.   }
  124.   Serial.println(ESPBuffer);
  125.  
  126.   if(powerdown)
  127.   {
  128.  
  129.    
  130.   }
  131.   delay(500);
  132.   if (i)    // timed out waiting for ack string
  133.     return true;         // ack blank or ack found
  134.     else return false;
  135.  
  136. }
  137.  
  138. // Interrupt function counting turnaround of waterflow sensor
  139. void flow()
  140. {
  141.   flow_frequency++;
  142. }
  143.  
  144. // Formatting json compatible output
  145. char* makejson(const char *valuename, const char *type, const char *value)
  146. {
  147.   char t2[3]="";
  148.   char t3[11]="";
  149.   static char tempchar[255];
  150.   strcpy(tempchar, "{");
  151.   strcat(tempchar,valuename);
  152.   strcat(tempchar, ":");
  153.  
  154.   switch(type[0])
  155.   {
  156.     case 's':
  157.       itoa(strlen(value),t2,10);
  158.       strcat(tempchar, t2);
  159.       strcat(tempchar, ":\"");
  160.       strcat(tempchar, value);
  161.       strcat(tempchar, "\",");
  162.       break;
  163.     case 'i':
  164.     case 'd':
  165.       strcat(tempchar, value);
  166.       strcat(tempchar, ",");
  167.       break;
  168.   }
  169.   strcat(tempchar, "runtime:");
  170.   ultoa(runtime, t3, 10);
  171.   strcat(tempchar, t3);
  172.   strcat(tempchar, "}");
  173.   return tempchar;
  174. }
  175.  
  176. // switching load on pin with serial documentation
  177. void switchLoad(int pin,int status)
  178. {
  179.   char tempBuff[3]="";
  180.   char tempBuff2[11] = "";
  181.   char tempBuff3[2]="";
  182.   if(pin!=IO_pumpPin)
  183.   {
  184.     strcat(tempBuff2,"Solenoid");
  185.     itoa(pin-IO_[0]+1,tempBuff,10);
  186.     strcat(tempBuff2,tempBuff);
  187.     }
  188.   else
  189.   {
  190.     {strcat(tempBuff2,"Pump");}
  191.   }
  192.   digitalWrite(pin, status); //Switch DC ON
  193.   itoa(status,tempBuff3,10);
  194.   SendCommand(makejson(tempBuff2, "i", tempBuff3),false,"switchLoad");
  195. }
  196.  
  197. // Waterpump on
  198. void water(boolean status)
  199. {
  200.   switchLoad(IO_pumpPin,status);
  201. }
  202.  
  203. // Solenoid on
  204. void solenoids(byte which)
  205. {
  206.   // if any on turn off
  207.   for(int i=0;i<SOL_NUM;i++)
  208.   {
  209.     if(digitalRead(IO_[i]))
  210.       switchLoad(IO_[i],LOW);
  211.   }
  212.   // switch solenoid on if OnOffStatus activated
  213.   for(int i=0;i<SOL_NUM;i++)
  214.   {
  215.     if(solenoidtouse[i]&&which==IO_[i])
  216.     switchLoad(IO_[i],HIGH);
  217.   }
  218. }
  219.  
  220. // Every second, calculate and print litres/hour (if debugging)
  221. void calcliters()
  222. {
  223.     // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
  224.     l_hour = (flow_frequency * 60.0 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
  225.     l_sec = flow_frequency * 1000.0 / 7.5 / 60.0; // Actual flowrate (this second) in L/hour
  226.     ml_total = ml_total + l_sec;
  227.     flow_frequency = 0; // Reset Counter
  228. }
  229.  
  230. void setup()
  231. {
  232.   // Init waterflow sensor
  233.   pinMode(IO_, INPUT); //Sets the pin as an input
  234.   digitalWrite(IO_, HIGH); // Optional Internal Pull-Up
  235.   //attachInterrupt(digitalPinToInterrupt(IO_), flow, RISING); // Setup Interrupt
  236.   sei();                            // Enable interrupts
  237.   // Init Transistors
  238.   for(int i=0; i<SOL_NUM; i++)
  239.   {
  240.     pinMode(IO_[i], OUTPUT); //Sets the pin as an output
  241.   }
  242.   pinMode(IO_pumpPin, OUTPUT); //Sets the pin as an output
  243.   pinMode(IO_, OUTPUT); //Sets the pin as an output
  244.   digitalWrite(IO_,HIGH);
  245.   // Init other stuff
  246.   Serial.begin(9600);
  247.   Serial.println("[Setup] Startup");
  248.   Serial3.begin(115200);
  249.   InitWiFi();
  250.   lastSend = 0;
  251.   Time_current = millis();
  252.   Time_logLoop = Time_current;
  253.   Time_secondLoop = Time_current;
  254.   Time_minuteLoop = Time_current;
  255.    if (!tb.connected())
  256.   {
  257.     reconnect();
  258.     tb.sendAttributeString("Device_Name",DEVICE_NAME);
  259.     tb.sendAttributeString("Device_Version",DEVICE_VERSION);
  260.     SendCommand(makejson("Startup","i","1"),false,"Startup");
  261.   }
  262. }
  263.  
  264. void loop()
  265. {
  266.   status = WiFi.status();
  267.   if (status != WL_CONNECTED)
  268.   {
  269.     while (status != WL_CONNECTED)
  270.     {
  271.       Serial.print("[Loop] Attempting to connect to WPA SSID: ");
  272.       Serial.println(WIFI_AP);
  273.       // Connect to WPA/WPA2 network
  274.       status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
  275.       delay(500);
  276.     }
  277.     Serial.println("[Loop] Connected to AP");
  278.   }
  279.  
  280.   if (!tb.connected())
  281.   {
  282.     reconnect();
  283.   }
  284.   Time_current = millis();
  285.   if (Time_current >= (Time_secondLoop + 1000)) // every second do...
  286.   {
  287.     Time_secondLoop = Time_current; // Updates Time_secondLoop
  288.     calcliters();
  289.     runtime++;
  290.   }
  291.   if (Time_current >= (Time_minuteLoop + 1000UL*60)) // every minute do...
  292.   {
  293.     Time_minuteLoop= Time_current; // Updates Time_minuteLoop
  294.     // if time to water
  295.     if(mincounter%timebetweenwatering==0)
  296.     {
  297.       startcounter=mincounter;
  298.       watering=true;
  299.       attachInterrupt(digitalPinToInterrupt(IO_flowsensorPin), flow, RISING); // Setup Interrupt
  300.       water(HIGH);
  301.     }
  302.     // if water, switch solenoids
  303.     if(watering)
  304.     {
  305.       int solsum=0;
  306.       int i=0;
  307.       if(mincounter==(startcounter))
  308.         solenoids(IO_[i]);
  309.       for(;i<SOL_NUM;i++)
  310.       {
  311.         solsum=solsum+solenoidtouse[i];
  312.         if(mincounter==(startcounter+solsum*timetowater))
  313.         {
  314.           solenoids(IO_[i+1]);
  315.           // if all solenoids done, turn water off
  316.           if(i+1==SOL_NUM)
  317.           {
  318.             water(LOW);
  319.             detachInterrupt(digitalPinToInterrupt(IO_));
  320.             watering=false;
  321.           }
  322.         }
  323.       }
  324.     }
  325.     mincounter++;
  326.   }
  327.   if (Time_current >= (Time_logLoop + logduration * 1000UL)) // every logduration do
  328.   {
  329.     Time_logLoop = Time_current;
  330.     // Log LiterTotal
  331.     dtostrf(ml_total / 1000.0, 0, 2, outstr);
  332.     SendCommand(makejson("LiterTotal","d",outstr),false,"loop");
  333.     // Log LiterAVG(logduration)
  334.     sprintf(outstr, "%d", logduration);
  335.     char buildStr1[50]="LiterAVG(";
  336.     char buildStr2[10]="";
  337.     itoa(logduration, buildStr2, 10);
  338.     strcat(buildStr1, buildStr2);
  339.     strcat(buildStr1,")");
  340.     dtostrf((ml_total - ml_total_old) / logduration / 1000.0 * 3600, 0, 2, outstr);
  341.     SendCommand(makejson(buildStr1, "d", outstr),true,"loop");
  342.     ml_total_old = ml_total;
  343.   }
  344.     tb.loop();
  345. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×