GPS ja Arduino

[size=150]Alkusanat[/size]

Tässä artikkelissa tutustutaan Arduino-kehitysympäristön alkeisiin,
ja yhteen elektroniikan peruskytkennöistä, jännitteenjakajaan.

Aikaisempi kokemus arduinosta tai ohjelmoinnista ei ole tarpeen, artikkeli on suunnattu aloittelijoille, vaikkakin koodi aukeaa lukijalle hieman helpommin jos jo jotain osaa.
Internetistä löytyy runsaasti elektroniikan perusteiden oppaita, joten tämä artikkeli ei niihin sen kummemmin keskity.

Artikkelin päämääränä on auttaa lukijaa ymmärtämään arduinon perustoimintaa pienen
esimerkkiprojektin avulla, joka on GPS-moduulin kytkentä arduinoon,
moduulin lähettämän datan käsittely ja tulostaminen tietokoneelle sarjaliikennettä hyväksi käyttäen.

Artikkeli on toteutettu allekirjoittaneen ulottuvilla olleiden välineiden ja
komponenttien ympärille, mutta on helposti sovellettavissa ja laajennettavissa
erilaisille kokoonpanoille. Käytetty Arduino IDE versio on 0022.

[size=150]Kytkentä[/size]

Tarvitset seuraavat komponentit:

-Arduino Uno (tai jokin muu arduino kehitysalusta) + Usb-kaapeli
-Fastrax UP501 GPS moduuli (Tai muu sarjaliikennettä tukeva GPS moduuli)
-8.2k ja 10k vastukset (esim. metallikalvovastus)
-Hyppylankoja + Koekytkentälevy
-(Kolvi jos haluat jottaa johdot kiinni GPS-moduuliin)

Arduino IDE sekä useita eri Arduino-kehitysalustoja esitellään ruuvipenkissä jo aiemmin julkaistussa artikkelissa
ruuvipenkki.fi/2010/08/12/ar … sittelyssa jonka on kirjoittanut Lauri Jämsä.
Ennen jatkamista on suuresti suositeltavaa tutustua tuohon artikkeliin.

Aloitetaan ensin raudan kokoonpanosta, eli GPS-moduulin kytkemisestä arduinoon.

Suositeltavaa on juottaa johdot kiinni GPS-moduuliin helpon kytkennän vuoksi, vaikkapa tähän malliin:

27022011144.jpg

Arduino itse toimii 5V jännitteellä jonka se saa USB-väylää pitkin, mutta GPS vaatii (datalehden mukaan) 3.0-4.2V jännitteen toimiakseen.
Onneksemme arduino Uno-kehitysalustalla on oma regulaattorinsa joka antaa ulos 3.3V, 50mA maksimivirralla, joka riittää meille.

Arduinosta l√∂ytyv√§ pinni ‚Äú3.3v‚ÄĚ (eli 3.3v j√§nnite) kytket√§√§n GPS:n pinneihin 4 ja 5 (Pinni 5 on oikeastaan paikka patterille,
joka pitää GPS:n sisäisen kellon ja asetukset vakioina vaikka käyttöjännite katkeaakin,
mutta laite vaatii jännitteen tähän pinniin toimiakseen)

Pinni 3 on GND, maa. Tämä kytketään arduinon GND pinniin

Sitten pääsemmekin Sarjaliikenneliitäntöihin, joita kutsutaan nimillä Tx (Transimit, Lähetys) ja Rx (Recieve, Vastaanotto)

UP501-GPS moduuli juttelee arduinon kanssa sarjaliikennettä käyttäen.
Kyseisen laitteen datalehdestä voidaan havaita, että sarjaliikenteen
jännitetasot ovat CMOS 2.8-yhteensopivia
(eli Tx ja Rx pinnit lähettävät ja vastaanottavat dataa n.2.8V jännitteellä).
Arduinon digitaalipinnit toimivat TTL-jännitetasoilla (0-5V), mutta ne näkevät jo 2V jännitteen loogisena ykkösenä.
Eli kun GPS lähettää dataa arduinolle käyttäen 2.8v signaalia, havaitsee arduino viestit ongelmitta.
Ongelma ilmenee vasta siinä vaiheessa kun haluamme lähettää arduinolta
dataa GPS-moduulille (vaikka sitä emme tässä artikkelissa vielä oikeastaan edes tee! Lue teksti lopusta!).
Arduinon lähettäessä viestejä 5V jännitteellä, ei herkkä laite välttämättä sitä kestä.

Jännitettä on siis laskettava GPS-moduulin suosimalle tasolle joka on datalehden mukaan 2.0-3.6v (Rx pinnin kestämä jännite siis)
Tähän otamme avuksi jännitteenjakajan:

27022011143.jpg
Kuvassa näkyy vasemmassa ylälaidassa kaksi vastusta - Nämä muodostavat jännitteenjakajan

Jännitteenjakokytkentä on vastuksilla tehty elektroniikan peruskytkentä, joka nimensä mukaan jakaa jännitettä:
Nyt tarkoituksenamme on saada Arduinon 5v jännite jaettua vastuksilla siten, että saamme
aikaiseksi n. 2.8v jännitteen, jottei GPS-moduuli hajoa dataa vastaanottaessaan.

(Itse jännitteenjaon teoriaa on tässä turha kertoa, sillä internetistä löytyy kaavoja
ja teoriaa ihan tarpeeksi niistä tarkemmin kiinnostuneille (vaikkakin luultavasti
kaikki jotka tätäkin lukevat, ymmärtänevät sen toiminnan))

Esim. Osoitteesta raltron.com/cust/tools/voltage_divider.asp löytyy
laskuri, jonka avulla voi laskea tarvittavien vastusten koot, jos tiedetään jännitteet
jotka halutaan saada aikaiseksi (tässä tapauksessa 5v -> 2.8v)

Laitetaan Vin (Voltage In, Jännite sisään) arvoksi arduinon antama 5v signaali, Vout (Voltage Out, Jännite ulos) arvoksi 2.8v.
Signaalin ja GND:n (kuvassa näkyvä alempi johdin) välissä olevan vastuksen arvon päätämme
olevan vaikkapa 10k ohmia.
Laitetaan R2 arvoksi 10k (10000). Nyt kun painamme nappia ‚Äúcompute‚ÄĚ laskee ohjelma meille
tarvitsemamme R1 arvon, joka näyttäisi olevan n.7900 ohmia.

Seuraavaksi katsomme lähimmän vastuksen joka on saatavilla tuohon vastusarvoon nähden,
ja kun tutkailemme E12-sarjan lukuja, huomaamme että hyvä valinta on 8200 ohmin vastus.
Tarkistamme vielä 8200 ohmin vastuksen aiheuttaman jännitteenjaon syöttämällä
arvot laskuriin: Vin: 5v, R1: 8200, R2: 10000, Vout: tyhjä

Jätä siis tällä kertaa Vout tyhjäksi, ja kun nyt painat compute-painiketta, huomaamme
että näillä vastuksilla saamme 2.747v jännitteen, joka siis menee vaaditun 2.0-3.6v jännitehaarukan väliin.

Kytkemme siis jännitteenjakajamme käyttäen 10k ja 8k2 vastuksia.

Kytkemme seuraavaksi GPS:n Rx:n (eli jännitteenjakajan Vin pinnin) ja Tx:n arduinon digitaalipinneihin 2 ja 3.
(Koska arduinon oma sisäänrakennettu sarjaportti tulee olemaan varattu tietokoneelle tulostettavan
datan vuoksi, joudumme muuttamaan arduinon kaksi digitaalista IO-pinniä
virtuaalisiksi sarjaporttiliitännöiksi. Tähän on onneksi helppo tapa, josta lisää edempänä.)

Kytkentä on siis seuraavanlainen:

kytkentä.png

[size=150]Softa[/size]

Nyt on vuorossa arduinon ohjelmointi. Päämääränämmehän on saada GPS:n ulostama data luettavaan muotoon PC:n ruudulle.
T√§h√§n v√§liin onkin kannattavaa tutustua siihen, miss√§ muodossa (miltei kaikki) gps moduulit tietoaan l√§hett√§v√§t, eli googlaa ‚ÄúNMEA‚ÄĚ ja tutustu kyseiseen protokollaan.
Tai suuntaa sivulle gpsinformation.org/dale/nmea.htm ja lue sieltä.
Myös UP501 käyttää NMEA-protokollaa.

Lainaus edellä linkitetyltä sivustolta:

‚ÄúEach sentence begins with a ‚Äė$‚Äô and ends with a carriage return/line feed sequence and can be no longer than 80 characters of visible text (plus the line t$
The data is contained within this single line with data items separated by commas. The data itself is just ascii text‚ÄĚ

Eli kun siis GPS sylkee ulos erilaista dataa, ne tulevat lause kerrallaan, jokainen lause alkaa dollarimerkillä ($),
päättyy rivinvaihtoon, ja ei voi olla yli 80 merkkiä (+rivinvaihtomerkki) pitkä.

Näistä tiedoista voimme päätellä arduino-ohjelmamme rakenteen, joka menee suurinpiirtein näin:

Kuuntele GPS-moduulia
-> Jos dataa löytyy, tulosta se
‚Äď> Jos l√∂ydetty data on $-merkki, tulosta rivinvaihto

Ja tätä toistetaan hamaan tulevaisuuteen asti. Täten saamme aikaiseksi tulosteen, joka on muotoa:

$DATAA,TULEE,T√ĄSS√Ą,N√ĄIN,KIVASTI

$JA,KUN,L√ĖYD√ĄMME,DOLLARIMERKIN,VAIHDAMME,RIVI√Ą,ELI

$AINA,KUN,UUSI,KOMENTO,ALKAA

… jne.

Nyt tyydymme vain näyttämään GPS:n tulosteen, ehkäpä seuraavassa artikkelissa siitä jo erotellaan GPS-koordinaatit
ja keksitään niille jotain mielenkiintoista käyttöä…

Tässä Arduino IDE:hen kirjoitettava koodi, kommentteineen.

[code]// Lue GPS-dataa käyttäen virtuaalista sarjaporttia, tulosta PC:n sarjaporttiin.
// Eero Holopainen - 25.02.2011

#include <NewSoftSerial.h> //Tämä kirjasto täytyy olla sisällytettynä koodiin jotta saadaan virtuaalisarjaportti mukaan kuvioihin
//kyseinen kirjasto on ladattavissa osoitteesta http://arduiniana.org/libraries/newsoftserial/ ja sen on tehnyt Mikal Hart

NewSoftSerial gps(2,3); //Luodaan arduinon digitaalipinneihin 2 ja 3 sarjaportti

void setup(void)
{
gps.begin(9600); //Virtuaalisarjaportin nopeudeksi 9600 (UP501:n datalehden mukaan)
Serial.begin(9600); //Tietokoneen sarjaportin nopeudeksi myös 9600
}

void loop(void)
{
char gps_byte = 0;

gps_byte = gps.read(); //Luetaan muuttujaan yksi kirjain
if (gps_byte != -1) //funktio gps.read() palauttaa arvon -1 jos se ei löydä mitään dataa,
{ //joten jos gps_byten arvo on jokin muu kuin -1, tulostetaan se tietokoneelle
if (gps_byte == ‚Äė$‚Äô) //ja jos l√∂ydet√§√§n dollarimerkki, tulostetaan ennen sit√§ rivinvaihto.
{
Serial.println("");
}
Serial.print(gps_byte);
}
}[/code]

Kopioituasi koodin IDE:hen, ja ladattuasi koodin arduinoon, avaa arduino IDE:stä löytyvä sarjaporttimonitori, ja totea että kaikki toimii niinkuin pitääkin :)!

[size=150]Loppuhölinät[/size]

Toivottavasti artikkelista oli hyötyä kaikille arduinosta kiinnostuneille, uusille harrastajille.
Kaivatessasi lisäinfoa, osaavat varmasti ruuvipenkin keskustelualueelta löytyvät käyttäjät neuvoa kaikissa ongelmissasi.
Jos huomaat artikkelissa kirjoitusvirheitä, tai väärää tietoa, tai olet vain puhtaasti
eri mieltä jostain, ilmoita siitä niin suoritan korjauksia.

(Terävät kaverit varmaankin huomasivat, että vaikka artikkelissa rakennettiin jännitteenjakokytkentä, ei sitä edes käytetä. Miksikö? Kenties seuraavassa mahdollisessa artikkelissa GPS-moduulin tilalla onkin jotain jossa jutellaan jo molempiin suuntiin, siksi allekirjoittanut koki hyödylliseksi kertoa kyseisestä kytkennästä. Ja oppiahan ei voi koskaan liikaa…)

-Eero Holopainen

VIITTEET:
interfacebus.com/voltage_threshold.html - TTL-jännitetasot
raltron.com/cust/tools/voltage_divider.asp - Jännitejakajalaskuri
gpsinformation.org/dale/nmea.htm - Tietoa NMEA-protokollasta
arduiniana.org/libraries/newsoftserial/ - NewSoftSerial kirjasto
fastraxgps.com/showfile.cfm? … 0234006b29 - UP501 Datalehti