#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include <ThingSpeak.h>
#include <WiFi.h>

#define DHTTYPE DHT22 //Using DHT22 sensor 

const char* ssid = "Wokwi-GUEST";   // your network SSID (name) 
const char* password = "";   // your network password

WiFiClient  client;
String studentName = "XXXXX"; // Replace xxxxx with your name
unsigned long myChannelNumber = 2568494;  //Put the correct channel number
const char * myWriteAPIKey = "2FAASIFFLK5MMJOK"; // Use correct Write API Key


unsigned long lastTime = 0;
unsigned long timerDelay = 10000;

const int DHT_PIN = 15;

DHT dht(DHT_PIN, DHTTYPE);

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     4
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int sensorPin = A0;
String dateReference;

void setup() {
  WiFi.mode(WIFI_STA);   
  ThingSpeak.begin(client);  // Initialize ThingSpeak

  // Connect or reconnect to WiFi
    if(WiFi.status() != WL_CONNECTED){
      Serial.print("Attempting to connect");
      while(WiFi.status() != WL_CONNECTED){
        WiFi.begin(ssid, password); 
        delay(5000);     
      } 
      Serial.println("\nConnected.");
    }

  
  Serial.begin(115200);
  
    // Checked the OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  Serial.println(F("CEIS490 Part 1 Project "));
  dateReference = String(__DATE__) + "\t" + String(__TIME__);
  Serial.println(dateReference);
  Serial.println("Name: " + studentName);

}

unsigned long t=0;
unsigned long interval = 20000; //the update interval should be at least 30s
bool tempScale = false ; // selects temperature scale. false = Celcius true = Fahrenheit 
int counter = 0;


void loop() {
  
  float temp = dht.readTemperature(tempScale); //the tempScale selects the reading temperature scale
  float hum = dht.readHumidity();
  //uint16_t pH = analogRead(sensorPin);
  //float pH = float(analogRead(sensorPin)) * 0.0017094f * 2.0f;
  float pH = 4.0f * float(analogRead(sensorPin))/4095.0f  + 5.0f ; //pH range from 5 to 9. Change the formula for the range to change.
  //Serial.println(analogRead(sensorPin));
  Serial.println(studentName  + "\t"+ dateReference);
  Serial.println("Temp: " + String(temp, 2) + "°C");
  Serial.println("Humidity: " + String(hum, 1) + "%");
  Serial.println("pH: " + String(pH, 1));
  Serial.println("---");
  delay(3000); // Wait for a new reading from the sensor (DHT22 has ~0.5Hz sample rate)

  display.clearDisplay();
  display.setTextSize(1.8);
  display.setTextColor(SSD1306_WHITE);
  
  display.setCursor(0, 0);
  display.println(studentName);
  display.setCursor(0, 15);
  display.println("Temp: " +String(temp, 2) + " C");
 
  display.setCursor(0, 30);
  display.println("Humidity: " +String(hum, 1) + " %");
  display.setCursor(0, 45);
  display.println("pH: " + String(pH, 1));
  display.display();
  if ( (millis()-t) > interval){
    ThingSpeak.setField(1, temp);
    ThingSpeak.setField(2, hum);
    ThingSpeak.setField(3, pH);
   
    // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
    // pieces of information in a channel.  Here, we write to field 1.
    //int x = ThingSpeak.writeField(myChannelNumber, 1, temp, myWriteAPIKey);
    // uncomment if you want to get temperature in Fahrenheit
    // int x = ThingSpeak.writeField(myChannelNumber, 1, temperatureF, myWriteAPIKey);
    int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
    
    
    if(x == 200){
      Serial.print("Channel update successful.");
      counter++;
      Serial.println("\tCounter="+String(counter));
    }
    else{
      Serial.println("Problem updating channel. HTTP error code " + String(x));
    }
    t = millis();

  }

}