It’s a very long code but I’ll post the main of it:
// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "no to be shown"
#define BLYNK_DEVICE_NAME "Dosif Continuo 4Ch"
#define BLYNK_FIRMWARE_VERSION "0.2.00"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
#define APP_DEBUG
// Uncomment your board, or configure a custom board in Settings.h
//#define USE_WROVER_BOARD
//#define USE_TTGO_T7
//#define USE_ESP32C3_DEV_MODULE
#define USE_ESP32S2_DEV_KIT
#include "BlynkEdgent.h"
#include <EEPROM.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include <WidgetRTC.h>
#define TFT_GREY 0x5AEB
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
SimpleTimer timer;
#define Max_Dosis 2881
#define Inicio_Eeprom 0
//Define Pines Virtuales Blynk
#define VIRTUAL_PIN_Terminal 0
#define VIRTUAL_PIN_Bomba_Accion 1
#define VIRTUAL_PIN_CANTIDAD_ACCION 2
#define VIRTUAL_PIN_ACCION_RELLENA 3
#define VIRTUAL_PIN_ACCION_ADITA 4
#define VIRTUAL_PIN_BUTTON_IMAGE 5
#define Setup_Notifica_Alarmas 6
#define Setup_Correo_Alarmas 7
#define VIRTUAL_PIN_INTERVALO_DOSIS 8
#define VIRTUAL_PIN_Dosis_Totales 9
#define Configura_Dosis_Canal_1 10
#define Configura_Dosis_Canal_2 11
#define Configura_Dosis_Canal_3 12
#define Configura_Dosis_Canal_4 13
#define Setup_Nombre_Bomba_1 20
#define Setup_Nombre_Bomba_2 21
#define Setup_Nombre_Bomba_3 22
#define Setup_Nombre_Bomba_4 23
#define Setup_Calibrar_Bomba_1 30
#define Setup_Calibrar_Bomba_2 31
#define Setup_Calibrar_Bomba_3 32
#define Setup_Calibrar_Bomba_4 33
#define Setup_Calibracion_Bomba_1 40
#define Setup_Calibracion_Bomba_2 41
#define Setup_Calibracion_Bomba_3 42
#define Setup_Calibracion_Bomba_4 43
#define Panel_Level_Bomba_1 50
#define Panel_Level_Bomba_2 51
#define Panel_Level_Bomba_3 52
#define Panel_Level_Bomba_4 53
#define Panel_Activa_Bomba_1 60
#define Panel_Activa_Bomba_2 61
#define Panel_Activa_Bomba_3 62
#define Panel_Activa_Bomba_4 63
#define Setup_Alarma_Aditivo_1 70
#define Setup_Alarma_Aditivo_2 71
#define Setup_Alarma_Aditivo_3 72
#define Setup_Alarma_Aditivo_4 73
#define Configura_Micro_Dosis_Bomba_1 80
#define Configura_Micro_Dosis_Bomba_2 81
#define Configura_Micro_Dosis_Bomba_3 82
#define Configura_Micro_Dosis_Bomba_4 83
#define Panel_Sensor_Bomba_1 90
#define Panel_Sensor_Bomba_2 91
#define Panel_Sensor_Bomba_3 92
#define Panel_Sensor_Bomba_4 93
#define LCD 100 // LCD Blynk
#define ON_OFF 101 // Enciende/Apaga dosificadora
//Define salidas/entradas DIO
#define Sleep_BCD_A 12 //GPIO D4
#define Sleep_BCD_B 13 //GPIO Tx
#define Sleep_BCD_C 14 //GPIO Rx
#define StepPin 16 //GPIO D0
// TFT Defines. The scrolling area must be a integral multiple of TEXT_HEIGHT
#define TEXT_HEIGHT 8 // Height of text to be printed and scrolled
#define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
#define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
#define YMAX 320 // Bottom of screen area
WidgetLCD lcd(LCD);
WidgetRTC rtc;
WidgetTerminal terminal(VIRTUAL_PIN_Terminal);
//Definiciones de variables TFT
// The initial y coordinate of the top of the scrolling area
uint16_t yStart = TOP_FIXED_AREA;
// yArea must be a integral multiple of TEXT_HEIGHT
uint16_t yArea = YMAX-TOP_FIXED_AREA-BOT_FIXED_AREA;
// The initial y coordinate of the top of the bottom text line
uint16_t yDraw = YMAX - BOT_FIXED_AREA - TEXT_HEIGHT;
// Keep track of the drawing x coordinate
uint16_t xPos = 0;
// For the byte we read from the serial port
//byte data = 0;
// A few test variables used during debugging
boolean change_colour = 1;
boolean selected = 1;
// We have to blank the top line each time the display is scrolled, but this takes up to 13 milliseconds
// for a full width line, meanwhile the serial buffer may be filling... and overflowing
// We can speed up scrolling of short text lines by just blanking the character we drew
int blank[19]; // We keep all the strings pixel lengths to optimise the speed of the top line blanking
float dosis[6] = { 0.0,0.0,0.0,0.0};
float paso[6] = { 0.0,0.0,0.0,0.0};
float Nro_Dosis[6] = {0,0,0,0,0};
float dosis_Blynk[6] = { 0.0,0.0,0.0,0.0};
float paso_Blynk[6] = { 0.0,0.0,0.0,0.0};
float micro_dosis[6] = {0.1,0.2,0.5,1.0,5.0};
int motor[6] = {0,0,0,0,0};
float Aditivo_Restante[6];
int Steps[6] = {0,0,0,0,0};
String Bomba[6];
int alarma_aditivo[6] = {0,0,0,0,0};
bool correo_alarmas = false;
bool notifica_alarmas = false;
float Numero_dosis = 0;
int index_dosis = 0;
byte Canales_Activos = 0;
bool Canal_Activo[5]={false, false, false, false};
bool encuentra;
bool Blynk_conectado = false;
bool dosificar = false;
unsigned long millis_anterior;
unsigned long millis_actual;
unsigned long Intervalo_dosis = 86400000;
unsigned long Ciclo_dosis;
byte secuencia[Max_Dosis];
bool conectado = false;
bool Restart = true;
bool Dosificador_activado = false;
byte Aditivo_Recarga = 0;
int Cantidad_Recarga = 0;
char Date_Time[32]; //contendrá la fecha y hora a imprimir
char Time[9]; // contendrá la hora a imprimir
int eeAddress = 1024;
// Inicia Rutinas Blynk
BLYNK_CONNECTED() {
// Synchronize time on connection
// Change Web Link Button message to "Congratulations!"
Blynk.sendInternal("rtc", "sync");
delay(10);
// rtc.begin();
// Blynk.setProperty(VIRTUAL_PIN_BUTTON_IMAGE, "offImageUrl", "https://jumpseller.s3.eu-west-1.amazonaws.com/store/triton-labs-chile/assets/Logo%20Sunny%20Reef%20On.png");
// Blynk.setProperty(VIRTUAL_PIN_BUTTON_IMAGE, "onImageUrl", "https://jumpseller.s3.eu-west-1.amazonaws.com/store/triton-labs-chile/assets/Logo%20Sunny%20Reef%20On.png");
Blynk.setProperty(VIRTUAL_PIN_BUTTON_IMAGE, "url", "https://www.triton-labs.cl/");
conectado = true;
terminal.println();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawCentreString(F("Blynk v" BLYNK_VERSION), 120, yDraw, 1);
yDraw = scroll_line();
terminal.println(F("Blynk v" BLYNK_VERSION));
tft.drawCentreString(F("---------------------"), 120, yDraw, 1);
yDraw = scroll_line();
terminal.println(F("---------------------"));
tft.drawCentreString(F("** Doser Continuo **"), 120, yDraw, 1);
yDraw = scroll_line();
terminal.println(F("** Doser Continuo **"));
tft.drawCentreString(F("** Listo **"), 120, yDraw, 1);
yDraw = scroll_line();
terminal.println(F("** Listo **"));
tft.drawCentreString(F("----------------------"), 120, yDraw, 1);
yDraw = scroll_line();
terminal.println(F("----------------------"));
terminal.print(F("V "));
terminal.println(BLYNK_FIRMWARE_VERSION);
int t = now(); // Guarda la hora actual en t
String currentTime = String(hour()) + ":" + minute();
int h = hour(t); // returns the hour for the given time t
int m = minute(t);// returns the minute for the given time t
Serial.println("hora " + String(h) + ":" + String(m));
terminal.println("hora " + String(h) + ":" + String(m));
if (Restart)
{
Blynk.notify("ALERTA DOSER: Reiniciando Dispositivo" + currentTime);
String Mensaje = String("ALERTA DOSER: Reiniciando Dispositivo " + currentTime);
Blynk.email("Alerta Dispositivo Acuario", Mensaje);
terminal.println(Mensaje);
Restart = false;
}
else
{
Blynk.notify("ALERTA DOSER: Reconectando Dispositivo" + currentTime);
String Mensaje = String("ALERTA DOSER: Reconectando Dispositivo " + currentTime);
Blynk.email("Alerta Dispositivo Acuario", Mensaje);
terminal.println(Mensaje);
}
terminal.flush();
Blynk.syncAll();
Filtra_Canales();
calcula_intervalo()
}
BLYNK_WRITE(Panel_Activa_Bomba_1)
{
int i = 0;
Canal_Activo[i] = param.asInt();
}
BLYNK_WRITE(Panel_Activa_Bomba_2)
{
int i = 1;
Canal_Activo[i] = param.asInt();
}
BLYNK_WRITE(Panel_Activa_Bomba_3)
{
int i = 2;
Canal_Activo[i] = param.asInt();
}
BLYNK_WRITE(Panel_Activa_Bomba_4)
{
int i = 3;
Canal_Activo[i] = param.asInt();
}
}
BLYNK_WRITE(Configura_Dosis_Canal_1)
{
int i = 0;
dosis_Blynk[i] = param.asFloat();
}
BLYNK_WRITE(Configura_Dosis_Canal_2)
{
int i = 1;
dosis_Blynk[i] = param.asFloat();
}
BLYNK_WRITE(Configura_Dosis_Canal_3)
{
int i = 2;
dosis_Blynk[i] = param.asFloat();
}
BLYNK_WRITE(Configura_Dosis_Canal_4)
{
int i = 3;
dosis_Blynk[i] = param.asFloat();
}
BLYNK_WRITE(Configura_Micro_Dosis_Bomba_1)
{
int i = 0;
paso_Blynk[i] = micro_dosis[param.asInt()];
}
BLYNK_WRITE(Configura_Micro_Dosis_Bomba_2)
{
int i = 1;
paso_Blynk[i] = micro_dosis[param.asInt()];
}
BLYNK_WRITE(Configura_Micro_Dosis_Bomba_3)
{
int i = 2;
paso_Blynk[i] = micro_dosis[param.asInt()];
}
BLYNK_WRITE(Configura_Micro_Dosis_Bomba_4)
{
int i = 3;
paso_Blynk[i] = micro_dosis[param.asInt()];
}
BLYNK_WRITE(ON_OFF)
{
bool change = false;
Dosificador_activado = param.asInt();
eeAddress = Inicio_Eeprom;
EEPROM.put(eeAddress,Dosificador_activado);
delay(10);
EEPROM.commit();
}
BLYNK_WRITE(Panel_Level_Bomba_1)
{
Aditivo_Restante[0] = param.asFloat();
}
BLYNK_WRITE(Panel_Level_Bomba_2)
{
Aditivo_Restante[1] = param.asFloat();
}
BLYNK_WRITE(Panel_Level_Bomba_3)
{
Aditivo_Restante[2] = param.asFloat();
}
BLYNK_WRITE(Panel_Level_Bomba_4)
{
Aditivo_Restante[3] = param.asFloat();
}
BLYNK_WRITE(Setup_Alarma_Aditivo_1)
{
alarma_aditivo[0] = param.asInt();
}
BLYNK_WRITE(Setup_Alarma_Aditivo_2)
{
alarma_aditivo[1] = param.asInt();
}
BLYNK_WRITE(Setup_Alarma_Aditivo_3)
{
alarma_aditivo[2] = param.asInt();
}
BLYNK_WRITE(Setup_Alarma_Aditivo_4)
{
alarma_aditivo[3] = param.asInt();
}
BLYNK_WRITE(Setup_Notifica_Alarmas)
{
if(param.asInt())
{
notifica_alarmas = true;
}
else
{
notifica_alarmas = false;
}
}
BLYNK_WRITE(Setup_Correo_Alarmas)
{
if(param.asInt())
{
correo_alarmas = true;
}
else
{
correo_alarmas = false;
}
}
BLYNK_WRITE(Setup_Nombre_Bomba_1)
{
int i = 0;
Bomba[i] = param.asStr();
// Blynk.setProperty(Configura_Dosis_Canal_1, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(VIRTUAL_PIN_Bomba_Accion, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(Panel_Level_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Panel_Activa_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Configura_Micro_Dosis_Bomba_1 + i,"label","Micro Dosis "+ Bomba[i]);
Blynk.setProperty(Configura_Dosis_Canal_1 + i,"label","Dosis "+ Bomba[i]);
Blynk.setProperty(Setup_Alarma_Aditivo_1 + i,"label","Alarma nivel "+ Bomba[i]);
}
BLYNK_WRITE(Setup_Nombre_Bomba_2)
{
int i = 1;
Bomba[i] = param.asStr();
// Blynk.setProperty(Configura_Dosis_Canal_1, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(VIRTUAL_PIN_Bomba_Accion, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(Panel_Level_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Panel_Activa_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Configura_Micro_Dosis_Bomba_1 + i,"label","Micro Dosis "+ Bomba[i]);
Blynk.setProperty(Configura_Dosis_Canal_1 + i,"label","Dosis "+ Bomba[i]);
Blynk.setProperty(Setup_Alarma_Aditivo_1 + i,"label","Alarma nivel "+ Bomba[i]);
}
BLYNK_WRITE(Setup_Nombre_Bomba_3)
{
int i = 2;
Bomba[i] = param.asStr();
// Blynk.setProperty(Configura_Dosis_Canal_1, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(VIRTUAL_PIN_Bomba_Accion, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(Panel_Level_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Panel_Activa_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Configura_Micro_Dosis_Bomba_1 + i,"label","Micro Dosis "+ Bomba[i]);
Blynk.setProperty(Configura_Dosis_Canal_1 + i,"label","Dosis "+ Bomba[i]);
Blynk.setProperty(Setup_Alarma_Aditivo_1 + i,"label","Alarma nivel "+ Bomba[i]);
}
BLYNK_WRITE(Setup_Nombre_Bomba_4)
{
int i = 3;
Bomba[i] = param.asStr();
// Blynk.setProperty(Configura_Dosis_Canal_1, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(VIRTUAL_PIN_Bomba_Accion, "labels", Bomba[0], Bomba[1], Bomba[2], Bomba[3]);
Blynk.setProperty(Panel_Level_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Panel_Activa_Bomba_1 + i, "label", Bomba[i]);
Blynk.setProperty(Configura_Micro_Dosis_Bomba_1 + i,"label","Micro Dosis "+ Bomba[i]);
Blynk.setProperty(Configura_Dosis_Canal_1 + i,"label","Dosis "+ Bomba[i]);
Blynk.setProperty(Setup_Alarma_Aditivo_1 + i,"label","Alarma nivel "+ Bomba[i]);
}
BLYNK_WRITE(VIRTUAL_PIN_Bomba_Accion)
{
Aditivo_Recarga = param.asInt();
}
BLYNK_WRITE(VIRTUAL_PIN_CANTIDAD_ACCION)
{
Cantidad_Recarga = param.asInt();
}
// Termina Rutinas Blynk
void guarda_activo( byte indice, bool dato )
{
eeAddress = 1 + (indice * sizeof(bool));
// Serial.println("Guarda Activo " + String(indice) + " en " + String(eeAddress));
EEPROM.put(eeAddress,dato);
EEPROM.commit();
}
void guarda_dosis( byte indice, float dato )
{
eeAddress = 5 + ( indice * sizeof(float));
// Serial.println("Guarda Dosis " + String(indice) + " en " + String(eeAddress));
EEPROM.put(eeAddress,dato);
EEPROM.commit();
}
void guarda_paso( byte indice, float dato)
{
eeAddress = 21 + (indice * sizeof(float));
// Serial.println("Guarda Paso " + String(indice) + " en " + String(eeAddress));
EEPROM.put(eeAddress,dato);
EEPROM.commit();
}
void dosificadora_off()
{
lcd.clear();
lcd.print(0,0," DETENIENDO ");
lcd.print(0,1," DOSIFICADORA ");
// 1234567890123456
Blynk.virtualWrite(ON_OFF, LOW);
Dosificador_activado = false;
}
float redondear(float valor)
{
long expo = 1;
float aux= (long)(valor*expo+0.5)/(float)expo;
return aux;
}
void Filtra_Canales()
{
// función que filtra solo los canales activos y recalcula el Numero_dosis
Canales_Activos = 0;
int indice = 0;
int fin = 0 ;
int index = 0;
for (int i = 0; i < 4 ; i++)
{
if (Canal_Activo[i])
{
dosis[index] = dosis_Blynk[i];
paso[index] = paso_Blynk[i];
fin = indice + (paso[index]/dosis[index]);
motor[index] = i;
for ( int x = inicio ; x < fin ; x++ )
{
secuencia[x] = motor[index]
indice++;
}
Canales_Activos++;
index++;
}
}
// Serial.println("Filtra Canales...");
for (int i = 0; i < Canales_Activos ; i++)
{
// Serial.println(String(i) + " : " + String(dosis[i]) + " : " + String(paso[i]));
}
}
bool calcula_intervalo()
{
// Calcula el total de dosis considerando las bombas activas, la dosis total y el paso de cada dosis
bool aux = false;
Numero_dosis = 0;
// Serial.println("Calcula Intervalo...:" + String(Numero_dosis));
for ( int i = 0 ; i < Canales_Activos ; i++)
{
Nro_Dosis[i] = dosis[i]/paso[i];
Numero_dosis = Numero_dosis + Nro_Dosis[i];
Steps[i] = paso[i] * 1000;
// Serial.println(String(i) + " : " + String(dosis[i]) + " : " + String(paso[i]) + " : " + String(Nro_Dosis[i]) + " : " + String(Numero_dosis));
}
if ( Numero_dosis < Max_Dosis )
{
for ( int i = 0; i < Numero_dosis ; i++)
{
secuencia[i] = 5;
}
Intervalo_dosis = 24*60*60*1000/(Numero_dosis + 1);
Blynk.virtualWrite(VIRTUAL_PIN_INTERVALO_DOSIS, Intervalo_dosis/1000);
Blynk.setProperty(VIRTUAL_PIN_Dosis_Totales, "color", "#23C48E");
Blynk.virtualWrite(VIRTUAL_PIN_Dosis_Totales, Numero_dosis);
aux = true;
}
else
{
lcd.print(0,0,"EXCESO DE DOSIS ");
lcd.print(0,1,"BAJAR MICRODOSIS");
Blynk.setProperty(VIRTUAL_PIN_Dosis_Totales, "color", "#D3435C");
Blynk.virtualWrite(VIRTUAL_PIN_Dosis_Totales, Numero_dosis);
}
return aux;
}
void activa_motor(int motor)
{
if ( motor == 0)
{
// digitalWrite(Enable1, LOW);
digitalWrite(Sleep_BCD_A, HIGH);
digitalWrite(Sleep_BCD_B, LOW);
digitalWrite(Sleep_BCD_C, LOW);
}
if ( motor == 1)
{
// digitalWrite(Enable2, LOW);
digitalWrite(Sleep_BCD_A, LOW);
digitalWrite(Sleep_BCD_B, HIGH);
digitalWrite(Sleep_BCD_C, LOW);
}
if ( motor == 2)
{
// digitalWrite(Enable3, LOW);
digitalWrite(Sleep_BCD_A, HIGH);
digitalWrite(Sleep_BCD_B, HIGH);
digitalWrite(Sleep_BCD_C, LOW);
}
if ( motor == 3)
{
// digitalWrite(Enable4, LOW);
digitalWrite(Sleep_BCD_A, LOW);
digitalWrite(Sleep_BCD_B, LOW);
digitalWrite(Sleep_BCD_C, HIGH);
}
if ( motor == 5)
{
digitalWrite(Sleep_BCD_A, LOW);
digitalWrite(Sleep_BCD_B, LOW);
digitalWrite(Sleep_BCD_C, LOW);
/* digitalWrite(Enable1, HIGH);
digitalWrite(Enable2, HIGH);
digitalWrite(Enable3, HIGH);
digitalWrite(Enable4, HIGH); */
}
}
void Verifica_dosis()
{
if (dosificar)
{
if (index_dosis >= Numero_dosis)
{
index_dosis = 0;
}
if (Dosificador_activado)
{
int t = now(); // Guarda la hora actual en t
String currentTime = String(hour(t)) + ":" + minute(t);
activa_motor(secuencia[index_dosis]);
delay(1);
for (int paso = 0; paso < Steps[secuencia[index_dosis]] ; paso++ )
{
digitalWrite(StepPin, HIGH);
delayMicroseconds(1000);
digitalWrite(StepPin, LOW);
delayMicroseconds(1000);
yield();
}
delay(1);
activa_motor(5);
Aditivo_Restante[secuencia[index_dosis]] = Aditivo_Restante[secuencia[index_dosis]] - paso_Blynk[secuencia[index_dosis]];
if ( Aditivo_Restante[secuencia[index_dosis]] < alarma_aditivo[secuencia[index_dosis]] )
{
String Mensaje = String(" Aditivo Bajo - Debe recargar " + Bomba[secuencia[index_dosis]]);
if (notifica_alarmas) Blynk.notify("ALERTA DOSER: " + currentTime + Mensaje);
if (correo_alarmas) Blynk.email("Alerta Dispositivo Acuario", Mensaje);
}
// Blynk.virtualWrite(Panel_Level_Bomba_1 + secuencia[index_dosis] , Aditivo_Restante[secuencia[index_dosis]]);
int h = hour(t); // returns the hour for the given time t
int m = minute(t);// returns the minute for the given time t
int s = second(t);// returns the seconds for the given time t
int y = year(t);
int mo = month(t);
int d = day(t);
char Txt_print_1[17];
char Txt_print_2[17];
char txt_paso[3];
lcd.clear();
// tft.drawString(" ", 0, yDraw, 1);
yDraw = scroll_line();
xPos = 0;
tft.setTextColor(TFT_WHITE, TFT_BLACK);
snprintf(Txt_print_1, sizeof(Txt_print_1), "%02d/%02d %02d:%02d:%02d ", d, mo, h, m, s);
lcd.print(0,0,Txt_print_1);
xPos += tft.drawString(Txt_print_1, xPos, yDraw, 1);
dtostrf(paso_Blynk[secuencia[index_dosis]], 3 , 1, txt_paso);
snprintf(Txt_print_2, sizeof(Txt_print_2), "%-9s\n", Bomba[secuencia[index_dosis]]);
// Blynk.logEvent("dosis", String(Txt_print_1) + String(Txt_print_2) + String(txt_paso) + String(" ml"));
lcd.print(0,1,Txt_print_2);
xPos += tft.drawString(Txt_print_2, xPos, yDraw, 1);
lcd.print(10,1,txt_paso);
xPos += tft.drawString(txt_paso, xPos, yDraw, 1);
lcd.print(14,1,"ml");
xPos += tft.drawString(" ml", xPos, yDraw, 1);
yDraw = scroll_line();
// Serial.println(String(index_dosis) + " : -> " + String(h) + ":" + String(m) + " - " + Bomba[secuencia[index_dosis]] + " " + String(Steps[secuencia[index_dosis]]));
}
index_dosis++;
dosificar = false;
}
}
void Update_time_TFT()
{
int t = now(); // Guarda la hora actual en t
String currentTime = String(hour()) + ":" + minute();
int h = hour(t); // returns the hour for the given time t
int m = minute(t);// returns the minute for the given time t
int s = second(t);// returns the seconds for the given time t
int y = year(t);
int mo = month(t);
int d = day(t);
snprintf(Date_Time, sizeof(Date_Time), "%02d/%02d/%4d %02d:%02d:%02d", d, mo, y, h, m, s);
tft.setTextColor(TFT_WHITE, TFT_BLUE);
tft.drawCentreString(Date_Time,120,32,2);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (Blynk.connected())
{
if (!Blynk_conectado)
{
Blynk_conectado = true;
for ( int i = 0 ; i < 4 ; i++)
{
tft.fillRect(222 + i*2,8 + i*4 , 16 - i*4 , 2, TFT_GREEN);
}
}
} else
{
if (Blynk_conectado)
{
Blynk_conectado = false;
for ( int i = 0 ; i < 4 ; i++)
{
tft.fillRect(222 + i*2,8 + i*4 , 16 - i*4 , 2, TFT_RED);
}
}
}
tft.setTextColor(TFT_WHITE, TFT_DARKGREY);
tft.setFreeFont(NULL);
}
void setup() {
// put your setup code here, to run once:
pinMode(Sleep_BCD_A, OUTPUT);
pinMode(Sleep_BCD_B, OUTPUT);
pinMode(Sleep_BCD_C, OUTPUT);
pinMode(StepPin, OUTPUT);
digitalWrite(StepPin, LOW);
activa_motor(5);
EEPROM.begin(2048);
// Serial.begin(115200);
// Serial.println("comienza algoritmo");
// dosis[0] = 12; paso[0] = 0.1; // 120
// dosis[1] = 16; paso[1] = 0.1; // 120
// dosis[2] = 18; paso[2] = 0.1; // 120
// dosis[3] = 20; paso[3] = 0.1; // 120 */
millis_anterior = millis();
// Setup the TFT display
tft.init();
tft.setRotation(0); // Must be setRotation(0) for this sketch to work correctly
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLUE);
tft.fillRect(0,0,240,48, TFT_BLUE);
tft.drawCentreString(" WWW.TRITON-LABS.CL ",120,0,2);
tft.drawCentreString(" Doser Cont. - V2.00 ",120,16,2);
// Change colour for scrolling zone text
tft.setTextColor(TFT_WHITE, TFT_BLACK);
// Setup scroll area
setupScrollArea(TOP_FIXED_AREA, BOT_FIXED_AREA);
// Zero the array
for (byte i = 0; i<18; i++) blank[i]=0;
BlynkEdgent.begin();
// xTaskCreatePinnedToCore(loop2, "loop2", 4096, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(loop1, "loop1", 4608, NULL, 1, NULL, 0);
timer.setInterval(1000, Verifica_dosis); //ejecuta cada 1 segundo
timer.setInterval(1000, Update_time_TFT);//actualiza la fecha/hora en la pantalla TFT
eeAddress = Inicio_Eeprom;
// Serial.println("comienza lectura eeprom");
EEPROM.get(eeAddress,Dosificador_activado);
eeAddress += sizeof(bool); //Mueve la dirección al próximo byte después de un booleano
// Serial.println("Ha leido el primer dato");
// Serial.println("Activado : " + String(Dosificador_activado));
for (int i = 0 ; i < 4 ; i++)
{
EEPROM.get(eeAddress,Canal_Activo[i]);
// Serial.print(String(eeAddress) + " : " + String(Canal_Activo[i]) + " ");
eeAddress += sizeof(bool); //Mueve la dirección al próximo byte después de un booleano
}
// Serial.println();
for (int i = 0 ; i < 4 ; i++)
{
EEPROM.get(eeAddress, dosis_Blynk[i]);
// Serial.print(String(eeAddress) + " : " + String(dosis_Blynk[i]) + " ");
eeAddress += sizeof(float); //Mueve la dirección al próximo byte después de un flotante.
}
// Serial.println();
for (int i = 0 ; i < 4 ; i++)
{
EEPROM.get(eeAddress, paso_Blynk[i]);
// Serial.print(String(eeAddress) + " : " + String(paso_Blynk[i]) + " ");
eeAddress += sizeof(float); //Mueve la dirección al próximo byte después de un flotante.
}
Filtra_Canales();
calcula_intervalo()
}
void loop1(void *pvParameters) //loop para procesos de BLYNK en Core0
{
while (1)
{
BlynkEdgent.run();
delay(1);
}
}
void loop() {
timer.run();
millis_actual = millis();
if ( (millis_actual - millis_anterior) >= Intervalo_dosis)
{
dosificar = true;
millis_anterior = millis_actual;
}
}
// ##############################################################################################
// Call this function to scroll the display one text line
// ##############################################################################################
int scroll_line() {
int yTemp = yStart; // Store the old yStart, this is where we draw the next line
// Use the record of line lengths to optimise the rectangle size we need to erase the top line
// tft.fillRect(0,yStart,blank[(yStart-TOP_FIXED_AREA)/TEXT_HEIGHT],TEXT_HEIGHT, TFT_BLACK);
tft.fillRect(0,yStart,240,TEXT_HEIGHT, TFT_BLACK);
// Change the top of the scroll area
yStart+=TEXT_HEIGHT;
// The value must wrap around as the screen memory is a circular buffer
if (yStart >= YMAX - BOT_FIXED_AREA) yStart = TOP_FIXED_AREA + (yStart - YMAX + BOT_FIXED_AREA);
// Now we can scroll the display
scrollAddress(yStart);
return yTemp;
}
// ##############################################################################################
// Setup a portion of the screen for vertical scrolling
// ##############################################################################################
// We are using a hardware feature of the display, so we can only scroll in portrait orientation
void setupScrollArea(uint16_t tfa, uint16_t bfa) {
tft.writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
tft.writedata(tfa >> 8); // Top Fixed Area line count
tft.writedata(tfa);
tft.writedata((YMAX-tfa-bfa)>>8); // Vertical Scrolling Area line count
tft.writedata(YMAX-tfa-bfa);
tft.writedata(bfa >> 8); // Bottom Fixed Area line count
tft.writedata(bfa);
}
// ##############################################################################################
// Setup the vertical scrolling start address pointer
// ##############################################################################################
void scrollAddress(uint16_t vsp) {
tft.writecommand(ILI9341_VSCRSADD); // Vertical scrolling pointer
tft.writedata(vsp>>8);
tft.writedata(vsp);
}