 }
 
 void stateSetup()
-{   
+{
   displaySetup();
 }
 


void displaySetup() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("T:");
  lcd.print(tempLimitPotValue);
  lcd.print("(");
  lcd.print(alertLevel);
  lcd.print(")          ");
  lcd.setCursor(0,1);
  lcd.print("H:");
  lcd.print(humLimitPotValue);
  lcd.print("(");

/**
 * Greenhouse-project
 * - monitor temperature and humidity. If temperature rises too high (or humidity), then open the window
 * - monitor also soil humidity
 * - send data to thingspeak every 10 minutes
 * - note the "state" is just state of display
 */
#include <SoftwareSerial.h>
#include <LiquidCrystal595.h>
#include <Servo.h>
#include <Wire.h>
#include <AM2320.h>
AM2320 th;

/**
   only print stuff to serial if DEBUG-build,
   disabling Serial frees alot of memory!
*/

#define DEBUG 0

#if (DEBUG > 0)
#define SERIAL_BEGIN(_sbaud)\
  Serial.begin(_sbaud);
#else
#define SERIAL_BEGIN(_sbaud)
#endif

#if (DEBUG > 0)
#define LOG_DEBUGLN(_log)\
  Serial.println(_log);
#define LOG_DEBUG(_log)\
  Serial.print(_log);
#else
#define LOG_DEBUGLN(_log)
#define LOG_DEBUG(_log)
#endif

#if (DEBUG > 1)
#define LOG_DEBUGLN2(_log)\
  Serial.println(_log);
#define LOG_DEBUG2(_log)\
  Serial.print(_log);
#else
#define LOG_DEBUGLN2(_log)
#define LOG_DEBUG2(_log)
#endif

//state handling
#define STATE_INITIAL   0
#define STATE_WORKING   1
#define STATE_SETUP     2
byte state = STATE_INITIAL;

//analog pin assignments
#define TEMP_POT_PIN     A0
#define HUM_POT_PIN      A1
#define MOIST_SENS1_PIN  A2

//digital pin assignments
#define LCDPIN1       2
#define LCDPIN2       3
#define LCDPIN3       4
#define BTNPIN        5
#define SERVOPIN      10
#define SSERIALTX     11  //to RX on ESP-05
#define SSERIALRX     12  //to TX on ESP-05
#define ESPRESETPIN   13

// The baud rate of the serial interface
#define SERIAL_BAUD  9600
#define ESP8266_BAUD 9600

//global variables
int8_t  maxC = 125, minC = -125;
float   tempSensorValue = 0;
uint8_t tempLimitPotValue = 0;
float   humSensorValue = 0;
uint8_t humLimitPotValue = 0;
uint8_t buttonState = LOW;
uint8_t alertLevel  = 30;
uint8_t humLevel = 80;
uint8_t wifiCheckCntr = 0;
boolean hatchOpen = false;
uint8_t updateValuesCntr = 0;
uint8_t moisture = 100;

unsigned long lastConnectionTime = 0;
const unsigned long updateThingSpeakInterval = 600000; //send values to thingspeak every 10 minutes

// Initialize the library with the numbers of the interface pins
LiquidCrystal595 lcd(LCDPIN1, LCDPIN2, LCDPIN3);
Servo servo1; // Create a servo object

//wifi esp8266
SoftwareSerial espSerial(SSERIALRX, SSERIALTX); // RX, TX

#define BUFFER_SIZE 100
char buffer[BUFFER_SIZE];

#define WIFI_APN "WLANAPN1"
#define WIFI_PWD "THISISYOURPWD1"
#define THINGSPEAK_IP "184.106.153.149"
#define TS_GET "GET /update?key=TSWRITEKEY123456"

//functions

void sendCommand ( const char * cmd,  uint16_t wait){
  String tmpData = "";
  byte cntr = 0;
  LOG_DEBUGLN(cmd);
resend:
  espSerial.println(cmd);
  delay(10);
  while (espSerial.available() > 0 )  {
    char c = espSerial.read();
    tmpData += c;

    if ( tmpData.indexOf(cmd) > -1 )
      tmpData = "";
    else
      tmpData.trim();
  }
  if (tmpData.indexOf("busy") > -1 ) {
    LOG_DEBUGLN("busy");
    delay(100);
    tmpData = "";
    if (++cntr < 10) goto resend;
  }
  LOG_DEBUGLN(tmpData);
  delay(wait);
}

void setupWifi()
{
  LOG_DEBUGLN("Restarting ESP");
  digitalWrite (ESPRESETPIN, LOW);
  delay(5000);
  digitalWrite (ESPRESETPIN, HIGH);
  delay(10000);
  clearSerialBuffer();
  sendCommand ("AT+CIOBAUD=9600", 1000);
  sendCommand ("AT+RST", 8000);
  sendCommand ("AT+CWMODE=1", 2000 );
  sendCommand ("AT+CWJAP=\""
                WIFI_APN
                "\",\""
                WIFI_PWD
                "\"", 15000);
  sendCommand ("AT+CIFSR\r", 3000);
  sendCommand ("AT+GMR\r", 3000);
}

void setup() {
  SERIAL_BEGIN(SERIAL_BAUD);
  servo1.attach(SERVOPIN); // Attaches the servo on pin 14 to the servo1 object
  servo1.write(180);  // Put servo1 at home position
  delay(2000);
  servo1.detach();

  // Open serial communications and wait for port to open:
  espSerial.begin(ESP8266_BAUD);
  espSerial.setTimeout(15000);
  delay(3000);
  LOG_DEBUGLN("\nStarting up...");
  analogReference(DEFAULT);
  pinMode(BTNPIN, INPUT);
  pinMode(ESPRESETPIN, OUTPUT);
  digitalWrite (ESPRESETPIN, HIGH);

  lcd.begin(16, 2); // Set the display to 16 columns and 2 rows
  lcd.clear();
  lcd.setCursor(0, 0);

  lcd.print("Setting up Wifi.");
  setupWifi();

  lcd.setCursor(0, 0);
  lcd.print("Wifi is set up.");
  delay(5000);
  lcd.clear();

  pinMode(MOIST_SENS1_PIN, INPUT);

  state = STATE_INITIAL;
}

void loop()
{
  lcd.setCursor(0, 0); // Set cursor to home position
  readValues();
  handleState();
  if (!(++wifiCheckCntr)) {
    espSerial.println("AT+GMR\r");
    if (espSerial.find((char*)"OK")) {
      LOG_DEBUGLN("Wifi OK");
    } else {
      LOG_DEBUGLN("Wifi NOK, restart WIfi");
      setupWifi();
    }
  }
  long temp = millis();
  if ((temp - lastConnectionTime) > updateThingSpeakInterval) {
    updateValues();
    lastConnectionTime = millis();
  }

  delay(1000);
}

void updateValues()
{
  char cmd[60] = {0};
  char float_str[10] = {0};
  char hum_str[10] = {0};
  char moist_str[10] = {0};

  snprintf(cmd, 59, "AT+CIPSTART=\"TCP\",\"%s\",80", THINGSPEAK_IP);
  espSerial.println(cmd);
  delay(2000);
  if (espSerial.find((char*)"Error")) {
    LOG_DEBUG("Error1");
    return;
  }
  snprintf(buffer, BUFFER_SIZE - 1, "%s&field1=%s&field2=%s&field3=%u&field4=%s\r\n",
           TS_GET,
           dtostrf(tempSensorValue, 4, 2, float_str),
           dtostrf(humSensorValue, 4, 2, hum_str),
           (hatchOpen) ? 1 : 0,
           dtostrf(moisture, 4, 2, moist_str));

  LOG_DEBUG(buffer);
  espSerial.print("AT+CIPSEND=");
  espSerial.println(strlen(buffer));

  if (espSerial.find((char*)">")) {
    espSerial.print(buffer);
  }
  else {
    espSerial.println("AT+CIPCLOSE");
  }
}

void clearSerialBuffer(void) {
  while ( espSerial.available() > 0 ) {
    espSerial.read();
  }
}

