Hi UKHeliBob,
I'm not a programmer, just a self-learning hobbist, so my code is most likely to be quite a mess, and not very efficient but here you have it:
#include <EEPROM.h>
#include <Keypad.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;
String daysOfTheWeek[7] = { "Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado" };
String monthsNames[12] = { "Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic" };
const byte rowsCount = 4;
const byte columsCount = 4;
char keys[rowsCount][columsCount] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
const byte rowPins[rowsCount] = { 4, 5, 6, 7 };
const byte columnPins[columsCount] = { 8, 9, 10, 11 };
Keypad keypad = Keypad(makeKeymap(keys), rowPins, columnPins, rowsCount, columsCount);
int rele = 12;
int ledrojo = 3;
int ledverde = 2;
int encendido = 0;
int activo = 1;
void setup() {
Serial.begin(9600);
pinMode(rele, OUTPUT);
pinMode(ledverde, OUTPUT);
pinMode(ledrojo, OUTPUT);
lcd.init(); // initialize the lcd
lcd.backlight();
#ifndef ESP8266
while (!Serial); // wait for serial port to connect. Needed for native USB
#endif
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}
void loop() {
if (activo == 1) {
lcd.setCursor(15, 0);
lcd.print("*");
if (encendido == 1) {
digitalWrite(ledrojo, HIGH);
digitalWrite(ledverde, LOW);
digitalWrite(rele, HIGH);
} else {
digitalWrite(ledrojo, LOW);
digitalWrite(ledverde, HIGH);
digitalWrite(rele, LOW);
}
} else {
digitalWrite(ledrojo, LOW);
digitalWrite(ledverde, HIGH);
lcd.setCursor(15, 0);
lcd.print(" ");
}
DateTime now = rtc.now();
char buf1[] = "DD/MM/YYYY";
char buf2[] = "hh";
char buf3[] = "mm";
char buf4[] = "ss";
lcd.setCursor(0, 0);
lcd.print(now.toString(buf1));
lcd.setCursor(0, 1);
lcd.print(now.toString(buf2));
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
lcd.print(now.toString(buf3));
lcd.setCursor(5, 1);
lcd.print(":");
lcd.setCursor(6, 1);
lcd.print(now.toString(buf4));
char key = keypad.getKey();
// if (key) {
// Serial.println(key);
// }
if (key == '*') {
lcd.backlight();
if (activo == 1) {
activo = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PROGRAMA");
lcd.setCursor(0, 1);
lcd.print("DESACTIVADO");
delay(5000);
lcd.clear();
} else {
activo = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PROGRAMA");
lcd.setCursor(0, 1);
lcd.print("ACTIVADO");
delay(5000);
lcd.clear();
}
lcd.noBacklight();
}
if (key == 'A') {
setTime("inicio");
setTime("final");
lcd.print("PROGRAMA");
lcd.setCursor(0, 1);
lcd.print("GUARDADO");
delay(5000);
lcd.clear();
lcd.noBacklight();
}
if (key == 'D') {
checkSetup();
}
}
void checkSetup() {
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hora inicio:");
lcd.setCursor(0, 1);
lcd.print(EEPROM.read(0));
lcd.setCursor(1, 1);
lcd.print(EEPROM.read(1));
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
lcd.print(EEPROM.read(2));
lcd.setCursor(4, 1);
lcd.print(EEPROM.read(3));
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hora final:");
lcd.setCursor(0, 1);
lcd.print(EEPROM.read(4));
lcd.setCursor(1, 1);
lcd.print(EEPROM.read(5));
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
lcd.print(EEPROM.read(6));
lcd.setCursor(4, 1);
lcd.print(EEPROM.read(7));
delay(5000);
lcd.clear();
lcd.noBacklight();
}
void setTime(String valor) {
int h1;
int h2;
int m1;
int m2;
int key;
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
if (valor == "inicio") {
lcd.print("Hora inicio:");
lcd.setCursor(0, 1);
lcd.print(EEPROM.read(0));
lcd.setCursor(1, 1);
lcd.print(EEPROM.read(1));
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
lcd.print(EEPROM.read(2));
lcd.setCursor(4, 1);
lcd.print(EEPROM.read(3));
} else {
lcd.print("Hora final:");
lcd.setCursor(0, 1);
lcd.print(EEPROM.read(4));
lcd.setCursor(1, 1);
lcd.print(EEPROM.read(5));
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
lcd.print(EEPROM.read(6));
lcd.setCursor(4, 1);
lcd.print(EEPROM.read(7));
}
lcd.setCursor(0, 1);
for (int pointer = 0; pointer <= 4; pointer++) {
lcd.blink();
lcd.setCursor(pointer, 1);
if (pointer != 2) {
key = keypad.waitForKey() - 48;
}
if (pointer == 0) {
if ((0 > key) || (key > 2)) {
pointer--;
} else {
lcd.print(key);
h1 = key;
}
}
if (pointer == 1) {
if ((0 > key) || ((h1 == 2) && (key > 3))) {
pointer--;
} else {
lcd.print(key);
h2 = key;
}
}
if (pointer == 3) {
if ((0 > key) || (key > 5)) {
pointer--;
} else {
lcd.print(key);
m1 = key;
}
}
if (pointer == 4) {
if (0 > key) {
pointer--;
} else {
lcd.print(key);
m2 = key;
}
}
}
lcd.clear();
lcd.noBlink();
lcd.setCursor(0, 0);
if (valor == "inicio") {
EEPROM.write(0, h1);
EEPROM.write(1, h2);
EEPROM.write(2, m1);
EEPROM.write(3, m2);
}
if (valor == "final") {
EEPROM.write(4, h1);
EEPROM.write(5, h2);
EEPROM.write(6, m1);
EEPROM.write(7, m2);
}
}
At this point of the development, the project does:
- Display the current date and time
- When clicking * this will enable/disable the functionality, which is still not coded. When off, the relay is normally closed regardless of the time, setup, etc. On will be a program to turn the relay on an off depending on the time of the day.
- When clicking A this will take you to a Start and end times setup. This saves a start and end hour and minute in the EEPROM, as you say one digit a byte, not bit.
- When clicking D this shows the current start and end time values in the EEPROM in a 5 second interval.
Thank you