莊志男
Published

MEGA2560, ESP8266 control water pump by wifi, thinkspeak IoT

Most families and buildings are used to reserve water by water tank and refill water by water pump in Taiwan.

IntermediateProtip1,985
MEGA2560, ESP8266 control water pump by wifi, thinkspeak IoT

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
ESP8266 ESP-01
Espressif ESP8266 ESP-01
×1
High Accuracy Pi RTC (DS3231)
Seeed Studio High Accuracy Pi RTC (DS3231)
×1
Solid State Relay
Solid State Relay
×1
AJ-SR04M Arduino Distance Measuring Transducer Sensor
×2
flow meter, FS400A G1"
×1
Current Transformer
×1
Ethernet Cable, Cat6
Ethernet Cable, Cat6
×1
Plastic Enclosure, Precision Miniature Case
Plastic Enclosure, Precision Miniature Case
×1
Ac to DC 9V switching adaptor
×1
Custom PCB
Custom PCB
×1
MicroSD Card with Adapter
Digilent MicroSD Card with Adapter
×1
Flash Memory Card, MicroSD Card
Flash Memory Card, MicroSD Card
×1

Software apps and online services

Arduino IDE
Arduino IDE
Android Studio
Android Studio

Hand tools and fabrication machines

Cable Cutter, 143mm
Cable Cutter, 143mm
Drill / Driver, Cordless
Drill / Driver, Cordless
Breadboard, Plastic
Breadboard, Plastic
Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Schematics

pump1.jpg

pump

Code

water_tower_hackster.ino

Arduino
// This is a water pump and tank monitoring, controlling and record circuit by ChihNan Chuang written
// Most functions were from open or Arduino examples using Arduino MEGA 2560 board
// ,Arduino,MEGA 2560
// AT version: 1.1.0.0(May 11 2016)
//
// < hall-effect flow sensor outputs approximately >
//   FS400A-G1    4.8 pulses per second (per litre/minute of flow).
//   FS400A-G3/4  6.0 pulses per second (per litre/minute of flow).
//
// < HC-SR04 >
//   3mm, 2~450cm
//    c = 331.5 + 0.607 * t ( t )
//   20 331.5 + 0.607*20 = 343.64 /
//   /  /343.64 * 100 / 1000000 = 0.034364 /
//   29.1 1 / 0.034364 = 29.1 /
//    = /2 , 29.1 /
//
// < Micro SD card module for Mega 2560 >
//   DIO pin 50: MISO
//   DIO pin 51: MOSI
//   DIO pin 52: SCK
//   DIO pin 53: CS
//   Vcc: 3.3~5V
//   GND: 0V
//
// < Important modification >
//   C:\Users\user\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\cores\arduino\HardwareSerial.h
//   Change: __#define SERIAL_TX_BUFFER_SIZE 64
//           __#define SERIAL_RX_BUFFER_SIZE 64
//   To:     __#define SERIAL_TX_BUFFER_SIZE 256
//           __#define SERIAL_RX_BUFFER_SIZE 256
//
// < alarm_code >
//    0: ,,
//    1: ,
//    2: ,
//    3: ,
//    4: ,,,
//    5: ,
//    6: ,,
//    7: ?,,
//    8: ,,
//    9: ,,,
//   10: ,,
//   11: ?,,
//   12: ?,,
//   13: ?,,
//   14: ,,;,
//       ,,
//   15: ,,;,
//       wifi,,
//   16: ,,;,
//   17: ,,;,
//       ,,
//   18: 1?cm,
//   19: 1?cm
//   20: 1?cm
//   21: 10cm,
//   22: 2?cm,
//   23: 2?cm
//   24: 2?cm
//   25: 20cm,
//   26: ?/,
//   27: ,,,<>,
//       
//
// < warning code(not use yet) >
//   28: ?A,
//   29: ?A,
//   *****

#include <SoftwareSerial.h>                         // 
#include "EmonLib.h"                                // 
#include <Wire.h>                                   // I2C/TWI
#include <TimeLib.h>                                // 
#include <DS3231.h>                                 // DS2321 RTC
#include <SPI.h>                                    // SPI
#include <SD.h>                                     // MicroSD card

#define SERVER_PORT              80                 // server port
#define BAUDRATE                 115200             // 

EnergyMonitor                    emon;              // emon
DS3231                           rtc(SDA, SCL);     // Init the DS3231 using the hardware interface
File                             myFile;            // MicroSD card filename

double  Irms;                                       // Irms,
double  Irms_tmp;                                   // Irms,
double  I01                      = 0;               // 0
double  I02                      = 0;               // 1
double  I03                      = 0;               // 2
double  I1                       = 0;               // ?
double  I2                       = 0;               // ?
int     CT_IN                    = 15;              // A15, CT, Irms
int     FLOWMETER_IN             = 31;              // D31, 
int     TRIG1_OUT                = 33;              // D33, 1Trig1
int     ECHO1_IN                 = 35;              // D35, 1Echo1
int     TRIG2_OUT                = 37;              // D37, 2Trig2
int     ECHO2_IN                 = 39;              // D39, 2Echo2
int     SSR_PUMP_IN              = 41;              // D41,  
int     SSR_PUMP_OUT             = 43;              // D43, 
int     SSR_TANK1_IN             = 45;              // D45, 1
int     SSR_TANK1_OUT            = 47;              // D47, 1
int     CHIPSELECT               = 53;              // D53, SD cardCS

float   CT_FACTOR                = 10;              // 10
float   CURRENT_0                = 0.4;             // 0.4,CT (A)
float   CURRENT_WATERFLOW        = 4.0;             // 4.0, (A)
float   CURRENT_TOLERANCE        = 0.5;             // 0.5,,  (A)
int     PUMP_CURRENT_SHUTDOWN    = 5;               // 5,(),0
int     TANK1_DRUM_HEIGHT        = 10;              // 120,1 (cm)
int     TANK2_DRUM_HEIGHT        = 10;              // 100,2 (cm)
int     TANK1_DRUM_CIRCUMFERENCE = 0;               // 351,1 (cm)
int     TANK2_DRUM_CIRCUMFERENCE = 0;               // 285,2 (cm)
int     TANK1_SONIC_TO_0         = 10;              // 130,1 (cm)
int     TANK2_SONIC_TO_0         = 10;              // 110,2 (cm)
int     TANK1_MAX_LEVEL          = 20;              // 95,1max (cm)
int     TANK1_MIN_LEVEL          = 10;              // 77,1min (cm)
int     TANK2_MAX_LEVEL          = 20;              // 54,2max (cm)
int     TANK2_MIN_LEVEL          = 10;              // 36,2min (cm)
int     FLOAT_BALL_FAILED        = 5;               // 5, (cm)
int     LEVEL_SENSOR_FAILED      = 5;               // 5, (cm)
int     LOW_FLOW                 = 8;               // 8, (L/min)
int     PUMP_WATER_SHUTDOWN      = 20;              // 20,(),0
float   FLOW_METER_FACTOR        = 6.00;            // 6.00,FS300A G3/4" -> 1 L/min = 5.5 pulse/sec, set 6.00
                                                    // 4.60,FS400A G1"   -> 1 L/min = 4.8 pulse/sec, set 4.60
int     AC_POWER                 = 110;             // 110, (V)
int     PUMP_AUTO_SHUTDOWN       = 60;              // 90, (min)
int     ENFORCE_REFILL           = 30;              // 60,, (min)

boolean first_coming             = false;           // Arduino1?
boolean FAIL_ESP8266             = true;            // ESP8266?
boolean link_status              = true;            // Wifi?
int     CONNECTION_ID;                              // ID
int     wifitimes                = 8;               // wifi
String  esp8266_ap               = "";              // ESP8266 AP IP
String  esp8266_sta              = "";              // ESP8266 STA IP
String  account[2];                                 // [0]home_AP_SSID & [1]home_AP_PASSWORD
String  feedback                 = "";              // 
String  home_AP_SSID             = "";              // esp8266 as STA default
String  home_AP_PASSWORD         = "";              // esp8266 as STA default
char    soft_AP_SSID[]           = "WATER_PUMP_0";  // esp8266 as AP default
char    soft_AP_PASSWORD[]       = "12345678";      // esp8266 as Ap default
char    wifi_ap[16];                                // AP IP, 16

int     average_flow_count       = 0;               // 
float   average_flow             = 0;               // 
float   total_pipe_flow          = 0;               // ,
float   pipe_flow                = 0;               // 

boolean water_low_alarm          = false;           // ,false
boolean current_alarm            = false;           // alarm,false
boolean pump_start_moment        = false;           // ( -> 0A)
boolean pump_stop_moment         = false;           // (0A -> )
int     current_fault            = 0;               // alarm? (0) (1) (2)
int     water_alarm_min          = 0;               // x
int     water_alarm_sec          = 0;               // x
int     water_alarm_sec_0        = 0;               // 
int     current_alarm_sec        = 0;               // alarmx
int     pump_start_min           = 0;               // x
int     pump_start_sec           = 0;               // x
int     pump_start_sec_0         = 0;               // 
int     total_refill             = 0;               // 
int     refill_stop_count        = 0;               // 
float   tank1_drum_scale;                           // 1(/)
float   tank2_drum_scale;                           // 2(/)
float   tank1_cm                 = 0;               // 1(cm)
float   tank2_cm                 = 0;               // 2(cm)
float   tank1_last_height1       = 0;               // 1
float   tank1_last_height2       = 0;               // 1
float   tank2_last_height1       = 0;               // 2
float   tank2_last_height2       = 0;               // 2
float   tank1_last_height1_pre   = 0;               // 1
float   tank2_last_height1_pre   = 0;               // 2

String  now_time                 = "";              // 
String  pump_last_start_time     = "";              //  ()
int     refill_mode              = 0;               // -> 0: 1:
int     ssr_state                = 1;               // SSR -> (0)  (1) (2) (3)
int     alarm_code_send          = 0;               // 
int     alarm_code_send_last     = 0;               // 

int     amper_start              = 0;               // 1,?
int     amper_start_count        = 0;               // counter
int     current_max_count        = 60;              // ?
int     current_pre_count        = 33;              // ?
int     amper[60];                                  // 0
int     pre_amper[33];                              // ?0
int     pump_max_count           = 60;              // ?,
String  pump_records[60];                           // ,xx
int     alarm_max_count          = 30;              // ?
int     alarm_code[30];                             // ?
String  alarm_time[30];                             // ?
int     wait_tank_ssr_time       = 0;               // SSR

unsigned long millis_end_time = 4294967295;         // millis(),0,4917247.295
unsigned long pump_start;                           // ,(ms)
unsigned long pump_start_ms;                        // ,
unsigned long waterflow_start_alarm_ms;             // 
unsigned long waterflow_start_alarm;                // 
unsigned long current_start_alarm_ms;               // alarm
unsigned long current_start_alarm;                  // alarm


void setup() {
  String  cmd, number[22];
  char    c;
  int     i, Num;
  boolean x = false, xx = false;
  
  Serial.begin(BAUDRATE);              // Arduino MEGA 2560 RX0<-(pin 0)/TX0->(pin 1)
  Serial1.begin(BAUDRATE);             // ESP8266, ESP8266 TX/RX  RX1(pin 19)/TX1(pin 18)
  rtc.begin();                         // DS2321 RTC
  
  pinMode(SSR_PUMP_OUT,     OUTPUT);   // SSRpin
  pinMode(SSR_PUMP_IN,       INPUT);   // SSRpin
  pinMode(SSR_TANK1_OUT,    OUTPUT);   // ssr_tank1pin
  pinMode(SSR_TANK1_IN,      INPUT);   // ssr_tank1pin
  pinMode(TRIG1_OUT,        OUTPUT);   // Trig1pin
  pinMode(ECHO1_IN,          INPUT);   // Echo1pin
  pinMode(TRIG2_OUT,        OUTPUT);   // Trig2pin
  pinMode(ECHO2_IN,          INPUT);   // Echo2pin
  pinMode(FLOWMETER_IN,      INPUT);   // pin
  digitalWrite(SSR_PUMP_OUT,  HIGH);   // SSRpinHIGH
  delay(300);
  digitalWrite(SSR_TANK1_OUT,  LOW);   // SSRpinLOW
  delay(300);

  // Recall pump constant from MicroSD card
  Serial.print("Initializing SD card... ");
  if (!SD.begin(53)) Serial.println("failed!");
                else Serial.println("done.");
  delay(200);

  if (SD.exists("constant.txt")) {
    for (i = 0; i < 22; i++) number[i] = "";
    i = 0;

    myFile = SD.open("constant.txt");
    if (myFile) {
      // read from the file until there's nothing else in it:
      while (myFile.available()) {
        c = myFile.read();
        Serial.write(c);
        if (c != '\r') number[i] += c;
           else {
             c = myFile.read();
             Serial.write(c);
             i++;
        }
      }
      // close the file:
      myFile.close();
    } else {
    // if the file didn't open, print an error:
    Serial.println("error opening constant.txt");
    }
    
    CT_FACTOR                 = number[0].toFloat();
    CURRENT_0                 = number[1].toFloat();
    CURRENT_WATERFLOW         = number[2].toFloat();
    CURRENT_TOLERANCE         = number[3].toFloat();
    PUMP_CURRENT_SHUTDOWN     = number[4].toInt();
    TANK1_DRUM_HEIGHT         = number[5].toInt();
    TANK2_DRUM_HEIGHT         = number[6].toInt();
    TANK1_DRUM_CIRCUMFERENCE  = number[7].toInt();
    TANK2_DRUM_CIRCUMFERENCE  = number[8].toInt();
    TANK1_SONIC_TO_0          = number[9].toInt();
    TANK2_SONIC_TO_0          = number[10].toInt();
    TANK1_MAX_LEVEL           = number[11].toInt();
    TANK1_MIN_LEVEL           = number[12].toInt();
    TANK2_MAX_LEVEL           = number[13].toInt();
    TANK2_MIN_LEVEL           = number[14].toInt();
    FLOAT_BALL_FAILED         = number[15].toInt();
    LEVEL_SENSOR_FAILED       = number[16].toInt();
    LOW_FLOW                  = number[17].toInt();
    PUMP_WATER_SHUTDOWN       = number[18].toInt();
    FLOW_METER_FACTOR         = number[19].toFloat();
    PUMP_AUTO_SHUTDOWN        = number[20].toInt();
    ENFORCE_REFILL            = number[21].toInt();
    
    Serial.print(String(CT_FACTOR,1)              + " " + String(CURRENT_0,1)              + " ");
    Serial.print(String(CURRENT_WATERFLOW,1)      + " " + String(CURRENT_TOLERANCE,1)      + " ");
    Serial.print(String(PUMP_CURRENT_SHUTDOWN)    + " ");
    Serial.print(String(TANK1_DRUM_HEIGHT)        + " " + String(TANK2_DRUM_HEIGHT)        + " ");
    Serial.print(String(TANK1_DRUM_CIRCUMFERENCE) + " " + String(TANK2_DRUM_CIRCUMFERENCE) + " ");
    Serial.print(String(TANK1_SONIC_TO_0)         + " " + String(TANK2_SONIC_TO_0)         + " ");
    Serial.print(String(TANK1_MAX_LEVEL)          + " " + String(TANK1_MIN_LEVEL)          + " ");
    Serial.print(String(TANK2_MAX_LEVEL)          + " " + String(TANK2_MIN_LEVEL)          + " ");
    Serial.print(String(FLOAT_BALL_FAILED)        + " " + String(LEVEL_SENSOR_FAILED)      + " ");
    Serial.print(String(LOW_FLOW)                 + " " + String(PUMP_WATER_SHUTDOWN)      + " ");
    Serial.print(String(FLOW_METER_FACTOR,2)      + " ");
    Serial.print(String(PUMP_AUTO_SHUTDOWN)       + " " + String(ENFORCE_REFILL));
  } else {
    // open a new file and immediately close it:
    Serial.println("Creating constant.txt...");
    myFile = SD.open("constant.txt", FILE_WRITE);
    myFile.close();
    
    // delete the file:
    Serial.println("Removing constant.txt...");
    SD.remove("constant.txt");

    // save pump constant for the first time
    myFile = SD.open("constant.txt", FILE_WRITE);
    // if the file opened okay, write to it:
    if (myFile) {
      Serial.print("Writing to constant.txt... ");
      myFile.println(CT_FACTOR);
      myFile.println(CURRENT_0);
      myFile.println(CURRENT_WATERFLOW);
      myFile.println(CURRENT_TOLERANCE);
      myFile.println(PUMP_CURRENT_SHUTDOWN);
      myFile.println(TANK1_DRUM_HEIGHT);
      myFile.println(TANK2_DRUM_HEIGHT);
      myFile.println(TANK1_DRUM_CIRCUMFERENCE);
      myFile.println(TANK2_DRUM_CIRCUMFERENCE);
      myFile.println(TANK1_SONIC_TO_0);
      myFile.println(TANK2_SONIC_TO_0);
      myFile.println(TANK1_MAX_LEVEL);
      myFile.println(TANK1_MIN_LEVEL);
      myFile.println(TANK2_MAX_LEVEL);
      myFile.println(TANK2_MIN_LEVEL);
      myFile.println(FLOAT_BALL_FAILED);
      myFile.println(LEVEL_SENSOR_FAILED);
      myFile.println(LOW_FLOW);
      myFile.println(PUMP_WATER_SHUTDOWN);
      myFile.println(FLOW_METER_FACTOR);
      myFile.println(PUMP_AUTO_SHUTDOWN);
      myFile.println(ENFORCE_REFILL);
      // close the file:
      myFile.close();
      Serial.println("done.");
    } else {
      // if the file didn't open, print an error:
      Serial.println("error opening constant.txt");
    }
  }
  
  for (int i = 0; i < pump_max_count; i++)
    pump_records[i] = "***";                            // ***

  for (int i = 0; i < alarm_max_count; i++) {
    alarm_time[i] = "*******************";              // ,19*
    alarm_code[i] = 0;                                  // ,0
  }

  for (int i = 0; i < current_max_count; i++) amper[i] = 0;      // 00
  for (int i = 0; i < current_pre_count; i++) pre_amper[i] = 0;  // 00
  
  emon.current(CT_IN, CT_FACTOR);                       // CT,   

  do {
    while (FAIL_ESP8266 == true)  startWiFi_AP();       // WiFi
    if (link_status == true) {
      feedback = esp8266_ap + "^" + esp8266_sta + "\r\n";
      Serial.print("esp8266 AP/STA IP = ");
      Serial.println(feedback);
      CIP_Close();
    } else {
        Serial.println("Wifi link_failed, retry...");
        FAIL_ESP8266 = true;                            // WiFi
    }
  } while (FAIL_ESP8266 == true);
}


void loop() {
  Do_Routing();                                         // , Irms
  receive_from_mobile();                                // Arduino
}


// WiFi
void startWiFi_AP() {
  char    c;
  String  s, cmd, AP_cmd;
  int     i, Num;
  boolean x = false, NG = false;;

  esp8266_ap = "";

  Serial.println("\r\nAT+RST");
  Serial1.println("AT+RST");                            // ESP8266
  do {
    delay(3000);
    while (!Serial1.available());
    if (Serial1.find("OK")) {                           // AP?
      delay(200);
      s = Serial_feedback(100,1);
      
      Serial1.println("AT+GMR");                        // ESP8266
      delay(300);
      s = Serial_feedback(100,1);
      
      Serial1.println("AT+CWMODE=3");                   // station+AP
      delay(300);
      s = Serial_feedback(100,1);

      Serial1.println("AT+CIPMUX=1");                   // 
      delay(300);
      s = Serial_feedback(100,1);
      
      cmd = "AT+CIPSERVER=1," + String(SERVER_PORT);
      serial_send(cmd,500);                             // SERVER
      
      AP_cmd  = "AT+CWSAP=\"";
      AP_cmd += soft_AP_SSID;                           // AP
      AP_cmd += "\",\"";
      AP_cmd += soft_AP_PASSWORD;                       // AP
      AP_cmd += "\",";
      AP_cmd += "1";                                    // AP
      AP_cmd += ",";
      AP_cmd += "3";                                    // AP
      Serial1.println(AP_cmd);                          // ESPAP
      delay(100);
      s = Serial_feedback(100,1);
      
      Serial.println("AT+CIPAP?");
      Serial1.println("AT+CIPAP?");                     // APIP
      delay(100);
      
      while (!Serial1.available());
      if (Serial1.find("+CIPAP:ip:\"")) {               // STA?
        delay(100);
        
        c = Serial1.read();
        do {
          if (((c >= '0') && (c <= '9')) || (c == '.')) esp8266_ap += c;
          c = Serial1.read();
        } while (c != '\"');
        Serial.print("+CIPAP:ip:\"");
        Serial.print(esp8266_ap + "\"");
        delay(100);
        while (!Serial1.available());
        do {
          c = Serial1.read();
          Serial.write(c);
        } while (Serial1.available());
        Serial.println("\r\n");
      }
      delay(100);
      s = Serial_feedback(100,1);

      Serial.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
      Serial.print("ESP8266 AP IP address = ");
      Serial.println(esp8266_ap);
      Serial.println("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n");

      do {
        while (!Serial1.available());                   // ESP8266?
        if (Serial1.find("+IPD,")) {                    // ESP8266
          Serial.print("+IPD,");
          delay(100);

          x = true;
          c = Serial1.read();
          Serial.print(c);
          CONNECTION_ID = c - '0';                        // ID
          if ((CONNECTION_ID < 0) || (CONNECTION_ID > 4)) {
            NG = true;
            Serial.println("CONNECTION_ID error!");
          }

          c = Serial1.read();                             // ,
          Serial.print(c);

          c = Serial1.read();                             // total number of characters
          Serial.print(c);
          if ((c < '1') || (c > '9')) {
            NG = true;
            Serial.println("The first number error!");
          }
          c = Serial1.read();
          Serial.print(c);
          if (c != ':') {
            if ((c < '0') || (c > '9')) {
              NG = true;
              Serial.println("The second number error!");
            }
            c = Serial1.read();
            Serial.print(c);
            if (c != ':') {
              if ((c < '0') || (c > '9')) {
                NG = true;
                Serial.println("The third number error!");
              }
            }
          }

          c = Serial1.read();
          Serial.print(c);
          if (c != 'p') NG = true;
          c = Serial1.read();
          Serial.print(c);
          if (c != 'u') NG = true;
          c = Serial1.read();
          Serial.print(c);
          if (c != 'm') NG = true;
          c = Serial1.read();
          Serial.print(c);
          if (c != 'p') NG = true;

          Num = Serial1.read() - '0';                     // pump ID
          Serial.print(Num);
          Serial1.read();                                 // space
          if (Num != 0) NG = true;

          if (Num == 0) {
            account[0] = "";
            account[1] = "";
            i = 0;
            Serial.print(" ");
            c = Serial1.read();
            while ((c != '~') && (i < 2)) {
              Serial.write(c);
              if (c != '^') { account[i] += c; }
                else { i++; }
              c = Serial1.read();
            }
            Serial.print("\n");

            home_AP_SSID     = account[0];
            home_AP_PASSWORD = account[1];

            if (NG == true) {
              home_AP_SSID     = "Transfer";
              home_AP_PASSWORD = "error!";
            }

            Serial.println("home_AP_SSID     = " + home_AP_SSID);
            Serial.println("home_AP_PASSWORD = " + home_AP_PASSWORD);
          }
        }
      } while (x == false);
    
      if (Num == 0) {
        if (connectWiFi_STA(wifitimes)) {                    // WIFI?
          FAIL_ESP8266 = false;                              // WIFI
          link_status  = true;
        } else {
            Serial.println(">>> connect WiFi Fail <<<\r\n"); // WIFI
            FAIL_ESP8266 = false;
            link_status  = false;
        }
      }
    } else {
        Serial.println(">>> Module has't response <<<");     // ESP8266
        FAIL_ESP8266 = false;
        link_status  = false;
    }
  } while (FAIL_ESP8266);                               // ,
}


// WIFI
boolean connectWiFi_STA(int time_out) {
  String cmd, AP_cmd, s;
  char   c;
  int    i, n, t = time_out;
  long   t0, t1;

  cmd  = "AT+CWJAP=\"";
  cmd += home_AP_SSID;                                  // 
  cmd += "\",\"";
  cmd += home_AP_PASSWORD;                              // 
  cmd += "\"";
  Serial.println("\n" + cmd);
    
  do {
    Serial.println(cmd);
    Serial1.println(cmd);                               // AP
    delay(100);
    
    t1 = 0;
    do {
      t0 = millis();
      while (!Serial1.available()) {
        t1 = millis() - t0;
        if (t1 < 0) t1 += millis_end_time;              // millis() overflow
        if (t1 > 3000) t1 = -1;
      }
    } while ((!Serial1.available()) && (t1 != -1));
    
    esp8266_sta = "";
    if (Serial1.find("OK")) {                           // AP?
      delay(100);
      Serial.println("Join AP OK\r\n");
      
      Serial1.println("AT+CIPSTA?");                    // STA IP
      if (Serial1.find("+CIPSTA:ip:\"")) {              // STA?
        delay(100);
        
        c = Serial1.read();
        do {
          if (((c >= '0') && (c <= '9')) || (c == '.')) esp8266_sta += c;
          c = Serial1.read();
        } while (c != '\"');
        
        Serial.print("+CIPSTA:ip:\"");
        Serial.print(esp8266_sta + "\"");
        delay(100);
        while (!Serial1.available());
        do {
          c = Serial1.read();
          Serial.write(c);
        } while (Serial1.available());
        Serial.println("\r\n");
        delay(100);
      }
      
      for (i = 0; i < esp8266_sta.length(); i++) {
            wifi_ap[i] = esp8266_sta.charAt(i);
      }
          wifi_ap[esp8266_sta.length()+1] = '\0';
      Serial.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
      Serial.println("ESP8266 STA IP address = " + esp8266_sta);
      Serial.println("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n");
      return true;                                      // WIFI
    }
    Serial.print("Trying to connect to AP #");
    Serial.println(t - time_out + 1);
  } while ((time_out--) > 0);
  return false;                                         // WIFI
}


// Arduino
void receive_from_mobile() {
  char    c;
  String  cmd;
  boolean NG = false;
  
  //receive_start       = millis();                     // 
  //mobile_running_time = receive_start - send_start;
  //if (mobile_running_time < 0) mobile_running_time += millis_end_time;             // millis() overflow
  //Serial.println("-------------------------------------------------------------");
  //Serial.print("mobile_running_time = ");
  //Serial.println(mobile_running_time);
  //Serial.println("-------------------------------------------------------------");
  
  if (Serial1.available()) {                            // ESP8266?
    if (Serial1.find("+IPD,")) {                        // ESP8266
      
      if (first_coming  == false) {
        first_coming = true;
      }      
      
      Serial.print("+IPD,");
      delay(100);
      
      c = Serial1.read();
      Serial.print(c);
      CONNECTION_ID = c - '0';                          // ID
      if ((CONNECTION_ID < 0) || (CONNECTION_ID > 4)) {
        NG = true;
        Serial.println("CONNECTION_ID error!");
      }
      
      c = Serial1.read();                               // ,
      Serial.print(c);

      c = Serial1.read();                               // total number of characters
      Serial.print(c);
      if ((c < '1') || (c > '9')) {
        NG = true;
        Serial.println("The first number error!");
      }
      
      c = Serial1.read();
      Serial.print(c);
      if (c != ':') {
        if ((c < '0') || (c > '9')) {
          NG = true;
          Serial.println("The second number error!");
        }
        
        c = Serial1.read();
        Serial.print(c);
        if (c != ':') {
          if ((c < '0') || (c > '9')) {
            NG = true;
            Serial.println("The third number error!");
          }
        }
      }
      
      c = Serial1.read();
      Serial.print(c);
      if (c != 'p') NG = true;
      c = Serial1.read();
      Serial.print(c);
      if (c != 'u') NG = true;
      c = Serial1.read();
      Serial.print(c);
      if (c != 'm') NG = true;
      c = Serial1.read();
      Serial.print(c);
      if (c != 'p') NG = true;
      
      int Num = Serial1.read() - '0';                   // pump ID
      Serial.print(Num);
      Serial1.read();                                   // space
      if ((Num < 0) || (Num > 7)) NG = true;
      if (NG == false) {
        if (Num == 0) pump_data0(); // wifi
        if (Num == 1) pump_data1(); // Arduinoon/off,,
        if (Num == 2) pump_data2(); // Arduino
        if (Num == 3) pump_data3(); // Arduino
        if (Num == 4) pump_data4(); // Arduino
        if (Num == 5) pump_data5(); // Arduino alarm
        if (Num == 6) pump_data6(); // Arduino current
        if (Num == 7) pump_data7(); // Arduino ?
      } else {
          Serial.println("Miss data while transferring...");
          feedback = "NG\r\n";                          // NG
          CIP_Close();
      }
    }
  } 
}


// wifi
void pump_data0() {

}


// on/off,,
void pump_data1() {

}


// 
void pump_data2() {

}


// 
void pump_data3() {

}


// 
void pump_data4() {

}


// Alarm
void pump_data5() {

}


// Arduino current
void pump_data6() {

}


 // Arduino ?
 void pump_data7() {

}

 
// CIPCLOSE function
void CIP_Close() {
  String  cmd;
  
  cmd  = "AT+CIPSEND=";                        // ESP8266
  cmd += CONNECTION_ID;
  cmd += ",";
  cmd += feedback.length();                    // 
  serial_send(cmd,20);                         // ESP8266
  Serial.println(feedback);
  Serial1.println(feedback);
  delay(300);

  cmd = "AT+CIPCLOSE=";
  cmd += CONNECTION_ID; 
  cmd += "\r\n";
  Serial1.println(cmd);
  delay(100);

  //send_start               = millis();         // 
  //receive_from_mobile_time = send_start - receive_start;
  //if (receive_from_mobile_time < 0) receive_from_mobile_time += millis_end_time;   // millis() overflow
  //Serial.println("-------------------------------------------------------------");
  //Serial.print("receive_from_mobile_time = ");
  //Serial.println(receive_from_mobile_time);
  //Serial.println("-------------------------------------------------------------");
}


// Serial1
String Serial_feedback(long t, long dt) {
  int    n,  i = 1;
  long   t0, t1 = 0;
  char   c;
  String s = "";

  do {
    t0 = millis();
    while ((!Serial1.available()) && (t1 != -1)) {
    t1 = millis() - t0;
    if (t1 < 0) t1 += millis_end_time;     // millis() overflow
    if (t1 > t) t1 = -1;
    }
    delay(dt);
    
    if ( t1 != -1) {
      n = Serial1.available();
      Serial.println("----- (" + String(i) + ") => " + String(n) + " -----");
      
      do {
        c = Serial1.read();
        if (((c >= ' ') && (c <= '~')) || (c == '\r') || (c == '\n')) {
          Serial.write(c);
          s += String(c);
        }
      } while (Serial1.available());
      
    }
    i++;
    Serial.println("\r");
    if (i > 20) t1 = -1;
  } while (t1 != -1);
  
  Serial.println("\r\n--------- END ---------\n");
  return s;
}


// Serial1
void serial_send(String information, int waitTime) {
  char c;
  Serial1.println(information);
  delay(waitTime);
  
  while (!Serial1.available());                                    // Serial1?
  while (Serial1.available()) {                                    // Serial1?
    c = Serial1.read();                                            // 
    if (((c >= ' ') && (c <= '~')) || (c == '\r') || (c == '\n'))
        { Serial.write(c); }                                       // Arduino
  }
}


// , 3,,
void Do_Routing() {
  int   i, swap;
  int   w1, w2, wt;
  float duration1, duration2;                  // 
  float distance1, distance2;                  // cm

  //unsigned long Do_Routing_start = millis();   // Do_Routing()
  
  Start_Stop();
  I01 = Irms;                                  // 3,1
  
  Get_Waterflow();                             // 

  Start_Stop();
  I02 = Irms;                                  // 3,2
  
  if ((digitalRead(SSR_PUMP_IN) == HIGH) && (Irms == 0)) ssr_state = 0;
  
// 2
  digitalWrite(TRIG1_OUT, HIGH);               // Trig120
  delayMicroseconds(20);
  digitalWrite(TRIG1_OUT, LOW);
  duration1 = pulseIn (ECHO1_IN, HIGH);        // echo1,
  distance1 = (duration1/2)/29.1;              // 1
  //Serial.println("distance1 = " + String(distance1));

  //unsigned long Do_Routing_half_time = millis() - Do_Routing_start;
  //if (Do_Routing_half_time < 0) Do_Routing_half_time += millis_end_time;  // millis() overflow
  //Serial.print("Do_Routing_half_time = ");
  //Serial.println(Do_Routing_half_time);
  
  digitalWrite(TRIG2_OUT, HIGH);               // Trig220
  delayMicroseconds(20);
  digitalWrite(TRIG2_OUT, LOW);
  duration2 = pulseIn (ECHO2_IN, HIGH);        // echo2,
  distance2 = (duration2/2)/29.1;              // 2
  //Serial.println("distance2 = " + String(distance2));
  
  tank1_cm         = TANK1_SONIC_TO_0 - distance1;                             // 1(cm)
  tank2_cm         = TANK2_SONIC_TO_0 - distance2;                             // 2(cm)
  tank1_drum_scale = (TANK1_DRUM_CIRCUMFERENCE * TANK1_DRUM_CIRCUMFERENCE)/(4 * 3.141592654 * 1000);
  tank2_drum_scale = (TANK2_DRUM_CIRCUMFERENCE * TANK2_DRUM_CIRCUMFERENCE)/(4 * 3.141592654 * 1000);

  Start_Stop();
  I03 = Irms;                                  // 3,3
  
  if ((I01 > 0) || (I02 > 0) || (I03 > 0)) {
    for (i = current_max_count - 1; i > 2; i--) amper[i] = amper[i - 3];
    amper[2]  = I01  * 100;
    amper[1]  = I02  * 100;
    amper[0]  = I03  * 100;
  }
  
  if ((amper_start == 1) && (amper_start_count <= current_max_count / 6)) {           // current_max_count/6+3
    pre_amper[amper_start_count * 3 + 2] = I01 * 100;
    pre_amper[amper_start_count * 3 + 1] = I02 * 100;
    pre_amper[amper_start_count * 3]     = I03 * 100;
    amper_start_count++;
  }
  
  if (TANK1_DRUM_CIRCUMFERENCE > 0) {
    // 1,
    if (tank1_cm <= 0) {
      tank1_cm = 0;
      alarm_code_send = 21;
      alarm_list(alarm_code_send);
    }

    // 1?cm,
    if ((tank1_cm > 0) && (tank1_cm <= (TANK1_MIN_LEVEL - LEVEL_SENSOR_FAILED))) {
      alarm_code_send = 20;
      alarm_list(alarm_code_send);
    }
  
    // 1?cm,
    if ((tank1_cm >= (TANK1_MAX_LEVEL + FLOAT_BALL_FAILED)) && (tank1_cm < TANK1_DRUM_HEIGHT)) {
      alarm_code_send = 19;
      alarm_list(alarm_code_send);
    }
  
    // 1,
    if (tank1_cm >= TANK1_DRUM_HEIGHT) {
      tank1_cm = TANK1_DRUM_HEIGHT;
      alarm_code_send = 18;
      alarm_list(alarm_code_send);
    }
  }

  if (TANK2_DRUM_CIRCUMFERENCE > 0) {
    // 2,
    if (tank2_cm <= 0) {
      tank2_cm = 0;
      alarm_code_send = 25;
      alarm_list(alarm_code_send);
    }

    // 2?cm,
    if ((tank2_cm > 0) && (tank2_cm <= (TANK2_MIN_LEVEL - LEVEL_SENSOR_FAILED))) {
      alarm_code_send = 24;
      alarm_list(alarm_code_send);
    }
  
    // 2?cm,
    if ((tank2_cm >= (TANK2_MAX_LEVEL + FLOAT_BALL_FAILED)) && (tank2_cm < TANK2_DRUM_HEIGHT)) {
      alarm_code_send = 23;
      alarm_list(alarm_code_send);
    }
  
    // 2,
    if (tank2_cm >= (TANK2_DRUM_HEIGHT)) {
      tank2_cm = TANK2_DRUM_HEIGHT;
      alarm_code_send = 22;
      alarm_list(alarm_code_send);
    }
  }
  
  // ,,,
  if ((pump_start_min >= ENFORCE_REFILL) && (Irms > 0) && (ssr_state == 3)) {
      Get_Irms();
      Irms_tmp = Irms;
      digitalWrite(SSR_TANK1_OUT, LOW);
      delay(300);
      Get_Irms();
      if ((Irms / 2) < Irms_tmp) {
        alarm_code_send    = 7;
        ssr_state          = 1;
        alarm_list(alarm_code_send);
      }
    }
  
  // ,,,
  if (((tank1_cm >= TANK1_MAX_LEVEL) && (TANK1_DRUM_CIRCUMFERENCE > 0)) && (Irms > 0)
       && ((tank2_cm >= TANK2_MAX_LEVEL) && (TANK2_DRUM_CIRCUMFERENCE > 0)) && (ssr_state == 3)) {
    Get_Irms();
    Irms_tmp = Irms;
    digitalWrite(SSR_TANK1_OUT, LOW);
    delay(300);
    Get_Irms();
    if ((Irms / 2) < Irms_tmp) {
      alarm_code_send    = 6;
      ssr_state          = 1;
      alarm_list(alarm_code_send);
    }
  }

...

This file has been truncated, please download it to see its full contents.

parts of thinkspeak

Arduino
#define BAUDRATE         115200              // 

int     CONNECTION_ID   = 0;                // ID

String  WriteKey        = ""; 
String  ReadKey         = ""; 
long    ChannelID       = 0; 
int     FieldID         = 8;                // For readThinkSpeak field No.

int     SSR_PUMP_IN            = 41;              // D41,  
int     SSR_PUMP_OUT           = 43;              // D43, 
int     SSR_TANK1_IN           = 45;              // D45, 1
int     SSR_TANK1_OUT          = 47;              // D47, 1

float   tank1_cm         = 0;               // 1(cm)
float   tank2_cm         = 0;               // 2(cm)
double  Irms             = 0;               // Irms,
float   pipe_flow        = 0;               // 
int     pump_start_sec_0  = 0;               // 
int     Pump_Refill      = 0;                // 0:No action;  1:Press Pump switch;  2:Press Refill switch  9:thinkspeak


void setup() {
  Serial.begin(BAUDRATE);              // Arduino MEGA 2560 RX0<-(pin 0)/TX0->(pin 1)
  Serial1.begin(BAUDRATE);             // ESP8266, ESP8266 TX/RX  RX1(pin 19)/TX1(pin 18)
  
  pinMode(SSR_PUMP_OUT,     OUTPUT);   // SSRpin
  pinMode(SSR_PUMP_IN,       INPUT);   // SSRpin
  pinMode(SSR_TANK1_OUT,    OUTPUT);   // ssr_tank1pin
  pinMode(SSR_TANK1_IN,      INPUT);   // ssr_tank1pin
  digitalWrite(SSR_PUMP_OUT,  HIGH);    // SSRpinHIGH
  delay(300);
  digitalWrite(SSR_TANK1_OUT,  LOW);    // SSRpinLOW
  delay(300);
}


void loop() {
  int writeResult;                           // 0:write failed    1:write OK
  writeResult = writeThingSpeak();
  Pump_Refill = readThingSpeak(ChannelID, FieldID);
}


// write data to Thingspeak
int writeThingSpeak(void) {
  String cmd, getStr;
  int result;

  result = startThingSpeakCmd();
  if (result == 1) return result;

  getStr = "GET /update?api_key=";
  getStr += WriteKey;
  getStr +="&field1=";
  getStr += String(tank1_cm);
  getStr +="&field2=";
  getStr += String(tank2_cm);
  getStr +="&field3=";
  getStr += String(Irms);
  getStr +="&field4=";
  getStr += String(pipe_flow);
  getStr +="&field5=";
  getStr += String(pump_start_sec_0);
  getStr +="&field6=";
  getStr += String(digitalRead(SSR_PUMP_OUT));
  getStr +="&field7=";
  getStr += String(digitalRead(SSR_TANK1_OUT));
  getStr +="&field8=";    
  getStr += String(Pump_Refill);
  getStr += "\r\n";

  cmd = "AT+CIPSEND=";
  cmd += CONNECTION_ID;
  cmd += ",";
  cmd += String(getStr.length());

  Serial1.println(cmd);
  delay(200);
  while (!Serial1.available());
  delay(100);
  if (Serial1.find(">")) {
    delay(200);
    Serial.print(">");
    Serial.print(getStr);
    Serial1.print(getStr);
    delay(200);
    
    //  ThingSpeak IoT Server 
    while (!Serial1.available());
    delay(100);
    if (Serial1.find("OK")) {
       result     = 0;
       Serial.println("Write data to pi.thingspeak.com OK");
    }  else {
       Serial.println( "Write data to pi.thingspeak.com Error" );
       result = 3;
    }
  } else {
    Serial.println( "Find > Error" );
    result = 2;
  }

  Serial.print("Write = ");
  Serial.println(result);
  
  cmd = "AT+CIPCLOSE=";
  cmd += CONNECTION_ID; 
  cmd += "\r\n";
  Serial1.println(cmd);
  delay(100);
  
  return result;
}


// read data from Thingspeak
int readThingSpeak(uint32_t channel_id, uint8_t field_id) {
  String cmd, getStr;
  char c;
  int value = 0;
  
  if (startThingSpeakCmd() == 1) return value;
  
  getStr = "GET /channels/";
  getStr += channel_id;
  getStr += "/fields/" + String(field_id) + "/last.json?api_key=" + ReadKey + "&timezone=Asia/Taipei&results=1";
  getStr += "\r\n";

  cmd = "AT+CIPSEND=";
  cmd += CONNECTION_ID;
  cmd += ",";
  cmd += String(getStr.length());
  
  Serial1.println(cmd);
  delay(200);
  while (!Serial1.available());
  delay(200);
  if (Serial1.find(">")) {
    delay(100);
    Serial.print(">");
    Serial.print(getStr);
    Serial1.print(getStr);
    delay(200);
    
    //  ThingSpeak IoT Server 
    while (!Serial1.available());
    delay(200);
    if (Serial1.find("field8")) {
       delay(100);
       c = Serial1.read();
       Serial.write(c);
       c = Serial1.read();
       Serial.write(c);
       c = Serial1.read();
       Serial.write(c);
       c = Serial1.read();
       Serial.write(c);
       Serial.print("  ");
       value = c - 48;
       if (Serial1.find("CLOSED")) Serial.println("Read CLOSED");
       } else {
       Serial.println( "Find field8 Error" );
       }
    } else {
    Serial.println( "Find > Error" );
    }

  Serial.print("Read = ");
  Serial.println(value);

  cmd = "AT+CIPCLOSE=";
  cmd += CONNECTION_ID; 
  cmd += "\r\n";
  Serial1.println(cmd);

  return value;
}


//Start communication with ThingSpeak
int startThingSpeakCmd(void) {
  String cmd;
  int result;
  
  cmd  = "AT+CIPSTART=";
  cmd += CONNECTION_ID;
  cmd += ",";
  cmd += "\"TCP\",\"";
  cmd += "api.thingspeak.com";                       // IP "184.106.153.149"
  cmd += "\",80";
  
  Serial1.println(cmd);
  delay(100);
  while (!Serial1.available());
  delay(200);
  if (Serial1.find("OK")) {                          //  api.thingspeak.com?
     result = 0;
  }  else {
     result = 1;
     cmd = "AT+CIPCLOSE=";
     cmd += CONNECTION_ID; 
     cmd += "\r\n";
     Serial1.println(cmd);
     delay(200);
     }
  
  return result;
}

Credits

莊志男
2 projects • 0 followers
Technology is to create new life, not to destroy anything.

Comments