Segunda entrada (la larga), aquí viene todo el código, que ya avisamos que no está optimizado, pero sí funcional.
Código
Es un poco extenso porque cubre mucha funcionalidad y también porque falta optimizarlo. Está desarrollado usando el IDE Visual Studio Code + Platformio, por eso hay algunas llamadas a librerías hechas de forma peculiar.
Se apoya en una librería creada a propósito para el proyecto.
MAIN.CPP:
// Inclusión de librerias
#include <Arduino.h> // Necesario para que compile en vscode+platformio
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include <Adafruit_GFX.h> //En platformio hacen falta las librerias: Adafruit GFX Library, Adafruit ILI9341, Adafruit LED Backpack
#include <Adafruit_SPITFT.h> //Sólo necesaria en platformio
#include "Adafruit_LEDBackpack.h"
#include <ThreeWire.h>
#include <RtcDS1302.h>
#include <LibreriaTimer.h>
/*-------------------------------------------------*/
//DEFINICIÓN DE CONSTANTES
/*-------------------------------------------------*/
const int RETARDO_REBOTES = 250; //Retardo para eliminar rebotes de los pulsadores
const int MODO_RELOJ = 0; //politimer funcionando como un reloj
const int MODO_ALARMA = 1; //politimer funcionando como una alarma
const int MODO_CUENTA_DELANTE = 2; //politimer funcionando como una cuenta adelante
const int MODO_CUENTA_ATRAS = 3; //politimer funcionando como una cuenta atrás
const int MODO_MARCADOR = 4; //politimer funcionando como un marcador deportivo
//---BOTONES---//
const int PIN_SUBIR_DECENAS_MINUTOS = 2; //Pin asociado a botón de subir decenas de minutos
const int PIN_BAJAR_DECENAS_MINUTOS = 3; //Pin asociado a botón de bajar decenas de minutos
const int PIN_SUBIR_UNIDADES_MINUTOS = 4; //Pin asociado a botón de subir unidades de minutos
const int PIN_BAJAR_UNIDADES_MINUTOS = 5; //Pin asociado a botón de bajar unidades de minutos
const int PIN_SUBIR_DECENAS_SEGUNDOS = 10; //Pin asociado a botón de subir decenas de segundos
const int PIN_BAJAR_DECENAS_SEGUNDOS = 11; //Pin asociado a botón de bajar decenas de segundos
const int PIN_SUBIR_UNIDADES_SEGUNDOS = 12; //Pin asociado a botón de subir unidades de segundos
const int PIN_BAJAR_UNIDADES_SEGUNDOS = 13; //Pin asociado a botón de bajar unidades de segundos
//Dejamos los analógicos para los botones de modo, ya que por encima del 13 son analógicos
//funcionando como digitales y tienen una respuesta ligeramente diferente a los digitales
const int PIN_APAGAR = 14; //Realmente es un pin analógico (A0) siendo usado como digital
const int PIN_RESET = 15; //Realmente es un pin analógico (A1) siendo usado como digital
const int PIN_MODO = 16; //Realmente es un pin analógico (A2) siendo usado como digital
const int PIN_PAUSA_PLAY = 17; //Realmente es un pin analógico (A3) siendo usado como digital
//---BOTONES---//
const int PIN_CLK_RTC = 6; //Pin asociado a pin CLK del módulo de reloj DS1302
const int PIN_DAT_RTC = 7; //Pin asociado a pin DAT del módulo de reloj DS1302
const int PIN_RST_RTC = 8; //Pin asociado a pin RST del módulo de reloj DS1302
const int PIN_SIG_BUZZER = 9; //Pin asociado a pin del módulo de buzzer pasivo
//Para lectura de pulsaciones largas (cambio de modo activo a modo edición)
const unsigned long TPULSACIONLARGA = 2000; //Tiempo pulsacion larga
//Valores por defecto a meter en cada modo
const byte VALOR_FABRICA_RELOJ_HORAS = 0;
const byte VALOR_FABRICA_RELOJ_MINUTOS = 0;
const byte VALOR_FABRICA_RELOJ_SEGUNDOS = 0;
const byte VALOR_FABRICA_ALARMA_HORAS = 12;
const byte VALOR_FABRICA_ALARMA_MINUTOS = 0;
const byte VALOR_FABRICA_ALARMA_SEGUNDOS = 0;
const byte VALOR_FABRICA_CUENTA_DELANTE_MINUTOS = 0;
const byte VALOR_FABRICA_CUENTA_DELANTE_SEGUNDOS = 0;
const byte VALOR_FABRICA_CUENTA_ATRAS_MINUTOS = 10;
const byte VALOR_FABRICA_CUENTA_ATRAS_SEGUNDOS = 0;
const byte VALOR_FABRICA_MARCADOR_LOCAL = 0;
const byte VALOR_FABRICA_MARCADOR_VISITANTE = 0;
/*-------------------------------------------------*/
//DEFINICIÓN DE VARIABLES
/*-------------------------------------------------*/
Adafruit_7segment display = Adafruit_7segment(); //Instancia del display de 7 segmentos
unsigned long tiempo = 0; //Control del tiempo
byte modo = MODO_RELOJ; //Por defecto, modo reloj
boolean modoEdicion = false; //Variable para controlar si estamos en edición o en visualización
boolean modoLedsApagados = false; //Variable para controlar el encendido o apagado de los leds de los displays (modo ahorro de energía)
boolean alarmaActiva = false; //Variable para controlar si se activa o desactiva la alarma
boolean contandoDelante = false; //Variable para controlar si la cuenta adelante está en marcha o no
boolean contandoAtras = false; //Variable para controlar si la cuenta atrás está en marcha o no
boolean arrancaCuentaDelante = false; //Variable para controlar si la cuenta adelante inicia por primera vez
boolean arrancaCuentaAtras = false; //Variable para controlar si la cuenta atrás inicia por primera vez
int lecturaBotonApagar = 0; //inicializo botón
int lecturaBotonReset = 0; //inicializo botón
int lecturaBotonSubirDecenasMinutos = 0; //inicializo botón
int lecturaBotonBajarDecenasMinutos = 0; //inicializo botón
int lecturaBotonSubirUnidadesMinutos = 0; //inicializo botón
int lecturaBotonBajarUnidadesMinutos = 0; //inicializo botón
int lecturaBotonSubirDecenasSegundos = 0; //inicializo botón
int lecturaBotonBajarDecenasSegundos = 0; //inicializo botón
int lecturaBotonSubirUnidadesSegundos = 0; //inicializo botón
int lecturaBotonBajarUnidadesSegundos = 0; //inicializo botón
int lecturaBotonModo = 0; //inicializo botón
int lecturaBotonPausaPlay = 0; //inicializo botón
byte horas = -1; //Definición de variable para controlar las horas del reloj
byte minutos = -1; //Definición de variable para controlar los minutos del reloj
byte segundos = -1; //Definición de variable para controlar los segundos del reloj
byte horasA = -1; //Definición de variable para controlar las horas de la alarma
byte minutosA = -1; //Definición de variable para controlar los minutos de la alarma
byte segundosA = -1; //Definición de variable para controlar los segundos de la alarma
byte minutosCuentaDelante = -1; //Definición de variable para controlar los minutos de la cuenta delante
byte segundosCuentaDelante = -1; //Definición de variable para controlar los segundos de la cuenta delante
byte minutosCuentaDelanteInicial = -1; //Definición de variable para controlar el valor incial de los minutos de la cuenta delante
byte segundosCuentaDelanteInicial = -1; //Definición de variable para controlar el valor incial de los segundos de la cuenta delante
byte minutosCuentaAtras = -1; //Definición de variable para controlar los minutos de la cuenta atrás
byte segundosCuentaAtras = -1; //Definición de variable para controlar los segundos de la cuenta atrás
byte minutosCuentaAtrasReseteoEnMarcha = -1; //Definición de variable para controlar el valor incial de los minutos de la cuenta atrás
byte segundosCuentaAtrasReseteoEnMarcha = -1; //Definición de variable para controlar el valor incial de los segundos de la cuenta atrás
long segundosTotalesCuentaAtras; //Definición de variable para controlar los segundos totales contando los minutos de la cuenta atrás
long segundosRestantesCuentaAtras; //Definición de variable para controlar los segundos restantes contando los minutos de la cuenta atrás una vez que ya ha empezado
byte marcadorLocal = -1; //Definición de variable para controlar el valor del marcador local
byte marcadorVisitante = -1; //Definición de variable para controlar el valor del marcador visitante
boolean drawDots = true; //Variable para controlar el encendido de los dos puntos centrales del display
ThreeWire myWire(PIN_DAT_RTC, PIN_CLK_RTC, PIN_RST_RTC); // DAT/IO, CLK/SCLK, RST/CE. Declaración de variable necesaria para el control del reloj RTC
RtcDS1302<ThreeWire> rtc(myWire); //Declaración del reloj RTC
//Para lectura de pulsaciones largas (cambio de modo normal a modo edición)
unsigned long tPulsacion;
unsigned long tInicio;
unsigned long tFin;
int estadoActual; //Estado actual pulsador
int estadoUltimo; //Estado ultimo pulsador
unsigned long contadorSegundosDelanteInicial;
unsigned long contadorSegundosDelante;
unsigned long contadorSegundosAtrasInicial;
unsigned long contadorSegundosAtras;
/*-------------------------------------------------*/
//FUNCIONES A IMPLEMENTAR EN MAIN
/*-------------------------------------------------*/
/*
Función para realizar la lectura de todos los botones conectados al politimer e introducir los valores leidos en las variables dispuestas a tal fin
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void LeerBotones()
{
//Se leen todos los botones
lecturaBotonApagar = digitalRead(PIN_APAGAR);
lecturaBotonReset = digitalRead(PIN_RESET);
lecturaBotonSubirDecenasMinutos = digitalRead(PIN_SUBIR_DECENAS_MINUTOS);
lecturaBotonBajarDecenasMinutos = digitalRead(PIN_BAJAR_DECENAS_MINUTOS);
lecturaBotonSubirUnidadesMinutos = digitalRead(PIN_SUBIR_UNIDADES_MINUTOS);
lecturaBotonBajarUnidadesMinutos = digitalRead(PIN_BAJAR_UNIDADES_MINUTOS);
lecturaBotonSubirDecenasSegundos = digitalRead(PIN_SUBIR_DECENAS_SEGUNDOS);
lecturaBotonBajarDecenasSegundos = digitalRead(PIN_BAJAR_DECENAS_SEGUNDOS);
lecturaBotonSubirUnidadesSegundos = digitalRead(PIN_SUBIR_UNIDADES_SEGUNDOS);
lecturaBotonBajarUnidadesSegundos = digitalRead(PIN_BAJAR_UNIDADES_SEGUNDOS);
lecturaBotonModo = digitalRead(PIN_MODO);
lecturaBotonPausaPlay = digitalRead(PIN_PAUSA_PLAY);
estadoActual = lecturaBotonModo;
}
/*
Función para realizar un flasheo rápido de los puntos centrales del display a modo de notificación de un evento
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void FlashDots()
{
for (byte indice = 0; indice < 4; indice++)
{
display.drawColon(drawDots);
drawDots = !drawDots;
display.writeDisplay();
delay(30);
}
}
/*
Función para controlar por completo el modo reloj.
Se realiza la visualización en los displays y se controla la edición del mismo.
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void Reloj()
{
RtcDateTime now = rtc.GetDateTime();
printDateTime(now);
Serial.println();
if (modoEdicion)
{
drawDots = true;
}
else
{
drawDots = !drawDots;
}
display.writeDigitNum(0, (now.Hour() / 10), drawDots);
display.writeDigitNum(1, (now.Hour() % 10), drawDots);
display.drawColon(drawDots);
display.writeDigitNum(3, (now.Minute() / 10), drawDots);
display.writeDigitNum(4, (now.Minute() % 10), drawDots);
display.writeDisplay();
if (!now.IsValid())
{
// Common Causes:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("RTC lost confidence in the DateTime! LA PILA NO VA...");
}
if (modoEdicion)
{
horas = now.Hour();
minutos = now.Minute();
segundos = now.Second();
if (lecturaBotonReset == HIGH)
{
horas = VALOR_FABRICA_RELOJ_HORAS;
minutos = VALOR_FABRICA_RELOJ_MINUTOS;
segundos = VALOR_FABRICA_RELOJ_SEGUNDOS;
}
if (lecturaBotonSubirDecenasMinutos == HIGH)
{
horas = horas + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasMinutos == HIGH)
{
horas = horas - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesMinutos == HIGH)
{
horas = horas + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesMinutos == HIGH)
{
horas = horas - 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirDecenasSegundos == HIGH)
{
minutos = minutos + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasSegundos == HIGH)
{
minutos = minutos - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesSegundos == HIGH)
{
minutos = minutos + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesSegundos == HIGH)
{
minutos = minutos - 1;
delay(RETARDO_REBOTES);
}
horas = corrigeHoras(horas);
minutos = corrigeMinSeg(minutos);
RtcDateTime dt = RtcDateTime(now.Year(), now.Month(), now.Day(), horas, minutos, segundos);
rtc.SetDateTime(dt);
}
delay(500); // cada medio segundo actualiza
}
/*
Función para establecer en la alarma un valor suministrado a través de tres variables tipo byte
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void EstablecerAlarma(byte horas, byte minutos, byte segundos)
{
horasA = horas;
minutosA = minutos;
segundosA = segundos;
}
/*
Función para controlar por completo el modo alarma.
Se realiza la visualización en los displays y se controla la edición del mismo con llamada a la función EstablecerAlarma.
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void Alarma()
{
if (modoEdicion)
{
drawDots = true;
}
else
{
drawDots = !drawDots;
}
//Activar alarma
if (lecturaBotonPausaPlay == HIGH)
{
alarmaActiva = !alarmaActiva;
FlashDots();
if (alarmaActiva)
{
modoEdicion = false;
}
}
if (alarmaActiva) //Si la alarma está activa los puntos centrales flashean visiblemente al ver la hora de la alarma
{
FlashDots();
}
horasA = corrigeHoras(horasA);
minutosA = corrigeMinSeg(minutosA);
segundosA = corrigeMinSeg(segundosA);
display.writeDigitNum(0, (horasA / 10), drawDots);
display.writeDigitNum(1, (horasA % 10), drawDots);
display.drawColon(drawDots);
display.writeDigitNum(3, (minutosA / 10), drawDots);
display.writeDigitNum(4, (minutosA % 10), drawDots);
display.writeDisplay();
if (modoEdicion)
{
if (lecturaBotonReset == HIGH)
{
EstablecerAlarma(VALOR_FABRICA_ALARMA_HORAS, VALOR_FABRICA_ALARMA_MINUTOS, VALOR_FABRICA_ALARMA_SEGUNDOS);
}
if (lecturaBotonSubirDecenasMinutos == HIGH)
{
horasA = horasA + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasMinutos == HIGH)
{
horasA = horasA - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesMinutos == HIGH)
{
horasA = horasA + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesMinutos == HIGH)
{
horasA = horasA - 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirDecenasSegundos == HIGH)
{
minutosA = minutosA + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasSegundos == HIGH)
{
minutosA = minutosA - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesSegundos == HIGH)
{
minutosA = minutosA + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesSegundos == HIGH)
{
minutosA = minutosA - 1;
delay(RETARDO_REBOTES);
}
}
delay(500); // actualiza cada medio segundo
}
/*
Función para establecer en la cuenta delante un valor suministrado a través de dos variables tipo byte
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void EstablecerCuentaDelante(byte minutos, byte segundos)
{
minutosCuentaDelante = minutos;
segundosCuentaDelante = segundos;
}
/*
Función para controlar el modo Cuenta Delante.
Se realiza la visualización en los displays y se controla la edición del mismo con llamada a la función EstablecerCuentaDelante.
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void CuentaDelante()
{
if (modoEdicion)
{
if (lecturaBotonReset == HIGH)
{
EstablecerCuentaDelante(VALOR_FABRICA_CUENTA_DELANTE_MINUTOS, VALOR_FABRICA_CUENTA_DELANTE_SEGUNDOS);
}
if (lecturaBotonSubirDecenasMinutos == HIGH)
{
minutosCuentaDelante = minutosCuentaDelante + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasMinutos == HIGH)
{
minutosCuentaDelante = minutosCuentaDelante - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesMinutos == HIGH)
{
minutosCuentaDelante = minutosCuentaDelante + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesMinutos == HIGH)
{
minutosCuentaDelante = minutosCuentaDelante - 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirDecenasSegundos == HIGH)
{
segundosCuentaDelante = segundosCuentaDelante + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasSegundos == HIGH)
{
segundosCuentaDelante = segundosCuentaDelante - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesSegundos == HIGH)
{
segundosCuentaDelante = segundosCuentaDelante + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesSegundos == HIGH)
{
segundosCuentaDelante = segundosCuentaDelante - 1;
delay(RETARDO_REBOTES);
}
drawDots = true;
}
else //modo normal, no edición
{
drawDots = !drawDots;
if (lecturaBotonReset == HIGH)
{
EstablecerCuentaDelante(VALOR_FABRICA_CUENTA_DELANTE_MINUTOS, VALOR_FABRICA_CUENTA_DELANTE_SEGUNDOS);
contandoDelante = false;
arrancaCuentaDelante = false;
}
}
if (lecturaBotonPausaPlay == HIGH) //Activar/parar cuenta
{
contandoDelante = !contandoDelante;
delay(RETARDO_REBOTES);
if (!contandoDelante)
{
arrancaCuentaDelante = false;
}
}
if (contandoDelante)
{
if (!arrancaCuentaDelante)
{
arrancaCuentaDelante = true;
contadorSegundosDelanteInicial = millis();
contadorSegundosDelante = 0;
minutosCuentaDelanteInicial = minutosCuentaDelante;
segundosCuentaDelanteInicial = segundosCuentaDelante;
}
else
{
contadorSegundosDelante = diferenciaCorrigiendoOverflow(millis(), contadorSegundosDelanteInicial) / 1000;
}
//Correcciones para la cuenta de minutos y segundos
byte minutosContados = contadorSegundosDelante / 60;
int segundosContados = contadorSegundosDelante % 60;
minutosCuentaDelante = minutosCuentaDelanteInicial + minutosContados;
segundosCuentaDelante = segundosCuentaDelanteInicial + segundosContados;
minutosCuentaDelante = minutosCuentaDelante + segundosCuentaDelante / 60;
if (segundosCuentaDelante > 59)
{
segundosCuentaDelante = segundosCuentaDelante % 60;
}
}
minutosCuentaDelante = corrigeMinSeg(minutosCuentaDelante);
segundosCuentaDelante = corrigeMinSeg(segundosCuentaDelante);
display.writeDigitNum(0, (minutosCuentaDelante / 10), drawDots);
display.writeDigitNum(1, (minutosCuentaDelante % 10), drawDots);
display.drawColon(drawDots);
display.writeDigitNum(3, (segundosCuentaDelante / 10), drawDots);
display.writeDigitNum(4, (segundosCuentaDelante % 10), drawDots);
display.writeDisplay();
delay(500);
}
/*
Función para establecer en la cuenta atrás un valor suministrado a través de dos variables tipo byte
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void EstablecerCuentaAtras(byte minutos, byte segundos)
{
minutosCuentaAtras = minutos;
segundosCuentaAtras = segundos;
minutosCuentaAtrasReseteoEnMarcha = minutos;
segundosCuentaAtrasReseteoEnMarcha = segundos;
}
/*
Función para controlar el modo Cuenta Atrás.
Se realiza la visualización en los displays y se controla la edición del mismo con llamada a la función EstablecerCuentaAtrás.
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void CuentaAtras()
{
if (modoEdicion)
{
if (lecturaBotonReset == HIGH)
{
EstablecerCuentaAtras(VALOR_FABRICA_CUENTA_ATRAS_MINUTOS, VALOR_FABRICA_CUENTA_ATRAS_SEGUNDOS);
}
if (lecturaBotonSubirDecenasMinutos == HIGH)
{
minutosCuentaAtras = minutosCuentaAtras + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasMinutos == HIGH)
{
minutosCuentaAtras = minutosCuentaAtras - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesMinutos == HIGH)
{
minutosCuentaAtras = minutosCuentaAtras + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesMinutos == HIGH)
{
minutosCuentaAtras = minutosCuentaAtras - 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirDecenasSegundos == HIGH)
{
segundosCuentaAtras = segundosCuentaAtras + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasSegundos == HIGH)
{
segundosCuentaAtras = segundosCuentaAtras - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesSegundos == HIGH)
{
segundosCuentaAtras = segundosCuentaAtras + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesSegundos == HIGH)
{
segundosCuentaAtras = segundosCuentaAtras - 1;
delay(RETARDO_REBOTES);
}
drawDots = true;
}
else //modo normal, no edición
{
drawDots = !drawDots;
if (lecturaBotonReset == HIGH)
{
EstablecerCuentaAtras(minutosCuentaAtrasReseteoEnMarcha, segundosCuentaAtrasReseteoEnMarcha);
contandoAtras = false;
arrancaCuentaAtras = false;
}
}
if (lecturaBotonPausaPlay == HIGH) //Activar/parar cuenta
{
contandoAtras = !contandoAtras;
delay(RETARDO_REBOTES);
if (!contandoAtras)
{
arrancaCuentaAtras = false;
}
}
if (contandoAtras)
{
if (!arrancaCuentaAtras)
{
arrancaCuentaAtras = true;
contadorSegundosAtrasInicial = millis();
segundosTotalesCuentaAtras = minutosCuentaAtras * 60 + segundosCuentaAtras;
contadorSegundosAtras = 0;
}
else
{
contadorSegundosAtras = diferenciaCorrigiendoOverflow(millis(), contadorSegundosAtrasInicial) / 1000;
}
segundosRestantesCuentaAtras = segundosTotalesCuentaAtras - contadorSegundosAtras;
if (segundosRestantesCuentaAtras <= 0)
{
arrancaCuentaAtras = false;
contandoAtras = false;
segundosRestantesCuentaAtras = 0;
display.writeDigitNum(0, 0, drawDots); //se duplica aquí este código para que aparezca el 00:00 antes de empezar a sonar la sirena
display.writeDigitNum(1, 0, drawDots);
display.drawColon(drawDots);
display.writeDigitNum(3, 0, drawDots);
display.writeDigitNum(4, 0, drawDots);
display.writeDisplay();
SonarSirena(PIN_SIG_BUZZER);
}
minutosCuentaAtras = segundosRestantesCuentaAtras / 60;
segundosCuentaAtras = segundosRestantesCuentaAtras % 60;
}
minutosCuentaAtras = corrigeMinSeg(minutosCuentaAtras);
segundosCuentaAtras = corrigeMinSeg(segundosCuentaAtras);
display.writeDigitNum(0, (minutosCuentaAtras / 10), drawDots);
display.writeDigitNum(1, (minutosCuentaAtras % 10), drawDots);
display.drawColon(drawDots);
display.writeDigitNum(3, (segundosCuentaAtras / 10), drawDots);
display.writeDigitNum(4, (segundosCuentaAtras % 10), drawDots);
display.writeDisplay();
delay(500); //actualiza cada medio segundo
}
/*
Función para establecer en el marcador un valor suministrado a través de dos variables tipo byte
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void EstablecerMarcador(byte local, byte visitante)
{
marcadorLocal = local;
marcadorVisitante = visitante;
}
/*
Función para controlar el modo Marcador.
Se realiza la visualización en los displays y se controla la edición del mismo con llamada a la función EstablecerMarcador.
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void Marcador()
{
if (lecturaBotonReset == HIGH)
{
EstablecerMarcador(VALOR_FABRICA_MARCADOR_LOCAL, VALOR_FABRICA_MARCADOR_VISITANTE);
}
if (lecturaBotonSubirDecenasMinutos == HIGH)
{
marcadorLocal = marcadorLocal + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasMinutos == HIGH)
{
marcadorLocal = marcadorLocal - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesMinutos == HIGH)
{
marcadorLocal = marcadorLocal + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesMinutos == HIGH)
{
marcadorLocal = marcadorLocal - 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirDecenasSegundos == HIGH)
{
marcadorVisitante = marcadorVisitante + 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarDecenasSegundos == HIGH)
{
marcadorVisitante = marcadorVisitante - 10;
delay(RETARDO_REBOTES);
}
if (lecturaBotonSubirUnidadesSegundos == HIGH)
{
marcadorVisitante = marcadorVisitante + 1;
delay(RETARDO_REBOTES);
}
if (lecturaBotonBajarUnidadesSegundos == HIGH)
{
marcadorVisitante = marcadorVisitante - 1;
delay(RETARDO_REBOTES);
}
drawDots = false;
marcadorLocal = corrigeMarcador(marcadorLocal);
marcadorVisitante = corrigeMarcador(marcadorVisitante);
display.writeDigitNum(0, (marcadorLocal / 10), drawDots);
display.writeDigitNum(1, (marcadorLocal % 10), drawDots);
display.drawColon(drawDots);
display.writeDigitNum(3, (marcadorVisitante / 10), drawDots);
display.writeDigitNum(4, (marcadorVisitante % 10), drawDots);
display.writeDisplay();
}
/*
Función de ahorro de energía. Apaga todos los leds
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void ApagarDisplay()
{
display.writeDigitRaw(0, 0); //digito más a la izquierda
display.writeDigitRaw(1, 0);
display.writeDigitRaw(2, 0); //dos puntos
display.writeDigitRaw(3, 0);
display.writeDigitRaw(4, 0); //dígito más a la derecha
display.writeDisplay();
}
/*
Función para leer de forma especial pulsación corta/larga del botón de modo
Si es larga se cambia entre modo edición/normal.
Si es corta se cambia de modo reloj / alarma / cuenta adelante / cuenta atrás / marcador
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void LecturaModos()
{
if (estadoActual != estadoUltimo)
{
if (estadoActual == HIGH)
{
tInicio = millis();
}
else
{
tFin = millis();
tPulsacion = diferenciaCorrigiendoOverflow(tFin, tInicio);
}
estadoUltimo = estadoActual;
if ((tPulsacion < TPULSACIONLARGA) && (estadoActual == LOW))
{
Serial.println("Cambio de modo");
modo++;
modoEdicion = false;
if (modo >= 5)
{
modo = 0;
}
SonarPitido(PIN_SIG_BUZZER, 1000);
delay(RETARDO_REBOTES);
}
}
else if ((estadoActual == estadoUltimo) && (estadoActual == HIGH) && (modo != MODO_MARCADOR))
{
if (tInicio != 0)
{
tFin = millis();
tPulsacion = diferenciaCorrigiendoOverflow(tFin, tInicio);
}
if (tPulsacion > TPULSACIONLARGA)
{
Serial.println("Cambio a EDICIÓN");
modoEdicion = !modoEdicion;
SonarPitido(PIN_SIG_BUZZER, 2000);
SonarPitido(PIN_SIG_BUZZER, 2000);
delay(RETARDO_REBOTES);
tPulsacion = 0;
tInicio = 0;
}
}
}
/*
Función de inicio de ARDUINO.
Aquí se establecen todos los valores iniciales o "de fábrica".
Aquí es donde se llama cada vez que se hace un HARD RESET pulsando el reset de la placa de Arduino.
put your setup code here, to run once:
*/
void setup()
{
Serial.begin(9600); //Establecemos velocidad de comunicación
#ifndef __AVR_ATtiny85__
Serial.println("Arranca setup");
#endif
display.begin(0x70);
//ASIGNACIÓN DE BOTONES CON PINES DE LA PLACA COMO ENTRADAS
pinMode(PIN_APAGAR, INPUT); //Establecemos el pin del botón de apagado como entrada
pinMode(PIN_RESET, INPUT); //Establecemos el pin del botón de reset como entrada
pinMode(PIN_SUBIR_DECENAS_MINUTOS, INPUT); //Establecemos el pin del botón de subir decenas de minutos como entrada
pinMode(PIN_BAJAR_DECENAS_MINUTOS, INPUT); //Establecemos el pin del botón de bajar decenas de minutos como entrada
pinMode(PIN_SUBIR_UNIDADES_MINUTOS, INPUT); //Establecemos el pin del botón de subir decenas de minutos como entrada
pinMode(PIN_BAJAR_UNIDADES_MINUTOS, INPUT); //Establecemos el pin del botón de bajar decenas de minutos como entrada
pinMode(PIN_SUBIR_DECENAS_SEGUNDOS, INPUT); //Establecemos el pin del botón de subir decenas de segundos como entrada
pinMode(PIN_BAJAR_DECENAS_SEGUNDOS, INPUT); //Establecemos el pin del botón de bajar decenas de segundos como entrada
pinMode(PIN_SUBIR_UNIDADES_SEGUNDOS, INPUT); //Establecemos el pin del botón de subir unidades de segundos como entrada
pinMode(PIN_BAJAR_UNIDADES_SEGUNDOS, INPUT); //Establecemos el pin del botón de bajar unidades de segundos como entrada
pinMode(PIN_MODO, INPUT); //Establecemos el pin del botón de modo como entrada
pinMode(PIN_PAUSA_PLAY, INPUT); //Establecemos el pin del botón de pausa/play como entrada
tiempo = millis();
SetupReloj(rtc);
EstablecerAlarma(VALOR_FABRICA_ALARMA_HORAS, VALOR_FABRICA_ALARMA_MINUTOS, VALOR_FABRICA_ALARMA_SEGUNDOS);
EstablecerCuentaDelante(VALOR_FABRICA_CUENTA_DELANTE_MINUTOS, VALOR_FABRICA_CUENTA_DELANTE_SEGUNDOS);
EstablecerCuentaAtras(VALOR_FABRICA_CUENTA_ATRAS_MINUTOS, VALOR_FABRICA_CUENTA_ATRAS_SEGUNDOS);
EstablecerMarcador(VALOR_FABRICA_MARCADOR_LOCAL, VALOR_FABRICA_MARCADOR_VISITANTE);
modoEdicion = false;
tPulsacion = 0;
tInicio = 0;
tFin = 0;
estadoActual = 0;
estadoUltimo = 0;
alarmaActiva = false;
contandoDelante = false;
contandoAtras = false;
arrancaCuentaDelante = false;
arrancaCuentaAtras = false;
contadorSegundosDelante = 0;
contadorSegundosDelanteInicial = 0;
contadorSegundosAtras = 0;
contadorSegundosAtrasInicial = 0;
segundosTotalesCuentaAtras = 0;
segundosRestantesCuentaAtras = 0;
}
/*
Función de lazo de ARDUINO.
Esto es lo que se ejecuta de forma contínua en Arduina tras la lectura de librerías, definición de constantes, variables y la llamada al setup.
put your main code here, to run repeatedly:
*/
void loop()
{
RtcDateTime ahora = rtc.GetDateTime();
if ((alarmaActiva) && (ahora.Hour() == horasA) && (ahora.Minute() == minutosA))
{
SonarMarchaImperial(PIN_SIG_BUZZER); //La alarma hace sonar la marcha imperial. Este sonido no se puede parar hasta que acaba
alarmaActiva = false;
}
if (millis() > tiempo + RETARDO_REBOTES) //Lectura contínua de los botones por si se están presionando y metiendo un retardo para evitar rebotes vía software
{
LeerBotones();
tiempo = millis(); //Se toma referencia del tiempo para el control de los rebotes
}
if (lecturaBotonApagar == HIGH) //Este es un botón prioritario. Si los leds están apagados, los demás botones no hacen nada, lógicamente.
{
Serial.println("Leds apagados/encendidos");
modoLedsApagados = !modoLedsApagados;
SonarPitidoApagado(PIN_SIG_BUZZER); //Suena un pitido especial grave para diferenciar el botón APAGADO/ENCENDIDO de los leds de los demás
delay(RETARDO_REBOTES);
}
if (modoLedsApagados) //Si los leds están apagados, los demás botones no hacen nada, lógicamente.
{
ApagarDisplay();
}
else //Si los leds están encendidos ya sí puede funcionar todo lo demás.
{
LecturaModos(); //Lectura especial del botón de modo para diferenciar pulsación larga/corta
if (lecturaBotonPausaPlay == HIGH)
{
Serial.println("Pausa/Play");
SonarPitidoPlayPause(PIN_SIG_BUZZER); //Suena un pitido especial agudo para diferenciar el botón PLAY/PAUSE de los demás
}
else if (lecturaBotonReset == HIGH)
{
Serial.println("Reset");
SonarPitidoReset(PIN_SIG_BUZZER); //Suena un pitido especial para diferenciar el botón RESET de los demás
}
switch (modo) //Estructura para derivar el flujo según el modo de funcionamiento
{
case MODO_RELOJ:
Reloj();
break;
case MODO_ALARMA:
Alarma();
break;
case MODO_CUENTA_DELANTE:
CuentaDelante();
break;
case MODO_CUENTA_ATRAS:
CuentaAtras();
break;
case MODO_MARCADOR:
Marcador();
break;
default: // Por defecto se va al modo reloj
Reloj();
break;
}
}
}
LIBRERIATIMER.H:
/*
LibreriaTimer.h - Library for support of Politecnico Timer
Created by José Luis Guerrero Marín, May 9, 2020.
*/
#ifndef LibreriaTimer_h
#define LibreriaTimer_h
#include "Arduino.h"
unsigned long diferenciaCorrigiendoOverflow(unsigned long fin,unsigned long inicio);
byte corrigeHoras(byte val);
byte corrigeMinSeg(byte val);
byte corrigeMarcador(byte val);
void printDateTime(const RtcDateTime &dt);
String getStringDateTime(const RtcDateTime &dt);
RtcDS1302<ThreeWire> SetupReloj(RtcDS1302<ThreeWire> rtc);
void SonarTono(int pin_SIG_buzzer);
void SonarPitido(int pin_SIG_buzzer, int frec);
void SonarPitido(int pin_SIG_buzzer, int frec, int ms);
void SonarPitidoApagado(int pin_SIG_buzzer);
void SonarPitidoPlayPause(int pin_SIG_buzzer);
void SonarPitidoReset(int pin_SIG_buzzer);
void SonarSirena(int pin_SIG_buzzer);
void SonarMarchaImperial(int pin_SIG_buzzer);
#endif
LIBRERIATIMER.CPP:
#include <Arduino.h> //Sólo necesaria en platformio
#include <ThreeWire.h>
#include <RtcDS1302.h>
#include <LibreriaTimer.h>
/*-------------------------------------------------*/
//------------DEFINICIÓN DE CONSTANTES-------------//
/*-------------------------------------------------*/
const int TONOS[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494};
const int numTonos = sizeof(TONOS) / sizeof(TONOS[0]);
const int c = 261;
const int d = 294;
const int e = 329;
const int f = 349;
const int g = 391;
const int gS = 415;
const int a = 440;
const int aS = 455;
const int b = 466;
const int cH = 523;
const int cSH = 554;
const int dH = 587;
const int dSH = 622;
const int eH = 659;
const int fH = 698;
const int fSH = 740;
const int gH = 784;
const int gSH = 830;
const int aH = 880;
/*-------------------------------------------------*/
//-------------FUNCIONES IMPLEMENTADAS-------------//
/*-------------------------------------------------*/
/*
Función para corregir el overflow de Arduino que ocurre aproxidamente una vez cada 50 días de uso continuo.
Problema descrito en la documentación oficial de Arduino inherente a la naturaleza del tipo de datos que devuelve millis()
https://www.arduino.cc/reference/en/language/functions/time/millis/
https://www.arduino.cc/en/Reference.UnsignedLong
*/
unsigned long diferenciaCorrigiendoOverflow(unsigned long fin,unsigned long inicio)
{
if (fin > inicio)
{
return (fin-inicio);
}
else
{
return (4294967295-inicio+fin); //4294967295 es el máximo valor de un unsigned long
}
}
/*
Función para corrección de horas. Devuelve un valor siempre correcto de las horas no permitiendo valores fuera de rango para un reloj.
*/
byte corrigeHoras(byte val)
{
if (val > 23 || val < 0)
{
return 0;
}
else
{
return val;
}
}
/*
Función para corrección de minutos o segundos. Devuelve un valor siempre correcto de las horas no permitiendo valores fuera de rango para un reloj.
*/
byte corrigeMinSeg(byte val)
{
if (val > 59 || val < 0)
{
return 0;
}
else
{
return val;
}
}
/*
Función para corrección del marcador hasta 100.
Para valores por encima de 100 solo contará el resto de dividir entre 100, es decir se queda con decenas y unidades.
*/
byte corrigeMarcador(byte val)
{
if (val > 99)
{
return (val % 100);
}
else if (val < 0)
{
return 0;
}
else
{
return val;
}
}
/*
Función auxiliar para imprimir en monitor serie la fecha y hora
*/
#define countof(a) (sizeof(a) / sizeof(a[0]))
void printDateTime(const RtcDateTime &dt)
{
char datestring[20];
snprintf_P(datestring,
countof(datestring),
PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
dt.Month(),
dt.Day(),
dt.Year(),
dt.Hour(),
dt.Minute(),
dt.Second());
Serial.print(datestring);
}
/*
Función para iniciar el reloj copiando la hora del ordenador si el Arduino está conectado por USB.
*/
RtcDS1302<ThreeWire> SetupReloj(RtcDS1302<ThreeWire> rtc)
{
RtcDS1302<ThreeWire> myRtc = rtc;
Serial.print("compiled: ");
Serial.print(__DATE__);
Serial.println(__TIME__);
myRtc.Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
Serial.print("EMPEZAMOS TOMANDO FECHA DEL SISTEMA: ");
printDateTime(compiled);
Serial.println();
if (!myRtc.IsDateTimeValid())
{
// Common Causes:
// 1) first time you ran and the device wasn't running yet
// 2) the battery on the device is low or even missing
Serial.println("RTC lost confidence in the DateTime! (first time )");
myRtc.SetDateTime(compiled);
}
if (myRtc.GetIsWriteProtected())
{
Serial.println("RTC was write protected, enabling writing now");
myRtc.SetIsWriteProtected(false);
}
if (!myRtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
myRtc.SetIsRunning(true);
}
RtcDateTime now = myRtc.GetDateTime();
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
myRtc.SetDateTime(compiled);
}
else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
return myRtc;
}
/*
Función para hacer sonar en el buzzer pasivo una corta melodía con una serie de tonos predefinidos
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void SonarTono(int pin_SIG_buzzer)
{
for (unsigned int iTono = 0; iTono < numTonos; iTono++)
{
tone(pin_SIG_buzzer, TONOS[iTono]);
delay(200);
}
noTone(pin_SIG_buzzer);
}
/*
Función para hacer sonar en el buzzer pasivo un pitido a una frecuencia durante medio segundo
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void SonarPitido(int pin_SIG_buzzer, int frec)
{
tone(pin_SIG_buzzer, frec);
delay(500);
noTone(pin_SIG_buzzer);
}
/*
Función para hacer sonar en el buzzer pasivo un pitido a una frecuencia un tiempo definido en ms
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void SonarPitido(int pin_SIG_buzzer, int frec, int ms)
{
tone(pin_SIG_buzzer, frec);
delay(ms);
noTone(pin_SIG_buzzer);
}
/*
Función para hacer sonar en el buzzer pasivo un pitido grave reservado para el botón de APAGADO de leds
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void SonarPitidoApagado(int pin_SIG_buzzer)
{
SonarPitido(pin_SIG_buzzer, 150);
}
/*
Función para hacer sonar en el buzzer pasivo un pitido agudo reservado para el botón de PLAY/PAUSE
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void SonarPitidoPlayPause(int pin_SIG_buzzer)
{
SonarPitido(pin_SIG_buzzer, 1500);
}
/*
Función para hacer sonar en el buzzer pasivo un pitido triple pensado para el reset
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void SonarPitidoReset(int pin_SIG_buzzer)
{
SonarPitido(pin_SIG_buzzer, b, 200);
delay(20);
SonarPitido(pin_SIG_buzzer, b, 200);
delay(20);
SonarPitido(pin_SIG_buzzer, b, 200);
delay(20);
}
/*
Función para hacer sonar en el buzzer pasivo un sonido de sirena
Created by José Luis Guerrero Marín, May 9, 2020.
*/
void SonarSirena(int pin_SIG_buzzer)
{
SonarPitido(pin_SIG_buzzer, b, 500);
SonarPitido(pin_SIG_buzzer, gS, 500);
delay(20);
SonarPitido(pin_SIG_buzzer, b, 500);
SonarPitido(pin_SIG_buzzer, gS, 500);
delay(20);
SonarPitido(pin_SIG_buzzer, b, 500);
SonarPitido(pin_SIG_buzzer, gS, 500);
delay(20);
}
/*
Función para hacer sonar en el buzzer pasivo la marcha imperial de Star Wars
*/
void SonarMarchaImperial(int pin_SIG_buzzer)
{
//PRIMERA SECCIÓN
SonarPitido(pin_SIG_buzzer, a, 500);
SonarPitido(pin_SIG_buzzer, a, 500);
SonarPitido(pin_SIG_buzzer, a, 500);
SonarPitido(pin_SIG_buzzer, f, 350);
SonarPitido(pin_SIG_buzzer, cH, 150);
SonarPitido(pin_SIG_buzzer, a, 500);
SonarPitido(pin_SIG_buzzer, f, 350);
SonarPitido(pin_SIG_buzzer, cH, 150);
SonarPitido(pin_SIG_buzzer, a, 650);
delay(500);
SonarPitido(pin_SIG_buzzer, eH, 500);
SonarPitido(pin_SIG_buzzer, eH, 500);
SonarPitido(pin_SIG_buzzer, eH, 500);
SonarPitido(pin_SIG_buzzer, fH, 350);
SonarPitido(pin_SIG_buzzer, cH, 150);
SonarPitido(pin_SIG_buzzer, gS, 500);
SonarPitido(pin_SIG_buzzer, f, 350);
SonarPitido(pin_SIG_buzzer, cH, 150);
SonarPitido(pin_SIG_buzzer, a, 650);
delay(500);
//SEGUNDA SECCIÓN
SonarPitido(pin_SIG_buzzer, aH, 500);
SonarPitido(pin_SIG_buzzer, a, 300);
SonarPitido(pin_SIG_buzzer, a, 150);
SonarPitido(pin_SIG_buzzer, aH, 500);
SonarPitido(pin_SIG_buzzer, gSH, 325);
SonarPitido(pin_SIG_buzzer, gH, 175);
SonarPitido(pin_SIG_buzzer, fSH, 125);
SonarPitido(pin_SIG_buzzer, fH, 125);
SonarPitido(pin_SIG_buzzer, fSH, 250);
delay(325);
SonarPitido(pin_SIG_buzzer, aS, 250);
SonarPitido(pin_SIG_buzzer, dSH, 500);
SonarPitido(pin_SIG_buzzer, dH, 325);
SonarPitido(pin_SIG_buzzer, cSH, 175);
SonarPitido(pin_SIG_buzzer, cH, 125);
SonarPitido(pin_SIG_buzzer, b, 125);
SonarPitido(pin_SIG_buzzer, cH, 250);
delay(350);
// Variante 1
SonarPitido(pin_SIG_buzzer, f, 250);
SonarPitido(pin_SIG_buzzer, gS, 500);
SonarPitido(pin_SIG_buzzer, f, 350);
SonarPitido(pin_SIG_buzzer, a, 125);
SonarPitido(pin_SIG_buzzer, cH, 500);
SonarPitido(pin_SIG_buzzer, a, 375);
SonarPitido(pin_SIG_buzzer, cH, 125);
SonarPitido(pin_SIG_buzzer, eH, 650);
delay(500);
// Se repite la segunda sección
SonarPitido(pin_SIG_buzzer, aH, 500);
SonarPitido(pin_SIG_buzzer, a, 300);
SonarPitido(pin_SIG_buzzer, a, 150);
SonarPitido(pin_SIG_buzzer, aH, 500);
SonarPitido(pin_SIG_buzzer, gSH, 325);
SonarPitido(pin_SIG_buzzer, gH, 175);
SonarPitido(pin_SIG_buzzer, fSH, 125);
SonarPitido(pin_SIG_buzzer, fH, 125);
SonarPitido(pin_SIG_buzzer, fSH, 250);
delay(325);
SonarPitido(pin_SIG_buzzer, aS, 250);
SonarPitido(pin_SIG_buzzer, dSH, 500);
SonarPitido(pin_SIG_buzzer, dH, 325);
SonarPitido(pin_SIG_buzzer, cSH, 175);
SonarPitido(pin_SIG_buzzer, cH, 125);
SonarPitido(pin_SIG_buzzer, b, 125);
SonarPitido(pin_SIG_buzzer, cH, 250);
delay(350);
// Variante 2
SonarPitido(pin_SIG_buzzer, f, 250);
SonarPitido(pin_SIG_buzzer, gS, 500);
SonarPitido(pin_SIG_buzzer, f, 375);
SonarPitido(pin_SIG_buzzer, cH, 125);
SonarPitido(pin_SIG_buzzer, a, 500);
SonarPitido(pin_SIG_buzzer, f, 375);
SonarPitido(pin_SIG_buzzer, cH, 125);
SonarPitido(pin_SIG_buzzer, a, 650);
delay(650);
}