Hola
Estoy haciendo un proyecto por que desde hace un rato tengo en el tintero, el cual quiero para uso personal, se trata de un reloj que me permita ver la hora en mi dormitorio de día y de noche, en la noche que no brille tanto como para que me quite el sueño y en el día que se pueda leer a simple vista.
Piezas:
DS3231 para el reloj y termómetro
TM1637 para el display de 7.4
Botones para interface
Arduino nano para desarrollo
Pilas AAA
Objetivos:
Muestra el tiempo en 12/24hrs
Muestra la temperatura en °C durante un pequeño lapso.
Ajuste de hora - minutos
Ajuste de lapso Temperatura
Ajuste de Brillo
Funciona con pilas
Señal de batería baja
Funciones del display:
Hay dos ciclos principales por decirlo de alguna manera, el primero es:
El que muestra la hora y la temperatura, esta ciclo muestra la hora y la temperatura en el lapso de un minuto y se repite al siguiente minuto, en este caso lo único que varia es el lapso en que se muestra la temperatura (de 2 a 10 seg), todo dentro del mismo minuto. Digamos que por ejemplo se ajuste a el lapso de la temperatura a 10 segundos la temperatura se mostrara dies segundos después la hora 50 segundos y así continuara repitiéndose.
El segundo ciclo principal estará dedicado a la configuración de los diferentes ajustes del reloj.
Los cuales serán la horas, minutos. Considero que las horas deben de grabarse en 24 hrs y después cambiarla a 12 antes de grabarla en el rtc si es necesario pero aun no se si el ds3231 pueda facilitarme esto y así evitar ciclos de reloj inecesarios, los minutos de 0 a 59 y la temperatura de 2 a 10.
Dentro de estos dos ciclos habrá un ciclo mas pequeño en tiempo pero no en funcionalidad que se encarga de leer los estados de los botones.
Por encima de estos ciclos deberá haber una condición para revisar cual de los dos ciclos principales es el que debe mostrarse y esta sera definido por el botón set/function, los botones aunque representan lo mismo, afectan a diferentes variables según el ciclo que este activo, lo cual describo a continuación:
Funciones de los botones:
-Mientras se muestra la hora(el principal ciclo) los botones de ajuste +/- ajustan el brillo. el botón set/function cambia entre 12 y 24 hrs.
-En los ajustes(el ciclo secundario) +/- ajustan las horas, minutos y lapso de temperatura, el botón set/function navega entre los diferentes parámetros.
-El botón set/funtion guarda cambios y cambia entre los dos ciclos principales pero solo si se mantiene presionado mas dos segundos.
Tengo las funciones pero me falta el núcleo del programa, aun no he encontrado la forma de manejar los diferentes ciclos con el uso de los botones, tengo una idea pero quizá este descuidando que esto debe funcionar con pilas aunque eso quizá se pueda arreglar mas adelante ya que tenga funcionando todo, quiero ver que me pueden recomendar.
El código:
//La tecla setFunction cambia las variables que seran afectadas por las teclas de cambio...
/*por ejemplo por defecto las teclas de cambio deberan manipular el valor de la luminocidad
al precioar la tecla setFunction se cambia el valor que sera afectado por las teclas de cambio
primeramente sera la hora, luego los minutos, luego el lapso de la temperatura.
*/
#include <Arduino.h>
#include <TM1637Display.h>//libreria para el lcd
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68 //I2C RTC ADDRESS
#define CLK 2 //CLK DISPLAY
#define DIO 3 //DIO DISPLAY
TM1637Display display(CLK, DIO); //OBJECT DISPLAY
//-------------------------------------------------BOTONES
#define up 9 //self expl
#define down 8
#define set 7
//-------------------------------------------------VARIABLES
byte buttonUp, buttonDown, setFunction; //VARIABLES DE ESTADO
byte second, minute, hour, lapTemp, temp, brillo; //variables globales de ajuste
int Count;
byte i = 0; //variable de indice
byte data[4] = {0xff, 0xff, 0xff, 0xff} ; //debug
unsigned long bounceLap, timeLap, tempLap;
void setup() {
Serial.begin(9600); //DEbug
//-------------------------------------------------Botones
pinMode(up, INPUT_PULLUP);
pinMode(down, INPUT_PULLUP);
pinMode(set, INPUT_PULLUP);
//-------------------------------------------------DS3231,TM1637 setup
Wire.begin();
display.setBrightness(0x0f);
display.showNumberDec(8888); //debug
}//--------------------------------------------------END SETUP
void loop() {
while (millis() - timeLap <= 60000) {// este wile es el main while, se ejecuta siempre.
readTime(&second, &minute, &hour);
display.showNumberDec(hour, true, 2, 0);
display.showNumberDec(minute, true, 2, 2);
byte dots[0];
dots[0] = 0b10000000 | display.encodeDigit(hour);
if (hour >= 10)dots[0] = 0b10000000 | display.encodeDigit(hour - 10);
if (hour >= 20)dots[0] = 0b10000000 | display.encodeDigit(hour - 20);
if (second % 2)display.setSegments(dots, 1, 1);
Serial.print(minute), Serial.print(":"), Serial.println(second);
while (millis() - bounceLap >= 220ul ) {//este while es el de los botones, aqui es donde se cambian las variables manual y evita el rebote.
buttonUp = digitalRead(up);
buttonDown = digitalRead(down);
setFunction = digitalRead(set);
bounceLap = millis();
if (!buttonUp) Count++;
if (!buttonDown) Count--;
if (!buttonUp) setBrillo(true);
if (!buttonDown) setBrillo(false);
}
timeLap = millis();
}
while (millis() - tempLap <= 4000) { // Ciclo que muestra la temperatura, por ahora fijo a 4 segundos.
readTemp(&temp);
display.showNumberDec(temp, true, 2, 2);
Serial.print(temp), Serial.println("°C");
tempLap = millis();
}
display.setSegments(data); //debug
}//-------------------------------------------END LOOP
void readTime(byte *second, byte *minute , byte *hour) {
Wire.beginTransmission (DS3231_I2C_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 3);
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read());
}//-------------------------------------------END READTIME
void readTemp(byte *tempMSB) {
Wire.beginTransmission (DS3231_I2C_ADDRESS);
Wire.write(0x11);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 1);
*tempMSB = bcdToDec(Wire.read());
}//-------------------------------------------END READTEMP
void setTime(byte *hour, byte *minute)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x01);
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.endTransmission();
}//-------------------------------------------END SETTIME
void setBrillo(bool brillo)
{
if (brillo) {
i--;
} else {
i++;
}
if (i > 7) i = 7;
if (i < 1) i = 1;
byte brillos[8] = {8, 9, 10, 11, 12, 13, 14, 15}; //valores que brillan del mas tenue al mas brillante.
display.setBrightness(brillos[i]);
//display.setBrightness(8);
Serial.print("Valor de Incremento: "), Serial.println(brillo); //debug
Serial.print("Valor Indice: "), Serial.println(i); //debug
Serial.print("Valor de brillo: "), Serial.println(brillos[i]); //debug
Serial.println();
delay(100);
}//-------------------------------------------END SETBRILLO
// Convert normal decimal numbers to binary coded decimal <--> Update Time
byte decToBcd(byte val)
{
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers <--> Read Time
byte bcdToDec(byte val)
{
return ( (val / 16 * 10) + (val % 16) );
}