Sulautetuissa järjestelmissä, olivatpa ne monimutkaisia taikka vähemmän monimutkaisia, on yleistä se, että mikrokontrollerin avulla säädetään jotain prosessia.
Tällä kertaa tulemme säätämään moottorin kierrosnopeutta PWM-ohjauksen ja potentiometrin avulla ja tämän osan perusteella jokainen halukas voikin jo rakentaa itselleen esimerkiksi säädettävän tuulettimen tai vaikkapa himmennettävän valon. Toki säätää voi mitä mieleen tulee, mutta edellä oli vain pari esimerkkiä.
Mikäli eksyit tälle sivulle Googlen tai jonkun muun linkin kautta, eikä PWM-ohjaus tai AD-muuntimen käyttö ole vielä tuttua, niin kannattaa lukea osat 15, 16 ja 17, sillä ne liittyvät oleellisesti läpi käytävään asiaan ja niissä on sovelluksen kannalta tärkeää teoriaa. Tämän vuoksi teoriaosuus on tässä osassa lyhkäinen, koska itsensä toistaminen on hieman puuduttavaa toimintaa ;).
Sovelluksen kytkennät
Koska haluamme ohjata moottoria potentiometrin avulla, tarvitsemme potentiometrin joka kytketään yhteen MSP430G2231 mikrokontrollerin analogia-tuloon. Käytetään tässä tapauksessa aiemmin tutuksi tullutta kytkentää, joka löytyy edellisestä osasta. Kytkentäkuva löytyy alta.
PWM-ohjauskytkentä on tässä tapauksessa sama kuin osassa 15, joten kytkennän kuva on alla.
Lopuksi vielä kuva koekytkentäalustasta sekä launchpadiin liitetyistä osista.
Moottorin akseliin on kiinnitetty pieni pala teippiä, jonka kuvan ottamisen jälkeen värjäsin tussilla siniseksi helpottamaan pyörimisnopeuden muutoksen havainnointia. Mutta ei tästä tämän enempää joten siirrytäänpä pidemmittä puheitta sovelluksen tekoon.
Esimerkki 1: Kierrosnopeuden säätö-ohjelma
Aluksi tehdään alustukset ja luodaan tarvittavat makrot sekä otetaan käyttöön tutut kirjastot (engl. header, .h).
#include <msp430g2231.h> // Ohjelman koko tavuina (byte) Flash/RAM = 450/2 // apumakroja käytetään helpottamaan koodin kirjoitusta #define INIT_LAUNCHPAD_LEDS (P1DIR |= BIT0+BIT6) #define INIT_PWM_OUTPUT (P1DIR |= BIT2) #define LED_OFF (P1OUT = 0) #define LED_P_ON (P1OUT = BIT0) #define LED_V_ON (P1OUT = BIT6) void main(void) { unsigned int pwm_speed = 0; // moottorin pyörimisnopeus WDTCTL = WDTPW + WDTHOLD; // watchdog pysäytys INIT_LAUNCHPAD_LEDS; // Ledien alustus INIT_PWM_OUTPUT; // PWM-lähdön alustus P1SEL |= BIT2; // porttipinnin tila timerin ohjaamaksi LED_OFF; // LED1 ja LED2 pois päältä // alustetaan CPU:n kello 1 Mhz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; // kiteen alustus BCSCTL3 = XCAP_3; // asetetaan P1.1 analog 1 -kanavaksi ADC10AE0 = BIT1; // Asetetaan kanava 1, valitaan kellosignaaliksi MCLK (1 Mhz) ja asetetaan yksi muunnos ADC10CTL1 = INCH_1 + ADC10SSEL_2 + CONSEQ_0; // Timerin asetus: CCTL0 = OUTMOD_4; // asetetaan moodi toggle CCTL1 = OUTMOD_7; // asetetaan moodi Reset/Set, huomaa että rekisteri on CCTL1 TACTL |= ID_0 + TASSEL_1; // asetetaan jakaja 0, laskentamoodi vertaileva ja ACLK-kello. CCR0 = 327; // ladataan 100 hertsin arvo CCR1 = pwm_speed; // ladataan pulssisuhteen arvo, aluksi 0 ettei moottori pyöri TACTL |= MC_1; // käynnistetään timer while(1) { // Oletuksena referenssijännitteet ovat Vcc (1) ja Vss (14) // Asetetaan näytteistysaika 64 kellojaksoa ja laitetaan ydin ja muunnos päälle ADC10CTL0 = ENC + ADC10SC + ADC10SHT_3 + ADC10ON; while( ! (ADC10CTL0 & ADC10IFG)); // odotetaan että muunnos valmis ADC10CTL0 &= ~ADC10IFG; // nollataan lippu // lukua täytyy skaalata, jotta voidaan käyttää koko jännitealuetta pwm_speed = ADC10MEM / 3.12; CCR1 = pwm_speed; // nopeuden päivitys if(pwm_speed > 163) { LED_P_ON; // asetetaan yli 50% tehon huomiovalo } else { LED_V_ON; // asetetaan alle 50% tehon huomiovalo } } }
Ohjelman kulku
Kun ohjelma käynnistyy, mikrokontrolleri alustaa portit, ledit, timerin ja AD-muuntimen kuten koodissa on kommentoitu. Ohjelman pääsilmukassa otetaan koko ajan muunnostietoja talteen mikrokontrollerin AD-muuntimelta ja saatua lukua skaalataan, jotta moottorin nopeuden säätö tapahtuu maltillisemmin. Punainen LED sytytetään silloin, kun PWM-pulssisuhde ylittää 50 %:a (noin puolet 327:stä) ja vastaavasti vihreä LED silloin kun pulssisuhde on alle edellä mainitun.
AD-muuntimelta saatua muunnoslukua myös skaalataan, kuten varmaan huomasitkin. Seuraavassa selitän miksi ja miten luku on saatu.
Jos AD-muuntimelta saatua lukua ei skaalattaisi, niin hyvin pieni muutos potentiometrillä vastaisi kovin äkillistä muutosta moottorin kierrosluvussa ja säätäminen olisi hankalaa.
Mikrokontrollerin ohjaaman PWM-pulssin leveys, eli pulssisuhde määräytyy CCR1 rekisterin mukaan. Jos arvo on yli tai yhtä suuri kuin 327, niin pulssisuhde on 100%. Koska AD-muuntimelta otetaan arvoja, jotka voivat olla väliltä 0 - 1023, niin ilman skaalausta jo 1,15 voltin jännite AD-muuntimen tulossa aiheuttaisi sen, että moottori pyörisi täysillä (327 vastaa tässä tapauksessa 1,15 voltin jännitettä, kun referenssinä on 3,6 volttia. Katso AD-muunnin jos menee yli hilseen).
Koska haluamme, että moottori pyörii täydellä teholla vasta kun potentiometrikin on ns. "täysillä", niin AD-muuntimen arvoa täytyy skaalata. Skaalausarvo saadaan kun AD-muuntimen täyden skaalan arvo (engl. Full-Scale) eli 1023 jaetaan PWM-pulssisuhteen 100 %:n täydellä arvolla eli 327:llä. Näin ollen tulokseksi saadaan:
1023/327 = 3,128440367 --> 3,12
Jos et heti ymmärtänyt selitystä, niin älä huoli. Ajan kanssa teksti käy varmasti selkeämmäksi ja saat punaisesta langasta kiinni. Kopioi siis koodi rauhassa CCS:n editoriin ja kokeile vaikkapa muuttaa skaalaus-arvoa joksikin toiseksi ja tutki kuinka moottorin kierrosluku muuttuu nyt.
Alla vielä lyhyt esittelyvideo kytkennän ja ohjelman toiminnasta:
Seuraavassa osassa perehdytään siihen, miten tietokone ja Launchpad saadaan kommunikoimaan keskenään. Asia voi kuulostaa vaikealta, mutta jos olet päässyt jo näin pitkälle, niin uskoisin senkin asian onnistuvan - ei se nyt niin vaikeaa ole 😉