#include <Adafruit_ILI9341.h>
#include <Adafruit_GFX.h>
// Pin del display ILI9341
#define TFT_CLK 52
#define TFT_MISO 50
#define TFT_MOSI 51
#define TFT_CS 53
#define TFT_DC 48
#define TFT_RST 49
// Pin fisici
#define BUTTON_PIN 2
#define POWER_PIN 3 //pin ritenuta alimentazione arduino
#define BACKLIGHT_PIN 4 //pin retroilluminazione display
const int BATTERY_PIN[] = {A0, A1, A2}; //pin lettura tensione batteria
const int BATTERY_HOLDER_PIN[] = {5, 6, 7}; //hjhjsdds
// Resistenze usate nel partitore di tensione
const float R1 = 10000.0; // 10kΩ
const float R2 = 10000.0; // 10kΩ
//Variabili relativi alla batteria e al carico
float I_load = 0.9; //assorbimento corrente del carico
float I_zero = 0.001; //assorbimento corrente nel partitore
int C_full = 5000; //capacita della batteria singola in mAh
float current;
//variabili per la lettura delle batterie
int n =0;
bool ready = false;
bool first = true;
bool connectionState = false;
unsigned long lastCheckTime = 0; // Tempo dell'ultimo controllo delle batterie
const unsigned long checkInterval = 30000; // Intervallo di 30 secondi (30000 millisecondi)
int indices[]={0, 1, 2};
int currentScreen = 0;
// Variabili per gestire la pressione del pulsante
bool buttonState = HIGH; // Variabile per memorizzare lo stato del pulsante
bool lastButtonState = HIGH; // Variabile per memorizzare l'ultimo stato del pulsante
int SHORT_PRESS_TIME = 2000;
unsigned long buttonPressDuration, buttonStartTime = 0;
//Variabili per gestire la retroilluminazione del display
unsigned long backlightTimeout = 0; // Tempo dell'ultimo controllo
const unsigned long backlightInterval = 8000; // Intervallo di 8 secondi
bool backlightOn = true;
// definizione struttura della variabile batteria
struct BatteryData {
int batteryNumber;
float voltage;
int soc;
float time;
};
BatteryData batteries[3]; // Array di batterie
int batteryCount = 3; // Numero di batterie
// Creazione dell'oggetto display
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
//definizione delle funzioni
void readAndSortBatteries(BatteryData* batteries, int* indices, int count); // Dichiarazione della funzione
void checkBatteries(BatteryData* batteries); // Dichiarazione della funzione2
void displayScreen1(BatteryData* batteries, int* indices, int n); // Dichiarazione della funzione2
void displayScreen2(BatteryData* batteries, int* indices, int n, float current); // Dichiarazione della funzione2
float interpolate(float I_load, float V_batt);
void displayFoxLogo();
void setup() {
Serial.begin(9600); // Inizializzazione della seriale
for (int k = 0; k <= batteryCount; k++) {
pinMode(BATTERY_HOLDER_PIN[k], OUTPUT);
}
// Configura il pulsante
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(POWER_PIN, OUTPUT);
pinMode(BACKLIGHT_PIN, OUTPUT);
digitalWrite(POWER_PIN,HIGH);
digitalWrite(BACKLIGHT_PIN, HIGH); // Accende la retroilluminazione all'avvio
backlightTimeout = millis() + 25000; // Imposta il timeout a 25 secondi dall'avvio
// Inizializza il display
tft.begin();
tft.setRotation(3);
displayFoxLogo();
delay(2000); // Mantieni il logo per 2 secondi
tft.fillScreen(ILI9341_BLACK);
}
void loop() {
if (!ready) { //Se non è stato eseguito un primo controllo sulle batterie
for (int i=0; i<batteryCount; i++) {
digitalWrite(BATTERY_PIN[batteries[i].batteryNumber],HIGH);
}
delay(1000);
readAndSortBatteries(batteries, indices, batteryCount); // Chiama la funzione che gestisce le batterie
Serial.println("Controllo batterie in corso... ");
for (int i=0; i<batteryCount; i++) {
digitalWrite(BATTERY_PIN[batteries[i].batteryNumber],LOW);
}
ready = true;
n=0;
}
else { //Se ready == true!
while (connectionState == false) { //controllo e connessione delle batterie
if (n<=3) {
Serial.print("controllo batteria ");
Serial.print(batteries[indices[n]].batteryNumber);
Serial.print("... ");
if (batteries[indices[n]].voltage>3.2 && batteries[indices[n]].voltage<4.2) {
if(connectionState == false) {
Serial.println("OK");
Serial.print("batteria ");
Serial.print(batteries[indices[n]].batteryNumber);
Serial.println(" collegata");
connectionState = true;
digitalWrite(BATTERY_HOLDER_PIN[indices[n]], HIGH);
}
}
else {
Serial.println(" SCARICA");
if(connectionState == true) {
Serial.print("batteria ");
Serial.print(indices[n]);
Serial.println(" scollegata");
connectionState = false;
digitalWrite(BATTERY_HOLDER_PIN[indices[n]], LOW);
}
n++;
}
}
else {
Serial.println("Tutte le batterie sono scariche ");
Serial.println("SPEGNIMENTO ");
displayErrorScreen();
delay(3000);
digitalWrite(POWER_PIN, LOW);
}
displayLoadingScreen();
}
if ((millis() - lastCheckTime >= checkInterval)|| first==true) {
for (int i=0; i<batteryCount; i++) {
digitalWrite(BATTERY_PIN[batteries[i].batteryNumber],HIGH);
}
checkBatteries(batteries); // Monitora le tensioni delle batterie
Serial.println(" ");
for (int i = 0; i < batteryCount; i++) {
if ( i == n ) {
current = I_load;
}
else {
current = I_zero;
}
batteries[i].soc = int(interpolate(current, batteries[i].voltage));
batteries[i].time = t_rem();
}
for (int i=0; i<batteryCount; i++) {
digitalWrite(BATTERY_PIN[batteries[i].batteryNumber],LOW);
}
lastCheckTime = millis(); // Aggiorna l'ultimo tempo di controllo
}
if (first) {
displayScreen2(batteries, indices, n, I_load);
first = false;
}
// Legge lo stato corrente del pulsante
buttonState = digitalRead(BUTTON_PIN);
delay(100);
if ( lastButtonState && !buttonState ) {
buttonStartTime = millis(); // Memorizza l'istante di inizio pressione del pulsante
}
else if ( !lastButtonState && buttonState ) {
buttonPressDuration = millis() - buttonStartTime;
if( buttonPressDuration < SHORT_PRESS_TIME ) {
if (!backlightOn) {
// Se la retroilluminazione è spenta, accendila e non cambiare schermata
digitalWrite(BACKLIGHT_PIN, HIGH);
backlightOn = true;
}
else {
// Esegui l'azione normale per la pressione breve
currentScreen = (currentScreen + 1) % 2;
// Cambia schermata
if (currentScreen == 0) {
displayScreen2(batteries, indices, n, I_load);
}
else {
displayScreen1(batteries, indices, n);
}
}
// Aggiorna il timeout della retroilluminazione
backlightTimeout = millis() + backlightInterval;
}
else {
Serial.println("Spegnimento del sistema in corso");
displayShutdownScreen();
delay(3000);
digitalWrite(POWER_PIN, LOW);
}
}
lastButtonState = buttonState;
// Spegne la retroilluminazione dopo 10 secondi
if (backlightOn && millis() > backlightTimeout) {
digitalWrite(BACKLIGHT_PIN, LOW);
backlightOn = false;
}
}
}