#include <Wire.h>
#include <EEPROM.h>
#include "MyTimer.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define EEPROM_SIZE 2
#define P_ONOFF 27
#define P_MENO 14
#define P_PIU 12
#define P_TIMER 13
#define RELE 26
#define LED 2
#define PinNTC 15
#define stato 0
#define temperatura 1


unsigned long currentMillis;
unsigned long StartingTimeStamp;
unsigned long TimeDelay = 500;
int Tc;
float tcstato;
int onoff;
int soglia;
int TempoTimer = 900; // 900 = 15 Min
int Countdown;

int StatoTimer;
int TimerTempo = 1000;
int TimerLettura = 1000; //5000
int TimerIngressi = 100;
int TimerStampa = 250;

int temp;
int temposec;
int Calcolo;
int TempSec;
int sogliaold = 1;
int tempold = 1;
int statoold0 = 1;
int statoold1 = 1;
int calcoloold = 1;

double T = 0;
double adc = 0;

static const unsigned char PROGMEM blank[] = // 24*24
{ B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111,
  B11111111, B11111111, B11111111
};

static const unsigned char PROGMEM gradi[] =
{ B01000000,
  B10100000,
  B01000000,
  B00000000
};

static const unsigned char PROGMEM punti[] =
{ B11000000,
  B11000000,
  B00000000,
  B00000000,
  B11000000,
  B11000000
};

MyTimer t1 = MyTimer();
MyTimer t2 = MyTimer();
MyTimer t3 = MyTimer();
MyTimer t4 = MyTimer();

Adafruit_SSD1306 display(128, 64);

void setup() {
  t1.set(TimerLettura);
  t2.set(TimerTempo);
  t3.set(TimerIngressi);
  t4.set(TimerStampa);
  
  pinMode(P_ONOFF, INPUT); //onoff
  pinMode(P_PIU, INPUT); //+
  pinMode(P_MENO, INPUT); //-
  pinMode(RELE, OUTPUT); //RELE
  pinMode(LED, OUTPUT);
  pinMode(P_TIMER, INPUT);
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  Serial.begin(9600);
  Wire.begin();
  EEPROM.begin(EEPROM_SIZE);
  EEPROM.write(temperatura, 25);
  EEPROM.commit();
  soglia = EEPROM.read(temperatura);
  display.clearDisplay();
  display.display();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(15, 28);
  display.println("Avvio Termostato");
  display.display();
  digitalWrite(RELE, HIGH);
  delay(1000);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(83, 7);
  display.println("ATTUALE");
  display.setCursor(71, 28);
  display.println("IMPOSTATA");
  display.setCursor(33, 7);
  display.println("C");
  display.setCursor(33, 28);
  display.println("C");
  display.setCursor(95, 49);
  display.println("TIMER");
  display.display(); 
  display.drawBitmap(29, 7,  gradi, 3, 3, 1);
  display.drawBitmap(29, 28,  gradi, 3, 3, 1);
  display.display();
  display.drawBitmap(28, 50,  punti, 2, 6, 1);
  display.display();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(4, 46);
  display.println("00");
  display.setCursor(32, 46);
  display.println("00");
  display.display();
  display.drawLine(0, 0, 127, 0, WHITE);
  
  display.drawLine(0, 21, 127, 21, WHITE);
  
  display.drawLine(0, 42, 127, 42, WHITE);
  
  display.drawLine(0, 63, 127, 63, WHITE);
  display.display();
  Countdown = TempoTimer;
}

void loop() {

   
   
  //------------------------------------------------ Lettura temperatura --------------------------------------
  if (t1.check()) {
    
  adc = analogRead(PinNTC); 
   
  T = (-0.0252 * adc)+68.725;
  Serial.println(T,1);
  Tc = round(T);
  
    if (tempold != Tc){
    display.drawBitmap(4, 4,  blank, 22, 14, 0);
    display.display();
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(4, 4);
    if (Tc != 0){display.println(Tc);} else {display.println("00");}
    display.display();
  }
    tempold = Tc;
    t1.set(TimerLettura);
  }

  //------------------------------------------- Gestione / Impostazioni --------------------------------------
  if (t3.check()) {

      if (digitalRead(P_TIMER) == HIGH) {
        if (digitalRead(P_TIMER) == HIGH && digitalRead(P_PIU) == HIGH){ TempoTimer = TempoTimer + 30;}
        if (digitalRead(P_TIMER) == HIGH && digitalRead(P_MENO) == HIGH){ TempoTimer = TempoTimer - 30;}
        if (digitalRead(P_TIMER) == HIGH && digitalRead(P_PIU) == LOW && digitalRead(P_PIU) == LOW) {
indice_timer:        
        if (digitalRead(P_TIMER) == LOW) {
          if (StatoTimer == 1){StatoTimer = 0; t3.set(TimerIngressi); goto reset_timer;} else {StatoTimer = 1;}
          delay(100);
          t3.set(TimerIngressi);
        } else {
          goto indice_timer;
        }
      }}
    uscita:
    if(EEPROM.read(stato) == 1){ 
      if (digitalRead(P_PIU) == HIGH && EEPROM.read(temperatura) <= 29) {
indice_piu:
        if (digitalRead(P_PIU) == LOW) {
          soglia ++;
          EEPROM.write(temperatura, soglia);
          EEPROM.commit();
          delay(100);
          t3.set(TimerIngressi);
        } else {
          goto indice_piu;
        }
      }
      if (digitalRead(P_MENO) == HIGH && EEPROM.read(temperatura) >= 21) {
indice_meno:
        if (digitalRead(P_MENO) == LOW) {
          soglia --;
          EEPROM.write(temperatura, soglia);
          EEPROM.commit();
          delay(100);
          t3.set(TimerIngressi);
        } else {
          goto indice_meno;
        }
      }
    }
    
    if (digitalRead(P_ONOFF) == HIGH && EEPROM.read(stato) >= 1) {
indice_off:
      if (digitalRead(P_ONOFF) == LOW) {
        onoff = 0;
        EEPROM.write(stato, onoff);
        EEPROM.commit();
        delay(100);
        t3.set(TimerIngressi);
      } else {
        goto indice_off;
      }
    }
    if (digitalRead(P_ONOFF) == HIGH && EEPROM.read(stato) >= 0) {
indice_on:
      if (digitalRead(P_ONOFF) == LOW) {
        onoff = 1;
        EEPROM.write(stato, onoff);
        EEPROM.commit();
        delay(100);
        if(onoff == 0){t3.set(TimerIngressi); StatoTimer = 0; goto reset_timer; }
        t3.set(TimerIngressi);
      } else {
        goto indice_on;
      }
    }

      if(soglia != sogliaold){
      display.drawBitmap(4, 25,  blank, 22, 14, 0);
      display.display();
      display.setTextColor(WHITE);
      display.setTextSize(2);
      display.setCursor(4, 25);
      display.println(soglia);
      display.display();
    }
      sogliaold = soglia;
  
    if (EEPROM.read(stato) == 1) {

      if (statoold1 != EEPROM.read(stato)){
      display.drawBitmap(4, 25,  blank, 22, 14, 0);
      display.drawBitmap(16, 25,  blank, 22, 14, 0);
      display.display();
      display.setTextColor(WHITE);
      display.setTextSize(1);
      display.setCursor(33, 28);
      display.println("C");
      display.drawBitmap(29, 28,  gradi, 3, 3, 1);
      display.display();
      display.setTextColor(WHITE);
      display.setTextSize(2);
      display.setCursor(4, 25);
      display.println(soglia);
      display.display();     
      }
      

    }
    statoold1 = EEPROM.read(stato);

    if (EEPROM.read(stato) == 0) {
      
      if (statoold0 != EEPROM.read(stato)){
      display.drawBitmap(4, 25,  blank, 22, 14, 0);
      display.drawBitmap(16, 25,  blank, 22, 14, 0);
      display.display();
      display.setTextColor(WHITE);
      display.setTextSize(2);
      display.setCursor(4, 25);
      display.println("OFF");
      display.display();}
    }
    statoold0 = EEPROM.read(stato);
    tcstato = Tc - EEPROM.read(temperatura);
    if (tcstato < 0 && onoff == 1) {
      digitalWrite(RELE, HIGH);
      digitalWrite(LED, LOW);
    }
    if (tcstato > 0 || onoff == 0) {
      digitalWrite(RELE, LOW);
      digitalWrite(LED, HIGH);
    }
    t3.set(TimerIngressi);
  }

  //---------------------------------------------- Timer autospegnimento -----------------------------------------------
  if (t2.check()) {

    //if (Countdown < 0){Countdown = TempoTimer;}
    if (StatoTimer == 1) {
      onoff = 1;
      EEPROM.write(stato, onoff);
      EEPROM.commit();
      Calcolo = Countdown / 60;
      if (calcoloold != Calcolo){
      display.drawBitmap(4, 46,  blank, 22, 14, 0);
      display.display();
      display.setTextColor(WHITE);
      display.setTextSize(2);
      if (Calcolo < 10) {
        display.setCursor(16, 46);
      } else {
        display.setCursor(4, 46);
      }

      display.println(Calcolo);
      display.display();
      }
      calcoloold = Calcolo;
      TempSec = Calcolo * 60;
      TempSec = Countdown - TempSec;

      display.drawBitmap(32, 46,  blank, 22, 14, 0);
      display.display();
      if (TempSec < 10) {
        display.setTextColor(WHITE);
        display.setTextSize(2);
        display.setCursor(32, 46);
        display.println("0");
        display.display();
        
        display.setTextColor(WHITE);
        display.setTextSize(2);
        display.setCursor(44, 46);
        display.println(TempSec);
        display.display();
      } else {
        display.setTextColor(WHITE);
        display.setTextSize(2);
        display.setCursor(32, 46);
        display.println(TempSec);
        display.display();
      }
      Countdown --;
      
      if (Countdown == -1) {
      reset_timer:
      onoff = 0;
      EEPROM.write(stato, onoff);
      EEPROM.commit();
      StatoTimer = 0;
      Countdown = TempoTimer;      
      delay(1000);
      temp = TempoTimer /60;
      temposec = TempoTimer - (temp*60);
      display.drawBitmap(4, 46,  blank, 22, 14, 0);
      display.display();
      display.setTextColor(WHITE);
      display.setTextSize(2);
      if (temp < 10) {
        display.setCursor(16, 46);
      } else {
        display.setCursor(4, 46);
      }
      display.println(temp);
      display.display();
      
      display.drawBitmap(32, 46,  blank, 22, 14, 0);
      display.display();
      if (temposec < 10) {
        display.setTextColor(WHITE);
        display.setTextSize(2);
        display.setCursor(32, 46);
        display.println("0");
        display.display();
        
        display.setTextColor(WHITE);
        display.setTextSize(2);
        display.setCursor(44, 46);
        display.println(temposec);
        display.display();
      } else {
        display.setTextColor(WHITE);
        display.setTextSize(2);
        display.setCursor(32, 46);
        display.println(temposec);
        display.display();
      }
      
      }
    }
    t2.set(TimerTempo);
  }
}
NOCOMNCVCCGNDINLED1PWRRelay Module