/*
  NTC Temperature Sensor using Franzininho, NTC and SSD1306
  by Anderson Costa with ❤ for the Wokwi community
  Modify by Leko 7-seg catodo comum with 74hc595 tabelado 30 a 40 graus
  Tabela site http://www.sebulli.com/ntc/index.php
  Visit https://wokwi.com to learn about the Wokwi Simulator
  Visit https://franzininho.com.br to learn about the Franzininho
*/

#define NTC_PIN A3
#define SetP_PIN A0
#define latchPin PB0
#define clockPin PB1
#define dataPin  PB2
#define Botao    PB4
#define disp1 6
#define disp2 5
#define disp3 3
#define releON  bitSet(Flagsreles, 5)
#define releOFF bitClear(Flagsreles, 5)
#define motorON  bitSet(Flagsreles, 6)
#define motorOFF bitClear(Flagsreles, 6)  
byte Valor; //Quarda o valor do digito
int temperatura, setpoint, histerese=200;
byte Flagsreles; 

const byte digits[] = {
 // abcdefgº
  0b11111100, // 0
  0b01100000, // 1
  0b11011010, // 2
  0b11110010, // 3
  0b01100110, // 4
  0b10110110, // 5
  0b10111110, // 6
  0b11100000, // 7
  0b11111110, // 8
  0b11110110, // 9
  0b10011110, // E
  0b00001010, // r
  0b10110110, // S
  0b00011111, // t

};

int NTC_table[17] = {
  12687, 10160, 7633, 6211, 5196, 4387, 3696, 
  3077, 2500, 1945, 1393, 825, 217, -471, -1318, 
  -2560, -3802
};

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin,  OUTPUT);
  pinMode(Botao,  INPUT_PULLUP);
}

void loop() {
  //while (!digitalRead(Botao)) Aprende();
  temperatura = NTC_ADC2Temperature(analogRead(NTC_PIN));
  while (!digitalRead(Botao)) Aprende();
  reles();
  if (temperatura < 000 || temperatura > 5200) { //testa faixa de temperatura aceitavel
    erro();
  } else JackRipper();
  }

void Aprende(){
  while (!digitalRead(Botao)) setp();
  while (digitalRead(Botao)){
      temperatura = map (analogRead(SetP_PIN),0,1023,3000,4500);
      setpoint = temperatura;
      JackRipper();
  }
      while (!digitalRead(Botao)) setp();
}   

void JackRipper(){
  temperatura=(temperatura/10)-1;
  Valor = temperatura %10;
  cospe(digits[Valor], disp1|Flagsreles);//Faz OR com Flags reles para usar pinos extras
  temperatura /= 10; 
  Valor = temperatura %10;
  cospe( digits[Valor]|1, disp2|Flagsreles);//coloca o ponto |1
  temperatura /= 10; 
  cospe( digits[temperatura], disp3|Flagsreles);
}

int NTC_ADC2Temperature(unsigned int adc_value){
 
  int p1,p2;
  /* Estimate the interpolating point before and after the ADC value. */
  p1 = NTC_table[ (adc_value >> 6)  ];
  p2 = NTC_table[ (adc_value >> 6)+1];
 
  /* Interpolate between both points. */
  return p1 - ( (p1-p2) * (adc_value & 0x003F) ) / 64;
}

void cospe(byte number, byte digito){
  //releON;
  shiftOut(dataPin, clockPin, MSBFIRST, digito);
  shiftOut(dataPin, clockPin, LSBFIRST, number);
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
}

void erro(void){
  cospe( digits[11], disp1);
  cospe( digits[11], disp2); 
  cospe( digits[10], disp3);
}

void setp(void){
  cospe( digits[13], disp1);
  cospe( digits[10], disp2); 
  cospe( digits[12], disp3);
}


void reles(void){
  setpoint = analogRead(SetP_PIN)*7;
  if (setpoint-histerese > temperatura) releON;
  else if (setpoint < temperatura) releOFF;
}