torstai 24. marraskuuta 2016

Automaattinen liekkivahti KY-26 ja KY-19

Synkkä syksyteema jatkuu. Iminen tarvitsee valoa, joten luonnollisesti valon ja myös tunnelman kohottamiseksi hän sytyttää iltojensa iloksi kynttilän. Avotuli on kuitenkin aina riski. Tämän riskin pienentämiseksi tekniikka onneksi tarjoaa apua, joten ihminen voi keskittyä mielekkäämpiin tehtäviin kuin kynttilän vahtimiseen. Vahtimisen voi hoitaa leikin tunnistin (KY-026). Se voi välittää hätätilan releelle (KY-019), mikä puolestaan käynnistää puhaltimen, jonka tehtävänä on sammuttaa tuli. Paremman kuvan kylän pelastamisesta saa katsomalla pienen videopätkän (antinarduvideo25. youtube.com).
Huojentavaa tietää, että kylä pelastuu

Kuvassa on kyllä ”vaahtosammuttaja”, mutta se on hämäystä. Sen etumerkki on negatiivinen. Se on sytkäri! Puhaltimen taustalla näkyy hiukan releen syrjää istutettuna tuohon testitasoon.







Kytkentä Arduinoon:













Puhallin (siis tämä käyttämäni) tarvitsee erilisen virtalähteen, sillä se ei toimi 5V:in jännitteellä. Myös sen ottama teho on paljon suurempi, mitä Arduinon pinni (noin 40mA) tai USB-linja pystyvät syöttämään. Paristot, akku tai tässä käyttämäni virtalähde toimivat oikein hyvin. On todella hyödyllistä omistaa jokin pieni virtalähde tai 12V:in akku erilaisten liitätälaitteiden syöttöön. Paristot myös, mutta niitä täytyy olla aika usein olla korvaamassa uusiin jos on innostunut kokeilija.

Jos Turussakin olisi aikoinaan (1827) ollut tällaisella Arduinolla toteutettu palovahti, niin kaupunki ei olisi tuhoutunut niin pahasti. Jos katsoo tuota videota (antinarduvideo25. youtube.com) voi huomata kuinka liekkianturin merkkiLEDi värähtelee sekä liekin ilmaisun alussa, että lopussa. Siksi on tärkeätä, että relettä ohjataan hallitusti ajan mukaan. Anturin (KY-026) levyllä on trimmeripotentiometri, minkä avulla tunnistuksen herkkyytä voi säätää. Arvon voi lukea ruudulta. Arvo vaihteli 30 (liekki tunnistettu) ja 800 välillä (ei liekkiä). Siksi olen jättänyt ohjelmaan tuon tulostuksen aliohjelman. Lisäksi printillä on käynti- ja ilmaisuLEDit.

OHJELMA 25
/***************************************
* Ohjelma 25
* 22.11.2016
* Liekkivahti (TY-026) tunnistaa kynttilän, jolloin
* rele (TY-019) vetää käynnistäen pahaltimen, mikä
* sammuttaa liekin.
**************************************/

// MÄÄRITTELYT:
// Ajastukset
const int Con_Kierrokset = 800;
unsigned int Unt_Sekunnit = 0; // Viivelaskuri
unsigned int Unt_Kierrokset = 0; // Ohjelmakierroslaskuri
int Int_Kierrokset = 0;

// Tulostuksen tahdistus
const int Con_PrintViive = 1000;
int Int_PrintViive = Con_PrintViive;

// Tulot ja lähdöt
const int Con_LiekData = 2;
boolean Bol_LiekData = false;
const int Con_Ohjaus = 3;
const int Con_LiekAna = 0;
int Int_LiekAna = 0;
const int Con_LED = 13;
int Seq_Ohjaus = 0;

// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_LiekData, INPUT);
pinMode(Con_Ohjaus, OUTPUT);
pinMode(Con_LED, OUTPUT);
}// Asetuksen loppu

// FUNKTIOT
void Fun_Tulostus(){
Serial.print("Tulon arvo :"); Serial.println(Int_LiekAna);
// Serial.print("Sekunnit :"); Serial.println(Unt_Sekunnit);
}

// PÄÄLOOPPI
void loop(){
Unt_Kierrokset++;
if(Unt_Kierrokset > Con_Kierrokset){ // Luvulla sovitetaan kierr -> sek
Unt_Sekunnit++;
Unt_Kierrokset = 0;
} // Kierroslakuri loppu

// Mittaukset ja merkkivalo tunnistuksesta
Int_LiekAna = analogRead(Con_LiekAna);
Bol_LiekData = digitalRead(Con_LiekData);
digitalWrite(Con_LED, Bol_LiekData);

// Puhallinjakson käynnistys
if(Bol_LiekData == true && Seq_Ohjaus == 0){Seq_Ohjaus = 1;}
// Puhallinjakson ohjaus. 5s jälkikäynti
switch (Seq_Ohjaus) {
case 1:
Unt_Sekunnit = 0;
digitalWrite(Con_Ohjaus, true );
Seq_Ohjaus = 2;
break;
case 2:
if(Unt_Sekunnit > 5){
digitalWrite(Con_Ohjaus, false);
Seq_Ohjaus = 0;
}
break;
}

Int_PrintViive--;
if(Int_PrintViive == 0){
Fun_Tulostus();
Int_PrintViive = Con_PrintViive;
} // Tulostuskutsu loppu
delay(1);
} // Pääohjelma LOPPU

maanantai 21. marraskuuta 2016

Hämäräkytkin KY-018 ja LED

Kodit muuttuvat nykyisin yhä enemmän ”älykkäiksi”. Ainakin tuosta aiheesta meuhkataan nykyään aika tavalla. Toisaalta on ehkä hyväkin miettiä, onko ihmisen syytä kovinkaan paljon luovuttaa aivotoimintaansa automaatille.

No, joka tapauksessa sarja-37:stä löytyy paljon hyödyllisiä osasia kodin ”älykkyyden” nostamiseksi. Näin syksyllä kun päivätkin hämärtyvät ja iltapäivät ovat jo aivan pimeitä, aloitan tämän teeman hämäräkytkimellä.

Sarjassa 37 on yhtenä osasena LDR (Light Dependent Resistor ) eli valovastus. Niin kuin nimikin kertoo, riippuu komponentin vastusarvo valon voimakkuudesta. Ensimmäiseksi ryhdyin mittaamaaan vastuksen arvon riippuvuutta valon voimakkuudesta. Sain aluksi aivan omituisia ja epäloogisia arvoja. Toisin sanoen törmäsin taas tähän kiinalaiseen ”laatuun”. Kun katselin piirilevyä suurennuslasin läpi, huomasin siinä kylmiä juotoksia. Toisin sanoen tina ei ollut kunnolla sulanut ja tarttunut valovastuksen ja liittimen johtoihin. Käytännössä tämä merkitsee sitä, että sähkön johtavuus näiden komponenttien rajapinnoissa on häilyvä. Tästä selvisin juottamalla komponentit uudestaan.

Nyt merkinnät piirilevyllä ovat oikein. Miinus tulee maihin, plus 5V kytketään keskelle ja signaali (analogia input) saadaan pisteestä S. Mitattaessa vastusarvo vaihteli 250 ohmin (kirkkaan valon alla) ja 500 kilo-ohmin (suojattuna kynän hylsyllä) välillä. 10 kilo-ohmin etuvastus on valmiina piirilevyllä. Kytkettynä Arduinon analogiatuloon, vaihteli muunnoksen jälkeinen signaali 150 (pöytälamppu päällä) ja 800 välillä (LDR peitettynä hylsyllä). Valitsin rajaksi 350 (const int Con_ValoRaja = 350;).

Ohessa kykentä Arduinoon:

 Raja-arvo sattui ihan hyvään kohtaan, sillä jo kädellä peittäminen sai LEDin syttymään.
Vasemmalla päytälamppu päällä ja oikealla pois päältä

Tästä on hyvä jatkaa älykodin kehittämistä. Voisi laittaa liiketunnistimen. Jos herää aamuyöstä, niin laite voisi laittaa vessaan valot valmiikisi päälle ja sammuttaa, kun tärkeimmät on hoidettu. LEDeillä voi myös lähettää dataa toiselle laitteelle joka voisi tallettaa käyntikerrat, jolloin aamulla ei tarvitsi keskustella asiasta, koska faktat ovat tallessa. Samoin kuorsausta voisi tarkkailla, jolloin voisi tilastoida jokaisen rahinan ja apnean ajankohdan ja keston. Ja varmaan paljon muutakin hyödyllistä. Mutta olkoon tässä nyt vain tämä hämäräkytkin.

HÄMÄRÄKYTKIMEN OHJELMA
/***************************************
* Ohjelma 24
* 21.11.2016
* Hämäräkytkin LDR -> LED
**************************************/

// MÄÄRITTELYT:
// Ajastukset
const int Con_Kierrokset = 800;
unsigned int Unt_Sekunnit = 0; // Viivelaskuri
unsigned int Unt_Kierrokset = 0; // Ohjelmakierroslaskuri
int Int_Kierrokset = 0;

// Tulostuksen tahdistus
const int Con_PrintViive = 1000;
int Int_PrintViive = Con_PrintViive;

// Hämärän määrittelyt
const int Con_LDR = 0; // Analogiamittaus A0
const int Con_ValoRaja = 350; // LEDin sytytysraja
int Int_LDR_Ana = 0; // LEDin mittausmuuttuja
const int Con_LED = 2; // Lähtöpinni LEDille

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

// FUNKTIOT
void Fun_Tulostus(){
Serial.print("Valomuunnos :"); Serial.println(Int_LDR_Ana);
}

// PÄÄLOOPPI
void loop(){
// Ohjelmakierros / viivelaskuri
Unt_Kierrokset++;
if(Unt_Kierrokset > Con_Kierrokset){ // Luvulla sovitetaan kierr -> sek
Unt_Sekunnit++;
Unt_Kierrokset = 0;
} // Kierroslakuri loppu

Int_LDR_Ana = analogRead(Con_LDR);

if(Int_LDR_Ana > Con_ValoRaja){
digitalWrite(Con_LED, HIGH);
}else{
digitalWrite(Con_LED, LOW);
}

Int_PrintViive--;
if(Int_PrintViive == 0){
Fun_Tulostus();
Int_PrintViive = Con_PrintViive;
}
delay(1);
} // Pääohjelma LOPPU


sunnuntai 20. marraskuuta 2016

SARJA 37 KY-004 ja KY-012

Sarja 37 on on varsin laaja lajitelma erilaisia antureita ja muita ”palikoita” joita on tarjolla Arduino ympäristöön. Niillä voi kokeilla kaikenlaista ja samalla kehitellä ohjelmien pätkiä järkevämpiin ja laajempiin sovelluksiin. Sarja käsittää lämpötilaan, kosteuteen, valoon, infarapunaan, tärinään ym. tulopuolen antureita. Lähtöpuolelle on rele, LEDejä, laser, infrapunalähetin jne. Jäljempänä pieni esimerkki, missä on painike ja summeri. Painettaessa painiketta, summeri vinkuu. Tämän blogin lopuksi luettelo sarjan sisältämistä laitteista. Jatkossa pyrin tuomaan esiin erilaisia kombinaatioita ja valaisemaan pienin ohjelmaesimerkein niiden käyttöä.


Tilasin oman sarjani kiinalaisesta nettikaupasta. Tuotteiden ”laatu” on nostanut esiin lisähaasteita. En ole vielä tutustunut tarkemmin kaikkiin yksiköihin, mutta silti muutamista olen jo havainnut virheitä. Esimerkiksi nyt käyttämässäni painikkeessa on liitynnän merkinnät väärin. S (=signaali) sijaitsee piirilevyllä päinvastaisella puolella ja myös miinus (-) on keskellä eikä reunassa merkinnän mukaan. On siis hyvä tarkistaa ”palikka” ennen käyttöä. Väärä napaisuus saattaa rikkoa piirillä olevan elektroniikan.
       Kun tein tuota lopussa olevaa luetteloa, jouduin moneen kertaan tarkistamaan tekemääni, joten toivon, ettei tekstiini olisi jäänyt kovin monia virheitä. Puuhaa vaikeutti lisäksi se, että luettelossa kuvat olivat hiukan eri näköisiä kuin yksikkö todellisuudessa. Ilmeisesti myös valikoima on muuttunut, viimeinen numero ei ole sarjan nimen mukainen 37, vaan KY-040.

Ohessa painikkeen ja summerin kytkentä sekä kuva fyysisestä järjestelystä. Taustalla näkyy hämärtynyt Arduino UNO. Noiden laitteiden käyttämä teho on niin pieni, että käyttötehoksi riittää USB-liittimestä saatu syöttö. Muuta teholähdettä ei tässä tapauksessa tarvita. Minua ensin ihmetytti tuo summerin päällä oleva liimalappu. Kun poistin sen ja painoin painiketta, palautin lapun. Äänen voimakkuus oli yllättävä kova. Tuota pientä summeria voi käyttää hälyttimenä isommassakin tilassa.

 
Pyrkimyksenäni oli typistää tämä ohjelmaesimerkki niin pieneksi kuin mahdollista. Ilmeisesti myös onnistuin siinä. Samalla se on esimerkki siitä, miten ohjelmia ei ole syytä kirjoittaa. Tietokoneella ei ole mitään vaikeuksiä ymmärtää sitä, mutta ihmiselle hiukankin laajemman kokonaisuuden hallinta, noin kryptisesti ja ”niukkasanaisesti” kirjoitettuna tuottaa varmasti vaikeuksia. Kommentit ja selkeät sekä kuvaavat muuttujanimet ovat aina paikallaan ja tarpeellisia.



/***************************************
* Ohjelma 23 v1
* 20.11.2016
* Painike ohjaa summeria
**************************************/

int I = 2; int O = 3;
void setup() {pinMode(I= 2, INPUT); pinMode(O = 3, OUTPUT);}
void loop() { digitalWrite(O, digitalRead(I));}

SARJA 37
Alla luettelo kaikista osista samassa järjestyksessä, missä ne näkyvät ”yhteiskuvassa”. Aina on tietysti myös poikkeuksia. Joissakin lokeroissa on kaksi yksikköä, ja koska koodinumerot ylittävät tuon 37 ja väliltä puuttuu joitakin numeroita, on niiden sijainti merkitty luetteloon.


SARJA 37 LUETTELO
Temperature sensor module KY-001
Lämpötilan mittausmoduuli



Vibration switch module KY-002
Tärinäanturi



Hall magnetic sensor module KY-003
Hall-anturi (Kytkin varustettuna merkkLEDillä.)




Key switch module KY-004
Mekaaninen painikemoduuli




Infrared emission sensor module KY-005
LED infrapunalähetin



Small passive buzzer module KY-006
Pieni passiivinen summeri. (Piezosähköinen elementti, mitä voidaan ohjata eri taajuuksilla.)







Laser sensor module KY-008
Laser-anturi. Lähettää punaista valoa.




3-color full-color LED SMD modules KY-009
3-värinen, värinäköalueen kattava LED-pintaliitoskomponentti.




Optical broken module KY-010
Optokytkin. (Valon este komponentin raossa aiheuttaa signaalin tilamuutoksen.)





2-color LED module KY-011
Kaksivärinen LED.



Active buzzer module KY-012
Aktiivinen summeri. (Tätä voidaan ainostaan ohjata päälle ja pois. Voidaan hälyttää, mutta ei voida tuottaa eri äänenkorkeuksia. Katso passiivinen summeri KY-006.)








Temperature sensor module KY-013
Lämpötila-anturi.




Temperature and humidity sensor module KY-015
Lämpötila ja kosteusanturi.





3-color LED module KY-016
3-värinen LED-moduli.


Mercury open optical module KY-017
Läpinäkyvä elohopeakytkin. (Elohopehelmi lasisessa putkessa.)






Photo resistor module KY-018
Valovastusanturi. (Komponentin vastus muuttuu valon kirkkauden mukaan.)



5V relay module KY-019
Relemoduli. Käyttöjännite 5V. Vaihtokytkentä; 10A DC/AC



Tilt switch module KY-020
Kallistuskytkimoduuli. Antaa signaalin TOSI / EPÄTOSI riippuen kallistuksesta.






Mini magnetic reed modules KY-021
Pieni reed-rele (Kytkin sulkeutuu, magneettikentän vaikutuksesta.)




Infrared sensor receiver module KY-022
Infrapuna tunnistinmoduuli.










XY-axis joystick module KY-023
Asento-ohjain. Analogia signaali sekä vaaka että pystysuunnassa.





Linear magnetic Hall sensors KY-024
Lineaarinen Hall-anturi. Antaa magneettikentän voimakkuuteen verrannollisen signaalin.





Reed module KY-025
Reedrele. (Ei pelkkä kytkin. Tähän mennessä analogiapuoli ei ole vielä selvinnyt?)







Flame sensor module KY-026
Liekin tunnistusanturi.






Magic light cup module KY-027
Lumoava maaginen valopari.





Temperature sensor module KY-028
Lämpötila-anturi.





Yin Yi 2-color LED module 3MM KY-029
Yin Yi (?) kaksivärinen (punainen ja vihreä) LED moduuli.





Hit sensor module KY-031
Iskun tunnistusmoduuli.




Obstacle avoidance sensor module KY-032
Esteen tunnistusoduuli (lähestymiskytkin.









Hunt sensor module KY-033
Saalistusanturi (toimii kylläkin lähestymiskytkimenä).












Automatic flashing colorful LED module KY-034
Automaattinen vilkkuLED. Vikuttaa punaista, sinistä ja vihreätä vaihtaen välillä vilkutusnopeutta.









Class Bihor magnetic sensor KY-035
Analoginen magneettianturi. Lähtöjännite muuttuu magneettikentän voimakkuuden mukaan. (Hall-anturi tyyppy 49E).



Metal touch sensor module KY-036
Kosketusanturi




Sensitive microphone sensor module KY-037 lokerossa 14
Äänianturi. Sekä analoginen että digitaalinen lähtö.





Microphone sound sensor module KY-038 lokerossa 14
Äänianturi. Sekä analoginen että digitaalinen lähtö.




Detect the heartbeat module KY-039 lokerossa 7
Sydämenlyöti indikaattori. Mittaa sormesta.






Rotary encoder module KY-040 lokerossa 30
Kooderi, mikä antaa pulsseja ja ilmaisee kiertosuunnan.


keskiviikko 16. marraskuuta 2016

Latausvalvoja

Minulla on käytössä kesämökillä aurinkopaneeleita. Yhtä paneelia valvoo Arduinolla toteutettu laite, mikä katkaisee akun latauksen, kun jännite nousee 14,5 voltiin. Periaatteessa aivan oikein, mutta valvoja sijaisee lähellä paneelia, jolloin se ei ota huomioon syöttöjohdossa syntyvää jännitehäviötä. Toisin sanoen, mitä paremmin aurinko paistaa, niin sitä suurempi on latausvirta, ja sitä aikaisemmin valvoja katkaisee latauksen akulta. Näin ei pitäisi olla.

Varsinkin silloin, jos käytössä on seurantalaite, eli paneeli seuraa aurinkon kulkua, ja valvonta on lähellä paneelia, on tärkeätä, että tuo mainittu jännitehäviö otetaan huomioon. On mahdollista vetää toiset johdot pelkästään jännitteen mittausta varten suoraan akun navoista, mutta siihen en halunnut ryhtyä. Toinen tapa on mitata virta juuri ennen katkaisua, tallettaa sen arvo ja välittömästi sen jälkeen mitata jännitepudotus. Välittömästi siksi, että akun napajännite alkaa pudota nopeasti latauksen loputtua. Ohmin laki U = I * R (jännite on virran ja vastuksen tulo) tarjoaa tarpeellisen evään ongelman ratkaisuun. Mainituilla mittauksilla voidaan johtojen vastus laskea R = U / I (jännitepudotus jaetaan talletetulla virralla, jolloin saadaan esille johtojen vastus). Jatkossa mitataan latausvirtaa ja lisätään virran ja lasketun vastuksen tulo tuohon 14,5 voltin katkaisujännitteeseen Näin yksinkertaista se on!

Tuo oli luonnollisesti ajatus ja käsitys ennen kuin aloin toteuttaa po. valvontalaitetta. Miten mitata? Arduinon analogiatulot ovat 0 .. 5VDC ja 10 bitin muunnos (lukulue 0 .. 1023). Toisin sanoen uusi lukema saadaan 5mV:in välein (5000mV / 1024 = 4,88mV). Latausjännite ei kuitenkaan suoraan käy analogiamittaukseen, koska se on paljon suurempi kuin 5V. Kytkennässä olevilla arvoilla (5,6kohm ja 17,7kohm) koko mitta-alueeksi tulee 20.8V. Toisin sanoen uusi jännitteen lukema saadaankin tällä kytkennällä noin 20mV välein. Sekin on hyvä ja aivan riittävä tarkkuus tähän tarkoitukseen.

Virran mittaukseen ajattelin ensin shunttivastusta. Toisin sanoen pieniohmista tehovastusta, joka kestää latausvirran vioittumatta. Tässä tapauksessa 0,125 ohmia (sellaisia oli laatikossa). Se ei voi olla kovin suuri, sillä latausvirran pitää päätyä akkuun eikä lämmittää tätä mittausvastusta. 5 ampeerin virralla (noin 100W paneeli) tuon mittausvastuksen yli vaikuttaa siten 5A * 0,125ohm = 0,625V. Jos shuttivastus sijoittetaan plus-johtoon, vaikuttaa siihen myös latauslinjan jännite. Tällöin shunttivastuksen molemmista päistä voidaan tehdä analogiamittaus ja muuntaa näin saatu jännite-ero latausvirraksi. Koska yli 5voltin jännitettä ei voida kytkeä suoraan analogiamittaukseen, tarvitaan ym. jännitteenjakovastukset. Tuolla järjestelyllä pääsisi melkein 3% resoluutioon, mutta hylkäsin tämänkin, sillä kuvittelin pääseväni parempaan tarkkuuteen sijoittamalla shuntin miinusjohtoon, jolloin tuo 0,625V voidaan kytkeä suoraan analogiatuloon. Tällöin resoluutio olisi hiukan prosenttia parempi. Näin kuvittelin. Ratkaisu ei toiminut, vaikka sama toimii kuvassa taustalla näkyvässä vanhassa teholähteessä, minkä alkuperäiset viisarimittarit lopettivat toimintansa. Se oli sopiva sovelluskohde Arduinolle. Ilmeisesti (?) ongelma johtui siitä, että miinus ja maapotentiaali eivät olleet enää sama piste.

Hall-generaattoreita "edestä ja takaa". Paksut johdot ovat päävirtaa varten ja ohuet signaalia varten.
 
Tasavirtaa voidaan mitata myös Hall-generaattorilla. Se on puolijohdekomponentti, mikä pystyy muuttamaan magneettikentän voimakkuuden analogiajännitteeksi. Pienin löytämäni Hall-generaattori on tyyppiä ACS758LCB-050B ja se on maksimissaa 50A:in virralle. Siis tarpeettoman suuri tähän käyttöön, mutta sillä lähdin eteenpäin. Sen herkkyys on 40mV/A. Jos ajatellaan tätä 5A:in mittausaluetta, on komponentista saatava jännite 200mV (0,2V). Tämä jännite voidaan kytkeä suoraan analogiatuloon, joten muunnosportaita syntyy noin 40kpl ja tarkkuus jää hiukan alle 2%. Tähän tarkoitukseen tämäkin tarkkuus on aivan riittävä. Hall-generaattorin lähtö (siis 0-virralla) ei ole kuitenkaan nolla, sillä maan ja muu ympäröivä magneettikenttä aiheuttaa pohjalukeman. Tämä hallitaan siten, että nollavirralla talletetaan Hall-generaattorin lukema, ja tämä luku vähennetään varsinaisesta mittausarvosta.

Tuo oli teoriaosuus. Käytäntö ei ollut lainkaan yksinkertaista ja suoraviivaista. Ison virheen tein ensinnäkin siinä, että ensimmäiseen versioon juotin johdot Hall-generaattorin virtapuolelle. Se on aika paksua kuparia ja kupari johtaa hyvin lämpöä, joten jotain vioittui puolijohdepiirissä. Lukemat olivat stabiileita ja järkeviä, niin kauan kun Arduinon syöttö tapahtui USB-liittimen kautta tietokoneesta, mutta heti syötön siirryttyä akulle, lukemat heittelivät miten sattui. Syöttöjännitteessä oli pientä häiriötä, mutta se ei edellyttänyt moisia heittoja. Vasta viimeiseksi epäilin Hall-generaattoria, joten teettikin paljon töitä, kun olin eliminoinut muut kuvittelemani virhelähteet pois. Uudella generaattorilla, mihin kytkin virtajohdot ruuviliitoksin, mitään tuollaista epämääräisyyttä ei ilmennyt. Johtuen yllä mainitusta, on tämän ohjelman versionumero 2.4. Aina kun pääsin testeissäni johonkin välitavoitteeseen, otin uuden versionumeron, jolloin helposti pääsi palaamaan takaisin edelliseen toimivaan toteutukseen ja kopioimaan niistä toimivia osuuksia. (Ei noita versioita kuitenkaan 24 tullut, vaan isomman ponnistuksen jälkeen siirryin uudelle kymmenluvulle.)

Oikealla oleva vastussarja simuloi johtovastusta
Se oli vain yksi virheläde. Kovin stabiilia mittausta tästä ei kuitenkaan ole mahdollista saada. Siksi ohjelmassa käytetään jossakin mittauksessa keskiarvolaskentaa (mitataan useita peräkkäisiä mittauksia ja lasketaan niiden keskiarvo) sekä suodatusta (talletetaan edellinen mitausarvo, otetaan siitä 90% ja uudesta mittauksesta 10%). Yksi melkoinen hankaluus on jännitteen mittaus juuri latauksen katkon jälkeen. Ohjelmassa olevat arvot ovat pitkälti tulosta kokeilusta ja järkevään lopputulokseen pyrkimisestä. Voin sanoa, että toiminta ei ole kovinkaan tarkkaa, mutta oikean suuntaista. Ensimmäisellä kerralla katkaisu tapahtuu 14,5 voltin arvolla ja seuraavilla kerroilla siihen lisätään saatu johtojen häviöjännite, mikä on varmuuden vuoksi rajoitettu alle yhden voltin, jottei akun latausjännite pääse kasvamaan liian suureksi. Sekä liian suuri latausvirta että liian suuri latausjännite pilaavat akun ennen pitkää.

Latausvalvojan kytkentä. Molemmat LEDit ovat samassa kuoressa.
OHJELMASTA
HUOM! Ilmeisesti työkaluohjelman (Arduino) uusimmassa versiossa on tapahtunut sellainen muutos, että aliohjelmat eivät voi enää sijaita pääohjelman perässä (mihin oli tottunut). Jos sijaitsevat, ilmoittaa kääntäjä virheestä (aliohjelmaa ei ole määritelty). Tässä ohjelmassa aliohjelmat (funktiot) on sijoitettu asetuksen (setup()) ja pääohjelman väliin. Tämä merkitsee myös sitä, että aiemmin täällä julkistamani ohjelmaesimerkit eivät toimi sellaisenaan, vaan funktiot on siirrettävä pääohjelman eteen.

Asetuksen lopussa talletetaan ensimmäisen kerran Hall-generaattorin pohjalukema. Koska tämä osio suoritetaan ainoastaan kerran, olen käyttänyt yksinkertaista viivettä (delay(ms)).

Analogiamittaukset (jännite ja virta) sekä kaksivärisen LEDin (punainen ja vihreä) sekä latausreleen ohjaus toteutetaan funktioina. Analogiapuolen aliohjelmat palauttavat liukuluvun. Siksi niiden tyyppi on float (eikä void).
      Pääohjelmassa on ensimmäisenä kierroslaskuri, millä simuloidaan viiveaikoja. Ajan tarkkuus ei kuitenkaan ole kovin tähdellistä. Latauskatkon jälkeinen tauko on noin 5 minuuttia. Muuttujat ovat tyyppiä etumerkitön kokonaisluku (unsigned int), joten niistä ei koskaan tule negatiivisiä lukuja. Jos lukualue ( 0 .. 65536) ylittyy, alkaa uusi laskenta nollasta. Aikalukema on siis aina positiivinen luku.
      Seuraavana latauksen pysäytys- ja käynnistyskytkimien käsittely (kytkin on kolmiasentoinen). Pysäytyskytkin pysyy asennossaan, joten lataus voidaan kytkeä tarvittaessa pois päältä. Käynnistyskytkin on palautuva ja lataus alkaa vivun palautuessa keskiasentoon. Pysäytyskytkimen (kuvassa irti) toiminnan merkkinä punainen LED palaa.
      Seuraavana on varsinainen latauksen valvontasekvenssi. Ensimmäisessä askeleessa aurinkopaneeli on kytketty akkuun ja lataus käynnistyy. Ensimmäisellä kerralla lataus katkaistaan 14,5 voltin arvolla ja seuraavilla kerroilla tuohon lisätään jännite, mikä saadaan kertomalla sen hetkinen latausvirta lasketulla syöttöjohtojen vastusarvolla. Tässä askeleessa vihreä LED palaa.
      Toisessa askeleessa mitataan lyhyen viiveen (delay(3)) jälkeen välitön jännitepudotus latauksen loputtua. Tässä kerätään viisi peräkkäistä mittausta ja lasketaan niiden keskiarvo. Tämä on jännite, mikä latauksen aikana hävisi johtoihin.
      Kolmannessa askeleessa lasketaan johtojen vastus (plus- ja miinus-johto yhteensä).
      Neljännessä askeleessa odotetaan noin viisi minuuttia ennen uutta latausta. Merkkinä askeleesta on punainen vilkku. Punainen LED vaihtaa tilaansa, jos kierrosten lukumäärä (const int Con_Kierrokset = 800;) on saavutettu, tai on saavutettu puolet siitä. Vilkutusaika on näin ollen 0,5s päällä ja 0,5s pois.
      Viidennessä askeleessa odotetaan, että akun jännite on laskenut (14,5V – 1,0V) sille tasolle, että uusi lataus voidaan aloittaa. Merkkinä tästä askeleesta on vihreä vilkku. Jos samoihin akkuihin on kytketty useampia paneeleita, voi olla, että ne ylläpitävät akun jännitettä tuon rajan yläpuolella. Lopuksi askeleessa päivitettään Hall-generaattorin pohja-arvo ja hypätään askeleeseen yksi uutta latauskierrosta varten.


/***************************************
* PaneeliValvonta_v24
* Antti Isännäinen
* 09.11.2016
* Valvonta käsi (haarukka) kääntimeen
**************************************/
/* Tähtäimenä paneelivalvoja, mikä ottaa huomioon siirtojohtojen
* jännitehäviön. Käynnistyksen jälkeen lataus loppuu jännite-
* arvolla 14,5V. Seuraavilla kerroilla mitataan jännitepudotus
* latauksen loppuessa ja lasketaan siirtojohtojen lenkkivastus.
* Seuraavilla kerroilla rajajännitteeeseen lisätään (14,5 + häviö)
* siirtojohtoihin häviävä, (virta * vastus = jännite) jännite.
*
* Versiossa 2.1 Jouduin jälleen lähtöruutuun, sillä jännitepudotuksen
* mittaus latauksen katkon jälkeen ei edellisessä versiossa (1.2)
* ollu riittävän luotettava.
*
* Versiossa 2.2 (v22) on pohjana melko luotettava latauskatkon
* jälkeinen jännitemittaus ja suodatus. Lyhyen viiveen (10 ms)
* muodostetaan viiden (5) mittauksen keskiarvo.
* Tässä versiossa on myös virran mittaus riittävän luotettava.
*
* Versiossa 2.3 (v23) jatkuu varsinaisen paneelivalvojan
* kehitys. Pohjana versio 1.2 (v12).
*
* Versiossa 2.4 (v24) on jännittteiden, virtojen, johtovastuksen
* ja näistä lasketun lisäjännitteen (katkaisupiste) arvot toteutuneet
* käytännössä riittävällä tarkuudella.
*/

// MÄÄRITTELYT:
// Ajastukset
const int Con_Kierrokset = 800;
unsigned int Unt_Sekunnit = 0; // Viivelaskuri
unsigned int Unt_Kierrokset = 0; // Ohjelmakierroslaskuri
int Int_Kierrokset = 0;
// Jännite
const int Con_AnaTuloV = 0; // Tulopinni A0
int Int_AnaRaakaV = 0; // Muunnosarvo
float Flo_Jannite = 0; // Jännitteen mittaus
float Flo_EdellJannite = 0;
float Flo_JannSuod = 0;
float Flo_JannMuisti = 0;
float Flo_JohtoSumma = 0;
// Virta
const int Con_AnaTuloI = 2; // Tulopinni A2
int Int_AnaRaakaI = 0; // Muunnosarvo
int Int_PohjaArvo = 0; // Hall-gen. pohjalukema luetaan asetuksissa
float Flo_Virta = 0;
float Flo_VirtaSuod = 0;
float Flo_EdellVirta = 0;
float Flo_VirtaMuisti = 0;
// Digitaalimäärittelyt
// Tulot
const int Con_Seis = 4; // Kytkin pysyvästi ylös
boolean Bol_Seis = false;
int Int_Seis_Viive = 5; // Kytkinvärähtelyn suodatus
int Seq_Seis = 1; // Kytkimen lukusekvenssi
const int Con_Start = 5; // Kytkin alas palautuva
boolean Bol_Start = false;
int Int_Start_Viive = 5;
int Seq_Start = 1;
// Lähdöt
const int Con_LEDpun = 8;
boolean Bol_LED_Pun = false;
const int Con_LEDvih = 9;
boolean Bol_LED_Vih = false;
const int Con_Rele = 10;
boolean Bol_Rele = false;

// Valvontasekvenssi
const float Con_Irti_Raja = 14.5; // Akun napojen rajajännite
float Flo_JohtoJannite = 0.0;
float Flo_SilmukkaVastus = 0.0;
int Seq_Valvonta = 0; // Valvontasekvenssi

void setup() {
Serial.begin(9600);
pinMode(Con_Seis, INPUT);
pinMode(Con_Start, INPUT);
pinMode(Con_LEDpun, OUTPUT);
pinMode(Con_LEDvih, OUTPUT);
pinMode(Con_Rele, OUTPUT);
digitalWrite(Con_Rele, true); delay(300); // Irroitetaan lataus
Int_PohjaArvo = analogRead(Con_AnaTuloI); // Alustetaan Hall-pohja-arvo
digitalWrite(Con_Rele, false); delay(100); // kytketään lataus
}// Asetusten loppu

// ALIOHJELMAT
// ANALOGIA ALIOHJELMAT
// Jännitteen käsittely
float Fun_MittaaV(){
Int_AnaRaakaV = analogRead(Con_AnaTuloV);
return Int_AnaRaakaV / 50.6;
}// Jännitteen mittaus loppu

// Virran käsittely
float Fun_MittaaI(){
Int_AnaRaakaI = analogRead(Con_AnaTuloI);
Int_AnaRaakaI = Int_AnaRaakaI - Int_PohjaArvo;
Int_AnaRaakaI = constrain(Int_AnaRaakaI, 0, 100);
return Int_AnaRaakaI / 8.2;
}// Virran mittaus loppu

// OHJAUSTEN ALIOHJELMAT
void Fun_LEDvih(boolean Tila){
digitalWrite(Con_LEDvih, Tila);
}// Vihreän LEDin ohjauksen loppu
void Fun_LEDpun(boolean Tila){
digitalWrite(Con_LEDpun, Tila);
}// Punaisen LEDin ohjauksen loppu
void Fun_Rele(boolean Tila){
digitalWrite(Con_Rele, Tila);
}// Irroitusreleen ohjauksen loppu


//PÄÄOHJELMA
void loop() {
// Ohjelmakierros / viivelaskuri
Unt_Kierrokset++;
if(Unt_Kierrokset > Con_Kierrokset){ // Luvulla sovitetaan kierr -> sek
Unt_Sekunnit++;
Unt_Kierrokset = 0;
} // Kierroslakuri loppu

// Kytkintietojen käsittely
// Seis-kytkin
Bol_Seis = digitalRead(Con_Seis); // Luetaan kytkimen tila
switch (Seq_Seis) {
case 1:
if(Bol_Seis == true){
Int_Seis_Viive --;
if(Int_Seis_Viive == 0){
Int_Seis_Viive = 5;
Seq_Valvonta = 0;
Fun_LEDvih(false);
Seq_Seis = 2;
}
}
break;
case 2:
Fun_LEDpun(true);
Fun_Rele(true);
if(Bol_Seis == false){
Fun_LEDpun(false);
Seq_Seis = 1;
}
break;
} // Seis kytkinsekvenssi loppu

// Start-kykin
Bol_Start = digitalRead(Con_Start); // Luetaan kytkimen tila
switch (Seq_Start) {
case 1:
if(Bol_Start == true){
Int_Start_Viive --;
if(Int_Start_Viive == 0){
Int_Start_Viive = 5;
Seq_Start = 2;
}
}
break;
case 2:
if(Bol_Start == false){
Int_PohjaArvo = analogRead(Con_AnaTuloI);
Seq_Valvonta = 1;
Seq_Start = 1;
}
break;
} // Start kytkinsekvenssi loppu

// Akun latauksen valvontasekvenssi
switch (Seq_Valvonta) {
case 1: // Latausaskel
Fun_LEDvih(true);
Fun_Rele(false); // rele päästää, lataus alkaa
Flo_Jannite = Fun_MittaaV();
Flo_JannSuod = Flo_EdellJannite * 0.9 + Flo_Jannite * 0.1;
Flo_EdellJannite = Flo_JannSuod;
Flo_Virta = Fun_MittaaI();
Flo_VirtaSuod = Flo_EdellVirta * 0.9 + Flo_Virta *0.1;
Flo_EdellVirta = Flo_VirtaSuod;
if(Flo_JannSuod > Con_Irti_Raja + Flo_SilmukkaVastus * Flo_VirtaSuod){
Flo_JannMuisti = Flo_JannSuod;
Flo_VirtaMuisti = Flo_EdellVirta;
Fun_Rele(true); // rele vetää, lataus katkaistaan
Unt_Sekunnit = 0; // Nollataan "sekunnit"
Fun_LEDvih(false);
Seq_Valvonta = 2;
}
break;
case 2: // Jännitepudotuksen mittaus
delay(3); // 3 ms stabilointiviive
for (int iV = 0; iV < 5; iV++){ // Mitataan 5 peräkkäistä arvoa
Flo_Jannite = Fun_MittaaV();
Flo_JohtoSumma = Flo_JohtoSumma + Flo_Jannite;
} // for-silmukan loppu
Flo_Jannite = Flo_JohtoSumma / 5; // Muodostetaan viiden keskiarvo
Flo_JohtoSumma = 0; // Nollataan muisti seuraavaa kierrosta varten
Flo_JohtoJannite = Flo_JannMuisti - Flo_Jannite;
Flo_JohtoJannite = constrain(Flo_JohtoJannite, 0.0, 1.0);
Seq_Valvonta = 3;
break;
case 3: // Johtovastuksen laskenta
Flo_SilmukkaVastus = Flo_JohtoJannite / Flo_VirtaMuisti;
Seq_Valvonta = 4;
break;
case 4: // Purkausviive
if(Unt_Kierrokset == Con_Kierrokset ||
Unt_Kierrokset == Con_Kierrokset / 2){
Bol_LED_Pun = !Bol_LED_Pun;}
Fun_LEDpun(Bol_LED_Pun);
if(Unt_Sekunnit > 300){
Fun_LEDpun(false);
Seq_Valvonta = 5;
}
break;
case 5: // Latauksen palautus
if(Unt_Kierrokset == Con_Kierrokset ||
Unt_Kierrokset == Con_Kierrokset / 2){
Bol_LED_Vih = !Bol_LED_Vih;}
Fun_LEDvih(Bol_LED_Vih);
Flo_Jannite = Fun_MittaaV();
Flo_JannSuod = Flo_EdellJannite * 0.9 + Flo_Jannite * 0.1;
Flo_EdellJannite = Flo_JannSuod;
if(Flo_JannSuod < Con_Irti_Raja - 1.0){
Int_PohjaArvo = analogRead(Con_AnaTuloI); // Alustetaan Hall-pohja-arvo
Fun_LEDvih(false);
Seq_Valvonta = 1;}
break;
} // Valvontasekvenssi loppu

delay(1);
} // Pääohjelman loppu