Ciao, sto scrivendo un programma per il cambio automatico dell’acqua del mio acquario, uso arduino uno r3 , un display oled per visualizzare le diverse fasi del programma cambio acqua, il codice funziona almeno in apparenza, ma ho problemi con l’impostazione la data e l’ora per l’avvio del programma, anche se imposto il giorno e l’ora il programma cambio acqua non parte, nel codice ho inserito 3 funzioni , una per stabilire l'intervallo dei cambi acqua, una per stabilire dopo il primo avvio quanti giorni il programma deve attendere per avviare il programma cambio acqua, e la terza per stabilire l'orario del cambio acqua, allego il codice, se qualcuno può aiutarmi a risolvere. Grazie
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <RTClib.h>
#include <TimeLib.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int livelloMaxPin = 2;
const int riscaldatorePin = 3;
const int pompaRicircoloPin = 4;
const int solenoidePin = 5;
const int temperaturaPin = 1;
const int motorePin = 9;
const int releScaricoPin = 10;
const int pompaAcquaPulitaPin = 11;
const int pompaScaricoPin = 12;
int livelloMax = 0;
float temperatura = 0;
unsigned long intervalloCambioAcqua = 7 * 24 * 60 * 60 * 1000; // Intervallo di 7 giorni in millisecondi
unsigned long ultimoCambioAcqua = 0; // Tempo dell'ultimo cambio acqua
DateTime prossimoCambio;
OneWire oneWire(temperaturaPin);
DallasTemperature sensors(&oneWire);
RTC_DS3231 rtc;
////////////
// Funzione per calcolare la posizione orizzontale centrata
int getCenteredX(int textWidth) {
return (SCREEN_WIDTH - textWidth) / 2;
}
//////////
enum WaterChangePhase {
RIEMPIMENTO,
RISCALDAMENTO,
POMPA_RICIRCOLO,
SALE,
SCARICO,
RIEMPIMENTO_ACQUA_PULITA
};
WaterChangePhase waterChangePhase = RIEMPIMENTO;
const char* phaseText[] = {"Riempio serbatoio", "Riscaldamento acqua", "Pompa di ricircolo", "Sale", "Scarico", "Riempimento acqua pulita"};
bool isWaterChangeInProgress = false;
unsigned long tempoAttivazionePompaRicircolo = 2 * 60 * 60 * 1000;
unsigned long tempoAttivazionePompaScarico = 2 * 60 * 1000;
unsigned long tempoAttivazionePompaAcquaPulita = 2 * 60 * 60 * 1000;
unsigned long tempoInizioPompaRicircolo = 0;
unsigned long tempoInizioPompaScarico = 0;
unsigned long tempoInizioPompaAcquaPulita = 0;
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setTextWrap(false);
display.setRotation(0);
///////////////////////////
int textWidth = 6 * 14; // Larghezza del testo "Aquarium Control" con dimensione del testo 2
int centerX = getCenteredX(textWidth);
display.setCursor(centerX, 10);
display.println("Aquarium");
display.display();
delay(5000);
display.clearDisplay();
display.display();
pinMode(livelloMaxPin, INPUT);
pinMode(riscaldatorePin, OUTPUT);
pinMode(pompaRicircoloPin, OUTPUT);
pinMode(solenoidePin, OUTPUT);
pinMode(motorePin, OUTPUT);
pinMode(releScaricoPin, OUTPUT);
pinMode(pompaAcquaPulitaPin, OUTPUT);
pinMode(pompaScaricoPin, OUTPUT);
sensors.begin();
Wire.begin();
rtc.begin();
// Recupera l'ultimo cambio acqua dal modulo RTC
DateTime now = rtc.now();
ultimoCambioAcqua = now.unixtime() * 1000; // Converti in millisecondi
// Calcola il prossimo cambio acqua
prossimoCambio = rtc.now() + TimeSpan(1, 0, 0, 0);//inserire intervallo giorni cambio acqua : 7 giorni
// Resto del codice...
// Imposta l'ora desiderata per il prossimo cambio acqua
prossimoCambio = DateTime(prossimoCambio.year(), prossimoCambio.month(), prossimoCambio.day(), 15, 47, 0);
}
String formatDigits(int digits) {
if (digits < 10) {
return "0" + String(digits);
} else {
return String(digits);
}
}
void updateDisplay() {
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.print("T: ");
display.print(temperatura, 1);
display.print(" C");
display.setCursor(0, 17);
if (isWaterChangeInProgress) {
display.print("P: ");
display.print(phaseText[waterChangePhase]);
} else {
display.print(" ");
}
display.setTextSize(1);
display.setCursor(0, 32);
display.print("Pros:");
display.setCursor(30, 32);
display.print(formatDigits(prossimoCambio.day()));
display.print("/");
display.print(formatDigits(prossimoCambio.month()));
display.print("/");
display.print(prossimoCambio.year());
display.setCursor(95, 32);
display.print(formatDigits(prossimoCambio.hour()));
display.print(":");
display.print(formatDigits(prossimoCambio.minute()));
display.setTextSize(1);
display.setCursor(0, 47);
display.print("Oggi:");
display.setCursor(32, 47);
DateTime now = rtc.now();
display.print(formatDigits(now.day()));
display.print("/");
display.print(formatDigits(now.month()));
display.print("/");
display.print(now.year());
display.setCursor(45, 56);
display.print(formatDigits(now.hour()));
display.print(":");
display.print(formatDigits(now.minute()));
display.print(":");
display.println(formatDigits(rtc.now().second()));
display.display();
}
DateTime calculateNextWaterChange(DateTime currentDateTime, unsigned long interval) {
return currentDateTime + TimeSpan(interval / 1000);
}
void loop() {
int livelloAcqua = digitalRead(livelloMaxPin);
if (livelloAcqua == HIGH) {
digitalWrite(solenoidePin, LOW);
digitalWrite(pompaRicircoloPin, HIGH);
} else {
digitalWrite(solenoidePin, HIGH);
digitalWrite(pompaRicircoloPin, LOW);
}
sensors.requestTemperatures();
temperatura = sensors.getTempCByIndex(0);
if (livelloAcqua == HIGH && temperatura < 25) {
digitalWrite(riscaldatorePin, HIGH);
} else {
digitalWrite(riscaldatorePin, LOW);
}
if (livelloAcqua == HIGH && waterChangePhase == POMPA_RICIRCOLO) {
tempoInizioPompaRicircolo = millis();
digitalWrite(pompaRicircoloPin, HIGH);
} else {
digitalWrite(pompaRicircoloPin, LOW);
}
if (waterChangePhase == SALE) {
tempoInizioPompaScarico = millis();
digitalWrite(pompaScaricoPin, HIGH);
} else {
digitalWrite(pompaScaricoPin, LOW);
}
if (waterChangePhase == RIEMPIMENTO_ACQUA_PULITA) {
tempoInizioPompaAcquaPulita = millis();
digitalWrite(pompaAcquaPulitaPin, HIGH);
} else {
digitalWrite(pompaAcquaPulitaPin, LOW);
}
unsigned long tempoTrascorso = millis() - ultimoCambioAcqua;
if (!isWaterChangeInProgress && tempoTrascorso >= intervalloCambioAcqua) {
DateTime currentDateTime = rtc.now();
prossimoCambio = calculateNextWaterChange(currentDateTime, intervalloCambioAcqua);
rtc.adjust(DateTime(prossimoCambio.year(), prossimoCambio.month(), prossimoCambio.day(), prossimoCambio.hour(), prossimoCambio.minute(), prossimoCambio.second()));
isWaterChangeInProgress = true;
waterChangePhase = RIEMPIMENTO;
ultimoCambioAcqua = millis();
} else if (isWaterChangeInProgress) {
if (waterChangePhase == RIEMPIMENTO) {
// ... Rest of the code ...
} else if (waterChangePhase == RISCALDAMENTO) {
// ... Rest of the code ...
} else if (waterChangePhase == POMPA_RICIRCOLO) {
// ... Rest of the code ...
} else if (waterChangePhase == SALE) {
// ... Rest of the code ...
} else if (waterChangePhase == SCARICO) {
// ... Rest of the code ...
} else if (waterChangePhase == RIEMPIMENTO_ACQUA_PULITA) {
// ... Rest of the code ...
}
}
updateDisplay();
}