#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Pin definitions
const int buzzerPin = 18;
const int relayPin = 4;
const int switchPin = 16; // Switch pin for relay control
const int solarPot = 13;
const int windMillPot = 12;
const int tempPin = 14;  // Analog temperature sensor pin (e.g., LM35)
const int battVoltPin = 27; // Battery voltage sensor pin

const int tempThreshold = 60;  // Temperature threshold in degrees Celsius
const int battThreshold = 12;  // Battery voltage threshold (12V)

void setup() {
  // Initialize serial communication
  Serial.begin(115200);
  
  // Initialize OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  
  // Initialize pins
  pinMode(buzzerPin, OUTPUT);
  pinMode(relayPin, OUTPUT);
  pinMode(switchPin, INPUT); // Set the switchPin as input
  pinMode(battVoltPin, INPUT); // Set the battVoltPin as input
  digitalWrite(relayPin, LOW); // Relay OFF initially
  
  // Welcome message
  Serial.println("Hybrid Power Generation System");
  displayMessage("Hybrid Power Gen", "Initializing...");
  delay(2000);
}

void loop() {
  // Read solar and wind potentiometer values and map them to 0-14V
  int solarValue = analogRead(solarPot);
  int windValue = analogRead(windMillPot);
  int solarVoltage = map(solarValue, 0, 4095, 0, 14); // 0-14V range
  int windVoltage = map(windValue, 0, 4095, 0, 14);   // 0-14V range
  
  // Read temperature sensor (analog) and map to 0-100°C range
  int tempValue = analogRead(tempPin);
  int temperatureC = map(tempValue, 0, 4095, 0, 100); // Mapping temperature sensor to 0-100°C
  
  // Read battery voltage and map to 0-13V
  int battValue = analogRead(battVoltPin);
  int batteryVoltage = map(battValue, 0, 4095, 0, 13); // 0-13V range
  
  // Check if temperature exceeds threshold
  if (temperatureC >= tempThreshold) {
    // Activate buzzer
    beepBuzzer();
  }

  // Read the switch state
  bool switchState = digitalRead(switchPin);
  
  // Control relay based on switch state and battery voltage threshold
  if (switchState == HIGH) {
    if (batteryVoltage >= battThreshold) {
        if (temperatureC >= tempThreshold) {
          // Activate buzzer
          beepBuzzer();
          digitalWrite(relayPin, LOW); // Relay ON
        }
        else{
          digitalWrite(relayPin, HIGH); // Relay ON
        }
    } else {
      digitalWrite(relayPin, LOW);  // Relay OFF (battery voltage too low)
    }
  } else {
    digitalWrite(relayPin, LOW);  // Relay OFF
  }
  
  // Display information on OLED
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(16, 0);
  display.println("Hybrid Power Gen");

  display.setCursor(4, 20);
  display.printf("Solar V : %d V\n", solarVoltage);
  display.setCursor(4, 30);
  display.printf("Wind  V : %d V\n", windVoltage);
  display.setCursor(4, 40);
  display.printf("T : %d degree\n", temperatureC);
  display.setCursor(4, 50);
  display.printf("Bat: %dV  L: %s", batteryVoltage, digitalRead(relayPin) == HIGH ? "ON" : "OFF");
  display.display();
  
  // Print information to serial monitor
  Serial.printf("Solar V : %d V\n", solarVoltage);
  Serial.printf("Wind  V : %d V\n", windVoltage);
  Serial.printf("T : %d °C\n", temperatureC);
  Serial.printf("Battery V : %d V\n", batteryVoltage);
  Serial.printf("L : %s\n", digitalRead(relayPin) == HIGH ? "ON" : "OFF");
  
  // Short delay between iterations
  delay(1000);
}

// Helper function to beep buzzer 3 times with delay
void beepBuzzer() {
  for (int i = 0; i < 3; i++) {
    digitalWrite(buzzerPin, HIGH);
    delay(100);
    digitalWrite(buzzerPin, LOW);
    delay(100);
  }
}

// Helper function to display a message on the OLED
void displayMessage(const char* title, const char* message) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(title);
  display.println(message);
  display.display();
}
NOCOMNCVCCGNDINLED1PWRRelay Module