#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//PIN
const int relayPin = 2; //Pin Relè pompa
const int waterLevelPin = A0; //Pin sensore livello acqua
const int redLedPin = 3; //Pin del led
//TIMER
const unsigned long irrigationInterval = 6 * 60 * 60 * 1000; //Attesa tra ogni irrigazione in ORE (2h)
const unsigned long irrigationDuration = 30 * 1000; //Durata irrigazione in SECONDI (30s)
// Variabili per gestire il countdown
unsigned long previousIrrigationTime = 0;
unsigned long timeRemaining = 0;
// Variabili per gestire lo stato dell'irrigazione
boolean isIrrigating = false;
// LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Testo da far scorrere
const char scrollingText[] = "Serra Idroponica: Denilson";
void clearFirstLine() {
lcd.setCursor(0, 0);
lcd.print(" "); // Pulisce la prima riga
}
void updateNextIrrigationTime() {
// Calcola il tempo rimanente alla prossima irrigazione
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - previousIrrigationTime;
unsigned long timeToNextIrrigation = max(0, irrigationInterval - elapsedTime);
// Aggiorna l'LCD con il tempo alla prossima irrigazione
lcd.setCursor(0, 1);
lcd.print("Irriga tra: ");
lcd.setCursor(26, 1);
lcd.print(timeToNextIrrigation / 1000);
lcd.print("s");
}
void setup() {
// Inizializza i pin
pinMode(relayPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
pinMode(waterLevelPin, INPUT);
// Inizializza l'LCD
lcd.begin(16, 2);
lcd.setBacklight(LOW);
lcd.clear();
// Scritta di presentazione
lcd.print("Serra Idroponica:");
// Salva il tempo di inizio per lo scorrimento del testo
previousIrrigationTime = millis();
}
void loop() {
// Leggi il livello dell'acqua
int waterLevel = digitalRead(waterLevelPin);
// Verifica se il livello dell'acqua è basso
if (waterLevel == LOW) {
// Attiva il lampeggio del LED rosso
digitalWrite(redLedPin, HIGH);
delay(500);
digitalWrite(redLedPin, LOW);
delay(500);
}
// Calcola il tempo trascorso dall'ultima irrigazione
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - previousIrrigationTime;
// Se è passato abbastanza tempo, avvia un'irrigazione
if (elapsedTime >= irrigationInterval && !isIrrigating) {
startIrrigation();
}
// Se l'irrigazione è in corso, aggiorna il countdown
if (isIrrigating) {
updateCountdown();
}
// Gestione del ritorno alla schermata iniziale dopo l'irrigazione
if (isIrrigating && elapsedTime >= irrigationDuration) {
endIrrigation();
}
// Gestisci lo scorrimento del testo solo se non è in corso l'irrigazione
if (!isIrrigating) {
updateNextIrrigationTime();
scrollText();
}
}
void startIrrigation() {
// Attiva la pompa
digitalWrite(relayPin, HIGH);
// Aggiorna lo stato e il countdown
isIrrigating = true;
timeRemaining = irrigationDuration;
lcd.clear();
lcd.print("Irrigazione in corso...");
lcd.setCursor(0, 1);
lcd.print("Tempo rimanente: ");
lcd.setCursor(15, 1);
lcd.print("s");
// Salva il tempo di inizio irrigazione
previousIrrigationTime = millis();
}
void updateCountdown() {
// Calcola il tempo rimanente
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - previousIrrigationTime;
timeRemaining = max(0, irrigationDuration - elapsedTime);
// Aggiorna l'LCD con il countdown
lcd.setCursor(15, 1);
lcd.print(timeRemaining / 1000);
// Lampeggia il LED rosso durante l'irrigazione
digitalWrite(redLedPin, (elapsedTime / 500) % 2 == 0);
}
void endIrrigation() {
// Disattiva la pompa
digitalWrite(relayPin, LOW);
// Aggiorna lo stato
isIrrigating = false;
// Torna alla schermata iniziale
lcd.clear();
lcd.print("Serra Idroponica:");
previousIrrigationTime = millis(); // Resetta il tempo dell'ultima irrigazione
}
void scrollText() {
static int scrollPosition = 0;
static unsigned long lastScrollTime = 0;
unsigned long currentTime = millis();
// Scrolla il testo solo se non è in corso l'irrigazione ogni 400 millisecondi
if (currentTime - lastScrollTime >= 350) {
clearFirstLine(); // Pulisce solo la prima riga prima di aggiornare lo scrollingText
lcd.setCursor(0, 0);
// Stampa una sottostringa dello scrollingText
lcd.print(scrollingText + scrollPosition);
// Incrementa la posizione di scorrimento
scrollPosition++;
// Se si raggiunge la fine del testo, ricomincia dal principio
if (scrollPosition >= sizeof(scrollingText) - 16) {
scrollPosition = 0;
}
// Salva il tempo dell'ultimo scorrimento
lastScrollTime = currentTime;
}
}