#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include "HX711.h"

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SCREEN_ADDRESS 0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

#define DHT_PIN 2
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);

#define HX711_DOUT 14
#define HX711_SCK 15
HX711 scale;

#define BUTTON_PIN 5
#define RELAY_1 4
#define RELAY_2 16
#define RELAY_3 17
#define RELAY_4 18

bool dryingStarted = false;
float dryingTemp = 40; // Default initial value
float initialMoisture = 0; // Default initial value
float targetMoisture = 0; // Default initial value
float initialWeight = 0;
float currentWeight = 0;
bool dryingFinished = false;

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY_1, OUTPUT);
  pinMode(RELAY_2, OUTPUT);
  pinMode(RELAY_3, OUTPUT);
  pinMode(RELAY_4, OUTPUT);

  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
  display.display();
  delay(2000);

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Set the Drying Temperature:");
  display.display();
}

void loop() {
  if (dryingStarted) {
    if (!dryingFinished) {
      // Check temperature and humidity
      float temperature = dht.readTemperature();
      float humidity = dht.readHumidity();

      if (humidity > 20) {
        digitalWrite(RELAY_1, HIGH);
      } else {
        digitalWrite(RELAY_1, LOW);
      }

      if (temperature >= dryingTemp) {
        digitalWrite(RELAY_2, LOW);
      } else if (temperature <= (dryingTemp - 2)) {
        digitalWrite(RELAY_2, HIGH);
      }

      // Display temperature, humidity, and weight one at a time
      display.clearDisplay();
      display.setCursor(0, 0);
      display.println("Temp: " + String(temperature) + "C");
      display.display();
      delay(2000);

      display.clearDisplay();
      display.setCursor(0, 0);
      display.println("Humidity: " + String(humidity) + "%");
      display.display();
      delay(2000);

      display.clearDisplay();
      display.setCursor(0, 0);
      display.println("Weight: " + String(currentWeight) + "g");
      display.display();
      delay(2000);

      // Check if the weight has reduced to 50%
      if (currentWeight / initialWeight <= 0.5) {
        dryingFinished = true;
        display.clearDisplay();
        display.setCursor(0, 0);
        display.println("Drying Operation Finished!");
        display.display();
      }
    }
  } else {
    if (digitalRead(BUTTON_PIN) == LOW) {
      setDryingParameters();
    }
  }
}

void setDryingParameters() {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Set the Drying Temperature:");
  display.display();

  // Use potentiometer to adjust dryingTemp
  while (digitalRead(BUTTON_PIN) == HIGH) {
    // Read the potentiometer value and update dryingTemp
    int potValue = analogRead(A0);
    dryingTemp = map(potValue, 0, 4095, 40, 80);
    delay(100); // Add debouncing delay
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Set the Initial Moisture Content:");
  display.display();

  // Use potentiometer to adjust initialMoisture
  while (digitalRead(BUTTON_PIN) == HIGH) {
    // Read the potentiometer value and update initialMoisture
    int potValue = analogRead(A0);
    initialMoisture = map(potValue, 0, 4095, 0, 100) / 10.0; // Adjust for 0.1 increments
    delay(100); // Add debouncing delay
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Set the Target Moisture Content:");
  display.display();

  // Use potentiometer to adjust targetMoisture
  while (digitalRead(BUTTON_PIN) == HIGH) {
    // Read the potentiometer value and update targetMoisture
    int potValue = analogRead(A0);
    targetMoisture = map(potValue, 0, 4095, 0, initialMoisture * 10) / 10.0; // Adjust for 0.1 increments
    delay(100); // Add debouncing delay
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Drying parameters set.");
  display.display();
  delay(2000);

  // Start the drying program
  dryingStarted = true;
  initialWeight = readInitialWeight();
}

float readInitialWeight() {
  // Initialize and configure the HX711
  scale.begin(HX711_DOUT, HX711_SCK);
  scale.set_scale(); // Call this to tare the scale to zero

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Place initial sample.");
  display.display();
  delay(2000);

  // Read and tare the initial weight
  scale.tare();

  while (scale.get_units() < 0) {
    // Continue reading weight until a non-negative value is obtained
    delay(1000);
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Initial Weight: " + String(scale.get_units(), 2) + "g");
  display.display();
  delay(2000);

  return scale.get_units();
}
$abcdeabcde151015202530354045505560fghijfghij
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module