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