/***************************************************************************************************************
 * IoT DHT Temp/Hum and Soil Moister Station using NodeMCU ESP-12 Develop Kit V1.0
 *  DHT connected to NodeMCU pin D3
 *  Soil Moister Sensor connected to A0
 *  Sensor Data on local OLED Display
 *  Sensor data sent to Thingspeak Channel: https://thingspeak.com/channels/CHANNEL_ID 
 *  Developed by MJRovai 12 October 2017
 ********************************************************************************************************************************/
#define SW_VERSION " ThinkSpeak.com" // SW version will appears at innitial LCD Display

/* ESP12-E & Thinkspeak*/
//#include <ESP8266WiFi.h>
WiFiClient client;
const char* MY_SSID = "Wokwi-GUEST";
const char* MY_PWD = "";
const char* TS_SERVER = "api.thingspeak.com";
String TS_API_KEY ="A82XWQT7Y9C8QUFB";
int sent = 0;

/* TIMER */
#include <SimpleTimer.h>
SimpleTimer timer;

/* OLED */
#include <Adafruit_SSD1306.h> // library for OLED: SCL ==> D1; SDA ==> D2
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#include <SPI.h>
#include <Wire.h>

/* DHT22*/
#include "DHT.h"
#define DHTPIN D3  
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);
float hum = 0;
float temp = 0;

/* Soil Moister */
#define soilMoisterPin A0
#define soilMoisterVcc D4 //not used. LM393 VCC connect to 3.3V
int soilMoister = 0;

void setup() 
{
  pinMode(soilMoisterVcc, OUTPUT);
  Serial.begin(115200);
  delay(10);
  dht.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //Inicializa OLED com endereço I2C 0x3C (para 128x64)
  connectWifi();
  timer.setInterval(2000L, getDhtData);
  timer.setInterval(7000L, getSoilMoisterData);
  timer.setInterval(19000L, sendDataTS);
  digitalWrite (soilMoisterVcc, LOW);
}

void loop() 
{
  displayData();
  timer.run(); // Initiates SimpleTimer
}

/***************************************************
 * Start OLED
 **************************************************/
void oledStart(void)
{
  Wire.begin();  
  display.init();                      // Initialze SSD1306 OLED display
  clearOledDisplay();
  display.clearDisplay();              // Clear screen
  display.setTextXY(0,0);              
  display.putString("  MJRoBot.org");
}

/***************************************************
 * Get DHT data
 **************************************************/
void getDhtData(void)
{
  float tempIni = temp;
  float humIni = hum;
  temp = dht.readTemperature();
  hum = dht.readHumidity();
  if (isnan(hum) || isnan(temp))   // Check if any reads failed and exit early (to try again).
  {
    Serial.println("Failed to read from DHT sensor!");
    temp = tempIni;
    hum = humIni;
    return;
  }
}

/***************************************************
 * Get Soil Moister Sensor data
 **************************************************/
void getSoilMoisterData(void)
{
  soilMoister = 0;
  digitalWrite (soilMoisterVcc, HIGH);
  delay (500);
  int N = 3;
  for(int i = 0; i < N; i++) // read sensor "N" times and get the average
  {
    soilMoister += analogRead(soilMoisterPin);   
    delay(150);
  }
  digitalWrite (soilMoisterVcc, LOW);
  soilMoister = soilMoister/N; 
  Serial.println(soilMoister);
  soilMoister = map(soilMoister, 380, 0, 0, 100); 
}

/***************************************************
 * Display data at Serial Monitora & OLED Display
 **************************************************/
void displayData(void)
{
  Serial.print(" Temperature: ");
  Serial.print(temp);
  Serial.print("oC   Humidity: ");
  Serial.print(hum);
  Serial.println("%");
  
  display.setTextXY(3,0);              // Set cursor position, start of line 2
  display.putString("TEMP: " + String(temp) + " oC");
  display.setTextXY(5,0);              // Set cursor position, start of line 2
  display.putString("HUM:  " + String(hum) + " %");
   display.setTextXY(7,0);              // Set cursor position, start of line 2
  display.putString("Soil: " + String(soilMoister) + " %");
}

/***************************************************
 * Clear OLED Display
 **************************************************/
void clearOledDisplay()
{
  display.setFont(font8x8);
  display.setTextXY(0,0); display.putString("                ");
  display.setTextXY(1,0); display.putString("                ");
  display.setTextXY(2,0); display.putString("                ");
  display.setTextXY(3,0); display.putString("                ");
  display.setTextXY(4,0); display.putString("                ");
  display.setTextXY(5,0); display.putString("                ");
  display.setTextXY(6,0); display.putString("                ");
  display.setTextXY(7,0); display.putString("                ");
  display.setTextXY(0,0); display.putString("                ");              
}

/***************************************************
 * Connecting WiFi
 **************************************************/
void connectWifi()
{
  Serial.print("Connecting to "+ *MY_SSID);
  WiFi.begin(MY_SSID, MY_PWD);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("");  
}

/***************************************************
 * Sending Data to Thinkspeak Channel
 **************************************************/
void sendDataTS(void)
{
   if (client.connect(TS_SERVER, 80)) 
   { 
     String postStr = TS_API_KEY;
     postStr += "&field1=";
     postStr += String(temp);
     postStr += "&field2=";
     postStr += String(hum);
     postStr += "&field3=";
     postStr += String(soilMoister);
     postStr += "\r\n\r\n";
   
     client.print("POST /update HTTP/1.1\n");
     client.print("Host: api.thingspeak.com\n");
     client.print("Connection: close\n");
     client.print("X-THINGSPEAKAPIKEY: " + TS_API_KEY + "\n");
     client.print("Content-Type: application/x-www-form-urlencoded\n");
     client.print("Content-Length: ");
     client.print(postStr.length());
     client.print("\n\n");
     client.print(postStr);
     delay(1000); 
   }
   sent++;
   client.stop();
}


































/*

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <BlynkESP32_BT_WF.h>


char auth[] = "YourAuthToken"; //AUTH TOKEN (FORNECIDO PELO PROJETO NO BLYNK E POR E-MAIL)
 
char ssid[] = "NOME DA SUA REDE WIFI"; //VARIÁVEL QUE ARMAZENA O NOME DA REDE SEM FIO EM QUE VAI CONECTAR
char pass[] = "SENHA DA SUA REDE WIFI"; //VARIÁVEL QUE ARMAZENA A SENHA DA REDE SEM FIO EM QUE VAI CO


#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

  const unsigned char LED_ON [] PROGMEM = {
	0x07, 0xc0, 0x1f, 0xf0, 0x3e, 0xf8, 0x7f, 0xfc, 0x6e, 0xec, 0xf7, 0xde, 0xff, 0xfe, 0xdd, 0x76, 
	0xea, 0xae, 0x7b, 0xbc, 0x7d, 0x7c, 0x3d, 0x78, 0x1d, 0x70, 0x1d, 0x70, 0x0d, 0x60, 0x0f, 0xe0, 
	0x0c, 0x20, 0x0b, 0x20, 0x08, 0xe0, 0x0e, 0x20, 0x09, 0xa0, 0x04, 0x40, 0x03, 0x80
};

  const unsigned char LED_OFF [] PROGMEM = {
  0x07, 0xc0, 0x18, 0x30, 0x20, 0x08, 0x40, 0x04, 0x40, 0x04, 0x80, 0x02, 0x80, 0x02, 0x82, 0x82, 
	0x85, 0x42, 0x44, 0x44, 0x42, 0x84, 0x22, 0x88, 0x12, 0x90, 0x12, 0x90, 0x0a, 0xa0, 0x0f, 0xe0, 
	0x0c, 0x20, 0x0b, 0x20, 0x08, 0xe0, 0x0e, 0x20, 0x09, 0xa0, 0x04, 0x40, 0x03, 0x80
};


#define P1 25
#define P2 20

#define ledPin 2
#define ledPin2 13

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //Inicializa OLED com endereço I2C 0x3C (para 128x64)
  display.clearDisplay(); //Limpa o display
  display.display();      //Enviar para o display
  display.setTextColor(1);  //configura o display para ativar 'branco' no pixel
  display.setTextSize(1); //tamanho do texto
  display.setCursor(0,0); //Pixel inicial para escrever menos metade das letras 
  display.print("Criado por:          Mario.Parente");	//*Escreve                                   
  display.display();
  display.setCursor(P1-20,P2+27);
  display.print("Estados LED");	//*Escreve
  delay(300); //Enviar para o display e espera
  
}
void loop() 
{
  display.fillRect(P1, P2, 15, 23, 0);
  digitalWrite(ledPin, HIGH);  
  digitalWrite(ledPin2, HIGH); 
  display.drawBitmap(P1,P2, LED_ON, 15, 23, 1); //* Deselha o Logo ON *  
  display.display();
  delay(1000);
  display.fillRect(P1, P2, 15, 23, 0);
  digitalWrite(ledPin, LOW);    
  digitalWrite(ledPin2, LOW);
  display.drawBitmap(P1,P2, LED_OFF, 15, 23, 1); //* Deselha o Logo OFF 
  display.display();
  delay(1000);  
  
}

*/