Kasutaja tarvikud

Lehe tööriistad


projektid:arendusprojektid:distantsisensor

Distantsisensor

Mõned lingid antud teema kohta

Dokumendid

PS/2 hiire kasutamine distantsisensorina

Robotex 2007 jaoks valmistudes sai valmis kirjutatud progamm Atmeli ATmega 8-bitiste mikrokontrollerite jaoks, mis võimaldab mikrokontrolleril suhelda arvutihiirega PS/2 protokolli järgi. Selle lahenduse eeliseks on kasutuselevõtu kiirus: hiirt ei ole vaja modifitseerida ning programm on tehtud universaalsust silmas pidades. Miinusteks võib lugeda riistvarapiiranguid: iga hiire kohta kulub mikrokontrolleril üks USART liides ning hiir peab kindlasti mööda maad lohisema. Lisaks on odavad optilised hiired üsna aeglased (sest nad kasutavad videotöötluseks madala jõudlusega arvutusüksusi) ja üldiselt arvutihiired ei tuvasta pööramist.

Tulevikus võiks keegi teha mikrokontrolleri ja hiire kontrolleri vahelise otseühenduse (ilma PS/2 protokollita nende vahel), ning I²C abil korraga palju hiiri ühele siinile panna. Samuti oleks tore, kui distantsi saaks mõõta paari sentimeetri kõrguselt. Samas võiks kaaluda ka hiire optikat kasutava täiustatud distantsisensori väljatöötamist, millel oleks rohkem arvutusjõudu ning programm suunamuutuste tuvastamiseks.

Riistvara

Vaja on ATmega mikrokontrollerit koos kõige selle juurde käivaga (resonaator, kondensaatorid, takistid väljaviigud jms ehk siis kõik, mida vaja mikrokontrolleri töölepanekuks), PS/2 otsaga hiirt ning ühendusjuhtmeid.

Edaspidi kasutan hiire elektriliste signaalide nimetamiseks Wikipedias toodud nimesid (+DATA, GND, Vcc, +CLK). Ettevaatust, wikipedias toodud pilt käib pistikupesa kohta, aga hiire juhtme otsas on isane konnektor! Mikrokontrolleri väljaviikude nimed on samad mis mikrokontrolleri andmelehel.

Kõige lihtsam on ühendada toidet. GND tuleb ühendada mikrokontrolleri „maaga“, mille nimi on samuti GND, hiire Vcc külge ühenda +5V toitepinge, mis suudab 100 mA voolu anda. Hiire +CLK peab ühendama ATmega XCK väljaviiguga, see on USARTi kellasignaal. +CLK signaaliga peab olema ühendatud ka üks asünkroonse katkestuse väljaviik. Näiteks ATmega128 asünkroonsed katkestused on nimedega INT0..INT3. Lisaks peab +CLK siiniga olema ühendatud ka üks digitaalne väljund, aga selleks võib kasutada sama väljaviiku, mida katkestuse jaokski. +DATA signaaliga peab ühendama mikrokontrolleri RXD ning ühe digitaalväljundi, mis võivad füüsiliselt olla sama väljaviigu küljes (nt ATmega128 RXD0 on sama mis PE0). Kindlasti ei tohi +DATA ja +CLK siinid olla omavahel ühenduses, seetõttu ei saa +CLK-ga ühendatud asünkroonse katkestuse viik olla RXD viik, nagu ka +DATA-ga ühendatud digitaalväljund ei tohi olla füüsiliselt sama, mis XCK!

Järgnevates näidetes on kasutusel ATmega128 (andmeleht) mikrokontrolleri USART1. Selleks on +CLK ühendatud XCK1(PD5) ja TXD1/INT3(PD3) külge ning +DATA ühendatud RXD1/INT2(PD2) külge.

Tarkvara

Programmijupp, mis hiirega suhtleb, on kirjutatud AVR C++ Lib'i kasutades. Programmi lähtekood on saadaval siin ning väikese näiteprojekti saate tõmmata siit.

Distantsisensori lähtekoodis on kolm faili: „PS2Mouse.h“, „GetDelegate.h“ ja „UsingDelegate.cpp“. Esimene neist on põhiline päisefail ning see tuleb lisada oma roboti koodile reaga:

#include "PS2Mouse.h"

Näiteprojektis on see rida „OptMouse.h“ päises. Ülejäänud kaks distantsisensori faili on vajalikud, sest distantsisensori kood kasutab delegaate. „UsingDelegate.cpp“ peab ära märkima ka projekti Makefile'is, näiteprojektis teeb seda kood:

# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC = OptMouse.cpp UsingDelegate.cpp

„UsingDelegate.cpp“ failis peab olema kirjeldatud andmete vastuvõtmisel kasutatav katkestus (Receive Complete), näiteks kui kasutusel on nii USART0 kui ka USART1, siis peaks see fail lõppema ridadega:

USING_FAST_DELEGATE(USART0_RX);
USING_FAST_DELEGATE(USART1_RX);

„GetDelegate.h“ on lisatud juba „PS2Mouse.h“ failis, seda ise lisama ei pea, kuid ka selles failis peab tegema muudatusi. Ka siin peab ära kirjeldama USARTi abil andmete saamisel kasutatavad katkestused, näiteks kui kasutusel on nii USART0 kui ka USART1, siis peaks see fail lõppema ridadega:

GET_DELEGATE_FUNCTIONS(AVRCpp::USART::USART0::ReceiveCompleteInterrupt)
GET_DELEGATE_FUNCTIONS(AVRCpp::USART::USART1::ReceiveCompleteInterrupt)



Nüüd ongi ettevalmistused tehtud ning võib asuda hiirt kasutama. Kõigepealt peaks hiire initsialiseerima, muidu ta andmeid ei saada. Seda saab teha ühe reaga sinu roboti programmi koodis, näiteks:

PS2Mouse< MouseUSART, ClockInterrupt, DataPin, ClockPin, 4000> Mouse;

See tähendab, et hiir kasutab USART liidest nimega MouseUSART, andmete saatmisel sünkroniseerib suhtlust asünkroonne katkestus nimega ClockInterrupt, hiirele saadetakse infot digitaalse väljundiga DataPin, mikrokontroller kontrollib +CLK siini digitaalväljundiga ClockPin ning hiir teatab ühemeetrise liikumise kohta 4000 ühikut liikumist.

MouseUSART asemel võib kirjutada ka näiteks USART::USART0, ClockInterrupt asemele näiteks ExternalInterrupt::Interrupt3, DataPin asemele OutputPin2<PortD> ja ClockPin asemele OutputPin3<PortD>, kuid see teeb koodi raskemini loetavaks. Õigem oleks kogu kasutatav riistvara ühes failis ära kirjeldada ning seejärel koodis kasutada kergemini mõistetavaid muutujanimesid. Sel juhul on ka lihtne riistvaras muudatusi teha. Näiteprojektis on hiire jaoks vajaminevad asjad kirjeldatud „Config.h“ failis:

typedef OutputPin3<PortD> Clock;
typedef OutputPin2<PortD> Data;
typedef USART::USART1 Mouse;
typedef ExternalInterrupt::Interrupt3 ClockInt;

See kirjeldus tähendab, et mikrokontroller saab +CLK siini juhtida PD3 (Port D pin 3) väljaviigu abil, käskude saatmine hiirele käib PD2 kaudu, vastuvõtmiseks kasutatakse USART1'e ning hiirele käskude saatmisel saadakse sünkroniseerimissignaali INT3 kaudu.

Tasub ära märkida, et väljaviikude kokkuhoidmise nimel on Clock ja ClockInt ühendatud sama väljaviigu külge, mida tavaolukorras saaks kasutada andmete saatmiseks, sest sellel viigul on kolm funktsiooni: TXD1 ehk USART1 transmitter, INT3 ehk asünkronne katkestus 3 ning PD3 ehk sisend/väljundviik. Veel on kokku hoitud üks väljaviik niimoodi, et Data kasutab väljaviiku PD2, mis on ühtlasi funktsiooniga RXD1 ehk USART1 Receiver, sest hiir ja mikrokontroller „räägivad“ vaheldumisi, mistõttu võib sama väljaviiku kasutada nii saatmiseks kui ka vastuvõtmiseks.

Näiteprojektis on sellise riistvara kirjeldamise tõttu hiir kasutuskõlbulik pärast käsku:

PS2Mouse< Mouse, ClockInt, Data, Clock, 7320> Maus(false);

Sõna false definitsioonis sulgudes tähendab seda, et eeldatakse, et kui programm jõuab selle reani, siis on hiirel juba mõnda ega toide taga olnud. Kui hiir ja mikrokontroller on sama toite otsas ning hiirt hakatakse kohe kasutama, siis peaks sulgudes olema true või hoopis mitte midagi. Põhjus on selles, et hiir saadab käivitudes kohe mikrokontrollerile kaks baiti, 0xAA ja 0x00, mis tähendab, et hiirega on riistvaraliselt kõik korras. Selline info saadetakse esimese sekundi jooksul. Ülaltoodud true tähendab, et mikrokontroller jääb neid baite ootama, false tähendab, et mikrokontroller eeldab, et need baidid on juba ära saadetud. Kokkuvõtteks: kui hiir käivitub mikrokontrolleriga samal ajal või hiljem ning hiirega hakatakse kohe tegelema, siis true, aga kui hiir käivitub varem või mikrokontroller tegeleb alguses paar sekundit muude asjadega, siis false.

Arv 7320 näiteprojektis on leitud katse-eksituse meetodil ning erineb KINDLASTI teie kasustuses olevast hiirest. Kui see on õigesti valitud, siis saab programmi sees distantsisensorilt vastuseid millimeetrites. Järgnevalt on toodud programmijupp näiteprojektist, mis saadab USART0 kaudu iga natukese aja tagant arvutisse infot hiire asukoha kohta.

PS2Mouse< Mouse, ClockInt, Data, Clock, 7320> Maus(false);
 
// nüüd hakkab hiir infot saatma
while(true)
{
    // viivitus
    for(volatile uint32_t i = 0; i < 1000000; i++)
        continue;
    // uus skoop
    {
 
        using namespace AVRCpp::Collection;
 
        StaticString<20> tempString, report;
        report += "::X=";
        // võta x-koordinaat millimeetrites
        tempString.FromInt(Maus.GetX());
        report += tempString;
        report += ";Y=";
        // võta y-koordinaat millimeetrites
        tempString.FromInt(Maus.GetY());
        report += tempString;
        // saada asukoht arvutile
        Debug::SendArray(report(), tempString.GetLength());
    }
    // vilguta tuld
    LED::Toggle();
}

Lõpetuseks veel paar õpetussõna:

  • Kohe pärast initsialiseerimist on hiire asukoht null. Seda võib ise muuta käskudega SetX(uusXkoordinaat) ja SetY(uusYkoordinaat), näiteks ülaltoodud koodinäite põhjal Maus.SetX(-40); paneb uueks asukohaks x-teljel -40 mm.
  • X-telg on see, mida mööda hiirt liigutades liiguks kursor arvutiekraanil vasakule või paremale. Y-telge mööda liikudes liiguks kursor üles-alla. Z-telge siinkirjeldatud lahendus ei võimalda, kuid kui see juurde programmeerida, siis näitaks z-koordinaat hiire kerimisratta liikumisest tekkinud vahemaad.
  • Kõik mõõtmistulemused sõltuvad hiirest. Sama telge mööda edasi ning seejärel tagasi alguspunkti liikumisel ei pruugi asukoht olla null. Ka erinevad teljed võivad olla erineva resolutsiooniga.
  • Iga uue hiire lisamine programmi võtab alla 700 baidi programmimahtu. Näiteprojekti seitsmest kilobaidist ligi kuus kilobaiti moodustab sõnetöötlus (et arvutile saadetav tekst oleks inimloetav).
  • Hiir ei saa aru, kui teda ümber oma telje pööratakse. Mööda kaart liikudes näitavad koordinaadid sirgjoonelist liikumist, sest hiir on (ideaaljuhul) igal ajahetkel suunatud liikumise suunas, mistõttu külgliikumist ei toimu.

Tegijad

projektid/arendusprojektid/distantsisensor.txt · Viimati muutnud: 2016/09/03 16:52 persoon raimond.vaba