//Proyecto monitor/controlador para FORD FOCUS 04
//Los datos de ajustes, calibración y diagramas son de mi autoria EV
//El modelado grafico toma referencia a recopilación de información en la web
#include <GyverWDT.h>
#include <math.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EasyBuzzer.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1); 

#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.974                //voltaje referencia vcc
#define ADC               1023                // Multiplo de entrada ADC
#define NUM_SAMPLES       5                   //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 (974 para spark)
#define RV1               98700               //RV1=100000 ohms
#define RV2               9780                //RV2=10000 ohms
#define niMin             0.72                // Voltaje nivel minimo
#define niMax             3.0                 // Voltaje nivel maximo
#define DEG2RAD 0.0174532925                  //Dato para calculo de coordenadas
#define correccion         5                  // - 5°C de correción de la temperatura


unsigned char sample_count=0, m, V, simbol;
int samples[NUMSAMPLES], sum=0, Nivel1, temp;
float steinhart, p, p3, Volt, ba, Nivel;
unsigned long timer, timer2, pausa;
static bool RL1s, RL2s, indicador;
volatile bool ActualizarOLED = false;

const unsigned char advert [] PROGMEM = 
{
	0x01, 0x00, 0x03, 0x80, 0x02, 0x40, 0x04, 0x40, 0x05, 0x20, 0x09, 0x10, 0x09, 0x30, 0x39, 0x38, 
	0x31, 0x18, 0x61, 0x0c, 0x40, 0x04, 0xc1, 0x06, 0xc0, 0x06, 0xff, 0xfe, 0x00, 0x00,
};
const unsigned char gasolina [] PROGMEM = 
{
  0x1f, 0xfc, 0x00, 0x3f, 0xfe, 0x00, 0x3f, 0xff, 0xc0, 0x30, 0x07, 0xe0, 0x30, 0x06, 0xf0, 0x30, 
	0x06, 0x78, 0x30, 0x06, 0x3c, 0x30, 0x06, 0x3c, 0x3f, 0xfe, 0x3c, 0x3f, 0xfe, 0x3c, 0x3f, 0xfe, 
	0x3c, 0x3f, 0xff, 0xdc, 0x3f, 0xff, 0xcc, 0x3f, 0xff, 0xec, 0x3f, 0xfe, 0xec, 0x3f, 0xfe, 0xec, 
	0x3f, 0xfe, 0xec, 0x3f, 0xfe, 0xec, 0x3f, 0xfe, 0xfc, 0x3f, 0xfe, 0x7c, 0xff, 0xff, 0xfc, 0xff, 
	0xff, 0x80
};
const unsigned char helice1 [] PROGMEM = 
{
  0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 0xfe, 0x00, 0x01, 0xfe, 0x00, 0x01, 0xfc, 0x00, 0x01, 
	0xf0, 0x00, 0x78, 0xf0, 0x00, 0x78, 0xf3, 0xc0, 0x7c, 0xff, 0xe0, 0x7f, 0xff, 0xf0, 0x7f, 0xdf, 
	0xf0, 0x7f, 0xff, 0xf0, 0x3c, 0x71, 0xf0, 0x00, 0x70, 0xe0, 0x00, 0xf8, 0xc0, 0x01, 0xf8, 0x00, 
	0x03, 0xf8, 0x00, 0x03, 0xf8, 0x00, 0x03, 0xf0, 0x00, 0x01, 0xf0, 0x00
  };
const unsigned char helice2 [] PROGMEM = 
{
 0x00, 0x00, 0x00, 0x0c, 0x0f, 0x80, 0x3c, 0x1f, 0xc0, 0x3e, 0x3f, 0xe0, 0x7e, 0x3f, 0xf0, 0x7e, 
	0x3f, 0xf0, 0x7f, 0x3f, 0xe0, 0x7f, 0xff, 0x00, 0x7f, 0xfc, 0x00, 0x3f, 0xfc, 0x00, 0x1f, 0xdf, 
	0x80, 0x01, 0xff, 0xe0, 0x01, 0xff, 0xf0, 0x07, 0xff, 0xf0, 0x3f, 0xe7, 0xf0, 0x7f, 0xe7, 0xf0, 
	0x7f, 0xe7, 0xf0, 0x7f, 0xc3, 0xe0, 0x3f, 0xc3, 0xe0, 0x0f, 0x81, 0xc0
  };
const unsigned char helice3 [] PROGMEM = 
{
  	0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x0f, 0x80, 0x00, 0x1f, 0x80, 0x00, 0x1f, 0x87, 0x00, 0x1f, 
	0x8f, 0x80, 0x1f, 0xbf, 0xe0, 0x0f, 0xff, 0xe0, 0x07, 0xff, 0xe0, 0x07, 0xff, 0xe0, 0x03, 0xb8, 
	0xc0, 0xff, 0xf8, 0x00, 0xff, 0xfc, 0x00, 0xff, 0xfc, 0x00, 0xff, 0x7f, 0x00, 0x7c, 0x3f, 0x00, 
	0x3c, 0x7f, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7c, 0x00
  };

const unsigned char logo [] PROGMEM = 
{
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x01, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x07, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xe0, 0x00, 0x00, 
	0x00, 0x00, 0x3f, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xf8, 0x00, 0x00, 
	0x00, 0x01, 0xf8, 0x1f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0x00, 
	0x00, 0x03, 0xc0, 0xff, 0xff, 0x03, 0xfc, 0x00, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0x07, 0xc0, 0x00, 
	0x00, 0x0f, 0x07, 0xff, 0xfe, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc1, 0xe0, 0x00, 
	0x00, 0x3c, 0x3f, 0xff, 0xfc, 0x7f, 0xff, 0x38, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x78, 0x00, 
	0x00, 0x70, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0x7f, 0x80, 0x03, 0xff, 0xff, 0xff, 0xfe, 0x1e, 0x00, 
	0x01, 0xe3, 0xff, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x87, 0x00, 
	0x03, 0x8f, 0xff, 0xff, 0xf1, 0xfb, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x80, 
	0x07, 0x1f, 0xff, 0xff, 0xf1, 0xf3, 0xf3, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xc0, 
	0x0e, 0x3f, 0xff, 0xff, 0xf1, 0xe3, 0xe7, 0xaf, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xfc, 0xe0, 
	0x1c, 0x7f, 0xff, 0xff, 0xf0, 0x07, 0xc7, 0x2f, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x70, 
	0x18, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0x8f, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0x30, 
	0x39, 0xff, 0xff, 0xff, 0xf8, 0x1e, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0x18, 
	0x33, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xdf, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0x98, 
	0x33, 0xff, 0xff, 0xff, 0xff, 0xee, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0x9c, 
	0x73, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x9f, 0xf1, 0xc7, 0xf8, 0xf1, 0xff, 0xff, 0xff, 0xcc, 
	0x73, 0xff, 0xff, 0xff, 0x1f, 0xfc, 0x7e, 0x13, 0xc0, 0x83, 0xe0, 0x21, 0xff, 0xff, 0xff, 0xcc, 
	0x73, 0xff, 0xff, 0xfe, 0x7f, 0xf8, 0xfc, 0x79, 0x88, 0x03, 0xc3, 0x03, 0xff, 0xff, 0xff, 0xcc, 
	0x73, 0xff, 0xff, 0xfc, 0xff, 0xf1, 0xf8, 0xf9, 0x18, 0x03, 0x8f, 0x83, 0xff, 0xff, 0xff, 0x9c, 
	0x33, 0xff, 0xff, 0xf8, 0xff, 0xe1, 0xf1, 0xf8, 0x38, 0x67, 0x1f, 0x87, 0xff, 0xff, 0xff, 0x98, 
	0x39, 0xff, 0xff, 0xf9, 0xff, 0xc3, 0xe3, 0xf8, 0x70, 0x7e, 0x3f, 0x07, 0xff, 0xff, 0xff, 0x98, 
	0x19, 0xff, 0xff, 0xf9, 0xff, 0x87, 0xe3, 0xf8, 0xf0, 0x7c, 0x3f, 0x0f, 0xff, 0xff, 0xff, 0x38, 
	0x1c, 0xff, 0xff, 0xf0, 0xff, 0x07, 0xc7, 0xf9, 0xe1, 0x00, 0x7e, 0x1f, 0x7f, 0xff, 0xfe, 0x70, 
	0x0e, 0x7f, 0xff, 0xf8, 0xfe, 0x0f, 0xc7, 0xf3, 0xe3, 0x80, 0x7e, 0x1e, 0xff, 0xff, 0xfc, 0x60, 
	0x07, 0x3f, 0xff, 0xf8, 0x70, 0x1f, 0x87, 0xe3, 0xc3, 0xfc, 0x7c, 0x3c, 0xff, 0xff, 0xf8, 0xc0, 
	0x03, 0x8f, 0xff, 0xf8, 0x00, 0x3f, 0x07, 0xc7, 0xc7, 0xfc, 0x78, 0x31, 0xff, 0xff, 0xe3, 0x80, 
	0x01, 0xc7, 0xff, 0xfc, 0x00, 0x7e, 0x60, 0x0f, 0x8f, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xc7, 0x00, 
	0x00, 0xf1, 0xff, 0xfe, 0x00, 0xff, 0xf0, 0x1f, 0x0f, 0xfe, 0x02, 0x0f, 0xff, 0xff, 0x1e, 0x00, 
	0x00, 0x3c, 0x3f, 0xff, 0x83, 0xff, 0xfc, 0x7f, 0x1f, 0xff, 0xff, 0x3f, 0xff, 0xfc, 0x3c, 0x00, 
	0x00, 0x1e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xf0, 0x00, 
	0x00, 0x07, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xc0, 0x00, 
	0x00, 0x01, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0x00, 0x00, 
	0x00, 0x00, 0x7e, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xfc, 0x00, 0x00, 
	0x00, 0x00, 0x0f, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xe0, 0x00, 0x00, 
	0x00, 0x00, 0x01, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0x80, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

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 = (ADC * 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)-correccion; //Aplicamos directamente Steinhart-hart para NTC                                           

  /* el  circuito     Analog pin A2
  *                         |
  *    GND |-----/\/\/\-----+-----/\/\/\-----| 5V
  *               ^                ^ 
  *           R termistor        SERIESRESISTOR */
}
int fillArc2(int x, int y, int start_angle, int seg_count, int rx, int ry, int w, unsigned int colour)
{
 // x,y == coordenadas del centro del arco
 // start_angle = 0 - 359
 // seg_count = número de segmentos de 3 grados para dibujar (120 = arco de 360 ​​grados)
 // rx = radio del eje x
 // yx = radio del eje y
 // w  = ancho (grosor) del arco en píxeles
 // color = valor de color de 8 bits "WHITE"
  byte seg = 3; // Los segmentos tienen 3 grados de ancho = 120 segmentos para 360 grados
  byte inc = 6; // Dibuje segmentos cada 3 grados, aumente a 6 para el anillo segmentado
    // Calcular el primer par de coordenadas para el inicio del segmento
    float sx = cos((start_angle - 90) * DEG2RAD);
    float sy = sin((start_angle - 90) * DEG2RAD);
    uint16_t x0 = sx * (rx - w) + x;
    uint16_t y0 = sy * (ry - w) + y;
    uint16_t x1 = sx * rx + x;
    uint16_t y1 = sy * ry + y;
  // Dibuja bloques de color cada grado inc.
  for (int i = start_angle; i < start_angle + seg * seg_count; i += inc) {
    // Calcular par de coordenadas para el final del segmento
    float sx2 = cos((i + seg - 90) * DEG2RAD);
    float sy2 = sin((i + seg - 90) * DEG2RAD);
    int x2 = sx2 * (rx - w) + x;
    int y2 = sy2 * (ry - w) + y;
    int x3 = sx2 * rx + x;
    int y3 = sy2 * ry + y;
    display.fillTriangle(x0, y0, x1, y1, x2, y2, colour);
    display.fillTriangle(x1, y1, x2, y2, x3, y3, colour);
    // Copie el final del segmento al inicio del segmento para el siguiente segmento
    x0 = x2;
    y0 = y2;
    x1 = x3;
    y1 = y3;
  }
}
void voltimetro(int volt)
{
  /* circuito divisor de voltaje:
  *                  Analog pin A1
  *                         |
  *    GND |-----/\/\/\-----+-----/\/\/\-----| 12V
  *               ^                ^ 
  *           10k resistencia        100K resistencia */
  display.setTextSize(2); display.setCursor(40,0); 
  display.print(Volt,1); display.print("V");
}
void helice()
{
  static uint8_t frame = 0 ;
  if(frame==0){display.drawBitmap(53,V,helice1,20,20,WHITE);}
  if(frame==1){display.drawBitmap(53,V,helice2,20,20,WHITE);}
  if(frame==2){display.drawBitmap(53,V,helice3,20,20,WHITE);}
  frame++;
  if(frame>2){ frame = 0; }
}
void ventilador()
{
    if (RL1s==true ) { V=22; helice();}
    if (RL2s==true ) { V=42; helice();}
}

void setup() 
{
  pinMode(ni,INPUT); pinMode(te,INPUT); pinMode(vo,INPUT); //Configurados entradas analogicas
  pinMode(RL1, OUTPUT); pinMode(RL2, OUTPUT);             //Configurados como salidas digitales
  PORTD&=~_BV(RL1); PORTD&=~_BV(RL2);                     //Relés inician apagados
  delay(1000);                                              // se da una espera de 100ms para que el display inicie correctamente
  Watchdog.enable(RST_MODE, WDT_TIMEOUT_4S);             // Modo de generación de interrupciones, tiempo de espera ~ 4s
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);              //Activar display con la dirección 0x3C
  display.clearDisplay();                                //Borrar buffer display
  display.setTextColor(WHITE);                           //Texto color blanco
  display.drawBitmap(0,16,logo,128,53,WHITE);            //carga grafico logo ford
  display.display();                                     //muestra datos cargados
  delay(800);                                            //pausa de 0.8 ó 1 seg
  display.clearDisplay();                                //Borrar buffer display
  EasyBuzzer.setPin(buzzer);                             //Selecciona el pin de salida pwm buzzer
  EasyBuzzer.beep( 2000, 1000, 500);                      //Frecuencia en Hz, Duración beep ms ,pausa silencio ms                          
  EasyBuzzer.stopBeep();                                 //Inicia buzzer en modo off
  
  timer = millis();  timer2 = millis();                   //tiempos igualados al contador millis
  pausa =  millis();
  
  // Configurar interrupción de tiempo para actualizar la pantalla cada 500ms
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  //OCR1A = 15624;  //15624 para 500ms
  OCR1A = 7812;   // 7812 para 250ms
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
}
  // Función de interrupción de tiempo para actualizar la pantalla

 ISR(TIMER1_COMPA_vect) 
 { 
  TCNT1  = 0; 
  ActualizarOLED = true;
 }

void loop() 
{
                                               
                                                       //(si en 8seg de bloqueo del micro no se verifica en el loop genera un reset general) 
                                                      //Solución al bloqueo por interrupción electromagnetica de los relé que congelaba el micro
  if (millis() > timer) 
  {
    while (sample_count < NUM_SAMPLES){sum += analogRead(ni); sample_count++;}
    p =((float)sum / (float)NUM_SAMPLES * Vref)/ADC;      // Promedio de muestras tomadas 
    m = constrain(p, niMin, niMax);//*10;                       //rango de voltaje y multiplica rango x10
    Nivel=map(m, niMin, niMax, 1,100);
    Nivel1=map(Nivel,1,100,15,55);
    sample_count = 0; sum = 0;                           // Reestablece los contadores
    timer = millis() + 10000UL;                          // actualización de muestras cada 10s
   Watchdog.reset();                                    //Verifica que se mantiene la protección de reseteo en línea
  }
 //****************************************************************************************///  
  if (millis() > timer2) 
  {
    while (sample_count < NUM_SAMPLES){sum += analogRead(vo); sample_count++;}
    p3 =((float)sum / (float)NUM_SAMPLES * Vref)/ADC;     // Promedio de muestras tomadas
    Volt = p3/((float)RV2/(RV1+RV2));                     // Lectura Voltaje final
    sample_count = 0; sum = 0;                           // Reestablece los contadores
    termistor();                                         // Activa la función void termistor
   timer2 = millis() + 2000UL;                           // actualización cada 3s
  Watchdog.reset();                                    //Verifica que se mantiene la protección de reseteo en línea
  }
 //****************************************************************************************

  if (ActualizarOLED) 
  {
    Watchdog.reset();                                  //Verifica que se mantiene la protección de reseteo en línea
    ventilador();
    voltimetro(vo);
    fillArc2(26,44,200,Nivel,25,25,3,WHITE);                                 // Nivel
    temp= map(steinhart,30,115,1,100);
    fillArc2(101,44,200,temp,25,25,3,WHITE);                                // Tempertura

    display.setTextSize(2); display.setCursor(9,36); display.print(Nivel1); display.print("L");
    if (steinhart>99.99){simbol=79;} else{simbol=85;}                      //desplazo de simbolo segun 3 caracteres
    display.setTextSize(2); display.setCursor(simbol,36); display.print(steinhart,0);
    display.setTextSize(1); display.println("o");                           // simbolo de grado
    display.setCursor(16,55); display.print(Nivel,0); display.println("%"); //Porcentaje de nivel en pantalla                          
    if (indicador==true || Volt>=15)  {display.drawBitmap(113,0,advert,15,15,WHITE);} //icono de advertencia
    if (Nivel1 < 22 ) {display.drawBitmap(0,0,gasolina,22,22,WHITE);}    //icono de suministro gasolina
    display.display();                                                 // Actualiza la pantalla                              
    ActualizarOLED = false;                                             // Refresco de pantalla
    display.clearDisplay();
   
  }
  //****************************************************************************************

  if (steinhart>=96){RL1s=true; PORTD|=_BV(RL1); }                         //RL1s=true; digitalWrite(RL1,HIGH); Vent 1 96°C
  if (steinhart<=90 ){RL1s=false; PORTD&=~_BV(RL1);}                      // si es menor igual a 90 RL1 off
  if (steinhart>=103){RL2s=true; PORTD|=_BV(RL2); }                          //RL1s=true; digitalWrite(RL2,HIGH); //Vent 2 104°C         
  if (steinhart<=98){RL2s=false; PORTD&=~_BV(RL2);}                         //RL2s=false; digitalWrite(RL2,LOW); 
  if (steinhart>=112){EasyBuzzer.update(); indicador=true;}                 // Alarma Alta temperatura 110
  else {EasyBuzzer.stopBeep(); indicador=false;}
   Watchdog.reset();                                  //Verifica que se mantiene la protección de reseteo en línea
}

// avrdude -c usbtiny -p m328p -U efuse:w:0x07:m desactiva proteccion de caida de voltaje
// uno.bootloader.extended_fuses=0x07 
// https://dbuezas.github.io/



NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
Proyecto para vehiculo Ford, control de ventilador, temperatura, nivel, tensión DC