Programma cambio acqua

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();
}

Buongiorno
Benvenuto nella sezione Italiana del forum :slight_smile:

Cortesemente, leggi attentamente il REGOLAMENTO di detta sezione:
[REGOLAMENTO] Come usare questa sezione del forum
(... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15)
e poi, come da suddetto regolamento (punto 16.7), fai la tua presentazione IN CODA ALL'APPOSITA DISCUSSIONE:
Presentazioni nuovi iscritti: fatevi conoscere da tutti! (Part 2)
spiegando bene quali esperienze hai in elettronica e in programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie
Gianluca

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento, nessuno ti risponderà (eventuali risposte, o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

P.P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ...

Inoltre, spiega meglio quali problemi hai:

Ricorda che nella programmazione (ma anche nell'elettronica) bisogna essere precisi e dettagliati, altrimenti non ci si capisce, e che basta una virgola in più o in meno o una parentesi o un qualsiasi altro carattere per non far funzionare il programma come desiderato o non farlo funzionare affatto!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.