Avtor: mag. Vladimir Mitrović
E-pošta: vmitrovic12@gmail.com
2017_255_56
V spletnih trgovinah boste z lahkoto našli veliko “Arduino kompatibilnih” modulov z različnimi nameni, velikokrat po nerazumljivo nizkih cenah. Že davno sem se prenehal jeziti na to “bližnjevzhodno konkurenco” s katero mi, v cenovnem smislu, ne moremo držati koraka in se odločil na najboljši način izkoristiti to, kar se ponuja – če se že ponuja.
Na sliki 1 je fotografija nekaterih takšnih modulov. Včasih gre samo za stikala ali nekakšen senzor, katerega priključki so pripeljani na priključne konektorje na tiskani ploščici. Včasih pa se na modulih nahajajo sofisticirana integrirana vezja za specifične namene, s katerimi je potrebno znati komunicirati. Čeprav imajo vsi zelo različne namene, jim je skupna ena stvar in naj jo poudarimo takoj: “Arduino kompatibilen modul” je samo marketinški trik, ki bo uporabnika Arduino platforme pritegnila, da ga pogleda in seveda kupi nekatere od ponujenih modulov. Seveda so te moduli uporabni tudi na vseh naših platformah, od najmanjše MikroPin do največje MegaPin plošče, ker tako Arduino kot Pini uporabljajo mikrokontrolerje iz AVR družine.
Prednost, ki jo imajo uporabniki Arduino platforme je, da je nekje na spletu možno najti navodilo ali shemo, kako povezati modul z Arduino ploščo in kar je še važneje, najti primer programa ali vsaj knjižnico, ki bo tudi manj veščim programerjem pokazala, kako se uporablja modul. Namen te serije člankov je pokazati, kako “Arduino kompatibilen” modul povezati z enim od naših Pinov in ga oživeti iz Bascom-AVR programskega orodja, s katerim jih najpogosteje povezujemo.
Uporabljali bomo dva mikrokontrolerja: ATtiny4313 in ATmega328P. ATtiny4313 je izbran kot primer “malega” AVR mikrokontrolerja, ki ga lahko popolnoma izkoristimo z Bascom-AVR Demo verzijo programa. Vsi primeri bodo predpostavljali, da se Attiny4313 nahaja v MiniPin, čeprav ga je mogoče na isti način uporabiti tudi na MegaPin-u ali z malo spretnosti tudi v MikroPin-u. ATmega328P je izbran kot primer tipičnega Arduino mikrokontrolerja s čemer bi pokazali, kaj lahko iz njega izvlečemo s pomočjo Bascom-AVR okolja. Vsi primeri bodo predpostavili, da se ATmega328P nahaja v razvojni plošči MegaPin, čeprav ga je možno na isti način uporabiti v MiniPin II plošči.
Izbrani mikrokontroler se lahko zamenja s pin in funkcionalno kompatibilnimi “mlajšimi brati” (ATtiny2313, ATmega8, Atmega48) ali z večjimi Mega v 40-pin ohišju pri čemer je potrebno upoštevati specifike posameznega uporabljenega mikrokontrolerja. V primerih je uporabljen demo Bascom-AVR, verzija 2.0.7.5.003. Predpostavljam, da bodo enako dobro delali tudi na novejših verzijah bodisi demo ali licenčne verzije Bascom-AVR programa.
Kot programator je uporabljen Proggy II (v Bascom-AVR je potrebno izbrati STK500 native driver, clock 125000, COM port je odvisen od USB priključka, ki ga uporabljate). Ko že iščemo povezavo med Bascom-AVR in Arduinom sem preizkusil kako deluje programiranje preko USB kabla na MegaPin plošči. In dela izjemno dobro! Predpostavljamo, da imate ATmega328P z Arduino bootloaderjem. Odvisno od verzije bootloaderja v Bascomu izberite ARDUINO ali ARDUINO STK500V2 programator, 115200 Baud. COM port pa odvisno od USB priključka, ki ga uporabljate. Ob mikrokontrolerju verjetno ne boste dobili informacije, katera verzija bootloaderja je vpisana zato je potrebno preizkusiti obe možnosti. Uporabljata se na identični način, ena funkcionalna razlika je v tem, da novejša STK500V2 verzija omogoča tudi programiranje fuse bitov (pazite!), medtem ko starejša tega ne omogoča. Ne pozabite na ploščico vstaviti kvarc, ker so fuse biti mikrokontrolerja z Arduino bootloaderjem programirani za uporabljanje zunanjega oscilatorja! Meni je programiranje dobro delalo s kvarci v razponu frekvenc od 4 do 20 MHz.
Opomba: v Bascom-AVR help se priporočajo nižje hitrosti pri uporabi starejše verzije Arduino bootloaderja, 57600 ali 19200 Baud. Medtem ko mikrokontrolerjem, ki sem jih imel na razpolagi te hitrosti niso ustrezale; programiranje je bilo uspešno šele, ko sem izbral 115200 Baud. V primeru ko Bascom-AVR ne prepozna mikrokontrolerja preverite COM port, na katerem PC “vidi” MegaPin ploščo oziroma poizkusite zamenjati hitrost komunikacije.
In zdaj, ko smo pojasnili vse predpostavke, smo se s pomočjo Bascoma pripravljeni potopiti v Arduino svet!
Primer: ZS-042 modul
Naš prvi primer bo modul, ki se prodaja pod oznako ZS-042. Slika 2 prikazuje fotografijo toga modula, slika 3 njegovu malo poenostavljeno shemo.
ZS-042 vsebuje dve integrirani vezji: DS3231 in AT24C32. DS3231 je ura realnega časa (RTC) z integriranim natančnim oscilatorjem, AT24C32 pa je serijski EEPROM kapacitete 4 kB. Ker uporabljata isti komunikacijski protokol I2C ne obstaja neka funkcionalna povezanost teh čipov in je nejasno zakaj ju je projektant postavil na isto ploščico. Če pa sta že tukaj pokažimo, kako izkoristiti oba.
Najprej se bomo posvetili bolj kompleksnemu, DS3231. Njegov temperaturno kompenziran oscilator poganja uro z 12- ali 24-urnim prikazom, firmware vzdržuje koledar tako, da upošteva število dni v mesecu in o prestopnih letih. Vgrajena sta dva medsebojno neodvisna alarma in temperaturni senzor. V temperaturnem razponu med 0 in 40°C je točnost znotraj ±2 ppm. Učinek staranja oscilatorja je možno softversko kompenzirati. Znotraj DS3231 se nahaja 19 8-bitnih registrov. V njih so vpisani časovni in datumski podatki, podatki o alarmu in izmerjena temperatura, medtem ko so trije registri kontrolni. Njihovo vsebino določa način dela RTC-ja, prikazuje status posameznih delov in omogoča korekcijo frekvence oscilatorja. Vsi časovni in datumski podatki so vpisani v BCD formatu (2 številki po registru). V nekaterih registrih (ure, mesec, vsi alarmni registri) so posamezni biti izkoriščeni kot konfiguracijski, kar do neke mere otežuje interpretacijo njihove vsebine. Če se odločimo za 24-urni prikaz časa in se zadržimo na datumski prikaz znotraj 21. stoletja bodo vsi kontrolni biti znotraj časovnih in datumskih registrov postavljeni na nič in ne bodo “motili” pri interpretaciji vsebine teh registrov.
Na slikah 2 in 3 se vidi, da ima ZS-042 modul 6 priključkov, in vseh 6 je povezano z integriranim vezjem DS3231: Vcc in GND so napajanje (2,3 – 5,5 V), SCL in SDA tvorita I2C vodilo, 32k je open drain izhod pravokotnega signala frekvence 32 kHz, medtem ko je izhod SQW večnamenski – možno ga je softversko nastaviti tako, da signalizira alarm ali pač da se na njemu pojavlja pravokotni signal izbrane frekvence.
Poraba RTC-ja je manjša od 150 µA razen med temperaturno konverzijo, ko naraste na maksimalno 650 µA. Da bi uro in koledar lahko nadaljevala delo med izpadom glavnega napajanja DS3231 zahteva rezervni vir napetosti Vbat. Poraba iz rezervnega izvora je izredno majhna, tipično okoli 1 µA, in je kot rezervni izvor prikladno uporabiti litijevo baterijo tipa 2032. Prav za takšno baterijo je predvideno podnožje na ZS-042 modulu (na sliki 2 se ne vidi, ker se podnožje baterije nahaja na zadnji strani ploščice).
Tukaj moramo biti pazljivi! Litijeve baterije tipa 2032 se proizvajajo kot standardna nepolnilna baterija (najpogostejša oznaka CR2032) in kot polnilna, akumulatorska baterija (LIR2032). Projektant je predvidel, da se v podnožje ZS-042 modula vstavi akumulatorska baterija LIR2032. Vezje za polnjenje sestavljajo upor R1 in dioda D1. Ko uporabljamo 5V napajalno napetost takšno vezje zagotavlja zanesljivo polnjenje akumulatorja z zaščito pred prenapolnjenostjo.
Kljub temu priporočam, da se kot rezervno napajanje ZS-042 modula uporabi nepolnilna litijeva baterija CR2032, ker je opazno cenejša, njena kapaciteta 220 mAh pa bo zadostovala za 10-20 let neprekinjenega napajanja! Za takšno baterijo pa je nujno narediti modifikacijo na ploščici modula, tam je potrebno odstraniti upor R1 in diodo D1. Položaj teh elementov je na sliki 2 spodaj označen s puščicama. Ker gre za SMD komponenti je potrebno biti pazljiv med odstranjevanjem. To najlažje naredimo tako, da uporabimo dva spajkalnika manjše moči (okoli 20W): sočasno se dotaknemo oba konca elementa in ga enostavno dvignemo ali odstranimo s ploščice. Alternativno se lahko prereže vezica med R1 in D1 označeno z znakom X.
Razen baterije lahko rezervno napajanje zagotovimo s kondenzatorjem velike kapacitete (0,1F ali več), medtem ko R1 in D1 ostaneta na svojih mestih. Takšni kondenzatorji se prodajajo pod komercialnimi imeni “gold-cap” ali “super-cap” in podobno. Za naš primer morajo imeti delovno napetost 5,5V. Kondenzator je potrebno zaspajkati (in pri tem paziti na polariteto) na priključke baterijskega podnožja. Kondenzator 0,1F zagotavlja rezervno napajanje v trajanju približno enega dne.
Zdaj, ko smo se spoznali z lastnostmi integriranega vezja DS3231 in modulom v katerem je vgrajen je čas, da pokažemo, kako ga uporabiti v Bascom-AVR programu. Da bi programiranje bilo lažje in enostavnejše, sem napisal vrsto podprogramov, ki sem jih namestil v knjižnico DS3231$SE.sub.
Knjižnica DS3231$SE.sub
Knjižnica vsebuje nekaj globalnih spremenljivk in rutine (podprograme) za pošiljanje ukazov in izmenjavo podatkov z integriranim vezjem DS2331 (te rutine imajo prefiks DS3231$), kot tudi rutine, ki olajšujejo delo s podatki zapisanimi v BCD formatu, v katerem jih uporablja to integrirano vezje (te rutine nimajo prefiksa).
Globalne spremenljivke, ki so z vključenjem DS3231$SE.sub knjižnice postale sestavni del vašega programa, so dimenzionirane takole:
Dim Ds3231$sec As Byte Ds3231$sec vsebuje kopijo RTC registra 00h (sekunde v BCD formatu, 00h-59h). Dim Ds3231$min As Byte Dim Ds3231$hour As Byte Dim Ds3231$time As Word At Ds3231$min Overlay
Ds3231$min vsebuje kopijo RTC registra 01h (minute v BCD formatu, 00h-59h). Ds3231$hour vsebuje kopijo RTC registra 02h (ure v BCD formatu, 00h-23h ili 01h-12h plus AM/PM indikator, odvisno od konfiguracije RTCa). Oba podatka se lahko sočasno dobita preko word spremenljivke Ds3231$time.
Dim Ds3231$day As Byte Ds3y231$day vsebuje kopijo RTC registra 03h (dan v tednu, 3-bitna binarna številka, 1-7). Dim Ds3231$dte As Byte Dim Ds3231$mth As Byte Dim Ds3231$date As Word At Ds3231$dte Overlay
Ds3231$dte vsebuje kopijo RTC registra 04h (dan v mesecu v BCD formatu, 01h-31h). Ds3231$mth vsebuje kopijo RTC registra 05h (mesecu v BCD formatu, 01h-12h plus indikator spremembe stoletja). Oba podatka se lahko sočasno dobita preko word spremenljivke Ds3231$date.
Dim Ds3231$yr As Byte Ds3231$yr vsebuje kopijo RTC registra 06h (leto v BCD formatu, 00h-99h). Dim Ds3231$stat As Byte Ds3231$stat vsebuje kopijo RTC registra 0Fh (Control/Status register).
Te spremenljivke služijo podprogramom iz knjižnice pri izmenjavi podatkov z RTC-jem, lahko pa se uporabljajo tudi iz uporabniškega programa. V principu vsi podprogrami, katerih ime je kot Ds3231$read… prenašajo vsebino enega ali več RTC registrov v pridružene spremenljivke podprogramov, vsi podprogrami, katerih ime je kot Ds3231$write… pa prenašajo vsebino ene ali več spremenljivk v pridružene RTC registre. Vse rutine iz knjižnice so iz programa vidne kot “običajni” Bascom-AVR ukazi. Sledi njihov opis v zavihku “Ukazi”.
U naslednjem nadaljevanju bomo pokazali, kako ukaze iz knjižnice DS3231$SE.sub uporabljati iz Bascom-AVR programa.
Opomba: DS3231$SE.sub knjižnico lahko brezplačno snamete v uredništvu revije Svet elektronike.
www.svet-el.si
Ukaz DS3231$write_reg
DS3231$write_reg par1, par2
Parametri: | par1 | konstanta ali ime byte spremenljivke, ki vsebuje naslov DS3231 registra (0-12h) v katerega bo podatek bil zapisan |
---|---|---|
par2 | konstanta ali ime byte spremenljivke, ki vsebuje podatek ki ga je potrebno vpisati | |
Namen: | Vpisuje podatek par2 v register na naslovu par1. |
Ukaz DS3231$read_reg
DS3231$read_reg par1, par2
Parametri: | par1 | konstanta ali ime byte spremenljivke, ki vsebuje naslov DS3231 registra (0-12h) katerega vsebino je potrebno pridobiti |
---|---|---|
par2 | ime byte spremenljivke, v katero se bo vpisala vsebina iz prebranega registra | |
Namen: | Prenosi vsebino naslovljenega registra v byte spremenljivko par2. |
Ta dva ukaza bi bila dovolj za konfiguracijo integriranega vezja DS3231, vpis začetnih podatkov v njegove registre in zajem trenutnega časa, datuma, temperature in statusnih registrov. Na kratko, za vso potrebno izmenjavo podatkov.
Da bi olajšal programiranje sem dodal še nekaj ukazov za branje in pisanje posameznih registrov ali skupine registrov.
Ukaz DS3231$read
DS3231$read
Parametri: | nima |
---|---|
Namen: | Prenaša vsebino registra na naslovih 00h-06h v globalne byte spremenljivke, ki so definirane na nivoju knjižnice:
Ds3231$sec (sekunde) Ds3231$min (minute) Ds3231$hour (ure) Ds3231$day (dan v tednu) Ds3231$dte (dan v mesecu) Ds3231$mth (mesec) Ds3231$yr (leto – zadnji dve številki) |
Ukaz DS3231$write_hour
DS3231$write_hour
Parametri: | nima |
---|---|
Namen: | Prenaša vsebino globalne spremenljivke Ds3231$hour (ure) v register na naslovu 02h in istočasno definira 24-urni format časa. |
Ukaz DS3231$write_min
DS3231$write_min
Parametri: | nima |
---|---|
Namen: | Prenaša vsebino globalne spremenljivke Ds3231$min (minute) v register na naslovu 01h. |
Ukaz DS3231$write_time
DS3231$write_time
Parametri: | nima |
---|---|
Namen: | Prenaša vsebino globalnih spremenljivk Ds3231$sec (sekunde), Ds3231$min (minute) in Ds3231$hour (ure) v registre na naslovih 00h-02h in sočasno definira 24-urni format časa. |
Ukaz DS3231$write_date
DS3231$write_date
Parametri: | nima |
---|---|
Namen: | Prenaša vsebino globalnih spremenljivk Ds3231$day (dan v tednu), Ds3231$dte (dan v mesecu), Ds3231$mth (mesec) in Ds3231$yr (leto – zadnji dve številki) v registre na naslovih 03h-06h in sočasno briše oznako spremembe stoletja. |
Ukaz DS3231$write_alarm1
DS3231$write_alarm1 par1, par2, par3, par4
Parametri: | par1 | konstanta ali ime byte spremenljivke, ki vsebuje podatek ki ga je treba vpisati v 1. register 1. alarma (07h) |
---|---|---|
par2 | konstanta ali ime byte spremenljivke, ki vsebuje podatek, ki ga je treba vpisati v 2. register 1. alarma (08h) | |
par3 | konstanta ali ime byte spremenljivke, ki vsebuje podatek, ki ga je treba vpisati v 3. register 1. alarma (09h) | |
par4 | konstanta ali ime byte spremenljivke, ki vsebuje podatek, ki ga je treba vpisati v 4. register 1. alarma (0Ah) | |
Namen: | Prenaša definirane byte podatke v registre alarma 1; podatki morajo biti ustrezno oblikovani (poglejte data-sheet DS3231). |
Ukaz DS3231$write_alarm2
DS3231$write_alarm2 par1, par2, par3
Parametri: | par1 | konstanta ali ime byte spremenljivke, ki vsebuje podatek ki ga je treba vpisati v 1. register 2. alarma (0Bh) |
---|---|---|
par2 | konstanta ali ime byte spremenljivke, ki vsebuje podatek ki ga je treba vpisati v 2. register 2. alarma (0Ch) | |
par3 | konstanta ali ime byte spremenljivke, ki vsebuje podatek ki ga je treba vpisati v 3. register 2. alarma (0Dh) | |
Namen: | Prenaša definirane byte podatke v registre alarma 2; podatki morajo biti ustrezno oblikovani (poglejte data-sheet DS3231). |
Ukaz DS3231$write_control
DS3231$write_control par1
Parametri: | par1 | konstanta ali ime byte spremenljivke ki vsebuje podatek ki ga je treba vpisati v kontrolni register (0Eh) |
---|---|---|
Namen: | Vpisuje podatek par1 v kontrolni register; podatek mora biti ustrezno oblikovan (poglejte data-sheet DS3231). |
Ukaz DS3231$write_status
DS3231$write_status
Parametri: | nima |
---|---|
Namen: |
Vpisuje vsebino globalne byte spremenljivke Ds3231$stat v statusni register (0Fh); podatek mora biti ustrezno oblikovan (poglejte data-sheet DS3231). |
Ukaz DS3231$read_status
DS3231$read_status
Parametri: | nima |
---|---|
Namen: | Prenaša vsebino statusnega registra (0Fh) v globalno byte spremenljivko Ds3231$stat. |
Ukaz DS3231$read_temp
DS3231$read_temp par1
Parametri: | par1 |
---|---|
Namen: | Prenaša vsebino temperaturnih registrov (11h-12h) v word spremenljivko par1 (za pravilno interpretacijo podatkov poglejte data-sheet DS3231). |
Ostali podprogrami iz knjižnice ne komunicirajo z integriranim vezjem DS3231, ampak olajšujejo delo s podatki zapisanimi v BCD formatu, ki jih to integrirano vezje uporablja. Sledi njihov opis.
Ukaz Incr_bcd
Incr_bcd par1
Parametri: | par1 | ime byte spremenljivke, ki vsebuje številko zapisano v BCD formatu |
---|---|---|
Namen: | Povečuje dvoštevilčno BCD številko za 1; 99 preskoči na 00. |
Ukaz Lcd_hh_mm
Lcd_hh_mm
Parametri: | nima |
---|---|
Namen: | Izpisuje na LCD displeju vsebino globalnih spremenljivk Ds3231$hour in Ds3231$min v formatu “HH:MM”, začenši od trenutne pozicije. Ukaz uporablja 24-urni format. |
Ukaz Lcd_hh_mm_ss
Lcd_hh_mm_ss
Parametri: | nima |
---|---|
Namen: | Izpisuje na LCD displeju vsebino globalnih spremenljivk Ds3231$hour, Ds3231$min in Ds3231$sec v formatu “HH:MM:SS”, začenši od trenutne pozicije. Ukaz uporablja 24-urni format. |
Ukaz Lcd_dd_mm_yy
Lcd_dd_mm_yy
Parametri: | nima |
---|---|
Namen: | Izpisuje na LCD displeju vsebino globalnih spremenljivk Ds3231$dte, Ds3231$mth in Ds3231$yr v formatu ” DD.MM.YY.”, začenši od trenutne pozicije. |
Ukaz Lcd_dd_mm_20yy
Lcd_dd_mm_20yy
Parametri: | nima |
---|---|
Namen: | Izpisuje na LCD displeju vsebino globalnih spremenljivk Ds3231$dte, Ds3231$mth in Ds3231$yr v formatu ” DD.MM.20YY.”, začenši od trenutne pozicije. |
Ukaz Lcd_dan_slo
Lcd_dan_slo
Parametri: | nima |
---|---|
Namen: | Konvertira številčno vrednost spremenljivke Ds3231$day (1-7) v tričrkovno kratico imena dne v tednu v slovenskem jeziku (“PON”, “TOR”, “SRE”, “CET”, “PET”, “SOB”, “NED”) in jo izpisuje na LCD displeju, začenši od trenutne pozicije. Ukaz upošteva, da je ponedeljek prvi dan v tednu. |
Ukaz Lcd_dan_hr
Lcd_dan_hr
Parametri: | nima |
---|---|
Namen: | Konvertira številčno vrednost spremenljivke Ds3231$day (1-7) v tričrkovno kratice imena dne v tednu v hrvaškem jeziku (“PON”, “UTO”, “SRE”, “CET”, “PET”, “SUB”, “NED”) in jo izpisuje na LCD displeju, začenši od trenutne pozicije. Ukaz upošteva, da je ponedeljek prvi dan v tednu. |
Ukaz Lcd_day
Lcd_day
Parametri: | nima |
---|---|
Namen: | Konvertira številčno vrednost spremenljivke Ds3231$day (1-7) v tričrkovno kratico imena dne v tednu v angleškem jeziku (“MON”, “TUE”, “WED”, “THU”, “FRI”, “SAT”, “SUN”) in jo izpisuje na LCD displeju, začenši od trenutne pozicije. Ukaz upošteva, da je ponedeljek prvi dan v tednu. |
Mitrovic_Barduino1