#include "HX711.h"
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// ================= OLED =================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// =====================HX711=====================
#define DT 3
#define SCK 2
HX711 scale;
//--------Constants
const float CALIBRATION_FACTOR = 0.42; // DA REGOLARE IN TARATURA
const float GRAMMI_PER_LITRO = 1000.0;
const float PLASTICA_BOTTIGLIA_LITRI = 0.5;
const float BOTTIGLIA_STANDARD = 0.5;
const float CO2_PER_BOTTIGLIA = 82.0; // grammi
// soglie
const float SOGLIA_BORRACCIA = 50.0; // grammi
const float SOGLIA_RIMOZIONE = 20.0;
//----Global variables
float pesoPrecedente = 0;
float litriTotali = 0;
float bottiglieEvitate = 0;
float co2Risparmiata = 0;
float litriErogati = 0;
float pesoAttuale = 0;
float pesoIniziale = 0;
float pesoFinale = 0;
// indirizzi EEPROM
int addrLitri = 0;
int addrBottiglie = sizeof(float);
int addrCO2 = sizeof(float) + sizeof(float);
// ================= STATI =================
enum Stato {
ATTESA,
BORRACCIA_PRESENTE
};
Stato stato = ATTESA;
// ===================== FILTRO SEMPLICE =====================
float leggiPesoFiltrato() {
const int N = 10;
float somma = 0;
for (int i = 0; i < N; i++) {
somma += scale.get_units(3);
delay(10);
}
return somma / N;
}
// ================= DISPLAY =================
void aggiornaDisplay(String messaggio) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("SMART WATER 4.0");
display.println("----------------");
display.println(messaggio);
display.println();
display.print("Tot L: ");
display.println(litriTotali, 2);
display.print("Bottiglie: ");
display.println(bottiglieEvitate, 1);
display.print("CO2 g: ");
display.println(co2Risparmiata, 0);
display.display();
}
void setup() {
Serial.begin(9600);
scale.begin(DT, SCK);
scale.set_scale(CALIBRATION_FACTOR); // fattore di scala
scale.tare(); // azzera
// OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
while (true);
}
// recupero dati EEPROM
EEPROM.get(addrLitri, litriTotali);
EEPROM.get(addrBottiglie, bottiglieEvitate);
EEPROM.get(addrCO2, co2Risparmiata);
aggiornaDisplay("Sistema pronto");
Serial.println("Smart Water Station avviata");
}
void loop() {
pesoAttuale = leggiPesoFiltrato();
switch (stato) {
// ================= ATTESA =================
case ATTESA:
aggiornaDisplay("Inserire borraccia");
// borraccia inserita
if (pesoAttuale > SOGLIA_BORRACCIA) {
pesoIniziale = pesoAttuale;
Serial.println("Borraccia rilevata");
stato = BORRACCIA_PRESENTE;
delay(1000);
}
break;
// ================= BORRACCIA PRESENTE =================
case BORRACCIA_PRESENTE:
aggiornaDisplay("Riempimento...");
if (pesoAttuale > pesoFinale) {
pesoFinale = pesoAttuale;
}
// borraccia rimossa
if (pesoAttuale < SOGLIA_RIMOZIONE) {
// calcolo acqua erogata
float deltaPeso = pesoFinale - pesoIniziale;
// sicurezza
if (deltaPeso < 0) {
deltaPeso = 0;
}
litriErogati = deltaPeso / GRAMMI_PER_LITRO;
// aggiornamento statistiche
litriTotali += litriErogati;
float bottiglie = litriErogati / BOTTIGLIA_STANDARD;
bottiglieEvitate += bottiglie;
co2Risparmiata += bottiglie * CO2_PER_BOTTIGLIA;
// EEPROM SAVE
EEPROM.put(addrLitri, litriTotali);
EEPROM.put(addrBottiglie, bottiglieEvitate);
EEPROM.put(addrCO2, co2Risparmiata);
// serial monitor
Serial.println("===== EROGAZIONE COMPLETATA =====");
Serial.print("Litri erogati: ");
Serial.println(litriErogati, 3);
Serial.print("Totale litri: ");
Serial.println(litriTotali, 2);
Serial.print("Bottiglie evitate: ");
Serial.println(bottiglieEvitate, 1);
Serial.println("================================");
aggiornaDisplay("Erogazione OK");
delay(3000);
pesoFinale = 0;
stato = ATTESA;
}
break;
}
delay(200);
}