#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 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 ADC 1024 // Multiplo de entrada ADC
#define NUM_SAMPLES 5 // NUMERO DE MUESTRAS TOMADAS Voltaje
#define THERMISTOR 10000 // 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 10000 // resistor en serie 10k (1k para spark)
#define RV1 98700 //RV1=100000 ohms
#define RV2 9780 //RV2=10000 ohms
#define DEG2RAD 0.0174532925
unsigned char sample_count=0, m;
int samples[NUMSAMPLES], sum=0, Nivel1, temp;
float steinhart, p, p3, Volt, ba, Nivel;
unsigned long timer, timer2, timer3;
boolean indicador;
const unsigned char bat2 [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x01, 0xfc, 0x00, 0x0f, 0xff, 0x80, 0x0f,
0xff, 0x80, 0x0c, 0x01, 0x80, 0x0c, 0x01, 0x80, 0x0c, 0x01, 0x80, 0x0c, 0x11, 0x80, 0x0c, 0x11,
0x80, 0x0c, 0x21, 0x80, 0x0c, 0x61, 0x80, 0x0c, 0xe1, 0x80, 0x0c, 0xf9, 0x80, 0x0c, 0x31, 0x80,
0x0c, 0x31, 0x80, 0x0c, 0x61, 0x80, 0x0c, 0x41, 0x80, 0x0c, 0x41, 0x80, 0x0c, 0x01, 0x80, 0x0c,
0x01, 0x80, 0x0c, 0x01, 0x80, 0x0f, 0xff, 0x80, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
};
const unsigned char advert [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x90, 0x00, 0x01, 0x98, 0x00, 0x03,
0x0c, 0x00, 0x02, 0x64, 0x00, 0x06, 0x66, 0x00, 0x04, 0x62, 0x00, 0x0c, 0x63, 0x00, 0x18, 0x61,
0x80, 0x18, 0x61, 0x80, 0x30, 0x60, 0xc0, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0xc0, 0x60, 0x30,
0xc0, 0x60, 0x30, 0xe0, 0x00, 0x70, 0x7f, 0xff, 0xe0, 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; //Aplicamos directamente Steinhart-hart para NTC
/* The easy circuit:
* Analog pin A2
* |
* GND |-----/\/\/\-----+-----/\/\/\-----| 5V
* ^ ^
* R termistor 10K resistor
*/
}
int fillArc2(int x, int y, int start_angle, int seg_count, int rx, int ry, int w, unsigned int colour)
{
// x,y == coords of centre of arc
// start_angle = 0 - 359
// seg_count = number of 3 degree segments to draw (120 => 360 degree arc)
// rx = x axis radius
// yx = y axis radius
// w = width (thickness) of arc in pixels
// colour = 8 bit colour value "WHITE"
byte seg = 3; // Segments are 3 degrees wide = 120 segments for 360 degrees
byte inc = 3; // Draw segments every 3 degrees, increase to 6 for segmented ring
// Calculate first pair of coordinates for segment start
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;
// Draw colour blocks every inc degrees
for (int i = start_angle; i < start_angle + seg * seg_count; i += inc) {
// Calculate pair of coordinates for segment end
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);
// Copy segment end to sgement start for next segment
x0 = x2;
y0 = y2;
x1 = x3;
y1 = y3;
}
}
void base(int volt)
{
/* circuito divisor de voltaje:
* Analog pin A1
* |
* GND |-----/\/\/\-----+-----/\/\/\-----| 12V
* ^ ^
* 1k termistor 10K resistor */
Volt=constrain(Volt,10,14.7); //centra solo un voltaje especifico
ba=map(Volt,10,14,127,1); //rango min y max de 10 a 14 voltios
display.drawRect(0,60,128,4,1); //barra exterior
display.fillRect(ba,61,127,3,1); //barra relleno
display.drawBitmap(55,25,bat2,20,27,WHITE); // icono bateria
display.setTextSize(1); display.setCursor(0,52); display.print("100");
display.setTextSize(1); display.setCursor(60,52); display.print("50");
display.setTextSize(1); display.setCursor(115,52); display.print("10");
}
void setup()
{
pinMode(ni, INPUT);
pinMode(te, INPUT); pinMode(vo, INPUT); // Configurados entradas analogicas
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextColor(WHITE);
display.clearDisplay();
display.setTextSize(2); display.setCursor(30,25); display.print("HOLA!!");
display.display();
delay(2000); display.clearDisplay();
EasyBuzzer.setPin(buzzer); //Selecciona el pin de salida
EasyBuzzer.beep( 2000, 500, 500, 3, 1000, 5); //Frecuencia en Hz, Duración beep ms
EasyBuzzer.stopBeep(); //Inicia buzzer en modo off
timer = millis(); timer2 = millis(); timer3 = millis();
}
void loop()
{
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, 0.44, 3.0)*10; //rango de voltaje y multiplica rango x10
Nivel=map(m,4.4, 30, 1,100);
Nivel1=map(Nivel,1,100,8,48);
sample_count = 0; sum = 0; // Reestablece los contadores
timer = millis() + 5000UL; // Refresco cada 5s
}
//****************************************************************************************///
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
timer2 = millis() + 3000UL; // Refresco cada 3s
}
//****************************************************************************************
if (millis() > timer3)
{
base(vo);
termistor();
fillArc2(25,25,200,Nivel,25,25,3,WHITE); // Nivel
temp= map(steinhart,30,115,1,100);
fillArc2(102,25,200,temp,25,25,3,WHITE); // Tempertura
display.setTextSize(2); display.setCursor(9,20); display.print(Nivel1); display.print("L");
display.setTextSize(2); display.setCursor(85,20); display.print(steinhart,0);
display.setTextSize(1); display.println("o"); //display.print((char)247); // degree symbol
if (indicador==true) {display.drawBitmap(54,0,advert,20,20,WHITE);}
display.display(); // Actualiza la pantalla
timer3 = millis() + 500UL; // Refresco cada 500ms
display.clearDisplay();
}
//Condicionales para alarma buzzer e indicación !
if (Volt<10.2 || Nivel1<=10) {EasyBuzzer.update(); indicador=true;}
if (Volt>10.3 || Nivel1>=11) {EasyBuzzer.stopBeep();}
if (steinhart>95) {EasyBuzzer.update(); indicador=true; }
if (steinhart<94 && Nivel1>=10) {EasyBuzzer.stopBeep(); indicador=false;}
}