#include <DHT.h>
#include <EEPROM.h>

#define DHTPIN 2
#define DHTTYPE DHT22
#define BUTTON_PIN 3
#define LIGHT_SENSOR_PIN A0
#define PERIOD 5000

DHT dht(DHTPIN, DHTTYPE);
unsigned long lastMillis = 0;
unsigned long startMillis = 0;
int eepromAddress = 0;

const float GAMMA = 0.7;
const float RL10 = 50;

void setup() {
  Serial.begin(9600);
  dht.begin();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  EEPROM.get(0, eepromAddress);
  if (eepromAddress == -1) {
    eepromAddress = 0;
  }
  startMillis = millis();
}

void loop() {
  if (millis() - lastMillis >= PERIOD) {
    lastMillis = millis();
    float humidity = dht.readHumidity();
    float temperature = dht.readTemperature();
    //рівень освітленості
    int analogValue = analogRead(LIGHT_SENSOR_PIN);
    float voltage = analogValue / 1024. * 5;
    float resistance = 2000 * voltage / (1 - voltage / 5);
    float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
    //збереження даних у пам'ять
    EEPROM.put(eepromAddress, humidity);
    EEPROM.put(eepromAddress + sizeof(float), temperature);
    EEPROM.put(eepromAddress + 2 * sizeof(float), lux);

    eepromAddress += 3 * sizeof(float);// блільшення адреси щоб дані не переписувались
    
    if (eepromAddress + 3 * sizeof(float) > EEPROM.length()) {//перевірка чи достатньо пам'яті
      eepromAddress = sizeof(int);
    }
    EEPROM.put(0, eepromAddress);
  }
  if (digitalRead(BUTTON_PIN) == LOW) {
    for (int i = 0; i < eepromAddress; i += 3 * sizeof(float)) {
      float humidity, temperature, lux;
      EEPROM.get(i, humidity);
      EEPROM.get(i + sizeof(float), temperature);
      EEPROM.get(i + 2 * sizeof(float), lux);
      unsigned long elapsedMillis = millis() - startMillis;
      Serial.print("T=");
      Serial.print(temperature, 1);
      Serial.print("°C");
      Serial.print(", H=");
      Serial.print(int(humidity));
      Serial.print("%");
      Serial.print(", L=");
      Serial.print(lux);
      Serial.print(" lux");
      Serial.print(" | Час:");
      Serial.print(elapsedMillis / 3600000); // години
      Serial.print(":");
      Serial.print((elapsedMillis % 3600000) / 60000); // хвилини
      Serial.print(":");
      Serial.println((elapsedMillis % 60000) / 1000); // секунди
    }
    for (int i = 0; i < EEPROM.length(); i++) { //очищення пам'яті для наступний даних
      EEPROM.write(i, 0);
    }
    eepromAddress = 0;
    EEPROM.put(0, eepromAddress);
    startMillis = millis();
  }
}