Buon giorno , il titolo pomposo vuole essere miele per orsi , conscio dei rischi connessi.
Scherzi a parte, tempo addietro avevo scritto la prima versione di questo codice con la finalità di testare la capacità di una generica batteria basandomi sulla legge di ohm (non ho le conoscenze elettroniche per andare oltre); ed in realtà non è che debba testare chissà quali e quante batterie , nessuna , per la verità ; ma fatico a "giocare" con l'uno a l'altro componente senza avere un "traguardo" d'insieme.
Con questo progetto ho potuto giocare con diverse situazioni , ora , alla luce di nuove (per me) nozioni apprese mi permetto di postare il codice nella speranza di non infastidire nessuno ed al contempo di risultare comprensibile e , perché nascondersi ? anche nella speranza di consigli e graffiate (restando in tema orsi) .
Grazie.
//TESTER BATTERIE FUNZIONANTE (bug permettendo)\\
/*A BORDO 5 PULSANTI [START] [SELEZIONE] [ + ] [ - ] [RESET]
2 SELETTORI [CARICO INTERNO ON/OFF] [CARICO ESTERNO ON/OFF]
5 LED [BLU CICLO IN CORSO] [VERDE CICLO TERMINATO BATTERIA OK] [ROSSO CICLO TERMINATO BATTERIA K.O]
[GIALLO STATO CARICO INTERNO ON/OFF] [GIALLO STATO CARICO ESTERNO ON/OFF] NOTA: COLLEGAMENTO HARDWARE
1 DISPLAY LCD 16,2 I2c
*/
#include <JC_Button.h> //libreria gestione pulsanti in ingresso
#include <Wire.h> //libreria porte I2c
#include <PCF8574_HD44780_I2C.h> //libreria display I2c
PCF8574_HD44780_I2C lcd(0x27, 16, 2); //creo oggetto display
//definisco ingressi-uscite
#define START 2 //avvio ciclo automatico di test
#define SELEZIONE 3 //selezione possibilità
#define INCREMENTO 4 //pulsante incremento
#define DECREMENTO 5 //pulsante decremento
#define CARICO_INTERNO 6 //rele di carico interno
#define CARICO_ESTERNO 7 //rele di carico esterno
#define LED_BLU 8 //led blu di scarica in corso (sarebbe bello se lampeggiasse)
#define LED_VERDE 9 //led rosso di fine scarica con esito negativo
#define LED_ROSSO 10 //led verde di fine scarica con esito positivo
//definizione case
int stato_scelto = 0; //stati case
#define HOME 0 //visualizzo schermata iniziale
#define TIPO_1 1 //batteria pre_impostata modello 1
#define TIPO_2 2 //batteria pre_impostata modello 2
#define TENSIONE_NOMINALE 3 //imposto valore tensione nominale batteria
#define TENSIONE_MINIMA 4 //imposto valore tensione minima batteria
#define CAPACITA_NOMINALE 5 //imposto valore capacità nominale batteria
#define TEMPO_PRESUNTO 6 //imposto valore tempo previsto,in funzione al carico applicato
#define TESTER_LIVE 7 //a riposo è un voltmetro , a seguito dello start avvia il test
unsigned long T_RIFERIMENTO ; //tengo traccia del tempo dall'accensione
//gestione pulsanti ingresso da libreria
Button start(START); //creo oggetto pulsante start/avvio
Button selezione(SELEZIONE); //creo oggetto pulsante selezione/scegli
// variabili globali
bool avvio; //avvio/accetta ciclo automatico
bool scegli; //scegli stato (case)
bool aumenta; //modifica valore aumentando
bool diminuisci; //modifica valore diminuendo
float voltmetro ; //qui assegno la tensione rilevata sul pin A0
float amperometro ; //qui assegno la corrente rilevata sul pin A1
float V_nominale; //dati targa batteria da impostare
float V_minima; //soglia di interruzione ciclo preimpostato o da impostare
float A_nominale; //capacità di targa o presunta preimpostata o da impostare
float A_carico; //potenza applicata dal carico preimpostata se interna da impostare se esterna
float T_scarica; //tempo scarica presunto preimpostato o da impostare
float contatore = 0.00; //variabile per impostare valori da assegnare con decimali
int contatore_tempo = 0; //variabile per impostare valore temporale con moltiplicatore preimpostato
int ciclo = 0 ; //varibile (superflua?) per conoscere provenienza del case attuale
void setup() {
Serial.begin(9600);
pinMode (SELEZIONE, INPUT);
pinMode (START, INPUT);
pinMode (INCREMENTO, INPUT);
pinMode (DECREMENTO, INPUT);
pinMode (CARICO_INTERNO, OUTPUT);
pinMode (CARICO_ESTERNO, OUTPUT);
pinMode (LED_BLU, OUTPUT);
pinMode (LED_VERDE, OUTPUT);
pinMode (LED_ROSSO, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(" BATTERY TESTER");
lcd.setCursor(0, 1);
lcd.print(" VERSIONE V 1"); //VERSIONE 7 mia
delay(2000);
}
void loop() {
voltmetro = digitalRead (A0);
amperometro = digitalRead (A1);
start.read();
avvio = start.wasReleased();
selezione.read();
scegli = selezione.wasReleased();
aumenta = (digitalRead(INCREMENTO) == true);
diminuisci = (digitalRead(DECREMENTO) == true);
if (scegli) { //ad ogni pressione incremento il valore
stato_scelto ++;
if (stato_scelto > TESTER_LIVE) { //se arrivo a 8
stato_scelto = HOME; //torno a 0
}
}
if (aumenta) {
contatore = contatore + 0.10;
contatore_tempo++;
}
if (diminuisci) {
contatore = contatore - 0.10;
contatore_tempo--;
}
//amperometro live
float Acslettura = 0.0, campioni = 0.0, media = 0.0;
for (int a = 0; a < 20; a++) { //ricavo 20 valori
Acslettura = amperometro ; //leggo valore ritorno acs712 c.to 1
campioni = campioni + Acslettura; //sommo i valori per calcolare la media
delay (10);
}
media = (campioni / 20); //calcolo la media dei valori
amperometro = (2.5 - (media * (5.0 / 1024.0)) ) / 0.0315; //formula per ottenere il valore definitivo
if (amperometro < 0.10) {
amperometro = 0.00;
}
// voltmetro live
voltmetro = ((5.0 / 1024.0) * voltmetro) * ((30 + 7.5) / 7.5);
switch (stato_scelto) {
case HOME:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" BATTERY TESTER");
lcd.setCursor(0, 1);
lcd.print(" SCEGLI OPZIONE");
break;
case TIPO_1: //BATTERIA Li-ION Vnominale 3,6 A 1,9
V_nominale = 3.6;
V_minima = 2.9;
A_nominale = 1.9;
T_scarica = 7200000; //2h 17minuti [impostato a 2h]
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Li-ION 1900mA");
lcd.setCursor(0, 1);
lcd.print("SCARICO ?");
if (avvio) {
stato_scelto = TESTER_LIVE;
}
break;
case TIPO_2 : //BATTERIA Li-ION Vnominale 3,6 A 2,2
V_nominale = 3.6;
V_minima = 2.9;
A_nominale = 2.2;
T_scarica = 8400000; //2h 39' [impostato a 2h20']
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Li-ION 2200mA");
lcd.setCursor(0, 1);
lcd.print("SCARICO ?");
if ((avvio)) {
stato_scelto = 7;
}
break;
case TENSIONE_NOMINALE : //IMPOSTA TENSIONE NOMINALE
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("IMPOSTA DATI");
lcd.setCursor(0, 1);
lcd.print("Vnom=");
lcd.setCursor(7, 1);
lcd.print(contatore);
delay(100);
if ((contatore != 0.00) && (avvio)) {
lcd.setCursor(14, 0);
lcd.print("OK");
delay(50);
V_nominale = contatore;
}
break;
case TENSIONE_MINIMA : //IMPOSTA TENSIONE MINIMA
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("IMPOSTA DATI");
lcd.setCursor(0, 1);
lcd.print("Vmin=");
lcd.setCursor(7, 1);
lcd.print(contatore);
delay(100);
if ((contatore != 0.00) && (avvio)) {
lcd.setCursor(14, 0);
lcd.print("OK");
delay(50);
V_minima = contatore;
}
break;
case CAPACITA_NOMINALE: //IMPOSTA CAPACITA NOMINALE
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("IMPOSTA DATI");
lcd.setCursor(0, 1);
lcd.print("Anom=");
lcd.setCursor(7, 1);
lcd.print(contatore);
delay(100);
if ((contatore != 0.00) && (avvio)) {
lcd.setCursor(14, 0);
lcd.print("OK");
delay(50);
A_nominale = contatore;
}
break;
case TEMPO_PRESUNTO: //IMPOSTA TEMPO SCARICA
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("IMPOSTA DATI");
lcd.setCursor(0, 1);
lcd.print("Tempo=");
lcd.setCursor(6, 1);
lcd.print(contatore_tempo);
lcd.setCursor(10, 1);
lcd.print("x00000");
delay(100);
if ((contatore_tempo != 0.00) && (avvio)) {
lcd.setCursor(14, 0);
lcd.print("OK");
delay(50);
T_scarica = (contatore_tempo * 100000);
}
break;
case TESTER_LIVE : // TESTER LIVE + CICLO
if ((ciclo == 0) && (voltmetro >= 0.8)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TENSIONE ");
lcd.setCursor(0, 1);
lcd.print("V= ");
lcd.setCursor(4, 1);
lcd.print(voltmetro);
delay(250);
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("INSERIRE ");
lcd.setCursor(0, 1);
lcd.print("BATTERIA");
delay(250);
}
if ((avvio) && (voltmetro >= V_minima)) {
digitalWrite(CARICO_INTERNO, HIGH);
digitalWrite(CARICO_ESTERNO, HIGH);
digitalWrite(LED_BLU, HIGH);
ciclo = 1;
}
if (((voltmetro <= V_minima) && ((millis() - T_RIFERIMENTO) <= T_scarica)) && (ciclo == 1)) {
ciclo = 2; //mi serve per impedire l'accavallamento dei due fine ciclo.
T_RIFERIMENTO = millis(); //aggirno millis
digitalWrite(CARICO_INTERNO, LOW);
digitalWrite(CARICO_ESTERNO, LOW);
digitalWrite(LED_BLU, LOW);
digitalWrite(LED_ROSSO, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("BATTERIA DA ");
lcd.setCursor(0, 1);
lcd.print("BUTTARE ");
delay(250);
}
if (((voltmetro <= V_minima) && ((millis() - T_RIFERIMENTO) >= T_scarica)) && (ciclo == 1)) {
ciclo = 3; //mi serve per impedire l'accavallamento dei due fine ciclo.
T_RIFERIMENTO = millis(); //aggirno millis
digitalWrite(CARICO_INTERNO, LOW);
digitalWrite(CARICO_ESTERNO, LOW);
digitalWrite(LED_BLU, LOW);
digitalWrite(LED_VERDE, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("BATTERIA DA ");
lcd.setCursor(0, 1);
lcd.print("UTILIZZARE ");
delay(250);
}
if ((voltmetro >= V_minima) && (ciclo == 1)) {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("SCARICA ");
lcd.setCursor(0, 1);
lcd.print("V= ");
lcd.setCursor(3, 1);
lcd.print(voltmetro);
lcd.setCursor(8, 1);
lcd.print("A= ");
lcd.print(amperometro);
delay(250);
}
break;
}
}