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.
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ä.
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
Ei kommentteja:
Lähetä kommentti