#include <U8g2lib.h>
#include <Wire.h>
#include <math.h>
#include <EasyBuzzer.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8g2(U8X8_PIN_NONE);
#define RL1               3                  //RELÉ 1
#define RL2               5                  //RELÉ 2
#define buzzer            11                  //Buzzer
#define ni                A0                   // entrada nivel
#define te                A2                  //entrada termistor
#define vo                A1                   //entrada voltimetro
#define Vref              4.97                 //voltaje referencia vcc
#define NUM_SAMPLES       10                  // NUMERO DE MUESTRAS TOMADAS Voltaje
#define THERMISTOR        992                 // VALOR OHM DEL SENSOR 25 °C(992 spark)(2500 optra)
#define NUMSAMPLES        10                  // NUMERO DE MUESTRAS TOMADAS NTC
#define BCOEFFICIENT      3680                // beta coefficient 3000-4000 (3680 spark) 
#define SERIESRESISTOR    974                 // resistor en serie 10k (1k para spark)
#define RV1               98700               //RV1=100000 ohms
#define RV2               9780                //RV2=10000 ohms
unsigned char sample_count=0, m, m1A, m2A, p2, w;
int samples[NUMSAMPLES], sum=0, w2;
float steinhart, p, p3, volt;
unsigned long tiempo, tiempo2; 
static const unsigned long lapso1 = 2000; 
static const unsigned long lapso2 = 10000; 
bool estado;


void nivel() 
{
        u8g2.drawBox(103, m1A, 15, 43-m1A);                         //barra grafica
        u8g2.drawFrame(103,0,15,43);
        u8g2.drawLine(122, 10, 125, 10);
        u8g2.drawLine(120, 20, 128, 20);                            //linea divisora
        u8g2.drawLine(122, 30, 125, 30);       
                            // Enviamos el buffer a nuestra pantalla
/* The circuit:
 *     Analog pin A0                                   
 *            ^                                           
 *GND |----/\/\/\--+------| B-              
 *    |----==>| 10k resistor                                   
 *     DZ4.7                                         
 */
}
void temp() 
{       
        u8g2.drawBox(15, m2A, 16, 43-m2A);                         //barra grafica
        u8g2.drawFrame(15,0,16,43);
        u8g2.drawLine(2, 10, 6, 10);
        u8g2.drawLine(0, 20, 8, 20);                               //linea divisora
        u8g2.drawLine(2, 30, 6, 30); 
  if (w2<0 ){ u8g2.drawStr( 1, 60, "error");}  
  else {u8g2.setFont(u8g2_font_profont22_tr);  
  u8g2.setCursor(1, 60); u8g2.print(w2);}   
  
       
}
void voltimetro ()
{ 
	u8g2.setFont(u8g2_font_profont22_tr);             
  u8g2.setCursor(40, 14);
  u8g2.print(volt,1);  u8g2.print("V"); 
  
}
void ventilador()
{   
  
     if (w2 >= 97 )
     { 
    u8g2.setFont(u8g2_font_profont29_tn);
    u8g2.drawStr( 59, 44, "*");
    u8g2.drawCircle(65,32, 8);  
     }
    if (w2 >= 105 )
     { 
    u8g2.drawStr( 59, 63, "*");
    u8g2.drawCircle(65,51,8);  
     }
        u8g2.setFont(u8g2_font_profont10_tr); 
        u8g2.drawStr( 120, 7, "F"); 
        u8g2.drawStr( 120, 42, "E");
        u8g2.drawStr( 0, 7, "120"); 
        u8g2.drawStr( 2, 42, "60"); 
         if (w2>99){u8g2.drawStr( 35, 52, "o");}                      //se desplaza el simbolo ° grados a 3 digitos
      else {u8g2.drawStr( 28, 52, "o");} 
        if (p < 0.40){u8g2.drawStr( 99, 60, "error");}
      else {u8g2.setFont(u8g2_font_profont22_tr); 
      u8g2.setCursor(98, 60); u8g2.print(w);}
      
      
}
void termistor()
{
  float Rth, average=0;  char i;                                                 
  for (i=0; i< NUMSAMPLES; i++) { samples[i] = analogRead(te); } 
  for (i=0; i< NUMSAMPLES; i++) { average += samples[i]; }
  average /= NUMSAMPLES;                                                        
  Rth = (1024 * float(THERMISTOR)/average)-float(THERMISTOR);      //Valor de Rth en funcion del conexionado de nuestro termistor
  steinhart = (1/((1/298.15)+(1/float(BCOEFFICIENT))*log(SERIESRESISTOR/Rth)))-273.15;                       //Aplicamos directamente Steinhart-hart para NTC                                           

/* The easy circuit:
 *                  Analog pin A2
 *                         |
 *    GND |-----/\/\/\-----+-----/\/\/\-----| 5V
 *               ^                ^ 
 *           R termistor        10K resistor
 */
}
void setup(void) 
{
  Serial.begin(9600);                                // Velocidad Port Serial
  pinMode(ni, INPUT);pinMode(te, INPUT); pinMode(vo, INPUT); // Configurados entradas analogicas
  pinMode(RL1, OUTPUT); pinMode(RL2, OUTPUT);       //Configurados como salidas digitales
  u8g2.begin();                                     //Inicializamos el dispositivo
  u8g2.setDrawColor(1);
 // u8g2.setPowerSave(0);
  EasyBuzzer.setPin(buzzer);                        //salida del buzzer
  EasyBuzzer.beep( 2000, 200  );                    // Frecuencia en herzios, Duración beep en ms
  tiempo= millis();
  tiempo2 = millis();
}

void loop()
{ 
     
//*****************************************************************************************//
if (millis() > tiempo)                              //Lectura lenta del nivel
{
while (sample_count < NUM_SAMPLES){sum += analogRead(ni); sample_count++;}
p =((float)sum / NUM_SAMPLES * Vref)/1024;          // Promedio de muestras tomadas 
m = constrain(p,0.44,2.6)*10;                        //Solo se enfoca en un rango de voltaje y multiplica rango x10
w = map(m,4.4,26.0,15,55);                            //mapea valores minimos y maximos del nivel en litros
if (w < 15) { w=15;}
m1A = map(w,15,55,42,0);                              //mapea valores para ajutar la barra max y min
sample_count = 0; sum = 0;
tiempo = millis() + lapso2;  
}   
//****************************************************************************************///
if (millis() > tiempo2) 
{
      estado = !estado;
termistor();                                          //ejecuta lecturas termistor
w2= steinhart;                                        //
p2= constrain(steinhart,60,130);                      // limita valores entre rangos grafica
if (p2 < 60) { p2=60;} 
m2A = map(p2,60,130,42,0);                            // grafica segun los mapeos la barra max y min                                        
//****************************************************************************************///  
while (sample_count < NUM_SAMPLES){sum += analogRead(vo); sample_count++;}
  p3 =((float)sum / NUM_SAMPLES * Vref)/1024;          // Promedio de muestras tomadas
  volt = p3/((float)RV2/(RV1+RV2));                             // Lectura Voltaje final
 sample_count = 0; sum = 0;                                     // Reestablece los contadores
//*****************************************************************************************///                                                                      
  if (w2>=97) {digitalWrite(RL1,HIGH);} else {digitalWrite(RL1,LOW);}            //activa a 97°C                   //Vent 1 97°C
  if (w2>=105) {digitalWrite(RL2,HIGH);} else {digitalWrite(RL2,LOW);}           //activa a 105°C                      //Vent 2 105°C         
  if (w2>=111) { EasyBuzzer.update();}   else {EasyBuzzer.stopBeep();}           //activa a 115°C 

if (estado) 
{
u8g2.clearBuffer();
//  u8g2.drawXBMP(0,0,128,64,macro);
 nivel(); temp(); voltimetro(); ventilador();                    // Mostrar graficos oled     
 u8g2.sendBuffer();                
}    
 else {   

Serial.print(F("Nivel:")); Serial.print(w,1);
Serial.print(F(" Bat:")); Serial.print(volt,1);  
Serial.print(F(" Temp:")); Serial.println(steinhart,1);
      }
 tiempo2 = millis() + lapso1;
    }
  }
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module