#define BLYNK_PRINT Serial

#define BLYNK_TEMPLATE_ID "TMPL6hDGGy027"
#define BLYNK_TEMPLATE_NAME "mushroomIOT"
#define BLYNK_AUTH_TOKEN "TGd-fYJi7JX1MQHUFofsgdMX9DpiqO4a"

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <ESP32Servo.h>
#include <Stepper.h>

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>


#define DHTPIN 12
#define DHTTYPE DHT22

#define LDRPIN 34
#define LEDPIN 2

#define LigthStat 26
#define HumiStat 27
#define TempStat 14

#define SERVOPIN 18
#define RELAYPIN 4
#define RELAY_CONTROL_BUTTON 32
#define LED_CONTROL_BUTTON 25

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 4);
Servo myservo;

int ldrValue = 0;
bool isServoOpen = false;
bool isLedOn = false;

bool lastRelayButtonState = HIGH;
bool lastLedButtonState = HIGH;
bool relayButtonState = HIGH;
bool ledButtonState = HIGH;

const int stepsPerRevolution = 200*4;

Stepper myStepper(stepsPerRevolution, 23, 15);
const int delayMS = 0;

char auth[] = BLYNK_AUTH_TOKEN; //token
char ssid[] = "Wokwi-GUEST"; //wifi จำลอง
char pass[] = ""; //รหัสผ่าน

WidgetLED LED(V5);

void setup() {
  Serial.begin(115200);

  Blynk.begin(auth, ssid, pass); //เช็ค token เชื่อมต่อ wifi จากนั้นจะไปทำการใน loop

  lcd.init();
  lcd.backlight();
  dht.begin();
  myservo.attach(SERVOPIN, 500, 2500);

  pinMode(LDRPIN, INPUT);
  pinMode(RELAY_CONTROL_BUTTON, INPUT_PULLUP);
  pinMode(LED_CONTROL_BUTTON, INPUT_PULLUP);
  pinMode(RELAYPIN, OUTPUT);
  pinMode(LEDPIN, OUTPUT);
  pinMode(LigthStat, OUTPUT);
  pinMode(HumiStat, OUTPUT);
  pinMode(TempStat, OUTPUT);

  myStepper.setSpeed(360);

}

BLYNK_WRITE(V3) 
{
  if(param.asInt() == 1)
  {
    for (int i = 0; i < 5; i++) {
      digitalWrite(RELAYPIN, HIGH);  
      digitalWrite(HumiStat, HIGH);
      Blynk.virtualWrite(V6, 255);
      myservo.write(90);  // Open the servo
      delay(500);
      myservo.write(0);   // Close the servo
      delay(500);
    }
    LED.on(); // เปิด LED ผ่านการควบคุม WidgetLED
  }else{
      digitalWrite(RELAYPIN, LOW);  
      digitalWrite(HumiStat, LOW);
      Blynk.virtualWrite(V6, 0);
      myservo.write(0);   
  }
}

BLYNK_WRITE(V4) 
{
  if(param.asInt() == 1){
    digitalWrite(LEDPIN, HIGH);    // Turn on the LED
    digitalWrite(LigthStat, HIGH);
    Blynk.virtualWrite(V7, 255);
    delay(5000);
  } else {
    digitalWrite(LEDPIN, LOW);     // Turn off the LED
    digitalWrite(LigthStat, HIGH);
    Blynk.virtualWrite(V7, 0);
  }
}


void loop() {
  // Read sensor values
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // อ่านค่า LDR จากเซ็นเซอร์
  ldrValue = analogRead(LDRPIN);

  // แปลงค่า LDR เป็นเปอร์เซ็นต์
  int percentage = map(ldrValue, 0,4063,100,0);

  // Display sensor values on LCD
  // lcd.clear();
  // delay(500);


  lcd.setCursor(3, 0);
  lcd.print("mushroom-iot");

  lcd.setCursor(0, 1);
  lcd.print("Temp: ");
  lcd.print(temperature);
  lcd.print(" C");

  lcd.setCursor(0, 2);
  lcd.print("Humidity: ");
  lcd.print(humidity);
  lcd.print(" %");

  lcd.setCursor(0, 3);
  lcd.print("Ligth: ");
  lcd.print(percentage);
  lcd.print(" %");

  // Display sensor values on Serial monitor
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.print(" °C, Humidity: ");
  Serial.print(humidity);
  Serial.print(" %, Light Level: ");
  Serial.println(percentage);

  // Control Servo with Relay button
  relayButtonState = digitalRead(RELAY_CONTROL_BUTTON);
  if (relayButtonState != lastRelayButtonState) {
    if (relayButtonState == LOW) {
      isServoOpen = !isServoOpen;
      if (isServoOpen) {
        for (int i = 0; i < 5; i++) {
          digitalWrite(HumiStat, HIGH);
          Blynk.virtualWrite(V6, 255);
          myservo.write(90);  // Open the servo
          delay(500);
          myservo.write(0);   // Close the servo
          delay(500);
        }
        Serial.println("Servo opened and closed");
      }
      digitalWrite(HumiStat, LOW);
      Blynk.virtualWrite(V6, 0);
    }
    delay(50);
  }
  lastRelayButtonState = relayButtonState;

  // Control LED with LED button
  ledButtonState = digitalRead(LED_CONTROL_BUTTON);
  if (ledButtonState != lastLedButtonState) {
    if (ledButtonState == LOW) {
      isLedOn = !isLedOn;
      if(isLedOn){
        Blynk.virtualWrite(V7, 255);
      }else{
        Blynk.virtualWrite(V7, 0);
      }
      digitalWrite(LEDPIN, isLedOn ? HIGH : LOW);
      digitalWrite(LigthStat, isLedOn ? HIGH : LOW);
      Serial.println(isLedOn ? "LED turned on" : "LED turned off");
    }
    delay(5000);
  }
  lastLedButtonState = ledButtonState;

  // Adjust Relay state based on humidity
  if (humidity <= 70) {
    for (int i = 0; i < 5; i++) {
        digitalWrite(RELAYPIN, HIGH);
          myservo.write(90);  // Open the servo
          delay(500);
          myservo.write(0);   // Close the servo
          digitalWrite(HumiStat, HIGH);
          Blynk.virtualWrite(V6, 255);
          delay(500);
        }
  } else {
    digitalWrite(RELAYPIN, LOW);   // Turn off the relay
    digitalWrite(HumiStat, LOW);
    Blynk.virtualWrite(V6, 0);
    myservo.write(0);   // Close the servo
    delay(500);
  }

  if(temperature>=40){
    for (int i = 0; i < 5; i++) {
      myStepper.step(stepsPerRevolution);
      delay(delayMS);
      digitalWrite(TempStat, HIGH);
      Blynk.virtualWrite(V5, 255);
    }
    Serial.println("open stepper");
  }else{
    Serial.println("stop stepper");
    digitalWrite(TempStat, LOW);
    Blynk.virtualWrite(V5, 0);
  }

  // Adjust Servo state based on DHT Sensor and Relay state
  if (isServoOpen && humidity <= 70) {
    digitalWrite(RELAYPIN, HIGH);  // Turn on the relay
    digitalWrite(HumiStat, HIGH);
    Blynk.virtualWrite(V6, 255);
  }

  // Adjust LED state based on light level
  if (percentage <= 10) {
    digitalWrite(LEDPIN, HIGH);    // Turn on the LED
    digitalWrite(LigthStat, HIGH);
    Blynk.virtualWrite(V7, 255);
  } else {
    digitalWrite(LEDPIN, LOW);     // Turn off the LED
    digitalWrite(LigthStat, LOW);
    Blynk.virtualWrite(V7, 0);
  }

  Blynk.run();
  Blynk.virtualWrite(V0, temperature); //temp
  Blynk.virtualWrite(V1, humidity); //humi
  Blynk.virtualWrite(V2, percentage); //ligth
  // Blynk.virtualWrite(V3, relayButtonState); //relay control btn
  // Blynk.virtualWrite(V4, ledButtonState); //led control btn
  Blynk.virtualWrite(V5, TempStat); //Stepper Status
  Blynk.virtualWrite(V6, HumiStat); //Servo Status
  Blynk.virtualWrite(V7, LigthStat); //LED Status
  
}
$abcdeabcde151015202530354045505560fghijfghij
NOCOMNCVCCGNDINLED1PWRRelay Module
A4988