30. SRF02 Ultraäänianturi

Alunperin julkaistu: 12.2.2017

Viimeksi muokattu: torstai 11.6.2020

Launchpadia ja elektroniikkaa -oppaan viimeisessä ja loistokkaassa osassa tutustutaan Robomaasta saatavaan ultraäänianturiin nimeltä SRF02.

Ultraääniantureita hyödynnetään nykypäivänä esimerkiksi autojen peruutustutkissa, robotiikassa, lääketieteessä ja jopa hyönteisten karkottimena. Tässä osassa käytetään ultraäänianturia etäisyyden mittaamiseen launchpadin ja jonkin kohteen välillä.

Ultraäänianturit toimivat samaan tapaan kuin lepakot suunnistavat. Kun anturi lähettää ultraäänen, se kimpoaa esteestä takaisin vastaanottimeen (joka tässä tapauksessa on sama kuin lähetin). Koska ääni etenee eri aineissa eri nopeudella, voidaan äänen kulkema edestakainen matka laskea, kun tiedetään äänen nopeus ko. aineessa. Meidän käyttötapauksessa äänen nopeus on tietenkin ilmassa, eli noin 330 m/s. Äänennopeus riippuu jonkin verran ilmanpaineesta, -kosteudesta ja lämpötilasta, mutta mitään sen kummempia laskutoimenpiteitä ei kuitenkaan tarvita, sillä kyseinen anturimoduuli hoitaa laskemisen meidän puolestamme ja tehtäväksi jää ainoastaan konfiguroida anturi oikein ja lukea siltä saadut tiedot.

SRF02 ultraäänianturilta voidaan lukea tietoja joko I2C-väylän tai sarjaportin välityksellä Mode-pinnin tilasta riippuen. Kyseinen anturi on asennettu pienelle piirilevylle yhdessä ohjauselektroniikan ja mikro-ohjaimen kanssa. Näitä antureita voidaan kytkeä jopa 16 kappaletta samalle väylälle. Ultraäänimoduulia voidaan ohjata lähettämään ultraääni purskeita ilman, että kaikua luetaan takaisin. Moduuli voidaan myös asettaa kuuntelutilaan, mikäli jostakin muusta lähteestä halutaan tutkia ultraääntä (olkoot ne nyt leikisti vaikka lepakoita).

Pienin etäisyys, minkä anturi voi havaita on n. 15-18 cm riippuen hieman ilman lämpötilasta. Suurin etäisyys, eli kaukaisin kohde voidaan havaita jopa kuuden metrin päästä, mutta äänen takaisinheijastuma riippuu kohteen pintamateriaalista, sillä kovemmat aineet heijastavat ääntä paremmin takaisin kuin pehmeät. Anturi antaa etäisyystiedon äänen kulkeman matkan viiveenä (mikrosekunteina), senttimetreinä tai tuumina.

Kyseisen anturin voi tilata Robomaasta ja lisätietoa löytyy alla olevista linkeistä:
SRF02 Infosivu (englanniksi)
Robomaan verkkokauppa

Tarvittavat osat

Esimerkin toteuttamiseen tarvitaan Launchpadin lisäksi SRF02 ultraäänianturi:

  • SRF02 ultaäänianturi
  • Launchpad + MSP430G2452 MCU
  • 4 kpl hyppylankoja​
  • 2 kpl 22 kilo-ohmin vastuksia

Anturin kytkeminen Launchpadille ja muut valmistelut

Oletuksena SRF02 ultraäänianturi toimii I2C-väyläisenä. Anturin voi asettaa toimimaan myös sarjaportin välityksellä, jolloin Mode-nasta täytyy kytkeä maahan. Mode-pinnissä on sisäinen ylösvetovastus, joten sen kytkemättä jättäminen asettaa anturin toimimaan I2C-väyläisenä. Koska aiemmissa kappaleissa on myös käytetty I2C-väylää, käytetään sitä esimerkin vuoksi myös tässäkin osassa.

Anturille voit halutessasi juottaa johtimet suoraan kiinni kytkentäpisteisiin, mutta itse ainakin käytin piikkiriman pätkää, jolloin anturia on kätevä liikutella kytkentäalustalta toiselle tarpeen niin vaatiessa. Lisäksi taitoin anturiin juotettuja piikkirimoja niin, että etäisyysmittausta on helppo testata vaakatasossa. Alla oleva kuva selventää asiaa:

SFR02 ja siihen juotetut taivutetut piikkirimat

Koska anturi toimii 5 voltin jännitteellä, otetaan sille käyttöjännite Launchpadilta alla olevan kuvan osoittamista kohdista. Näihin kohtiin olen juottanut kaksi hyppylankaa joiden avulla 5 voltin jännite on kätevä ottaa käyttöön koekytkentäalustalla.

LaunchpadUSB-Volt

Anturin I2C-väylän SDA ja SCL -linjoihin asetetaan 22k alasvetovastukset, jotka pudottavat IO-jännitettä 3,3 voltin tasolle. Tämä tehdään siitä syystä, että logiikkajännite varmasti toimii oikein Launchpadilla. Samalla jännitteen aleneminen myös suojaa MCU:ta, koska anturi itsessään toimii 5 voltin jännitteellä. Kokonaisuudessaan kytkennästä on kuvat alla:

Kytkentä IRL

Kytkentäkuva

Kytkennän tekemisen jälkeen voidaan siirtyä ohjelmoinnin pariin.

Esimerkki 1. Anturin yhteyden testaus

Aluksi testataan, saadaanko laitteeseen yhteyttä tehdyllä kytkennällä. SRF02 moduulissa on oletuksena I2C-väylän osoitteena E0, joten tarkistamalla vastaako kukaan osoitteeseen E0 saadaan tieto siitä toimiiko kommunikaatio vai ei.

Osoitteen pollaaminen siis paljastaa kytketyn anturin ja se tapahtuu tekemäni USI-kirjaston funktion CheckForSlaveExists() -avulla. Funktiolle annetaan parametrina osoite, mistä halutaan ottaa selvää. Koska tässä tapauksessa SRF02-laitteella on oletusosoitteena 0xE0, niin käytetään sitä. Alla esimerkkikoodi pääohjelmasta:

(HUOM! Koodissa on virheellisesti käytetty nimeä SFR02, vaikka oikea olisi SRF02, tämä on helppo korjata kuitenkin koodieditorilla mikäli tarve niin vaatii.)

    while(1)
    {
        // Printataan että ollaan valmiita
        printf(" Master Ready! ");

        // Tutkitaan onko anturi paikalla
        SFR02_online = CheckForSlaveExists(0xE0);

        // Jos anturi on paikalla, asetetaan punainen LED päälle. Vihreää ei kannata käyttää,
        // koska se on kytketty P1.6-pinniin, joka on SDA-linja.
        if(SFR02_online == 1)
        {
            printf("SFR02 online!");
            LED_RED_ON;
        }
        else
        {
            printf("SFR02 offline!");
            LED_RED_OFF;
        }

        // Nukuskellaan 1 sekunti (vaihtoehtoina kaksi eri funktiota joita voi käyttää)
        //TimerA_msDelay(1000);
        TimerA_Delay(1);

    }

Kuten ohjelmasta huomataan, tulostetaan "Master Ready!" -teksti sarjaporttiin kun ohjelman pääsilmukka pyörii. Väylältä tarkistetaan onko orjalaite, eli SRF02-anturi paikalla ja tulostetaan sen mukaisesti joko "SFR02 online!" tai "SFR02 offline!" ja asetetaan punainen led. Vihreää lediä ei tässä käytetä, koska se on kytketty P1.6:een, joka on myös SDA-datalinja I2C-väylällä.

Kun anturia on "haisteltu" niin ohjelma nukkuu LPM3-tilassa yhden sekunnin. Kirjoitin esimerkkiin kaksi vaihtoehtoista delay-funktiota, joiden avulla nukkuminen toteutetaan. TimerA_msDelay() toimii siten, että CPU tarkistaa millisekunnin välein, onko annettu aika kulunut, joten tätä voidaan käyttää millisekunnin tarkkuudella tehtäviin nukkumis- tai viiveajastuksiin. TimerA_Delay() puolestaan toimii niin, että CPU tarkistaa sekunnin välein onko annettu aika kulunut, joten tätä voidaan käyttää sekunnin tarkkuudella tehtäviin nukkumis- tai viiveajastuksiin. Tässä tapauksessa viivefunktioiden resoluutio on siis millisekunti ja sekunti.

Ohjelman toimintaa voi testata siten, että irroittaa esimerkiksi Launchpadille menevän SDA-johtimen, jolloin tiedonsiirto menee poikki eikä isäntälaite (MSP430G2452) saa kuittausta orjalaitteelta osoitteeseensa. Tällöin sarjaporttitulosteeseen ilmestyy kuten kuvassa alla:

Tässä kaikki esimerkistä 1:stä. Seuraavaksi hieman monimuotoisempi esimerkki ja muutama uusi asia C-ohjelmoinnista sekä anturista itsestään.

Lataa CCSv5 esimerkkiprojekti 1 tästä linkistä. (koodi päivitetty 13.6.2014)

Esimerkki 2. Anturin tietojen kerääminen

Kun kytkentä toimii ja tiedonsiirtokin on saatu "pelittämään" niin on aika niin sanotusti laittaa suurempaa vaihdetta silmään.

Tässä esimerkissä käytetään tekemääni SFR02-kirjastoa (huom. nimi väärin), jonka avulla anturilta voidaan kerätä tietoja etäisyydestä ja sen ohjelman versiosta (jos omistaa vaikkapa kaksi anturia ja haluaa tietää onko niiden sisällä sama ohjelmaversio).

Ohjelmaan on laitettu funktioiden käytöistä esimerkit ja selostettu koodiin, kuinka niitä käytetään. Alle olen ottanut projektista koodin pätkiä ja selostanut niiden toimintaa.

    // Tulostetaan että ollaan valmiita
    printf("Master Ready! ");

    // Kun tiedetään osoite, voidaan tarkistaa se suoraan näin:
    if(SFR02_CheckDevice(SFR02_ADDRESS) == 1)
    {
        P1OUT |= BIT5;     // tähän on kytketty vihreä LED hyppylangalla

        SFR02_CollectDeviceData();    // Kerätään t_SFR02 -struktuuriin tietoa anturista

        online = 1;    // merkitään että anturi on onlinessa
    }
    else
    {
        // tämä aiheuttaa ohjelman resetoitumisen ja alkamisen alusta jos anturia ei löydy
        WDTCTL = 0xFFFF;
    }

Ohjelma toimii siten, että alustusten jälkeen sarjaporttiin tulostetaan tuttuun tapaan "Master Ready!" -teksti. Tämän jälkeen anturin osoitteen perusteella tehdään kysely SFR02_CheckDevice() -funktiolla. Funktion parametriksi annetaan tiedetty osoite eli 0xE0. Mikäli SRF02-anturissa on virrat päällä ja se on kytketty oikein, niin isäntälaite saa kuittauksen kyselyyn ja kommunikointi on kunnossa. Tästä merkkinä palaa puolestaan vihreä led, joka on kytketty hyppylangalla Launchpadin vihreän ledin jumpperiin (jumpperi on siis poistettu, koska sitä ei voida portista P1.6 käyttää hyvin).

Kun laite löytyy, niin SFR02_CollectDeviceData() -funktiolla kerätään tiedot anturilta talteen. Tiedot tallentuvat SFR02_firstDevice -nimiseen struktuuriin, mistä kerron hetken päästä myöhemmin lisää. Tämän lisäksi asetetaan online -muuttuja arvoon 1, joka on merkkinä myös, että anturi löytyi.

Mikäli anturia ei löydetä, niin ohjelma resetoi itsensä ja sarjaporttiin alkaa tulostumaan yhtenä liutana "Master Ready!" -tekstiä, kunnes yhteys anturiin palautuu.

Jos ohjelmoija ei tiedä mikä anturin osoite on, niin se saadaan selville esimerkiksi funktion SFR02_CollectDevices() -avulla. Tämä funktio palauttaa lukuarvon, joka kertoo montako SRF02-tyyppistä anturia on väylälle kytketty. Samalla funktio kerää viimeisimmän löydetyn anturin tiedot, eli alimmassa osoitteessa olevan anturin tiedot.

Mutta hetkinen hetkinen, mikäs se oli se struktuuri?

Struktuuri, mihin tiedot tallennetaan on ikäänkuin taulukko mikä pitää sisällään tietoja anturista. Kyseinen struktuuri, jota tässä käytetään on määritelty SFR02.h -tiedostossa ja se pitää sisällään seuraavanlaisen määrityksen:

typedef struct
{
    UINT8    SW_revision;
    // UINT8    unused;
    UINT8     RangeHighByte;
    UINT8     RangeLowByte;
    UINT8     AutotuneHighByte;
    UINT8     AutotuneLowByte;
} t_SFR02;

Sanoilla typedef struct kerrotaan kääntäjälle, että seuraava lohko pitää sisällään kourallisen UINT8 tyyppistä tietoa (unsigned char eli 8-bittisiä kenttiä). Koska alkuun on kirjoitettu typedef, niin se tarkoittaa myös sitä että struktuuri "tyypitetään" lohkon lopusta löytyvällä nimellä. Toisin sanoen struktuurille annetaan nimi.

Kun struktuuri on esitelty tai määritelty, se voidaan ottaa käyttöön hieman samaan tapaan kuin muuttujiakin otetaan käyttöön. Tämä onkin tehty SFR02.c tiedoston alussa näin:

// Create at least one SFR02
t_SFR02        SFR02_firstDevice;

Struktuurit ovat tällä tavalla käytettynä hieno keino niputtaa tietoa yhden tietotyypin taakse. Nyt SFR02_firstDevice muuttujaa voidaan ajatella kuten... noh, muuttujaa ;).

Struktuurin käytöstä ei tähän väliin tämän enempää, mutta sitä voit opiskella lisää internetissä tai tarkastelemalla ohjelman lähdekoodia joka löytyy hieman alempaa, jatketaan ohjelman selittämistä.

Pääohjelman toiminta

Pääohjelmassa asetetaan SRF02-anturi mittaamaan etäisyyttä SFR02_StartRanging() -funktiolla. Funktioille voidaan syöttää parametrina formaatti, missä muodossa tulokset halutaan mitata. Vaihtoehtoina ovat INCHES, CENTIMETERS ja MICROSECONDS. Toisena parametrina annetaan laitteen osoite. Funktio lisäksi palauttaa arvon 1, kun mittauksen "liipaisu" on onnistunut - eli orjalaite on väylällä. Ja kuten aiemmin, ohjelma resetoi itsensä mikäli laite on hävinnyt väylältä:

online = SFR02_StartRanging(CENTIMETERS,SFR02_ADDRESS);

if(online == 0)
{
     // tämä aiheuttaa ohjelman resetoitumisen ja alkamisen alusta
     WDTCTL = 0xFFFF;
}

Kun anturi on liipaistu, täytyy odottaa noin 66 ms ennen kuin laitteelta voidaan etäisyys lukea. Mikäli tätä yritetään aiemmin, niin laite ei välttämättä vastaa osoitteeseensa. Tässä odotellaan varmuuden vuoksi 70 ms, minkä jälkeen kerätään anturin tiedot talteen aiemmin tutuksi tulleella SFR02_CollectDeviceData() -funktiolla, mikä tallettaa ne aiemmin mainittuu SFR02_firstDevice -struktuuriin.

Kerätyt tiedot tulostetaan näytölle ja alla olevassa kuvassa nähdään ohjelman tuloste ensimmäisen ohjelmakierroksen jälkeen. Seuraavalla ohjelmakierroksella tulosteesta on hävinnyt tekstit "Master Ready!" ja "Found 1 devices", koska ne tulostettiin ennen pääohjelman silmukkaa.

Esimerkkiohjelman 2 tulosteet

Loput ohjelmasta ja sen toiminnasta löytyy tietenkin lähdekoodista, jonka voit ladata tutkiskeltavaksi alta löytyvästä linkistä.

Lataa CCSv5 esimerkkiprojekti 1 tästä linkistä. (koodi päivitetty 13.6.2014)

Loppusanat

Tähän päättyy Launchpad opas. Menneissä kirjoituksissa ja esimerkeissä on käyty läpi MSP430G2-prosessorien vähävirtaisuuden hyödyntämistä, erilaisia tiedonsiirtomenetelmiä, erilaisten ulkoisten laitteiden käyttämistä, näytöille tulostamista, moottorin ohjausta, AD-muunnosta ja muuta kaikkea mitä matkan varrella on mieleen syntynyt kirjoittaa.

Kaikesta mahdollisesta maan ja taivaan väliltä ei tietenkään voi kirjoittaa, mutta siihen olen pyrkinyt että aiheet olisivat mahdollisimman erilaisia ja tässä pienessä opuksessa olisi kaikille vähän kaikkea. Mielestäni käsiteltyjen aiheiden kautta lukija pystyy rakentamaan monimutkaisiakin systeemeitä ja järjestelmiä kunhan osaa vain soveltaa. Tekemällä oppii, sanotaan.

Kuten alussakin on mainittu, niin tämä ei ole mikään "Raamattu" C-kielestä eikä sulautetusta ohjelmoinnista, mutta toivon mukaan tästä on ollut apua aloittelijoille ja miksei myös edistyneemmillekin henkilöille.

Sulautettuja juttuja tullaan jatkossakin kyllä kirjoittelemaan, mutta enemmän Sulautettu elektroniikka -pääsivuston taakse, sillä tahdon keskittyä myös muunlaisiin kehitysalustoihin joita on tullut hommattua tässä ajan saatossa, mutta jotka kuitenkin ovat ihan "validia kamaa" vielä tänä päivänä.