torstai 10. toukokuuta 2018

VILKKU

On toki oikeutettua kysyä, onko tämän pitkän tauon aikana kaikki unohtunut, kun pitää jälleen siirtyä alkeisiin, eli vilkuttamaan LEDiä? Päivät ovat täyttyneet kaikenlaisesta muusta menneen talven aikana.

Nyt kuitenkin tuli jo kiire kehitellä ensi kesäksi uutta aurinkopaneelin kääntäjäprotoa (jokainen edellistä yksinkertaisempi), ja siinä yhteydessä syntyi ajatus: voisiko noiden parin LEDin avulla saada yksinkertaisella ohjelman pätkällä aikaan enemmän informaatiota toiminnan tilasta kuin pelkästään toimii / seis?
    Kun aurinko siirtyy kolme (3) tuntia paneelin suunnasta sivuun, putoaa paneelin tuotto noin puoleen. Toisin sanoen, jos paneeli seuraa aurinkoa klo 9 .. 15, (6h eli 90 astetta), tuottaa paneeli klo 6 – 9 keskim. 75% ja siitä eteenpäin 9 – 15 yli 90% (jos korjataan esim. kerran tunnissa). Sitten taas klo 15 – 18 keskim. 75%. Aurinkoa seuraamalla korvataan käytännössä yhden paneelin tuotto. Pilvet tietysti sotkevat tämän optimismin!
    Minulle on myös sanottu (ja epäilty), että paneelin tuotto kuluu nimenomaan tähän kääntämiseen. Minulla on ollut jo useamman kerran käytössä veneen lasinpyyhkijän moottorit (hiukan modifioituina). Ne toimivat 12 V:n jännitteellä ja niissä on sopiva vaihteisto.
    Tämä on pelkkää laskentoa: jos käännetään kuusi (6) kertaa ja yksi tunnin kääntö kestää yhden (1) minuutin, kuluttaa kääntö 6 Amin aamusta iltaan plus paluu toiset kuusi Ah. Mikrokontrolleri on kuitenkin päällä ja kulutta sähköä koko ajan, joten jos se kuluttaa 5 mA (<Leonardo, UNO noin 150mA, tietysti riippuu ja roikkuu!), kuluu siihen 1440min * 0,005A = 7,2 Amin. Yhteensä siis 13,2 Amin. Jos varaudutaan vaikkapa tuplaan, noin 30 Amin, eli 0,03 Ah:iin, niin 85W panelilta (tuotto noin 4A) kuluu tuotosta kääntäjän pyörittämiseen auringon heloituksessa noin 8 min.
Päässä pyörii jo ensi talven proto. Siinä ei lasin pyyhkijään tarvitse tehdä muutoksia, ja sen tulisi kääntää useampia rinnan olevia paneeleja yhdessä. Saa nähdä toteutuuko??

Päädyin miettimisen jälkeen aliohjelmaan, minkä avulla yksi kaksivärinen LEDi tarjoaa kuusi (6) eri tilatietoa (sen lisäksi, että kumpikaan LEDi ei valaise). Ajattelin laittaa sen tänne blogiin ajatuksella, että sillä saattaisi olla käyttöä muillekin. Minulle ainakin myös jatkossa myös muissa sovelluksissa.
    Tässä ohjelmaesimerkissä on kuusi (6) painiketta. Käytännössä informaatio tulee tietysti prosessin tilatietoina. Aliohjelmassa ( void Fun_LEDit(int led, int toiminto){) on kolme toiminnallista askelta ja oletusaskeleena (default:) LEDien sammutus ja aikalaskurin palautus, jotta uusi ohjaus alkaisi aina LEDin syttymisellä
    Askeleet ovat: 1. LED palaa niin kauan kun tuloinformaatio on TOSI. 2. LEDin lyhyt välähdys ja loppu kokonaisajasta sammuneena ja 3. Kokonaisaika puolitetaan, jolloin LED on puolet ajasta valo päällä ja puolet ajasta pimeänä.
    Tämä valittavana kutsussa (esim. {Fun_LEDit(Con_LEDvih, 1), jolloin vihreä valo palaa niin kauan kuin tulo on aktiivinen. Eli pääohjelman kutsussa määritellään kahdella parametrilla, kumpi LEDi aktivoituu ja millä tavalla.
    Jos mikään ohjaus ei ole aktiivinen, kutsutaan oletusaskelta (}else{Fun_LEDit(0, 0);}), missä molemmat LEDit ohjataan nollaan ja aika palautetaan alkuun, jotta seuraava ohjaus alkaa LEDin syttymisellä.

Koska tulot (tässä tapauksessa) on määritelty sisäisesti ylös (pinMode(Con_Pain1, INPUT_PULLUP );), muuttuu prosessorin tulo alas ( 1 → 0 ), käännetään tulon tilaa luettaessa huutomerkillä (!) (Bol_Pain1 = !digitalRead(Con_Pain1);). Tämä on kyllä vain ihmisen aivoja varten.

Tässäkin aliohjelmassa on tietysti rajoituksensa. Tämä edellyttää, että sille syötetään ainoastaan yksi tieto kerrallaan. Jos halutaan vilkuttaa useampaa lamppua samaan aikaan ja eri tahtiin, pitää aliohjelmalle välittää myös yksilöllinen aikainformaatio. Samoin pitää myös valojen sammutus valvoa yksilöllisesti. Tässä sen toteuttaa oletusaskel (default:), mikä edellyttää, että aliohjelmaa ei kutsuta lainkaan.
    Jos nuo ajat (919 ja 43) ihmetyttävät, niin niiden lukuarvoilla ei sinänsä ole merkitystä. Noilla ajoilla (monien muiden lähellä olevien lisäksi) vilkutus tuntui sopivalta. Mutta miksi juuri noin oudot luvut? Molemmat ovat alkulukuja ja niiden valinnan taustalla on viimeaikainen toisen ohjelmointikielen (python) harjoitteleminen. Sen harjoituksissa on ollut hauskoja ”numeromurskausjuttuja”, mm. alkulukujen (jaollinen vain yhdellä(1) ja itsellään) laskeminen. Toinen kiva harjoitus purki tietoa, että kaikki luonnolliset luvut ovat alkulukujen tuloja. Esim. kertolasku 2*3*3*5*3607*3803 antaa tulokseksi luvun : 1234567890. Numerot ovat hauskoja!
 
OHJELMA 53
 
/***************************************
* Vilkku_v1
* 10.05.2018
* Laajempaa LEDi-informaatiota
**************************************/

// MÄÄRITTELYT:
// Ledit
const int Con_LEDpun = 2; // Ohjaukset seis
const int  Con_LEDvih = 3; // Automaatilla

// Tulot
const int  Con_Pain1 = 4;
boolean Bol_Pain1 = false;
const int  Con_Pain2 = 5;
boolean Bol_Pain2 = false;
const int  Con_Pain3 = 6;
boolean Bol_Pain3 = false;
const int  Con_Pain4 = 7;
boolean Bol_Pain4 = false;
const int  Con_Pain5 = 8;
boolean Bol_Pain5 = false;
const int  Con_Pain6 = 9;
boolean Bol_Pain6 = false;

// Muutamia perusmäärityksiä
const int Con_Kierros = 919; // Kokonaiskesto
const int Con_Ero = 43; // Pilkahdusaika
int Int_Kierros = Con_Kierros;// Keston välimuisti

// ALIOHJELMAT
// LEDien ohjaus
void Fun_LEDit(int led, int toiminto){
   switch (toiminto) {
     case 1: // Jatkuva
     digitalWrite(led, HIGH);
   break;
   case 2: // Pilkahdus
     if (Int_Kierros > (Con_Kierros - Con_Ero))
       {digitalWrite(led, HIGH);
    }else{digitalWrite(led, LOW);}
       Int_Kierros = Int_Kierros - 1;
     if (Int_Kierros == 0){Int_Kierros = Con_Kierros;}
   break;
   case 3: // Vilkku
     if (Int_Kierros > (Con_Kierros / 2))
       {digitalWrite(led, HIGH);
     }else{digitalWrite(led, LOW);}
       Int_Kierros = Int_Kierros - 1;
    if (Int_Kierros == 0){Int_Kierros = Con_Kierros;}
   break;
   default: // LEDien sammutus ja ajan palautus
     digitalWrite(Con_LEDvih, LOW);
     digitalWrite(Con_LEDpun, LOW);
     Int_Kierros = Con_Kierros;
   }// sekvenssi loppu
}// LEDien funktion loppu

// ASETUKSET:
void setup(){
Serial.begin(9600);
pinMode(Con_LEDpun, OUTPUT);
pinMode(Con_LEDvih, OUTPUT);
pinMode(Con_Pain1, INPUT_PULLUP );
pinMode(Con_Pain2, INPUT_PULLUP);
pinMode(Con_Pain3, INPUT_PULLUP);
pinMode(Con_Pain4, INPUT_PULLUP);
pinMode(Con_Pain5, INPUT_PULLUP);
pinMode(Con_Pain6, INPUT_PULLUP);
}// Asetuksen loppu

// PÄÄLOOPPI
void loop(){
Bol_Pain1 = !digitalRead(Con_Pain1);
Bol_Pain2 = !digitalRead(Con_Pain2);
Bol_Pain3 = !digitalRead(Con_Pain3);
Bol_Pain4 = !digitalRead(Con_Pain4);
Bol_Pain5 = !digitalRead(Con_Pain5);
Bol_Pain6 = !digitalRead(Con_Pain6);

if (Bol_Pain1 == true){Fun_LEDit(Con_LEDvih, 1); // jatkuva
}else if(Bol_Pain2 == true){Fun_LEDit(Con_LEDpun, 1);
}else if(Bol_Pain3 == true){Fun_LEDit(Con_LEDvih, 2); // pilkahdus
}else if(Bol_Pain4 == true){Fun_LEDit(Con_LEDpun, 2);
}else if(Bol_Pain5 == true){Fun_LEDit(Con_LEDvih, 3); // tasavilkku
}else if(Bol_Pain6 == true){Fun_LEDit(Con_LEDpun, 3);
}else {Fun_LEDit(0, 0);} // LEDien sammutus (default)
delay(1);
} // Pääohjelma LOPPU

sunnuntai 3. joulukuuta 2017

LC-MITTARI

Kuva 1.
Tämä ei ole mikään tarkkuusmittalaite. Pyrkimyksenä onkin hiukan valottaa joitakin elektroniikan perusasioita. Mittausperiaate tässä on se, että sarjaan kytketyn sekä reaktanssin (kondensaattori tai kela) että ohmisen vastuksen yli oleva jännitehäviö on yhtä suuri.

Kuvassa 1 kytkentä on kondensaattorin osalta.

Sinijännite syötetään kondensaattorin napaan (U1) ja 10-kierrospotentiometrillä säädetään vastusarvo (R) sellaiseksi, että jännite (U2) säätövastuksen navassa on puolet syöttöjännitteestä. Jännitteitä mitataan Arduinon analogiatuloilla ja vertaillaan ohjelmallisesti. Seuraavassa kuvassa on laskentakaavat kondensaattorin ja kelan ”vastusten” riippuvuudelle taajuudesta. Niistä on helppo havaita, että kondensaattorin ”vastus” pienenee taajuuden kasvaessa, ja kelan vastaavasti kasvaa.

Kuva 2. Laskentakaavat
Kuva 3.
Vastuksessa jännite ja virta ovat samanvaiheisia, mutta kapasitanssissa virta on 90 astetta jännitettä edellä. (Vastaavasti induktanssissa virta on 90 astetta jännitettä jäljessä.) Kuva 2 havainnollistaa tilannetta kondensaattorin osalta.
Kuvassa suurempi signaali on U1 ja pienempi U2. Näytöltä on helppo havaita, miten vastuksen navoissa oleva jännite on puolet syöttöjännitteestä ja noin 45 astetta syöttöjännitettä edellä. Virta molempien läpi on samanvaiheinen, joten muutos näkyy jännitteessä.

Arduinolla, kuten muutamassa edellisessä päivityksessä on toteutettu, on varsin helppoa muodostaa suorakulmasignaalia aika korkeillekin taajuuksille. Sen sijaan siniaallon synnyttäminen on melko mahdotonta. Tämän mittausperiaatteen käyttäminen suorakaideaallolla on mahdotonta, sillä signaalin sisältämät harmoniset taajuudet sotkevat täysin jännitevertailuna toteutetun mittausperiaatteen.

Kuva 4. Testielektroniikan kytkentä.
Yllä olevassa kaaviossa on Arduinon lisäksi viisi (5) toiminnallista osaa. 1). Kondensaattorien 0,32 uF ja 1 kohm vastusten muodostamat (vasemmalla ylhäällä) vaiheensiirtopiirit. Niitä on kolme (3) kappaletta, ja tällä pyritään 180 asteen vaihesiirtoon. Kukin sarjapiiri kääntää jännitettä noin 60 astetta ( 3 x 60 = 180). Tosin kaikki muutkin kapasitanssit, kuten hajakapasitanssi vaikuttavat vaihesiirtoon, mutta niiden vaikutuksen vähäisyyden vuoksi ne voidaan tässä unohtaa. Joka tapauksessa ainoastaan yhdellä taajuudella voi tämä 180 asteen vaihesiirto toteutua, joten signaali on hyvin puhdasta siniaaltoa. Näillä arvoilla taajuudeksi tuli 403 Hz. Siniaallon puhtauden edellytyksenä on, että koko signaalitie toimii lineaarisella alueella. 2). Seuraavaksi signaali viedään vahvistinpiirille (LM3900) ja sen negatiiviseen tuloon. Vahvistinpiirissä tapahtuu täten jälleen 180 asteen vaihesiirto. Vahvistimen lähdöstä vahvistettu signaali johdetaan takaisin CR-vaihesiirto-osan alkuun. Tässä tapahtuu täten myötäkytkentä. Kun vahvistus kumoaa piirissä syntyvät häviöt, alkaa piiri värähdellä. Vahvistusta voi säätää trimmeripotentiometrillä P2.
   Säätö on hyvin herkkä ja liika vahvistus saa signaalin negatiiviset huiput ”tökkimään” maapotentiaaliin ja positiiviset huiput syöttöjännitteeseen (+12 VDC tässä tapauksessa). Signaali siis säröytyy, jolloin se ei enää ole puhdasta siniaaltoa. Yritinkin tehdä automaattisen säädön LDR-vastuksen ja LEDin avulla, mutta tuo tarjokkaana ollut valovastus ei toiminut vaihtojännitteellä.
   Signaalin saa säädettyä käsinkin puhtaaksi. Tuo operaatiovahvistin (siinä on yhdessä piirissä neljä (4) vahvistinta) on virtatuloinen piiri. Siksi negatiiviseen napaan johdetaan pieni virta (bias) ja positiiviseen napaan trimmerillä säädettävä virta, minkä avulla vahvistimen lähtö säädetään noin puoleen väliin, jotta lineaarinen alue olisi mahdollisimman laaja.
   Myös tämän vahvistimen lähtö on virtasyöttöinen, joten siinä on oltava kuormitusvastus. Maksimivirta on 1,3 mA, joten tuolla 5,7 kohm:in vastuksella on helppo säätää lähtöjännite syöttöjännitteen puoleen väliin. 3). Koska tuota vahvistinta ei voi juurikaan kuormittaa, toimii transistori 2N3904 emitteriseuraajana pienentäen lähtöimpedanssia. 4). Transistorin emitteriltä signaali johdetaan mittauspiiriin (TEST). Sen etupuolelta tasasuunnataan kahdella diodilla jännite Arduinon analogiatuloa varten.
   Jos vaihtojännitemittari (yleensä näyttää tehollisarvoa RMS) näyttää 1,5 VAC, on dioditasasuuntauksen (molempia puoliaaltoja varten on oltava diodi) jälkeen noin 4,3 VDC. Tehollisarvo pitää jakaa 0,7 :llä, jotta saadaan huippuarvo ja diodit vielä kertovat jännitteet kahdella. Siis: tuon huipusta huippuun (pp) 4,3 volttia pitää voida värähdellä piirin lineaarisella alueella. Samoin jännitteen tulee olla alle 5 VDC, mikä on Arduinon analogiatulon maksimijännite. 5). Kymmenkierrospotentiometrillä säädetään testikappaleen (kondensaattori tai kela) ja potikan välinen jännite puoleen väliin syöttöjännitteestä. Tämän indikointia varten on kaksivärinen LED, mikä vilkkuu punaista hitaasti, jos jännite on alle puolen välin ja nopeasti, mikäli jännite on yli puolen välin. Oikealla arvolla (luonnollisesti pieni toleranssi) palaa LED vihreänä.

Kymmenkierrospotentiometrin lukema syötetään EXELiin, missä lasketaan mitattavan komponentin arvo.
Kuva 5. Taulukkolaskennan tuloste.
Kuva 6. Kytkentähässäkkä.
Potentiometrin vastusarvo on siis kymmenkertainen säätimen lukemaan verrattuna. Tuo ylimääräinen 5 ohm johtuu siitä, että potikka ei mene aivan nollaan, vaan pohjalla on juuri tuo viisi (5) ohmia. Samassa taulukossa on myös induktanssin laskenta. Tuolla taajuudella ja potikan lukemalla induktanssi olisi siis 1,11 Henryä. Se on todella iso kela. Edellisen päivityksen tehohakkurissa oli käytössä 3,1 mH kela. Jos sitä kelaa mitatessa haluttaisiin potentiometrille sama lukema (165), pitäisi värähtelytaajuuden olla noin 144 kHz (tätä en edes kokeillut).

Oheisessa kuvassa on koko kytkentähässäkkä. Mitattava kondensaattori on tuo sininen suorakaide melko keskellä kuvaa. LED palaa juuri vihreänä, joten mittaus on ok.

Ohjelma on varsin yksinkertainen. Pääohjelmassa aluksi mitataan molemmat analogia-arvot ja vertaillaan if .. esle if .. else rakenteella, onko mitattavan kapasitanssin jälkeinen jännite alle puolen välin; miinus neljän (-4) toleranssi, jos ei, niin onko se yli puolenvälin; plus neljän (+4) toleranssi. JOS kumpikaan tilanne ei toteudu, on jännite toleranssin puitteissa puolessa välissä. Itse vilkutus tapahtuu aliohjelmassa (void Fun_Vilkku(int askel){), mihin kutsussa välitetään tulostusaskelta vastaava numero (1, 2 tai 3). Aliohjelmassa tutkitaan ensin, onko askel erisuuri kuin kaksi (2). Jos on, niin vihreä valo sammutetaan ja suoritus hyppää joko nopeaan tai hitaaseen vilkutukseen. Ohjelman suoritus ei kuitenkaan jää aliohjelmaan viiveen ajaksi, vaan käy ainoastaan katsomassa, milloin vilkun puolijakso on kulunut.

OHJELMA 52

/***************************************
* Ohjelma LC_Mittari_52
* 3.12.2017
* Ohjelma vertailee kahta jännitettä ja
* ohjaa LEDejä sen mukaan.
**************************************/

// MÄÄRITTELYT:
// Mittauksen märittelyt
    const int Con_AnaTulo1 = 0;
    int Int_AnaArvo1 = 0;
    const int Con_AnaTulo2 = 1;
    int Int_AnaArvo2 = 0;
    int Int_Ohjaus = 0;

// Vilkutuksen määrittelyt
    int intViive = 1;
     const int Con_LED_Vih = 2;
    const int Con_LED_Pun = 3;
    boolean LED_Tila = false;


// ALIOHJELMAT
    void Fun_Vilkku(int askel){
    const int conHid = 750;
    const int conNop = 200;
    if(askel != 2){digitalWrite(Con_LED_Vih, LOW);}

    switch (askel) {
        case 1:
            digitalWrite(Con_LED_Pun, LED_Tila);
            intViive--;
            if(intViive == 0){
                intViive = conHid;
                LED_Tila = !LED_Tila;
        }
        break;
        case 2:
            digitalWrite(Con_LED_Vih, HIGH);
            digitalWrite(Con_LED_Pun, LOW);
        break;
        case 3:
            digitalWrite(Con_LED_Pun, LED_Tila);
            intViive--;
            if(intViive == 0){
                intViive = conNop;
                LED_Tila = !LED_Tila;
        }
        break;
    }// Case-rakenteen loppu
}// Vilkku loppu


void setup() {
    Serial.begin(9600);
    pinMode(Con_LED_Vih, OUTPUT);
    pinMode(Con_LED_Pun, OUTPUT);
}

void loop() {

    Int_AnaArvo1 = analogRead(Con_AnaTulo1);
    Int_AnaArvo2 = analogRead(Con_AnaTulo2);

    if(Int_AnaArvo2 < Int_AnaArvo1/2 -4){Int_Ohjaus = 1;}
    else if(Int_AnaArvo2 > Int_AnaArvo1/2 +4){Int_Ohjaus = 3;}
    else Int_Ohjaus = 2;
    Fun_Vilkku(Int_Ohjaus);

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

perjantai 10. marraskuuta 2017

TEHOHAKKURI

Ohjaamalla virtaa kelan läpi, syntyy siihen magneettikenttä. Kun virta katkaistaan, on sillä hetkellä magneettikenttä vielä olemassa ja se pyrkii purkautumaan heti virran katkettua. Jos sillä ei ole galvaanista yhteyttä muualle kytkentään, nousee jännite hyvin suureksi. Tällä periaatteella toimii esimerkiksi bensiinikäyttöisen moottorin sytytys. Jännite nousee, kunnes se on niin korkea, että tulpassa tapahtuu läpilyönti ja magneettikenttä pääsee purkautumaan tätä kautta.


Jännitteen alentamista varten kytkentä olikin jo edellisessä blogissa, missä hakkurilla (pulssinleveysmodulaatiolla, PWM) jännitettä nostettiin nollasta (0) sinimuotoisen jännitteen huippuarvoon, ja seuraavalla neljänneksellä päin vastoin. Tällöin kytkintransistori on kelan (L) etu, eli syöttöpuolella ja diodi poikittain samassa pisteessä. Kun kytkin aukeaa, pääsee magneettikentän luoma virta purkautumaan diodin kautta. Lähdön jännite voi täten muuttua nollasta (0) tulojännitteeseen.

Tämän kertaisessa jaksossa jännitettä nostetaan syöttöjännitteestä ylöspäin. Nyt kytkintransistori sijaitsee kelan jälkeen, ja sitä seuraa diodi. Kun kytkin aukeaa, purkautuu magneettikentän luoma virta diodin kautta kuormaan. Muuttamalla pulssisuhdetta, voidaan lähtöjännitettä säätää.

Tässä ohjelmassa trimmeripotikan jännite johdetaan analogiatuloon, jaetaan luvulla sata (100), jolloin säätöön saadaan kymmenen (19) porrasta. Tässä tapauksessa kytkentätaajuus on noin 83 kHz. Lähtöä ei voida säätää 100 prosenttiin, vaan ohjauksessa on minimissään 2 us tauko. Aliohjelmassa (void Fun_PWM(int pulssi){) on 100 kierroksen looppi. Kun nämä ”pumppaukset” on suoritettu, palataan pääohjelmaan, missä luetaan trimmeripotikan arvo ja kutsutaan aliohjelmaa uudestaan. Säätöä luetaan siis noin 1,2 – 2 ms välin, mikä on niin nopea, että ihminen kokee sen olevan jatkuva säätö.

 
Tuo kuormana oleva lamppu on 12 V, 7W. Tuo 470 uF:in elektrolyyttikondensaattori jaksaa syöttää lamppua myös tauon (OFF) aikana. Lampulle siirtyy siis tasavirtaa, mutta el-konkka ei ole enää näillä taajuuksilla oikein toimiva. Se näkyy siinä, että transistorin kytkentähetkillä jännitteessä näkyy suurtaajuista värähtelyä. Jos käyttöön tarvitaan puhtaampaa tasajännitettä, on lähtöön syytä sijoittaa kelalla (L) ja kondensaattorilla (C) toteutettu alipäästösuodin. Kuvista voi huomata, että ohjauksen ollessa minimissään, lamppu edelleen hehkuu. Sinne johtuu virtalähteen jännite. Tässä tapauksessa 7 V. Kasvattamalla potikalla ON-tilan pituutta, jännite lampun navoissa nousi hiukan yli 15 V:iin.

 
OHJELMA 51
/*******************************
* Ohjelma TehoHakkuri_51
* 10.11.2017
* DC-jännitteen korotus
* pulssinleveysmodulaatiolla (PWM)
*/

// Määrittelyt
    const int Con_AnaTulo = 0;
    int Int_AnaTulo = 0;
    const int Con_Pulssit = 3;


// FUNKTIOT
// Pulssien muodostus (PWM)
    void Fun_PWM(int pulssi){
        const int jakso = 12; // = 12 us ON + OFF
        int ON = pulssi;
        int OFF = jakso - pulssi;
            for(int i = 0; i < 100; i++){
                bitSet(PORTD,Con_Pulssit);
                delayMicroseconds(ON);
                bitClear(PORTD,Con_Pulssit);
              delayMicroseconds(OFF);
            } // for-loopin loppu
    }// pulssien muodostus loppu

void setup() {
    pinMode(Con_Pulssit, OUTPUT);
    Serial.begin(9600);
} // Asetusten loppu

// Pääohjelma, missä luetaan potentiometri
    void loop() {
        Int_AnaTulo = analogRead(Con_AnaTulo);
        Fun_PWM(Int_AnaTulo / 100);
    } // Pääohjelma loppu

keskiviikko 8. marraskuuta 2017

KANTTIAALTOINVERTTERI

Jos tyydytään suorakulma-aaltoon, tulee kytkennästä yksinkertainen. Edelleenkin on Arduino hyvä eristää tehopuolesta galvaanisesti. Lisäksi tarvitaan tehotransistorit kytkemään muuntajan reunoja maahan (miinukseen), muuntajan, minkä ensiön väliottoon syötetään esim. 12 V akkujännite. Käyttämälläni muuntajalla (mikä oli myös siniaaltoinvertterissä: ensiö 2 x 115 V, toisio 2 x 6 V ja jälleen päinvastoin kytkettynä), syöttöjännitteeksi tuli 8,8 V, jolloin lähtöön muodostui 230 VAC (RMS). Tuo lamppu palaa nyt hiukan kirkkaammin, koska kanttiaallon huippujännite kestää kauemmin.

Jos toteuttaa tällaisen esimerkiksi kännyköiden ja läppäreiden latausta varten, on tuon muuntajan ensiön syytä olla vaikkapa 10 V tai 12 V. Niiden latureilla on laaja tulojännitealue, joten jännitteen arvon ei tarvitse olla tiukissa rajoissa. Toisaalta syöttöjännite voi olla myös säädettävä, jolloin lähtöjännitettä voi myös säätää kuormituksen muutosten mukaan. Jos säätö on analoginen, syntyy enemmän lämpöhäviöitä, ja jos hakkuriperiaatteella, niin vähemmän. Jännitteen lasku hakkurilla on nähtävissä tuossa edellisessä, osana siniaaltoinvertterin toteutusta.

Tällaisen hakkuri-invertterin ohjauksessa on ainoastaan tärkeätä huolehtia siitä, että tehotransistorit eivät jännitteen napaisuuden vaihtohetkellä ole samanaikaisesti johtavassa tilassa. Siksi ohjelmassa on jokaisen ”vuoronvaihdon” välissä 2 ms tauko. Tänä aikana muuntajassa oleva magneettivuo ehtii purkautua.

OHJELMA 50
/*******************************
* Ohjelma KanttiInvertteri_50
* 08.11.2017
* 230 VAC-jännitteen muodostus
* suorakulma-aallolla.
*/
// Määrittelyt
   const int Con_VasenTr = 8;
   const int Con_OikeaTr = 9;
   boolean Bol_Vaihto = false;

// Alustukset
   void setup() {
      pinMode(Con_VasenTr, OUTPUT);
      pinMode(Con_OikeaTr, OUTPUT);
      Serial.begin(9600);
}

// Pääohjelma
void loop() {
   digitalWrite(Con_VasenTr, HIGH); delay(8);
   digitalWrite(Con_VasenTr, LOW); delay(2);
   digitalWrite(Con_OikeaTr, HIGH); delay(8);
   digitalWrite(Con_OikeaTr, LOW); delay(2);
}// Pääohjelma loppu

SINIAALTOINVERTTERI

Kun siniaalto kokoaaltotasasuunnataan, muodostuu sykkivää tasajännitettä, mistä voidaan suodattamalla ja reguloimalla sada stabiilia tasajännitettä kulloiseenkin tarpeeseen. Kokoaaltotasasuuntauksen jälkeen signaali näyttää oheisin kuvan kaltaiselta. Siinä nollatason yläpuolella on 50 Hz siniaallon puolikkaita.
   Tässä päivityksessä teen täsmälleen päin vastoin. Arduinon avulla ”hakkaan” siniaallon puolikkaita, joita sitten kytkintransistorien avulla jaan muuntajan ensiön puolelta toiselle. Itse asiassa muuntajaakin käytän väärinpäin, sillä sen merkinnät ovat: ensiö 2 x 115V/50 – 60 Hz ja toisio 2 x 6V 1,25A. Eli tässä toisio muutetaan ensiöksi. Molemmat puoliskot kytketään sarjaan siten että keskikohtaan syötetään näitä aallon puolikkaita ja reunoja kytketään maahan aina puolijakson keston ajaksi. Toision puolikkaat kytketään sarjaan, jolloin lähdössä on 230V:in sinimuotoinen vaihtojännite.
  
Vaikka tämä nyt onkin lähinnä vain yksi Arduinon ohjelman sovellusesimerkki, tulee inverttereiden käyttö tulevaisuudessa voimakkaasti kasvamaan, koska sähköautot lisääntyvät ja mm. niiden akkuja tullaan käyttämään energiavarastona. Kaikki muukin uusiutuvan energia käyttö kasvaa tulevaisuudessa voimakkaasti. 
    Tätä laitetta ei kuitenkaan saa mennä kytkemään verkkoon, sillä se vaatii kytkijältä koulutuksen, osaamisen ja asianomaiset luvat. Invertterin kytkeminen verkkoon energian syöttötarkoituksessa ei ole jokamiehen oikeus, kuten marjastus ja sienestys.
   Videolla (antinarduvideo49.youtube.com) näkyy kylläkin, että kytkin tämän johtohässäkän verkkoon osoittaakseni sen, että tämä voitaisiin myös synkronoida verkkojännitteen tahtiin, jolloin energian syöttö sähköverkon suuntaan olisi mahdollista. Indikaattorina tässä on kaksi hohtopurkauslamppua sarjassa (jännite on maksimissaan siniaaltojen puolikkaiden ollessa vastakkaisvaiheisina 460V RMS, eli 649V (huippu on tehollisarvo (RMS) kertaa neliöjuuri 2, eli 460 * 1,41 = 648,6V)). Hehkulamppu (tai analoginen jännitemittari) olisi parempi osoittamaan synkronointia, mutta sopivan tehoisia ei ”miljoonalaatikko” sattunut sisältämään. Tuollainen glimlamppu syttyy ja sammuu noin 210 voltin (noin 150V RMS sinimuotoisella) jännitteellä. Kun nuo kaksi sarjassa olevaa lamppua palavat kirkkaimmillaan, ovat verkkojännite ja tämän invertterin jännitteet vastakkaisvaiheisia (huippujännite kaksinkertainen) ja puolessa välissä pimeäaikana samanvaiheisia. Tämä tarkkuus riittäkköön, sillä tarkoitus ei ole kytkeä tätä verkkoon. Jaksonaikaa on mahdollista säätää muuttujalla int Int_Kesto = 380; Tässä olen säätänyt sen havainnollisuuden vuoksi hiukan pieleen, jotta verkkojännitteen ja invertterin taajuusero tulisi videolla havainnollisemmaksi. Lamppujen värinästä voi myös nähdä, että invertterin jännite ei ole aivan puhdasta siniaaltoa (lähelle kylläkin), vaan siinä on säröä johtuen siniaallon muodostamisesta pulssinleveysmodulaatiolla (taajuus noin 200 kHz).
    Kuvassa näkyy koko hässäkkä. Kun käytetään suurempia tehoja, on hyvä kytkeä Arduinon ja tehoelektroniikan väliin optoerottimet. Tässä kuvassa nämä ovat kokonaan galvaanisesti erossa toisistaan, koska Arduino UNO saa syöttönsä tietokoneelta. Jos tämä olisi todellinen laite, jolloin kaikki tehosyöttö tulisi yhdestä lähteestä, esimerkiksi akusta, olisi erotus silloinkin tarpeen ja maat (- potentiaali) kytkeä yhteen ainoastaan yhdestä pisteestä, jolloin maajohtojen virrat ja niissä syntyvät jännitehäviöt eivät aiheuttaisi häiriöitä. Seuraavassa ”hässäkän” kytkentä:

Tuosta kytkentäkaaviosta on hyvä huomioida seuraavaa: 6 voltin muuntajan syöttöön tarvitaan kuitenkin 18V syöttöjännite? Tuon verkkomuuntajan arvot ovat ensiö 230V (käämit sarjaan kytkettynä) ja toiso 2 x 6V. Nämä ovat nimellisarvot, mitkä toteutuvat nimelliskuormituksella. Tuo verkkomuuntaja on tarkoitettu käytettäväksi päinvastaiseen suuntaan. Kun sen ensiöön kytketään 230 V, on toisiossa kuormittamattomana 2 x 7 V. Eli muuntosuhde nyt käytettyyn suuntaan ei ole tuo 230/6. Lisäksi muuntajan ensiöön (siis tässä käytössä) pitää tulla jännite 9,87 V, eli sinijännitteen huippuarvo. Lisäksi muuntajan häviöt ovat nyt tähän suuntaan. Seuraavaksi kuristimen (tässä 3,1 mH, mikä ei ole optimoitu tähän käyttöön) yli pitää olla jännitettä myös siniaallon huipun kohdalla. Lisäksi pulssimodulaation kutsussa vähennetään (Fun_Pulssit(Int_Kesto - 50);) maksimista ”jotain, tässä tapauksessa 50 us. Tällöin induktanssin jälkeinen huippujännite jään alle maksimin. Tällä vähennyksellä voidaan säätää jännitettä kuormituksen tarpeen mukaan. Tätä säätöä ei ole toteutettu tässä esityksessä. Tietysti myös kytkintransistorin BDX34C yli jää myös pieni jännite, vaikka se ohjataankin täysin johtavaan tilaan.
   Transistorin kollektorilla oleva diodi (NFC25G) on välttämätön, sillä tuon kytkintransistorin siirtyessä johtamattomaan tilaan, on induktanssissa edelleen olemassa magneettivuo, mikä purkautuessaan synnyttää virran, millä täytyy olla purkaustie kondensaattoriin ja muuntajaan.
   Tässä käyttämäni puolijohteet eivät tietenkään ole ainoita mahdollisia, vaan sellaisia, mitä sattui olemaan. Toiminta ja komponenttien jännite- ja tehon kestot ovat oleellisia. Ongelmana minulla onkin, että lajitelmani alkaa olla niin iäkästä, että datan löytyminen netistä on toisinaan mahdotonta.

Toteutuksessa pääohjelman osuus on varsin vaatimaton. Siinä ainoastaan kutsutaan aliohjelmaa, missä muodostetaan siniaallon puolikkaita ja varmennetaan niiden välissä nollajännite. Sen jälkeen vaihdetaan muuntajan ohjaustransistoreiden tila.
Neljän kanavan optoerotin.
   Aliohjemassa on kolme (3) osaa: 1. Lasketaan ja ohjataan nousevan siniaallon arvo ja vastaava pulssin leveys yhdeksän (9) asteen välein. Koska Sini-funktio (Arduinon C-kielessä) käyttää radiaaneja, on asteiden ja radiaanin suhde laskettu valmiiksi ( 0.01744). 2. Saadulla sinin arvolla kerrotaan perusviive ja saadaan kullekin kulmalle kytkintransistorin (2N3904 ja BDX34C) johtavuusaika (ON). 3. Perusviiveestä vähentämällä johtavuusaika, saadaan taukoaika (OFF). Tämän muuttuvan suhteen ansiosta jännite muuntajan syötössä kasvaa siniaallon mukaan.
Tehot pieniä, mutta tukeva kiinnitys.
   Seuraavaksi muodostetaan laskevan siniaallon (eli kokoaallon neljännes) päinvastaisessa järjestyksessä. Periaate on kuitenkin sama. Lopuksi ohjataan nollaustransistori (IRFZ44N) johtavaksi, eli oikosulkuun, jotta päätetransistorien vaihdon aikana muuntajan syöttöpisteen jännite on varmasti nolla (0) volttia.
   Miksi sitten ei käytetä Arduinon tarjoamaa analogialähtöä (PWM), mikä on myös pulssinleveysmoduloitu, johtuu siitä että sen taajuus on 1 ms, jolloin 50 Hz taajuudella neljännesaallolle tulisi ainoastaan viisi (5) porrasta. Tämä on liian karkea ohjaus. Mitä korkeampi ohjauksen kytkintaajuus on, sitä paremmin ohjaus noudattaa siniaallon muotoa.

OHJELMA 49
/*******************************
* Ohjelma SiniInvertteri_49
* 07.11.2017
* Muodostetaan 230V:in 50H:n siniaaltoa
*/

// Määrittelyt
    const int Con_Pulssit = 6;
    const int Con_Nollaus = 5;
    const int Con_VasenTr = 8;
    const int Con_OikeaTr = 9;
    boolean Bol_Vaihto = false;
    int Int_Kesto = 380; // Määrittää puolijakson keston
    int Int_MaxArvo = Int_Kesto;

// Siniaallon puolikkaan aliohjelma
void Fun_Pulssit(int maksimi){
    int Viive = maksimi;
    int kulma = 9;
    float radian = 0.0;
    double sini = 0.0;
    int ONviive = 0;
    int OFFviive = 0;

// Kasvava looppi
    for(int i = 0; i < 91; i = i + kulma){
        radian = 0.01744 * i;
        sini = sin(radian);
        ONviive = sini * Viive;
        OFFviive = 380 - ONviive; //Int_Kesto - ONviive;

    // Kasvava sinineljännes
        bitSet(PORTD,Con_Pulssit);
        delayMicroseconds(ONviive);
        bitClear(PORTD,Con_Pulssit);
       delayMicroseconds  (OFFviive);
    } // Kasvava neljännes loppu

// Laskeva sinineljännes
   for  (int i = 90; i > 0; i = i - kulma){
        radian = 0.01744 * i;
        sini = sin(radian);
        ONviive = sini * Viive;
        OFFviive = Int_Kesto - ONviive;

    // Laskeva sinineljännes
       bitSet  (PORTD,Con_Pulssit);
       delayMicroseconds  (ONviive);
       bitClear  (PORTD,Con_Pulssit);
       delayMicroseconds  (OFFviive);
    } // Laskeva neljännes loppu

// Puolijakson nollaus
   bitSet  (PORTD,Con_Nollaus);
   delayMicroseconds  (70);
   bitClear  (PORTD,Con_Nollaus);
   delayMicroseconds  (70);
} // Pulssien aliohjelma loppu

// Asetukset
    void setup() {
    pinMode(Con_Pulssit, OUTPUT);
    pinMode(Con_Nollaus, OUTPUT);
    pinMode(Con_VasenTr, OUTPUT);
    pinMode(Con_OikeaTr, OUTPUT);
    Serial.begin(9600);
}

//Pääohjelma
 void loop() {
    Fun_Pulssit(Int_Kesto - 50);// Vakiolla voi säätää jännitettä
    digitalWrite(Con_VasenTr, Bol_Vaihto);
    digitalWrite(Con_OikeaTr, !Bol_Vaihto);
    Bol_Vaihto = !Bol_Vaihto;
} // Pääohjelma loppu