perjantai 1. toukokuuta 2020

AKKUTESTERI 56

Kuva 1. Testeri kotelossaan päältä nähtynä
Tämän projektin tähtäimenä oli rakentaa testeri, millä voi tutkia akun jäljellä olevan kapasiteetin. Käyttö on sellaisia olosuhteita varten, missä aurinkopaneeleilla tai / ja tuuligeneraattoreilla ladataan akkuja. Toisin sanoen tilanteessa, missä verkkosähköä ei ole käytettävissä akkujen lataamiseen.
Näissä olosuhteissa on tyypillisesti useita akkuja rinnan. Ne voivat hyvinkin olla eri ikäisiä, ja tavoitteena on akku kerrallaan tutkia, onko kyseinen akku vielä käyttöön riittävä, vai syytä vaihtaa uuteen. Tämä ei ole mikään tarkkuusmittalaite, vaan pyrkimyksenä on saada tietää mitatun akun käyttökelpoisuus.

Kuva 2. Lataus- ja purkuvirtojen reittien kytkentä.
Kuva 3. Laite alta. Ylhäällä kuormituslamput.


Vaatimuksena ja edellytyksenä on siis mahdollisuus ladata testattava akku muista akuista. Suositeltavaa onkin aloittaa testaus silloin, kun akut ovat mahdollisimman täynnä. Tällöin lataukseen kuluu aikaa mahdollisimman vähän.
Kuormaksi on mahdollista valita yhdestä kolmeen 20 W lamppua. Kun kaikki kolme ovat käytössä, on kuorman virta noin 5 A, mikä on suurin piirtein sama, minkä esim. tuollainen Peltier-elementillä toimiva pieni jääkaappi. Testi toisin sanoen testi kertoo suoraan, miten kauan testattava akku pystyisi syöttämään tuollaista jääkaappia.


Annoin yllä ymmärtää, että laitteen tarkkuus ei ole kovin hyvä. Virhetekijöitä on mm. seuraavia:
  1. Akku ladataan noin 7 A virralla 14,5 V:n jännitteeseen. Akku ei välttämättä ole täysin latautunut jännitteen käväistessä tuossa tasossa. Tilannetta parantaa tosin se seikka, että lataus pulssituksen kautta tapahtuu siten että 2 s latausta ja 1 s taukoa. Tähän suurin syy on kuitenkin jäähdytyslevynä toimivan alumiinisen U-palkin pienuus. Se taas johtuu siitä, että kotelo vaihtui kehityksen aikana suuremmaksi.
  2. Kuva 4. Aikamoinen sotku.
    Hall-generaattorin (LCB-050B) mittausalue on 50 A. Joten esim. 5 A kuormalla tarkkuus ei voi olla juurikaan 10 % parempi.
  3. Akku puretaan 11 V tasoon. Tällöin akku ei ole täysin tyhjä, vaan kapasiteettia on vielä jäljellä. Tämä taso säästää akkua. Syvemmästä purkauksesta ei tässä tapauksessa ole mitään hyötyä, sillä (testimittauksissa ilmennyt) noin 70 – 80 % tarkkuus kertoo kyllä mainiosti akun käyttökelpoisuuden jatkossa.
  Laitetta on rakennettu ja kokeiltu pienissä erissä. Sisäkuvasta näkee, että se ei sovi kenellekään malliksi ja ohjeeksi; korkeintaan varoittavaksi esimerkiksi.
Kuva 5. Hakkuriohjaimen kytkentä.
Kuva 6. Erillisten releiden kytkentä. Koskettimet näkyvät kuvassa 2.
Alussa ohjelma tuntui varsin yksinkertaiselta. Ladataan akku, puretaan se ja samalla mitataan kuorman virta sekunnin välein, jaetaan lopuksi luvulla 3600, ja saadaan näin akun kapasiteetti ampeeritunneissa. Lopuksi ladataan akku.
Periaatteessa kylläkin näin. Tuota ajatusta vastaan sotii tieto, että esim. alla oleva ohjelma on versio 14. Eri ohjelmia syntyi kaikkiaan 36 kappaletta. Jotain pieniä yksityiskohtia piti kehittää erikseen. Suurin syy tähän oli häiriöt. Tässä käsitellään kuitenkin melko suuria tehoja, mitkä aiheuttavat jännitepiikkejä. Yksi ongelma on myös minussa. En suunnittele etukäteen sopivia komponentteja, vaan pengon laatikoita ja valitsen siltä, mitä löytyy ja mitkä saattaisivat olla soveltavissa. Tässä toimii jälleen vana viisaus: ”Älä tee niin kuin minä teen, vaan tee niin kuin minä sanon!”
Alussa käytössä oli ”sopiva” ja laadukas induktanssi. Nyt hakkurin (mikä siirtää tehoa akusta toiseen) teho nousi yli 200 watin, joten käytössä ollut neljän releen yksikkö (4 Relay Module) otti nokkiinsa, totesi että nyt riitti, katkoi painitun piirin kalvoja ja ilmoitti mielipiteensä savumerkein.
Piti rakentaa uusi yksikkö tukevammin relein. Käytin siinä autojen varaosareleitä (12 V 20/30 A). Samalla pienensin hakkurin oskillaattorin pulssisuhdetta ja latausvirtaa.
Yksi iso ongelma pysyi kuitenkin melko tiukasti mukana. Se oli häiriö, mikä sotki LCD-näytön. Näytöllä pyöri ihan mitä sattuu juuri kun testi oli edennyt ja Ah-lukema pian luettavissa. Tähän oleellisin ratkaisu oli ottaa LCD-näytön 5 V:n syöttö Arduinon vastaavasta lähdöstä. Silti muutama suodatuskonkka releiden kytkimissä oli paikallaan.
Laitteessa on myös reset-painike, sillä kytkettäessä laite akkuun (A1, syöttävä), on hetkellinen virtapulssi melko suuri. Kun akut on kytketty, onkin hyvä painaa resettiä, jonka jälkeen ohjelma latautuu uudestaan, ja kuorma voidaan valita ja testi käynnistää.



LAITTEEN KÄYTTÖ:
 
Muutama sana ohjelmasta ja käytöstä: Ensin kytketään laitteen liittimet syöttävään akkuun (A1). Kun näyttöön ilmestyy kehotus valita purkausteho ja käynnistys, voidaan liittimet kytkeä testattavaan akkuun (A2). Käynnistyksen jälkeen ohjelma tutkiin, ettei akkujen jännite-ero ole liian suuri. Seuraavaksi tutkitaan, onko akussa A1 riittävä jännite (yli 13,5 V). Jos kaikki on tähän saakka kunnossa, alkaa latausvaihe. Aluksi lataus tapahtuu induktanssin ja diodin kautta akkuun A2. Hetken perästä kytkeytyy hakkuri kahdeksi sekunniksi ja ”pumppaa” virtaa akkuun A2. Samalla valvotaan, ettei akun A1 jännite putoa alle 12 V:n. Jos näin tapahtuu, palataan edelliseen askeleeseen ja odotetaan, että syöttävän jännite on taas yli 13,5 volttia. Näin jatketaan kunnes testattava akku on ”täynnä”. Sen jälkeen irrotetaan akku A1 testattavasta akusta, puretaan akku ja mitataan kapasiteetti. Lopuksi ladataan akku ilman virtapumppausta. Jos akkujen jännite-ero (A1 – A2 < 0,5 V) on riittävä pieni, kytketään akut suoraan yhteen. Nämä eri vaiheet tulostetaan LCD-näytölle.


 
Ohjelma 56

/* Nimi: A_Kapa56_v14
Luotu: 30.04.2020
Luoja: Antti Isännäinen

KUVAUS:
Pyrkimyksenä on tutkia akun jäljellä oleva kapasiteetti
ympäristössä, missä enenergiaa talletetaan useisiin
rinnakkain kytkettyihin akkuihin. Ja missä energia
tuotetaan arinkopaneeleilla ja tuuligeneraattoreilla.
*/

// MÄÄRITTELYT:
#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 2, 7,6,5,4);
const byte api = B11100001;

// Kellon määrittely
unsigned long Ulo_MilliSek = 0;
unsigned long Ulo_UusiMilliSek = 0;
unsigned long Ulo_PulsMiSek = 0;
int Int_Viive = 100;
int Int_LCDvii = 300;
int Int_Sekunti = 0;
int Int_ViSek = 0;
boolean Bol_LCD_tulostus = false;
unsigned long Ulo_UusiLCD = 0;
boolean Bol_AskelViive = false;
// Tekstit
char tx1[] = "V";
char tx2[] = "A";
char tx3[] = "A1";
char tx4[] = "A2";
char tx5[] = "VAL. KUORMA => START";
char tx6[] = "Kuorma: 3 == 5.25 A";
char tx7[] = "Kuorma: 2 == 3.50 A";
char tx8[] = "Kuorma: 1 == 1.75 A";
char tx9[] = "VALMISTELUT:";
char tx10[] = "ODOTTAA: A1>13.5V";
char tx11[] = "A2 LATAUS";
char tx12[] = "A2 PURKAUS";
char tx13[] = "VALMIS";
char tx14[] = "AKUT KYTKETTY YHTEEN";
char tx15[] = "Ah";

// Analogiatulot
const int Con_A1V = 0;
const int Con_A2V = 1;
const int Con_Virta = 2;

// Muuttujat
int Int_A1raaka = 0;
float A1_Jannite = 0.00;
int Int_A2raaka = 0;
float A2_Jannite = 0.00;
int Int_VirtaPohja = 0;
int Int_Virta = 0;
float Flo_Virta = 0.00;
boolean Bol_Summaus = false;
int Int_Kapasi = 0;
float Flo_Kapasi = 0.00;
float Flo_U_Ero = 0.00;

// Kuormituksen ja käynnistyksen valinta
const int Con_Start = 18;
boolean Bol_Start = false;
const int Con_Kuorma = 19;
boolean Bol_Kuorma = false;
int Seq_Kuorma = 1;
const int Con_K1 = 8;
const int Con_K2 = 10;
const int Con_K3 = 9;
const int Con_K4 = 11;
const int Con_Pulssi = 13;
boolean Bol_Pulssi = false;
int Int_Lamput = 3;
int Seq_Mittaus = 0;

// ALIOHJELMAT
// Näytön aliohjelmat
// Tekstien päivitys
void Fun_Teksti(int kohta, int rivi, char teksti[]){
   lcd.setCursor(kohta, rivi);
   lcd.print(teksti);
}// Teksti_ali loppu

//Numeroiden päivitys
void Fun_Mittaus(int kohta, int rivi, float lukema){
   lcd.setCursor(kohta, rivi);
   lcd.print(lukema);
}// Mittaus_ali loppu

// Releyksikön aliohjelma
void Fun_Rele(int k1,int k2,int k3,int k4){
   delay(50);
     digitalWrite(Con_K1, k1);
     digitalWrite(Con_K2, k2);
     digitalWrite(Con_K3, k3);
     digitalWrite(Con_K4, k4);
   delay(100);
}// Rele aliohjelman loppu

// Kuormavalinnan aliohjelma
void Fun_Kuormitus(int valinta){
   switch (valinta) {
   case 1:
     Fun_Teksti(0, 1, tx8);
   break;
   case 2:
     Fun_Teksti(0, 1, tx7);
   break;
   case 3:
     Fun_Teksti(0, 1, tx6);
   break;
   }// Sekvenssi loppu
}// Kuormitusvalinnan aliohjelman loppu

// ASETUKSET:
void setup(){
   Serial.begin(9600);
   lcd.begin(20,2);
   Fun_Teksti(0, 0, tx5);
   Fun_Teksti(0, 1, tx6);
   pinMode(Con_Kuorma, INPUT_PULLUP);
   pinMode(Con_Start, INPUT_PULLUP);
   pinMode(Con_K1, OUTPUT);
   pinMode(Con_K2, OUTPUT);
   pinMode(Con_K3, OUTPUT);
   pinMode(Con_K4, OUTPUT);
   pinMode(Con_Pulssi, OUTPUT);
   Fun_Rele(1, 0, 0, 0); // Asetetaan releiden perusasetus
   delay(Int_Viive * 7);
   Int_VirtaPohja = analogRead(Con_Virta);
   Ulo_UusiMilliSek = millis();
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
  Ulo_MilliSek = millis();
  if(Ulo_MilliSek > Ulo_UusiMilliSek + (Int_Viive * 10)){
     Bol_Summaus = true;
     Int_Sekunti += 1;
     Int_ViSek += 1;
     Ulo_UusiMilliSek = millis();
} // Tahdistus loppu

// LCD-näytön tahdistus
if(Seq_Mittaus > 0){
   if(Ulo_MilliSek > Ulo_UusiLCD + Int_LCDvii){
     Bol_LCD_tulostus = true;
     lcd.clear();
     Ulo_UusiLCD = millis();
}} // Näytön päivityksen loppu

//Mittaukset
Int_A1raaka = analogRead(Con_A1V);
A1_Jannite = Int_A1raaka / 60.176;
Int_A2raaka = analogRead(Con_A2V);
A2_Jannite = Int_A2raaka / 60.176;
Int_Virta = analogRead(Con_Virta);
Int_Virta = Int_Virta - Int_VirtaPohja;
Flo_Virta = Int_Virta * 0.11;

// Kytkimet
Bol_Kuorma = !digitalRead(Con_Kuorma);
Bol_Start = !digitalRead(Con_Start);
if(Bol_Start == true && Seq_Kuorma > 0){
   Seq_Mittaus = 1;
   Seq_Kuorma = 0;
   Int_ViSek = 0;
} // Kuormavalinta loppu

// Kuormavalinnan sekvenssi
switch (Seq_Kuorma) {
   case 1:
     if(Bol_Kuorma == true && Ulo_MilliSek - Ulo_UusiMilliSek > (Int_Viive * 2)){
       Ulo_UusiMilliSek = Ulo_MilliSek;
       Int_Lamput --;if(Int_Lamput == 0){Int_Lamput = 3;}
       Fun_Kuormitus(Int_Lamput);
       Seq_Kuorma = 2;
   }
   break;
   case 2:
     if(Bol_Kuorma == false){Seq_Kuorma = 1;}
   break;
  }// Sekvenssin loppu

// PÄÄSEKVENSSI
// Akun kapasiteetin mittaussekvenssi
switch (Seq_Mittaus) {
   case 1: // Valmistelut
     if(Bol_LCD_tulostus == true){
       Fun_Teksti(0, 0, tx9);
       Fun_Teksti(0, 1, tx3);
       Fun_Teksti(11, 1, tx4);
       Fun_Mittaus(3, 1, A1_Jannite);
       Fun_Teksti(8, 1, tx1);
       Fun_Mittaus(14, 1, A2_Jannite);
       Fun_Teksti(19, 1, tx1);
} // LCD-tulostus
// Tarkastetaan, ettei akkujen jännite-ero ole liian suuri
   if(A2_Jannite > (A1_Jannite - 2.0)){
     if(Int_ViSek > 3){
       Seq_Mittaus = 2;
       Int_ViSek = 0;
   }// Viiven loppu
}// Jännitetarkastuksen loppu
break;
case 2: // Odottaa, että A1 > 13.5 V
   if(Bol_LCD_tulostus == true){
       Fun_Mittaus(3, 1, A1_Jannite);
       Fun_Teksti(8, 1, tx1);
       Fun_Teksti(0, 0, tx10);
       Fun_Teksti(0, 1, tx3);
       Fun_Teksti(11, 1, tx4);
       Fun_Teksti(19, 1, tx1);
       Fun_Mittaus(3, 1, A1_Jannite);
       Fun_Mittaus(14, 1, A2_Jannite);
   } // LCD-tulostus loppu
   if(A1_Jannite > 13.5 && Int_ViSek > 3){
       Int_ViSek = 0;
       Ulo_PulsMiSek = Ulo_MilliSek;
       Bol_Pulssi = true;
       Seq_Mittaus = 3;
   } // Jännite ja viivetarkastus loppu
break;
case 3: // Latausaskel
   if(Bol_LCD_tulostus == true){
       Fun_Teksti(0, 0, tx11);
       Fun_Teksti(0, 1, tx3);
       Fun_Teksti(8, 1, tx1);
       Fun_Teksti(11, 1, tx4);
       Fun_Teksti(19, 1, tx1);
       Fun_Mittaus(3, 1, A1_Jannite);
       Fun_Mittaus(14, 1, A2_Jannite);
       Fun_Mittaus(11, 0, -1 * Flo_Virta);
       Fun_Teksti(15, 0, tx2);
   } // LCD-tulostus loppu
   Fun_Rele(0, 0, 0, 0);
   if(Bol_Pulssi == true && Ulo_MilliSek > Ulo_PulsMiSek + 2000){
       Ulo_PulsMiSek = Ulo_MilliSek;
       Bol_Pulssi = false;
   } // Pulssitus päällä
   if(Bol_Pulssi == false && Ulo_MilliSek > Ulo_PulsMiSek + 1000){
       Ulo_PulsMiSek = Ulo_MilliSek;
       Bol_Pulssi = true;
   } // Pulssitus pois päältä
   digitalWrite(Con_Pulssi, Bol_Pulssi);

// Tarkastetaan, onko ladattava akku täysi
   if(A2_Jannite > 14.5){
       Bol_Pulssi = false; digitalWrite(Con_Pulssi, Bol_Pulssi);
       Int_ViSek = 0;
       Seq_Mittaus = 4;
   } // Latausgeneraattorin pysäytys loppu
// Tarkastetaan, laskeeko syöttöjännite liikaa
   if(A1_Jannite < 12.0){
       Bol_Pulssi = false; digitalWrite(Con_Pulssi, Bol_Pulssi);
       Seq_Mittaus = 2;}
   break;
   case 4: // Akun purkaus
   if(Bol_Summaus == true){
       Flo_Kapasi = Flo_Kapasi + 1 * Flo_Virta;
}// Kapasiteetin keruun loppu
   if(Bol_LCD_tulostus == true){
       Fun_Teksti(0, 0, tx12);
       Fun_Teksti(0, 0, tx12);
       Fun_Teksti(15, 1, tx2);
       Fun_Mittaus(12, 0, Flo_Kapasi / 3600);
       Fun_Teksti(17, 0, tx15);
       Fun_Teksti(0, 1, tx4);
       Fun_Teksti(8, 1, tx1);
       Fun_Mittaus(3, 1, A2_Jannite);
       Fun_Mittaus(11, 1, 1 * Flo_Virta);
   } // LCD-tulostus loppu
// Valitaan asettettu kuorma
   if(Int_Lamput == 3){Fun_Rele(1,1,1,0);}
       else if(Int_Lamput == 2){Fun_Rele(1,0,1,0);}
       else {Fun_Rele(1,1,0,0);}
   if(Int_ViSek > 5 && A2_Jannite < 11.0){
       Seq_Mittaus = 5;
       Int_ViSek = 0;
   }// viiven loppu
   break;
   case 5: // Lataus
     if(Bol_LCD_tulostus == true){
       Fun_Teksti(0, 0, tx11);
       Fun_Mittaus(11, 0, Flo_Kapasi / 3600);
       Fun_Teksti(17, 0, tx15);
       Fun_Teksti(0, 1, tx3);
       Fun_Mittaus(3, 1, A1_Jannite);
       Fun_Teksti(8, 1, tx1);
       Fun_Teksti(11, 1, tx4);
       Fun_Mittaus(14, 1, A2_Jannite);
       Fun_Teksti(19, 1, tx1);
   } // LCD-tulostus loppu
   Fun_Rele(0, 0, 0, 0);
   Flo_U_Ero = A1_Jannite - A2_Jannite;
   if(Int_ViSek > 5 && Flo_U_Ero < 0.5){
       Seq_Mittaus = 6;
       Int_ViSek = 0;
   }// viiven loppu
                        break
 case 6: // Valmis
   if(Bol_LCD_tulostus == true){
       Fun_Teksti(0, 0, tx13);
       Fun_Teksti(8, 0, tx4);
       Fun_Mittaus(11, 0, Flo_Kapasi / 3600);
       Fun_Teksti(17, 0, tx15);
       Fun_Teksti(0, 1, tx14);
   } // LCD-tulostus loppu
   Fun_Rele(1, 0, 0, 1);
break;
}// Mittaussekvenssi loppu

Bol_Summaus = false;
Bol_LCD_tulostus = false;
Bol_AskelViive = false;
delay(1);
} // Pääohjelma LOPPU

2 kommenttia:

  1. Tällaista olen kaipaillut omiin suunnitelmiini.
    Tästäa saa hyvää vinkkiä. Hyvä julkaisu! Kiitos

    VastaaPoista
    Vastaukset
    1. Kiitos kommentistasi. Tulee vain niin harvoin selattua näitä, joten vastaukseni viipyi. Hyvää kesän jatkoa.

      Poista