Salve a tutti,
Sono un novizio su Arduino e da autodidatta sto usando ora per la prima volta il modulo RTC. Ho realizzato un sistema che muove un servo a due specifiche ore del giorno, selezionabili attraverso un menù. Sto avendo problemi con LCD, vorrei poter attivare la backlight solo qual'ora si prema un pulsante e dopo diversi secondi di inattività si spenga. Sto utilizzando un sistema di debouncing, ma funziona solo finché un tasto viene premuto, altrimenti smette di funzionare. So che mi sto perdendo qualcosa nello script, magari qualcosa di semplice.
Per favore aiutatemi.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
#include <Servo.h>
RTC_DS3231 rtc;
#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
Servo servo1;
//Input & Button Logic
const int numOfInputs = 4;
const int inputPins[numOfInputs] = {8,9,10,11};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW,LOW,LOW,LOW};
bool inputFlags[numOfInputs] = {LOW,LOW,LOW,LOW};
long lastDebounceTime[numOfInputs] = {0,0,0,0};
long debounceDelay = 5;
//LCD Menu Logic
const int numOfScreens = 5;
int currentScreen = 0;
String screens[numOfScreens][2] = {{"Turn:",""}, {"Set ON:", "Hour"},
{"Set ON:","Minutes"},{"Set OFF:","Hour"}, {"Set OFF:", "Minutes"}};
int parameters[numOfScreens];
int timeforOFF = 180;
int timeforON = 0;
//int setOnHour = 0;
//int setOnMinute = 0;
//int setOffHour = 0;
//int setOffMinute = 0;
long t = 0;
long debdelay = 5000;
void setup() {
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("Verifica Connessione DS3231");
while(true);
}
if (rtc.lostPower()){
rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
}
servo1.attach(12);
servo1.write(90);
for(int i = 0; i < numOfInputs; i++) {
pinMode(inputPins[i], INPUT);
digitalWrite(inputPins[i], HIGH); // pull-up 20k
}
lcd.begin(16,2);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(LOW);
}
void loop() {
DateTime currentTime = rtc.now();
printTimeScreen(currentTime);
setInputFlags();
resolveInputFlags();
screenLight(t);
Serial.print(t);
if (parameters[0] == 0){
servo1.write(timeforOFF);
}else if (parameters[0] == 1){
servo1.write(timeforON);
}else if (parameters[0] == 2){
if(checkAlarm(currentTime, parameters[1], parameters[2], parameters[3], parameters[4])){
servo1.write(timeforOFF);
}else{
servo1.write(timeforON);
}
}
}
void printTimeScreen(DateTime selTime){
Serial.println(" ");
Serial.print(selTime.hour());
Serial.print(":");
Serial.print(selTime.minute());
Serial.print(":");
Serial.print(selTime.second());
Serial.println(" ");
}
void setInputFlags() {
for(int i = 0; i < numOfInputs; i++) {
int reading = digitalRead(inputPins[i]);
if (reading != lastInputState[i]) {
lastDebounceTime[i] = millis();
}
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (reading != inputState[i]) {
inputState[i] = reading;
if (inputState[i] == HIGH) {
inputFlags[i] = HIGH;
t = millis();
}
}
}
lastInputState[i] = reading;
}
}
void resolveInputFlags() {
for(int i = 0; i < numOfInputs; i++) {
if(inputFlags[i] == HIGH) {
inputAction(i);
inputFlags[i] = LOW;
printScreen();
}
}
}
void screenLight (int tempo){
if((millis() - tempo)< debdelay){
lcd.setBacklight(HIGH);
time = 0;
}else{
lcd.setBacklight(LOW);
}
}
void inputAction(int input) {
if(input == 0) {
if (currentScreen == 0) {
currentScreen = numOfScreens-1;
}else{
currentScreen--;
}
}else if(input == 1) {
if (currentScreen == numOfScreens-1) {
currentScreen = 0;
}else{
currentScreen++;
}
}else if(input == 2) {
parameterChange(0);
}else if(input == 3) {
parameterChange(1);
}
}
void parameterChange(int key) {
if(key == 0) {
if (currentScreen == 1 || currentScreen == 3){
if (parameters[currentScreen]>= 0 && parameters[currentScreen]<23){
parameters[currentScreen]++;
}
}
if (currentScreen == 2 || currentScreen == 4){
if (parameters[currentScreen]>= 0 && parameters[currentScreen]<55){
parameters[currentScreen]= parameters[currentScreen]+5;
}
}
if (currentScreen == 0){
if (parameters[currentScreen]>= 0 && parameters[currentScreen]<2){
parameters[currentScreen]++;
}
}
}else if(key == 1) {
if (parameters[currentScreen] >0) {
if (currentScreen == 2 || currentScreen == 4){
if (parameters[currentScreen]> 0 && parameters[currentScreen]<=55){
parameters[currentScreen]= parameters[currentScreen]-5;
}
}else{
parameters[currentScreen]--;
}
}
}
}
void printScreen() {
if (currentScreen == 0 && parameters[currentScreen] == 0){
lcd.clear();
lcd.print(screens[currentScreen][0]);
lcd.setCursor(0,1);
// lcd.print(parameters[currentScreen]);
lcd.print(" ");
lcd.print("OFF");
} else if (currentScreen == 0 && parameters[currentScreen] == 1){
lcd.clear();
lcd.print(screens[currentScreen][0]);
lcd.setCursor(0,1);
// lcd.print(parameters[currentScreen]);
lcd.print(" ");
lcd.print("ON");
} else if (currentScreen == 0 && parameters[currentScreen] == 2){
lcd.clear();
lcd.print(screens[currentScreen][0]);
lcd.setCursor(0,1);
// lcd.print(parameters[currentScreen]);
lcd.print(" ");
lcd.print("ON + TIMER");
}else{
lcd.clear();
lcd.print(screens[currentScreen][0]);
lcd.setCursor(0,1);
lcd.print(parameters[currentScreen]);
lcd.print(" ");
lcd.print(screens[currentScreen][1]);
}
}
boolean checkAlarm(DateTime timeNow, int setOnHour, int setOnMinute, int setOffHour, int setOffMinute){
DateTime midNight( timeNow.year(), timeNow.month(), timeNow.day(),00, 00, 00);
DateTime lastTime( timeNow.year(), timeNow.month(), timeNow.day(),23, 59, 59);
DateTime timeSetOn( timeNow.year(), timeNow.month(), timeNow.day(),setOnHour, setOnMinute, 00);
DateTime timeSetOff( timeNow.year(), timeNow.month(), timeNow.day(),setOffHour, setOffMinute, 00);
if (timeSetOn>=timeSetOff){
if (timeNow>=timeSetOff && timeNow <= timeSetOn){
return true;
}else if (timeNow<=timeSetOff && timeNow>=midNight){
return false;
}else if (timeNow>=timeSetOn && timeNow<=lastTime){
return false;
}
}else if (timeSetOn<=timeSetOff){
if (timeNow>=timeSetOn && timeNow<=timeSetOff){
return false;
}else if (timeNow>=midNight && timeNow<=timeSetOn){
return true;
}else if (timeNow>=timeSetOff && timeNow<=lastTime){
return true;
}
}
}
PS: Perdonate se lo script non è pulito e può sicuramente essere semplificato, prometto che migliorerò.