sunnuntai 29. syyskuuta 2019

MUUTAMIA TESTEJÄ

Kun näiden mikrokontrollerilevyjen parissa puuhailee ja kokeilee, niin silloin tällöin sattuu vahinkoja (puhun omasta kokemuksestani). Tämän jakson ideana on muutama pieni ja yksinkertainen ohjelma, joilla voi testata, onko Arduino kunnossa, ja miltä osin. Jos piirilevy ei vastaa työkaluohjelman lataustoimintaan, tulee ko. piiristä harmi. Toki siitä on hyvä käyttää joitakin toimivia osia, kuten liittimiä, LEDejä, 5 V-regulaattoria ja mahdollisesti joitain muitakin komponentteja.

 On toki mahdollista, että on onnistunut tuhoamaan ainoastaan jonkun I/O:n. Tämänkertainen jakso tähtää nimenomaan liityntöjen testaukseen. Enin osa testeistä on tehty Arduino UNO:lla. Joitakin myös Arduino LEONARDOLLA, mutta muut kuvassa näkyvät piirit eivät osallistuneet näiden ohjelmien kehitykseen.

 
HUOM! Noissa kaikissa kolmessa ohjelman määrittelyosiossa on mukana myös sarjaliikenne ohjelmointityökalulle (Serial.begin(9600);). Se ei ole tarpeen näiden testiohjelmien kannalta, mutta hyvähän sen on siellä olla, jos tekee muutoksia ohjelmaan ja haluaa ajankohtaista dataa näytölle.


DIGITAALILÄHDÖT
Ensimmäisenä on lähtöpinnien testaus. Niitähän on 12 kpl (D/I 2 .. 13). Mutta sen lisäksi analogiatulot (A0 .. A5) voidaan määritellä (14 .. 19) ja käyttää myös digitaalisena (paitsi LEONARDO, jossa täten toimivat vain A0 ja A1). Kokemukseni mukaan aiemmin myös D/I-pinnit D0 ja D1 olivat määriteltävissä tuloiksi ja lähdöiksi, mutta näissä testeissäni se ei onnistunut. Ne on nähtävästi täysin ”pyhitetty” sarjaliikenteelle. DIO0 on RX (sarjadatan tulo) ja DIO1 on TX (sarjadatan lähtö).

Indikaationa (ei kaivanne kytkentäkaaviota) voi olla esim. 1 kohm (sopiva valinta, sillä se etuvastuksena ei kuormita lähtöpinniä liikaa) vastus sarjassa LEDin kanssa. Eli: lähtöpinni, vastus, LED ja maa. (LEDin pitää olla oikein päin kytkettynä). Kun vastus vaihdetaan eri pinneihin, vilkahtaa myös levyllä oleva (OUT13 LED) säännöllisin välein
. Aika koostuu LOOPista 50 + 50 ms, sekä siitä, että luuppi käy läpi kaikki 17 lähtöä. Kun ulkoinen LED välähtää, toimii kyseinen lähtö oikein.

/***************************************
* OUT_Test_1
* 26.09.2019
* I/O-pinnien OUTput - testaus
**************************************/

// ASETUKSET:
void setup(){
Serial.begin(9600);
// Asetetaan DIGI ja ANA I/O-pinnit lähdöiksi
for(int i = 2;i <= 19; i ++){
   pinMode(i, OUTPUT);}
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
for(int j = 2; j <= 19; j++){
   digitalWrite(j, HIGH);
   delay(50);
   digitalWrite(j, LOW);
   delay(50);
}
delay(1);
} // Pääohjelma LOPPU


DIGITAALITULOT
Tässä toisessa ohjelmassa käydään läpi kaikki digitaalitulot paitsi DIO-13, minkä LEDiä käytetään indikaattorina. Sen vuoksi se määritellään erikseen OUT-bitiksi. Muut määritellään kahdella eri luupilla tuloiksi, joissa on sisäinen ylös veto vastus (INPUT_PULLUP). Myös pääohjelma jakaantuu tämän vuoksi kahdeksi FOR-luupiksi. Kun jonkin tuloista kytkee maahan, suorittaa ohjelma aliohjelmakutsun. Tällöin piirilevyllä oleva LED (DIO-13) vilkkuu. Kyseinen tulopinni toimii siis oikein.

/***************************************
* IN_Test_1
* 26.09.2019
* I/O-pinnien INput - testaus
**************************************/
// Määrittlyt
int LEDout = 13;
boolean tila = false;

// LEDin aliohjelma
void Fun_LED(){
   digitalWrite(LEDout, HIGH);
   delay(150);
   digitalWrite(LEDout, LOW);
   delay(150);
}

// ASETUKSET:
void setup(){
Serial.begin(9600);
// Asetetaan pinnin 13 LED lähdöksi
pinMode(LEDout, OUTPUT);
// Asetetaan varsinaiset I/O-pinnit tuloiksi
for(int i = 2;i <= 12; i ++){
   pinMode(i, INPUT_PULLUP);}
// Asetetaan ANAlogia pinnit tuloiksi
for(int i = 14;i <= 19; i ++){
   pinMode(i, INPUT_PULLUP);}
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
for(int j = 2; j <= 12; j++){
   tila = !digitalRead(j);
   if(tila == true){Fun_LED();}
} // for loppu
for(int j = 14; j <= 19; j++){
   tila = !digitalRead(j);
   if(tila == true){Fun_LED();}
} // for loppu
delay(1);
} // Pääohjelma LOPPU


ANALOGIATULOT
Tässä kolmannessa testiohjelmassa tutkitaan analogiatulojen toiminta. UNOssa ja LEONARDOssa niitä on kuusi (A0 .. A5) kappaletta. Niiden tulojännitealue on 0 .. 5 V. Tämä voidaan syöttää ulkopuolelta tai tehdä niin, että potentiometrin äärinavat kytketään Arduinon maan (GND) ja 5 V:n lähdön väliin ja potentiometrin liu'ulta viedään jännite mitattavaan analogiatuloon. Indikaattoriksi tähän testiin voidaan käyttää ensimmäisen testin LED / vastusyhdistelmää, kytkettynä johonkin analogialähtöön (PWM, pulssinleveysmodulaatio). Tässä ohjelmassa on käytetty lähtöä DO3. Lähdön jännite vaihtelee noin 1 kHz taajuudella nollan (0 V) ja viiden (5 V) voltin välillä, mutta näiden jännitteiden aikasuhde muuttuu ohjauksen mukaan. Analogiatulon muunnos on 10 bittinen, eli lukualue on 0 .. 1023 ja lähdön lukualue kahdeksan (8) bittinen, eli 0 .. 255, joten tuloarvo pitää jakaa neljällä. Kun potentiometria, säätää, vaihtuu tulojännite, minkä muutos ilmenee LEDin kirkkauden vaihteluna. Vaihtamalla potikan johtoa eri tuloihin voi tarkastaa jokaisen tulon toimivuus.


/***************************************
* ANA_Test_3
* 27.09.2019
* Muutetaan analogia-arvojen tuloarvo
* LEDin kirkkaudeksi
**************************************/

// MÄÄRITTELYT:
int Ana_Raaka = 0;
int Ana_Out = 0;
int PWM_LED = 3;

// ASETUKSET:
void setup(){
Serial.begin(9600);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
for(int i = 0; i <= 5; i++){
   Ana_Raaka = analogRead(i);
   Ana_Out = Ana_Raaka / 4;
   Ana_Out = constrain(Ana_Out, 0, 255);
}
analogWrite(PWM_LED, Ana_Out);
delay(1);
} // Pääohjelma LOPPU

maanantai 24. kesäkuuta 2019

AKUN KAPASITEETTIMITTAUS I

Otsikossa on ykkönen sen vuoksi, että tähän akun kapasiteetin mittaukseen akku pitää ladata ulkoisella laturilla esim. verkkovirrasta. Seuraavan (II) sovelluksen on tarkoitus sopia olosuhteisiin, missä verkkovirtaa ei ole käytettävissä, vaan sähkövarastona käytettäviä akkuja ladataan aurinkopaneeleilla tai tuuligeneraattoreilla. Testattavana oleva akku ladataan siis toisten akkujen avulla.

Akkukin kuluu käytössä, joten on hyvä tietää paljonko akussa on kapasiteettia jäljellä. Tässä mittarissa purkauksen kuormituksena on lamppuja ( 1 .. 3, 21 W lamppua, 1,75 .. 5,25 ampeeria) ja virran mittaukseen käytetään Hall-anturia (alue 0 .. 50 A). Anturin mittausalue on huomattavasti laajempi kuin purkausvirrat, joten kovin hyvään tarkkuuteen (muutama %) ei päästä, mutta se ei ole tarpeenkaan, sillä tarkoituksena on saada selville, onko akku vielä käyttökelpoinen vai syytä jo vaihtaa uuteen. Tuo 5 ampeerin virta on samaa luokkaa, mitä 12 V:n Peltier-elementillä toimiva jääkaappi kuluttaa, joten tämä on hyvä tutkimus juuri mökkikäyttöön.

Tämän päivän trendi on tallettaa energiaa, sillä enemmän ja enemmän ollaan siirtymässä sähköllä toimiviin laitteisiin. Energiaa saamme auringosta. Vaahtoamme uusiutuvasta energiasta. Tuuligeneraattorit, aurinkopaneelit, aurinkokeräimet jne. Ihan hyvä ja tällä hetkellä erittäin tärkeä argumentti, mutta tuo tuonne alkuun lykkäämäni sana ”vaahtoamme” johtuu siitä, että ihmisille halutaan antaa ”mielikuva” siitä, että auringon energia olisi uusiutuvaa. Ei ole! Aurinko muuttaa vedyn fuusioreaktiossa syntyvän energian fotovirraksi, mistä me saamme osamme (maapallon puolisko on vain pieni pläntti avaruudessa). Auringon vety ei uusiudu, sitä ei tule mistään lisää, mutta sen loppumista meistä kukaan tällä hetkellä täällä ihmettelevä ei tule näkemään. Käytetään siis sitä hyvällä omallatunnolla, sillä sen käyttö ei lisää kasvihuoneilmiötä, eikä se meidän elinaikanamme juurikaan vähene, eikä tulevien tuhansienkaan sukupolvien aikana sitä tee.

Nyt olen hiukan heikoilla jäillä. Etsin kyllä netistä ja tietosanakirjoista ja muista teknisistä lähteistä, mutta en oikein löytänyt tukea opiskeluaikani käsitykselle, että akun kapasiteetti standardin mukaan ilmoitetaan 10% purkausajalla. Toisin sanoen, jos akun kapasiteetiksi ilmoitetaan 100 Ah, niin 10 A:in virralla se pystyy syöttämään virtaa 10 tunnin ajan (lopussa 12 V:n akun jännite on noin 10,5 V). Tälle en löytänyt tukea, mutta kuten myöhemmin tässä käy ilmi, niin erisuuruisilla purkausvirroilla akun kapasiteetiksi saadaan erilaisia arvoja. Jos tuo standardi pitää paikkansa, niin kaupallisesti on tarjolla akkuja, joiden ampeerituntimäärä (Ah) on merkitty 20 tunnin aikana (5% purkausvirta kapasiteetista). Täten halutaan ostajalle antaa standardia positiivisempi mielikuva. Myös latausvirran olisi hyvä olla 10% kapasiteetista. Akutkin kehittyvät ja niitä voidaan myös pika ladata. Se tosin jossain määrin lyhentää akun käyttöikää.

Näissä testeissä olen käyttänyt vanhoja, käytöstä poistettuja akkuja. Ne ovat sopivia juuri tähän tarkoitukseen, sillä niiden kapasiteetit ovat hyvin vähissä, mistä johtuen purkautumista ei tarvitse odotella pitkään.
Esimerkki: purkausvirran vaikutuksesta akun kapasiteettiin: Testissä oli vanha 75 Ah akku, jossa oli jäljellä muutama ampeeritunti. Yhden lampun purkauksella (noin 1,7 A) kapasiteetiksi tuli 8,4 Ah ja kolmen lampun purkauksella noin 7 Ah. Kapasiteetti pieneni siis noin 17,5 %.

Tällä kerralla en ole piirtänyt kytkentäkaaviota. Tuo kuvassa näkyvä ”rakkine” ei ole varsinaisesti mikään laite, vaan alusta, mille on helppo kytkeä erilaisia yksikköjä vaihdellen aina tarpeen ja meneillään olevan ”projektin” mukaan. Sen pohja on sähköisen eriste (akryyliä), joten ei tarvitse huolehtia painettujen piirien oikosuluista.

Kun johdot on kytketty akkuun, tulee LCD-näyttöön kehotus käynnistyksestä. Koska ihminen on hätäinen (varsinkin tekniikasta kiinnostunut), alkaa laite mittaamaan ampeerisekunteja (Asek). Koko mittauksen ajan virta luetaan ja summataan sekunnin välein. Kun ensimmäinen minuutti on ohi, näyttöön päivittyy ampeeriminuutit (Amin). Saatu summa jaetaan nyt luvulla 60. Kun tunti tulee täyteen, päivittyvät ampeeritunnit (Atun Oikeastihan ne ovat As, Amin ja Ah) ja summa jaetaan luvulla 3600.

Kytkimillä voidaan valita 1, 2 tai 3 kpl 21 W:in lamppua kuormaksi. Kun akun jännite on laskenut 10,5 V:iin, päästää rele ja näyttöön ilmestyy kokonaisampeerimäärä sekä akun jännite, mikä hiukan nousee kuormituksen loputtua. Jos jännite laskee alle tuon rajan jo sekuntien tai minuuttien aikana, vapautuu kuorma ja näyttöön jää sen hetkinen kapasiteetti ja jännitearvo 10,5 V. Näyttöä ei enää päivitetä.



Ohjelmasta
Aluksi määritellään vakiot ja muuttujat. Asetuksissa (suoritetaan ainoastaan kerran) päivitetään ensimmäinen näyttö. Sen jälkeen on 1 s tauko, jotta tilanne stabiloituu. Sitten talletetaan Hall-generaattorin pohjalukema, mikä on noin puolet käyttöjännitteestä (5 V). Hall-generaattori mittaa magneettikentän voimakkuutta, joten ympäristökin vaikuttaa tähän pohjalukemaan. Siksi se pitää kerran tallettaa. Virran suunta joko kasvattaa tätä generaattorin lähtöarvoa tai pienentää sitä. Tämän arvon ja pohjalukeman erotuksesta muodostetaan mitattu virta-arvo. Lopuksi asetuksissa määritellään painike tuloksi ja rele lähdöksi.

Itse toimiva ohjelma muodostuu muutamasta sekvenssiaskeleesta ja parista aliohjelmasta. Toisessa aliohjelmassa päivitetään näytön tekstejä ja toisessa mitattuja numeroarvoja.

Ohjelma57
/***************************************
* AkunKapa
* 22.06.2019
* Akunkapasiteettimittaus.
**************************************/

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

// Mittaukset
   const int Con_Akku = 0; // Akun jännitteen mittaus
   int Int_AkkuRaaka = 0;
   const int Con_Virta = 1; // Purkausvirran mittaus
   int Int_VirtaRaaka = 0;
   int Int_VirtaPohja = 0;
   float Flo_Akku = 0.0; // Akun jännitemittaus
   float Flo_Virta = 0.0; // Kuormitusvirran mittaus
   float Flo_Kapa = 0.00; // Laskettu kapasiteetti
   const float Con_Pohja = 0.25; // Laitteen omakäyttö

// Ohjaukset
   const int Con_START = 8;
   boolean Bol_START = false;
   const int Con_Rele = 9;
   boolean Kep_Rele = false;
   int Seq_Purku = 0; // Purkaussekvenssi

// Kellon määrittely (sisäinen kello)
   unsigned long Ulo_MilliSek = 0;
   unsigned long Ulo_UusiMilliSek = 0;
   const long CoL_EroSekunti = 999;
   long Lng_Sekunti = 0;
   boolean Bol_Tulosta = false;

// ALIOHJELMAT
// Tekstien päivitys
   void Fun_Tekstit(int kohta, int rivi,String teksti){
   lcd.setCursor(kohta, rivi);
   lcd.print(teksti);
   }// Teksti_ali loppu

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

// ASETUKSET:
   void setup(){
   Serial.begin(9600);
   lcd.begin(20,2);
   lcd.clear();
   lcd.setCursor(5, 0);
   lcd.print("K");
   lcd.write(api);
   lcd.print("ynnist");
   lcd.write(api);
   lcd.print(",");
   lcd.setCursor(4, 1);
   lcd.print("paina START");
   delay(1000);
// Hall-generaattin pohjatason talletus
   Int_VirtaPohja = analogRead(Con_Virta);
   pinMode(Con_START, INPUT_PULLUP);
   pinMode(Kep_Rele, OUTPUT);
   }// Asetuksen loppu

// PÄÄLOOPPI
   void loop(){
   // Sisäisen kellon käyttö
      Ulo_MilliSek = millis();
     if(Ulo_MilliSek - Ulo_UusiMilliSek > CoL_EroSekunti){
        Ulo_UusiMilliSek = Ulo_MilliSek;
         Lng_Sekunti++;
      if(Seq_Purku > 0 && Seq_Purku < 5){
         Flo_Kapa = Flo_Kapa + Flo_Virta;
      }
   // Akun jännitteenmittaus
      Int_AkkuRaaka = analogRead(Con_Akku);
      Flo_Akku = Int_AkkuRaaka / 68.2;
   // Purkuvirran mittaus
      Int_VirtaRaaka = analogRead(Con_Virta);
      Flo_Virta = (Int_VirtaRaaka - Int_VirtaPohja) / 8.7;
   }

   // Luetaan tulo
      Bol_START = !digitalRead(Con_START);
   // Käynnistetään purkusekvenssi
      if(Seq_Purku == 0 && Bol_START == true){
        Lng_Sekunti = 0;
        Seq_Purku = 1;
      }

   // Purkaussekvenssi
      switch (Seq_Purku) {
         case 1: // Päivitetään näyttö
            lcd.clear();
            Fun_Tekstit(0, 0, "Akun purku: V");
            Fun_Tekstit(13, 1, "A");
            Fun_Lukemat(16, 1, Flo_Virta);
            Kep_Rele = true;
            Seq_Purku = 2;
         break;
         case 2: // Ampeerisekunnit
            Fun_Lukemat(15, 0, Flo_Akku);
            Fun_Tekstit(0, 1, "Asek: ");
            Fun_Lukemat(6, 1, Flo_Kapa + Con_Pohja);
            Fun_Lukemat(16, 1, Flo_Virta);
            if(Flo_Akku < 10.5){ Seq_Purku = 0;Kep_Rele = false;}
            if(Lng_Sekunti >= 60){
               Fun_Tekstit(6, 1, " ");
         Seq_Purku = 3;
       }
      break;
      case 3: // Ampeeriminuutit
         Fun_Tekstit(0, 1, "Amin: ");
         Fun_Lukemat(6, 1, (Flo_Kapa + Con_Pohja)/60);
         Fun_Lukemat(15, 0, Flo_Akku);
         Fun_Lukemat(16, 1, Flo_Virta);
         if(Flo_Akku < 10.5){ Seq_Purku = 0;Kep_Rele = false;}
         if(Lng_Sekunti >= 3600){
            Fun_Tekstit(6, 1, " ");
         Seq_Purku = 4;
      }
      break;
      case 4: // Ampeeritunnit
         Fun_Tekstit(0, 1, "Atun: ");
         Fun_Lukemat(6, 1, (Flo_Kapa + Con_Pohja)/3600);
         Fun_Lukemat(15, 0, Flo_Akku);
         Fun_Lukemat(16, 1, Flo_Virta);
         if(Flo_Akku < 10.5){
            lcd.clear();
            Kep_Rele = false;
            Seq_Purku = 5;}
      break;
      case 5:
         Fun_Tekstit(0, 0, "VALMIS! V");
         Fun_Lukemat(15, 0, Flo_Akku);
         Fun_Tekstit(0, 1, "Akun kapas. Ah");
         Fun_Lukemat(15, 1, (Flo_Kapa + Con_Pohja)/3600);
      break;
      }// Purkaussekvenssin loppu

// Releen ohjaus
      digitalWrite(Con_Rele, Kep_Rele);
      delay(1);
} // Pääohjelma LOPPU







lauantai 11. toukokuuta 2019

AURINKOENERGIAA

Blogin motto toteutui jälleen erinomaisesti. Monessa kohdassa opin uutta. Ainakin monet jutut tarkentuivat tai käsitteet ja odotukset täsmentyivät. Syksyllä kun asensin pienen aurinkopaneelin parvekkeen katolle, laitoin sen sellaiseen kulmaan, jotta auringon korkeuden muuttuessa se olisi keskimäärin mahdollisimman edullisessa asennossa. Siis noin 30 – 40 asteeseen vertikaalisesti.
    Ensimmäinen virhe oli se, etteipä sillä hetkellä käväissyt mielessä, että Suomessa sataa talvisin lunta. Viime talvi olikin tuossa suhteessa erinomainen ja täällä etelässäkin oli hyvä hiihtää. Ja sitä aikaakin hiihtämiseen vapautui tältä projektilta, sillä paneeli oli useita kuukausia lumen peitossa, eikä tuottanut energiaa. Tulevana syksynä se on järkevää kääntää pystyyn, jottei se peity lumeen.

Ideana oli toteuttaa pieni varavoimalaitos ”muistikirjaa” varten. Toisin sanoen Raspberry Pi korttitietokone pienen näytön kanssa on jatkuvasti käytettävissä. Tällöin hetkelliset ideat on helppo tallettaa tulevaa pohtimista ja käyttöä varten. Käytäntö on osoittanut, ettei niistä yöllisistä pikkuisten lappujen käsialasta kuitenkaan saa mitään selvää. 
    Tämä on toteutettu siten että paneeli lataa akkua. Akun jännitteen aletessa kytketään lataus verkkoon. Ohjaukset tapahtuvat teeman mukaan tietysti Arduinolla.

 Akun perässä on kolme stabiloitua lähtöä: 9 V Arduinoa varten, 5 V pienempivirtainen syöttö Raspberryä varten ja suurempivirtainen 5 V lähtö esim. kännykän lataamista varten. Näyttö on liitetty suoraan akun jännitteeseen. 5 V lähdöt kytketään USB-liittimien kautta.
    Nyt toteutuneessa laitteessa akun tilaa osoitetaan kaksois – LEDillä. Punainen merkitsee alhaista ja vihreä korkeampaa jännitettä. Sen lisäksi vilkuttamalla ilmaistaan toiminnan eri tiloja. LEDiä ohjaavassa aliohjelmassa on välitilasta pulssinleveysmodulaatiolla (PWM) toteutettu ”liukuva” siirtymä punaisesta vihreään (tai päin vastoin) jännitteen nousun (tai laskun) mukaan. Siitä saa vilkaisulla käsityksen ”missä mennään”.
    Alla olevaan ohjelmaan olen jättänyt myös tulostuksen ohjauksen ja aliohjelman esimerkkinä siitä syystä, että tässä tulostusvälien mittaus on toteutettu sisäisellä kellolla (millis), eikä laskemalla ohjelmakierroksia kuten useimmiten olen tehnyt. Täten toteutettuna viiveet (delay(ms)) eivät muuta tulostusväliä. Aliohjelmakutsu on merkitty tässä kommentiksi (//), joten tulostus ei ole tuossa toimivassa ohjelmassa aktiivinen.
  
Kun tällainen paneelilaturi tehdään oikein, liitetään paneeli pulssinleveysmoduloidun (PWM) kytkimen ja kytkintaajuuteen sopivan induktanssin välityksellä akkuun. Kytkintä ohjataan siten, että paneelin lähtöjännite pysyy noin 17 – 18 voltin paikkeilla riippumatta siitä, miten suurta virtaa (riippuen auringon säteilyn voimakkuudesta) se pystyy syöttämään. Tällöin virran (I) ja jännitteen (V) tulo eli teho (P) on mahdollisimman suuri kussakin tilanteessa.
     Koska noin se pitäisi tehdä, niin tietysti halusin kokeilla jotain muuta. Arvelin, että ladattaessa ja purettaessa kondensaattoria päästään myös hyvään hyötysuhteeseen. Niinpä tein kytkennän, missä yksi tyristori kytkee paneelin suureen kondensaattoriin (10 mF = 10 000 uF) ja kun se on latautunut, toinen tyristori kytkee tämän kondensaattorin kahteen rinnan olevaan kondensaattoriin ja niiden rinnalla olevaan akkuun.
    Tyristorit saivat ohjauspulssin Arduinolta. Tyristori sulkeutuu (menee johtamattomaan tilaan) itsestään, kun sen läpi menevä virta laskee tarpeeksi pieneksi. Kun kondensaattori on latautunut, loppuu siis tyristorin kautta kulkeva virta.
    Toimi, eikä hyötysuhde osoittautunut ongelmaksi. Paneelin lähtöjännite vaihteli siellä 19 ja 16 voltin välillä. Ensinnäkin paneelin virta riippuu valon voimakkuudesta. Tästä johtuen kondensaattorien latausaika vaihteli voimakkaasti.
    Tyristorit eivät saa olla johtavassa tilassa samanaikaisesti, vaan vuorotellen. Tästä koitui tämän kytkennän ongelma. Oli aika vaikea luotettavasti vaihtelevissa tilanteissa määritellä se hetki, milloin ylempi tyristori oli johtamaton, ja latautunut kondensaattori voitiin kytkeä akkuun. Aikaa kului sekä lataukseen että purkamiseen. Tämä latauksen ja purkamisen vuorottaisuus kulutti niin paljon aikaa, että keskimääräinen latausvirta jäi pienemmäksi kuin paneeli kytkettäessä suoraan akkuun.
    Yksi virhe oli kytkeä Arduino transistorien välityksellä galvaanisesti tyristoreihin. Kytkentätapahtumassa syntynyt häiriöpulssi pisti kuitenkin Ardun pään sekaisin, joten ohjaus piti eristää optisten kytkimien välityksellä.
 
Siksi tällä kertaa päädyin suoraan kytkentään täysin tietoisena sen puutteellisuudesta hyötysuhteen kannalta. Tuleeko sitten joskus toteutettua tuo lataus paremmin (ja oikealla tavalla), jää nähtäväksi, jos ja mihin intoa riittää. Todennäköisesti paneeli saa syksyllä pystysuunnan. Tuohon kytkentään on jäänyt komponentteja tuosta tyristorikokeilusta. Siinä on myös varauduttu joihinkin tuleviin ideoihin. Olisi mukava tietää miten paljon energiaa saadaan auringosta ja miten usein joudutaan turvautumaan verkkosähköön. Tarkoitus (mahdollisesti) on joskus kytkeä laitteeseen LCD-näyttö ja painikkeet millä selata menuta.
  
Muutama sana kytkennästä:
Edellä jo toinkin esiin tämän kytkennän ”historiaa”. Syy, että akun rinnalla on kaksi suurta kondensaattoria, johtui juuri tuosta tyristorikytkennästä. Kun paneelin lataama kondensaattori (jännite noin 19 .. 20V) purettiin kaksinkertaiseen kapasitanssiin, puolittui jännitepulssi ja oli parempi akulle. Tuo tulolinjassa olevan diodin tehtävänä on pimeällä (paneelin jännite laskee alle akun jännitteen) estää virran kulkemisen väärään suuntaan. Nuo 5 V regulaattoriin kytkettyjen diodien tehtävänä on kompensoida suurempivirtaisessa lähdössä olevan tehotransistorin kanta- / emitterijännite (noin0,7V). Raspberryä varten siitä taas vähennetään tuo kynnysjännite. Arduinon analogiatulon jännitealue on 0 .. 5 V, joten tulojännite on vastuksilla sovitettava tuolle alueelle. Todellisessa kytkennässä on jäljellä vielä paneelin ja välikondensaattorin jännitemittaukset, mutta tässä kytkentäkaaviossa ne eivät näy. Laitteen kuva ei täten kaikilta osin vastaa esitettyä kytkentäkaavaa, mutta ovatpahan siellä mukana vastaisuuden varalta.



 
Muutama sana ohjelmasta:
Kuten aiemmin mainitsin, olen jättänyt tulostuksen aliohjelman mukaan esimerkiksi tuon muuttuneen tahdistuksen vuoksi. Muutoin ohjelma on aika vakiokamaa. Merkittävä osuus on kuitenkin tuolla LEDien ohjauksen aliohjelmalla.
Sen tarkoitus on havainnollistaa toiminnan tilaa. Askeleessa 1 vihreä LED vilkkuu merkkinä siitä, että akku on melkein täysi (14,0 .. 14,2 V). Askeleessa 2 vihreä LED palaa jatkuvasti merkkinä (jännite alle 14.2 V. Tämä liittyy siihen, että akku on lähestymässä latauksen lopettamista (tämä vain paneelilatauksessa). Askel 3 on tavallaan ”jännitteen mittari” Punaisen ja vihreän LEDin valon voimakkuuden suhde muuttuu jännitteen mukaan. Mitä korkeampi jännite (välillä 12 .. 13,5 V) sitä vihertävämpi valo. Valon kirkkaus ei ole aivan lineaarinen, vaan on himmein mittausalueen puolessa välillä (pun 50% ja vih 50%). Sitähän tietysti voisi muuttaa epälineaarisen ohjauksen mukaan, mutta olkoon se jokin toinen projekti. Askel 4 vilkuttaa punaista LEDiä, mutta ei näköjään ole mukana tässä mittauksessa. Askel 5 vilkuttaa punaista hitaaseen tahtiin. Tämä on merkki ylilatauksesta. Askel 6 palaa punainen LED jatkuvasti ja on merkkinä verkkolatauksesta. Kun verkkolataus on aktiivinen, hypätään jännitteestä riippuvien aliohjelmakutsujen yli.
  
OHJELMA 55
 
/***************************************
* Ohjelma_55
* 08.05.2019
**************************************/

// MÄÄRITTELYT:
// Tulostuksen tahdistus
   unsigned long Con_TulostusEro = 1000;
   unsigned long Vanha_tulostus = 0;
   unsigned long Uusi_Tulostus = 0;

// Analogiamittausten määrittelyt
   const int Con_AnaAkku = 0;
   int Int_AkkuRaaka = 0;

// Osoitin LEDin määrittelyt
   const int Con_LEDv = 11;
   const int Con_LEDp = 10;
   int Int_Vihrea = 0;
   int Int_Punainen = 0;
   const int Con_Kierros = 1000;
   int Int_Kierros = Con_Kierros;
   const int Con_Lata = 830; // Verkkolatauksen käynnistys
   const int Con_AlRa = 822; // Vaihtuvan alaraja 12 V
   const int Con_YlRa = 924; // Vaihtuvan yläraja 13,5 V
   const int Con_LaLo = 925; // Latauksen yläraja
   int Int_LED_pwm = 0; // LEDien pulssisuhdeohjaus

// Verkkolatauksen muutujamäärittelyt
   const int Con_LatOhj = 8;
   boolean Bol_LatOhj = false;

// Paneeliohjauksen muuttujat
   int Pls_Lataa = 2;
   boolean Bol_Lataa = false;
   const int Con_PaneeliStart = 910;
   const int Con_PaneeliStop = 970;

// ALIOHJELMAT
   void Fun_Tulostus(){
   Serial.print("Akun Muunnos :"); Serial.println(Int_AkkuRaaka);
// Serial.println();
}

// Osoitin LEDin aliohjelma
   void Fun_LEDit(int askel, int lukema){
      int Ohjaus = 0;
     switch (askel) {
        case 1:
           if(Int_Kierros > Con_Kierros / 2){
              digitalWrite(Con_LEDv, HIGH);}
           else {digitalWrite(Con_LEDv, LOW);}
              Int_Kierros = Int_Kierros - 1;
               if (Int_Kierros < 1){Int_Kierros = Con_Kierros;}
         break;
         case 2:
            digitalWrite(Con_LEDv, HIGH);
            digitalWrite(Con_LEDp, LOW);
         break;
         case 3:
            Ohjaus = (Int_AkkuRaaka - Con_AlRa) * 2.5;
            if (Ohjaus > 255) {Ohjaus = 255;}
               analogWrite(Con_LEDv, Ohjaus);
               analogWrite(Con_LEDp, 255 - Ohjaus);
          break;
         case 4:
            digitalWrite(Con_LEDv, LOW);
            if(Int_Kierros > Con_Kierros / 2){
               digitalWrite(Con_LEDp, HIGH);}
            else {digitalWrite(Con_LEDp, LOW);}
               Int_Kierros = Int_Kierros - 1;
            if (Int_Kierros < 1){Int_Kierros = Con_Kierros;}
         break;
         case 5:
            if(Int_Kierros > Con_Kierros){
               digitalWrite(Con_LEDp, HIGH);
               digitalWrite(Con_LEDv, LOW);}
            else {digitalWrite(Con_LEDp, LOW);
               digitalWrite(Con_LEDv, HIGH);}
               Int_Kierros = Int_Kierros - 1;
               if (Int_Kierros < 1){Int_Kierros = 2 * Con_Kierros;}
            break;
            case 6:
               digitalWrite(Con_LEDp, HIGH);
               digitalWrite(Con_LEDv, LOW);
            break;
         }// sekvenssin loppu
      }// LED - aliohjelman loppu

// ASETUKSET:
void setup(){
   Serial.begin(9600);
   pinMode(Con_LEDv, OUTPUT);
   pinMode(Con_LEDp, OUTPUT);
   pinMode(Con_LatOhj, OUTPUT);
   pinMode(Pls_Lataa, OUTPUT);
   Vanha_tulostus = millis();
}// Asetuksen loppu

// PÄÄLOOPPI
   void loop(){
   // Analogiamittaukset
   Int_AkkuRaaka = analogRead(Con_AnaAkku);

   // Paneelilatauksen hallinta
      if(Int_AkkuRaaka < Con_PaneeliStart){Bol_Lataa = true;}
      if(Int_AkkuRaaka > Con_PaneeliStop){Bol_Lataa = false;}
      digitalWrite(Pls_Lataa, Bol_Lataa);

   // Lataus verkosta
      if(Bol_LatOhj == false && Int_AkkuRaaka < Con_Lata){Bol_LatOhj = true;}
      if(Int_AkkuRaaka > Con_LaLo){Bol_LatOhj = false;}
      digitalWrite(Con_LatOhj, Bol_LatOhj);
      if(Bol_LatOhj == true){Fun_LEDit(6, Int_AkkuRaaka);}

   // Merkki LEDin ohjaus
      if(Bol_LatOhj == true){goto ohitus;}
      if(Int_AkkuRaaka >= Con_YlRa + 20){Fun_LEDit(1, Int_AkkuRaaka);}
      if(Int_AkkuRaaka < Con_YlRa + 20 && Int_AkkuRaaka > Con_YlRa) 
         {Fun_LEDit(2, Int_AkkuRaaka);}
      if(Int_AkkuRaaka <= Con_YlRa && Int_AkkuRaaka > Con_AlRa)
        {Fun_LEDit(3, Int_AkkuRaaka);}
      if(Int_AkkuRaaka < Con_AlRa){Fun_LEDit(6, Int_AkkuRaaka);}
      if(Int_AkkuRaaka > Con_LaLo){Fun_LEDit(5, Int_AkkuRaaka);}
   ohitus:

   Uusi_Tulostus = millis();
   if (Uusi_Tulostus > Vanha_tulostus + Con_TulostusEro){
   // Fun_Tulostus();
   Vanha_tulostus = millis();
   } // Tulostuskutsu loppu
} // Pääohjelma LOPPU