Windows 10 IoT Core
Windows 10 on saadaval arvutitele, tahvlitele, mobiilidele ja Raspberry Pi'le. Seejuures on Microsoft teinud erinevaid Windows 10 versioone omavate seadmete omavahel ühendamise võimalikult lihtsaks. Seekordses laagris vaatleme täpsemalt, mille poolest erineb Raspberry Pi'le paigaldatav Windows 10 tavapärasest Raspbianist ning kuidas Visual Studio abiga arendada Pi'le lihtne viike juhtiv äpp.
Juhendi järgimiseks on vajalikud:
- Arvuti, millele on paigaldatud Windows 10 ja Visual Studio 2015. Visual Studio Community Edition on tasuta kättesaadav siit.
- UWP tööriistad Visual Studiole, mis on paigaldatavad Visual Studio paigaldamisel või eraldi.
- MicroSD kaart vähemalt 8GB kiirusklassiga vähemalt 10.
- MicroSD kaarti lugeja arvuti jaoks.
- Raspberry Pi 2 - teised Raspberryd on Windows 10 IoT Core jooksutamiseks ebapiisava võimsusega.
- HDMI kaabel Raspberry ekraaniga ühendamiseks.
- 150-oomised takistid ja LEDid
- Raspberry Pi'ga ühilduv WiFi pulk või võrgukaabel.
- juhtmed LEDide ühendamiseks.
- USB klaviatuur ja/või hiir Raspberryga kasutamiseks.
Windows 10 IoT Core seadistamine Raspberry Pi jaoks
- Tõmba alla Windows 10 IoT Core ametlikult veebilehelt.
- Tee topeltklõps allalaetud failile, et iso fail ühendada arvutiga. iso failid on kujutis plaadist, mille Windows 10 lubab arvutiga ühendada ilma faili kirjutamiseta füüsilisele plaadile.
- Käivita plaadil olev paigaldusfail. Paigaldus võib nõuda kõrgendatud kasutajaõiguseid. Paigaldatakse mitu Raspberry üles seadmisega ja arvutiga ühendamisega seotud rakendust.
- iso kujutise võib pärast paigaldust arvutist lahti ühendada, valides failihalduris plaadile paremkliki rippmenüüst valiku Eject.
- Ühenda MicroSD kaart arvutiga.
- Käivita IoTCoreImageHelper rakendus, vali sobiv SD kaart ja ffu kujutis (vaikimisi paigaldatakse kausta C:\Program Files (x86)\Microsoft IoT\FFU\RaspberryPi2 ) ja vajuta nupule 'Flash', et kirjutada kujutis SD kaartile.
Kui SD kaartile kirjutamine on lõpetatud, kuvatakse vastav teade.
Kui nüüd Raspberry ühendada ekraaniga ja sisse lülitada, lõpetatakse Windows 10 IoT Core paigaldamine ning kuvatakse Raspberry andmed. Et Raspberryga saaks rohkem teha, soovitame ühendada ka klaviatuuri ja/või hiire ja WiFipulga või võrgukaabli, mille teise otsaga on ühendatud arvuti. Laagris kasutame WiFit nimega utpublic, kuhu ühenduvad kõik arvutid ja Raspberryd, mistõttu on tähtis teada Raspberry IP aadressi, mis samuti kuvatakse ekraanile. Hetkel sinna veel ühendada ei saa. Pi'le on kaasa pandud ka paar näidisäppi, mida võib proovida ekraani üleval vasakul nurgas olevast sakist. Raspberry sätteid saab muuta ekraani üleval paremal nurgas olevale hammasrattale klõpsates.
WiFi pulga draiverite paigaldamine Raspberry Pi'le
Windows 10 IoT Core toetab vaikimisi võrdlemisi väheseid erinevaid USB-ühendusega seadmeid. Meie kasutatavad Edimaxi WiFi pulgad vajavad töötamiseks eraldi draiverite paigaldamist - draiver on n-ö vaheprogramm, mis võimaldab kahe seadme omavahelist suhtlust. Vastavad draiverite failid saab arvutisse laadida EDImaxi kodulehelt või siitsamast.
Alla laetud zip fail sisaldab kolme faili, mis tuleb liigutada või kopeerida SD kaartile. Selleks on soovitatav taassisestada Windows 10 IoT Core'i SD-kaart, teha sellele kaust 'Temp' ('ajutine') ning paigutada need kolm faili sellesse kausta. Seejärel võib SD-kaarti taas sisestada Raspberry Pi'sse, ühendada Pi võrgukaabliga arvutiga ning voolukaabliga elektrivõrku.
Nüüd tuleb kasutada Microsofti uut käsureaprogrammi PowerShell, et Pi'l olevad draiveri failid paigaldataks. Käivitame PowerShelli administraatoriõigustega, otsides Start menüüst PowerShelli, tehes tema peal paremklõpsu ning valides 'Run as Administrator'. Trükkida tuleb järgmised käsud:
net start WinRM
See kindlustab, et me saame teha kaugühenduse teise masinaga ('Remote Machine').
Set-Item WSMan:\localhost\Client\TrustedHosts -Value minwinpc
Ütleme, et Pi on usaldatud (mitte võõras) seade. Kui olete juba Pi nime muutnud, siis tuleb 'minwinpc' asemel kirjutada vastav uus nimi või Pi IP-aadress, mille leiame kas Pi'ga ühendatud ekraanilt või IoT Core Watcher rakendusest, mida vaatleme täpsemalt veidi hiljem.
Enter-PSSession -ComputerName minwinpc -Credential minwinpc\Administrator
Sellega üritame sisse logida Pi kasutajana Administrator. Administratori vaikimisi salasõna on p@ssw0rd.
Kui ühendus õnnestus, oleme saavutanud olukorra, kus me saame arvutist anda Pi'le käsureakäsklusi. Käsurealt saame Pi'le teha restardi, lülitada ta ekraanita režiimile ('headless mode'), muuta vaikekasutaja andmeid, Raspberry Pi seadmenime, vaadelda hetkel töötavaid protsesse ja nii mõndagi muud. Hetkel tahame paigaldada draiverit WiFi pulga jaoks.
cd C:\EFIESP\Temp
'cd' ehk 'Change Directory' ('vaheta kausta') käsuga saame vahetada kausta, kus hetkel teeme toiminguid. Võib õigesse kausta minna ka pikemat teed, korduvalt kirjutades
cd ..
, et liikuda ülemkausta, ning
cd EFIESP cd Temp
, et liikuda õigesse kausta. Vahepeal võib vaadata kaustas ringi käsuga 'dir', mis loetleb kaustas olevad failid ja alamkaustad.
Et paigaldada kaustas olevad draiverid, trükime
devcon install netrtwlanu.inf "USB\VID_7392&PID7811"
Selle käsuga paigaldame draiverid seadmele, mille VID ja PID koodid vastavad meie kasutatavale Edimaxi WiFi pulgale. Kui trükivigu pole tehtud, algab draiveri paigaldus. Paigaldus võib küll lõppeda 'RemoteException' veateatega, kuid sellest hoolimata draiverid töötavad. Nüüd võime Raspberryle taaskäivituse teha käsuga
shutdown /r /t 0
Nüüdseks võime PowerShelli sulgeda 'exit' käsuga või nurga pealt X nupule vajutades. Raspberry käivitamisel ja ta ekraaniga ühendades saame tema sätetest (hammasrattanupp) valida meile sobiva WiFi ühenduse. Kui ühtegi ühendust ei kuvata, on midagi draiveri paigaldusel kogemata valesti läinud ning PowerShell sammud tuleks korrata.
Raspberry Pi arvutiga ühendamine
Windows 10 IoT Core SD-kaartile paigaldamiseks tarviliku tarkvara paigaldamisel paigaldati arvutisse ka rakendus nimega Windows IoT Core Watcher. Kui see rakendus käivitada, näeme loendit kohalikku kohtvõrku ühendatud Raspberry Pi'dest. Täpsemalt kuvatakse Pi nimi, MAC-aadress, IP-aadress, viimase ühenduskatse aeg jpm. Kui loendist enda Pi'd ei leia, võib proovida nuppu Refresh.
Enda Pi leides tuleb teha vastaval real paremklõps ja valida 'Web Browser Here'. See avab Raspberry sätted Windowsi vaikesirvijas, mis laagri arvutites on Edge. Sätetele ligipääsuks tuleb sisse logida kasutajanimega Administrator ja salasõnaga p@ssw0rd.
Sätete lehelt saab muuta Raspberry avaliku nime kergemini äratuntavaks, saab ka muuta sisselogimissätteid. Siinkohal soovitame sätetes ringi liikuda ning uurida, mida kõike muuta või näha lubatakse. Eraldi pöörame tähelepanu Performance sakile, mis näitab kasutatavat jõudlust Pi'l. Hetkel Pi ei tee midagi peale arvutile info saatmise ning seetõttu on jõudluskasutus võrdlemisi tühine. Kui Pi'l käivitada uus äpp või Pi'le saata (deploy) mõni äpp, on siiski jõudluskasvu näha. Kuna tegemist on 900MHz neljatuumalise protsessoriga, on mõnevõrra keeruline tekitada Pi'le ülekoormust.
Raspberry Pi ühendamine Visual Studioga
Visual Studio on Microsofti loodud arenduskeskkond, mis toetab mitmeid programmeerimiskeeli (C++, C#, Visual Basic, Visual F#, paljudele juba varasemast tuttav Python jpm). Seejuures saab vaikepaketiga või väikeste lisadega arendada ühes keskkonnas kirjutada äppe, mis töötavad Androidil, iOSil või ka Windows Phone'il, teha .NET veebirakendusi, töölauarakendusi ning ka Universal Windows Platform äppe. UWP äpid töötavad Windows 10 operatsioonisüsteemidel, mistõttu on just UWP äpi tegemine Windows 10 IoT Core'i puhul paslik valik.
Et Visual Studio toetab arendusjärgus äpi testimist ühendatud Raspberry Pi peal, on mõistlik seda võimalust kasutada. Selleks peab töölaua arvuti Windowsis olema lubatud arendamiseks 'Developer mode' ehk lubada äppide jooksutamine ametlikult usaldamata allikast (Windows Store). Selleks tuleb minna arvuti sätetesse, valida 'Update&Security', külgmenüüst 'For developers' ning valida 'Developer mode'. Kinnitada valik.
Järgmisena tuleb käivitada Visual Studio. Laagris olevatele arvutitele on eelpaigaldatud Visual Studio tasuta Community Edition versioon. Järgmisena tuleb alla laadida Candle projekt, see enda valitud kausta lahti pakkida ning selles avada Candle.sln laiendiga fail - see laeb sisse projekti andmed ja projektis kasutatavad failid Visual Studiosse.
Nüüd tuleb parempoolsest menüüst avada MainPage.xaml.cs. MainPage.xaml failis on info äpi peamise kasutajaliidese vaate kohta, ka seda tasub uurida, ning MainPage.xaml.cs failis on kirjeldatud selle vaatega seotud funktsionaalsus. Hetkel on mõlemad võrdlemisi tühjad, kuid selle vea me parandame kiiresti. Soovitame vaadata koodi, et paremini aru saada, milline rida mida täpsemalt teeb mida. Selleks on koodiread ka kommenteeritud '//' järgselt.
Kui koodil kuvatakse punaseid ridu veateatega "namespace 'Gpiopin' could not be found", tuleb lisada projektile Raspberryga seotud ressursside kogum. Selleks tuleb valida ülevalt 'Project' menüüst 'Add Reference', külgmenüüst valida 'Universal Windows', 'Extensions' ning leida loendist 'Windows IoT Extensions for the UWP' versiooniga 10.0.1058 või uuem, selle ette teha linnuke ja valida 'Ok'.
Lisaks tuleb Visual Studiole öelda, et me tahame äppi teha ARM arhitektuurile ja testida seda välisel arvutil. Seda saab valida tööribalt.
Kui Valida rippmenüüst Remote Machine, küsitakse, milline Remote Machine on sobiv vastavaks eesmärgiks. Kui automaatselt leitavate seadmete hulgas ei paista - siinkohal teeb õige seadme leidmise lihtsamaks seadmele omistatav unikaalne nimi - olevat varem valmis pandud Raspberryt, tuleb ühendus käsitsi konfigureerida, sisestades Raspberry IP-aadressi. Lisaks võib olla vajalik Visual Studiole öelda, et Pi'le äpi saatmiseks ei ole vajalik turvakoodi sisestamine. Seda saab teha, tehes projekti nimele paremkliki või Project menüü avamisel valides 'Properties' ning kinnitades, et 'Authentication Mode:' sätteks on valitud 'None'. Vastasel juhul Visual Studio võib küsida kasutajalt Pi'ga ühendamiseks PIN-koodi, mida väline seade eelduste kohaselt peaks näitama. Et tegu on Raspberry Pi'ga, mitte mobiili või tahvelarvutiga, ei ole kasutajal võimalik ühtegi kehtivat PIN'i leida - autentimist pole vaja.
Vaatleme koodi:
GpioPinValue value1 = GpioPinValue.High; //pin1 hetkeseis
pin1 = GpioController.GetDefault().OpenPin(18); pin1.Write(value1); pin1.SetDriveMode(GpioPinDriveMode.Output);
Selle koodi järgi kasutame pin1 puhul viiki 18, anname talle väärtuse 'High' (muutuja 'value1' väärtuse ehk tahame anda talle pinget) ning ütleme, et kasutame seda viiki signaali välja saatmiseks ('output'). Kui nüüd vajutada rohelise noolega nupule kirjaga 'Remote Machine', kompileeritakse kirjutatud kood, saadetakse see Raspberryle ning käivitatakse. Kui nüüd ühendada LEDi takistiga otsa 5V pingega ja takistita otsa 18. viigiga, siis näeme, et LED ei põle. Mõtleme, miks see nii on.
LED on ühelt poolt ühendatud pingeallikaga ja teiselt poolt juhitava pingega viigiga, kuhu on pinge lülitatud. Füüsikast teame, et kui tarbija on kahe vooluallika vahel, siis vool temast läbi ei käi. Võime kontrollida seda, ühendades LEDi 5V viigiga ja maandusega (GND). Kui peatame katse, vajutades Visual Studios punase kastiga 'Stop' nupule ning vahetame 'High' väärtuse 'Low' vastu ning käivitame rakenduse uuesti, läheb LED eredalt põlema. Vool liigub pingeviigilt läbi LEDi ning suundub pingeta juhitud viiki. Seega 'Low' seisus lamp põleb ja 'High' seisus lamp on kustunud.
Lambi vilgutamiseks saame kasutada ajamõõturit. Lisame MainPage() meetodisse järgmised read:
timer.Interval = TimeSpan.FromMilliseconds(2); timer.Tick += Ticker; timer.Start();
Selle koodiga ütleme, et ajamõõtur teeb iga kahe millisekundi tagant 'tiksu', nagu analoogkell tiksub iga sekundi tagant. Igal tiksul kasutab ta meetodit 'Ticker' ('tiksuja'), mis omakorda sisaldab lihtsat käsku 'Switch' ('lüliti'), mis lülitab pin1 väärtust 'High' ja 'Low' vahel. Koodi käivitades näeme toredalt vilkuvat LEDi.
Pulsilaiusmodulatsioon
LEDide kasutamisel on valida vaid kahe seisundi vahel, kas LED põleb või on kustunud. Kui võrrelda seda servoga ehk juhitava mootoriga, on LEDi juhtimine suhteliselt lihtne - servo või pöörelda ühtepidi, teistpidi, või ka seista. Et Pi viigid on binaarse loogikaga (võimalikud väärtused on vaid '0' või '1' ehk 'Low' või 'High'), on kolme erineva signaali saatmiseks kasutusel tehnika, mida kutsutakse pulsilaiusmodulatsiooniks. Sisuliselt tähendab see seda, et servot juhitakse pulsikaupa - korra antakse voolu, siis ei anta, siis jälle antakse, siis ei anta. Servo järgnev tegevus sõltub sellest, kui pikk on igas taktis servole antav energiapulss. Olenevalt servost on 'neutraalpulsi' ehk tasakaalupunkti pulsi pikkus erinev ning võib olla ka käsitsi või tarkvaraliselt reguleeritav. Kui pulss on tasakaalupunkti pulsist pikem, siis servo pöörleb ühte pidi, kui lühem, siis teist pidi. Nutiroboti praktikumis kasutati servosid, mille tasakaalupunkti pulsi pikkuseks oli 1,5 millisekundit ning iga 'takt' oli 20 millisekundit.
Et võrreldes Raspbianiga on Windows 10 IoT Core'il mitmeid lisafunktsionaalsusi (eeskätt rohkemate programmeerimiskeelte tugi ja Visual Studioga ühendamise võimalus), on teatud funktsionaalsused selle nimel ohvriks toodud. Raspbianil oli pulsilaiusmodulatsiooni ülesseadmine kiire, lihtne ja täpne, Windowsi puhul on 1,5 ms täpsust raskem saavutada ning ka pulsilaiusmodulatsiooni ülesseadmine nõuab selle pikemat kirjeldust koodis.
Teeme kasutatavale pin1-le sõbra juurde, et paremini visualiseerida PWM loogikat. Selleks tuleb ridade
pin1 = GpioController.GetDefault().OpenPin(18); pin1.Write(value1); pin1.SetDriveMode(GpioPinDriveMode.Output);
juurde lisada read
pin2 = GpioController.GetDefault().OpenPin(24); pin2.Write(value2); pin2.SetDriveMode(GpioPinDriveMode.Output);
Nagu näeme, võtame kasutusele viigi 24. Võib kasutada ka teisi viike, mille leiame juhendi alguses toodud viikide nummerdamise pildilt - kasutame ainult GPIO viike. Kuna me tahame näha, kui midagi viigiga muutub, oleks paslik just nüüd ühendada LED vastava viigiga ning 5V väljundiga.
Olgu pin1 ehk algne LED see, millel püüame tekitada servo jaoks sobilikku signaali, ning pin2 selle vastassignaal. Teisisõnu kui pin1 tekitab signaali, siis pin2 vaikib, ja vastupidi.
Et tekitada viitega lülitus igal ajamõõturi 'tiksul', on vajalik kasutada abimuutujaid. Koodi alguses on sobivad muutujad juba defineeritud:
int stall = 1; int stall_limit = 10;
Meie ülesanne on teha nõnda, et iga kümne 'tiksu' jooksul ühe ajal oleks põleks esimene LED, ülejäänud 'tiksude' ajal teine LED. Kiire arvutus näitab, et nõnda saame pulsi laiuseks 2ms (ehk tiksu intervalli) ja taktiks (ehk ajavahe kahe pulsi alguse vahel) 20ms, mis on võrreldav servo pööramiseks sobiliku signaaliga.
Selleks võiksime täiendada meetodit 'Ticker', kuid siinkohal me seda ei tee. Selle asemel kirjutame sisu meetodile 'Pulser'. Selles meetodis on sisenditeks kaks pin'i isendit p1 ja p2 ning nende pin'ide hetkeväärtused (High/Low) gpv1 ja gpv2. Kui lisame järgnevad read olemasoleva tingimuslause järele:
if (stall == 1) { Switch(p1,gpv1); Switch(p2,gpv2); stall++; } else if (stall < stall_limit) { stall++; } else { Switch(p1,gpv1); Switch(p2,gpv2); stall=1; }
Vaatame lähemalt, mida selline kood teeb. Kui viiteloendur on äsja alustatud, siis lülitatakse mõlemat LEDi ning liidetakse viiteloendurile väärtus 1 (kuju "stall++" on siinkohal võrdväärne kujuga "stall+=1" või kujuga "stall = stall + 1"). Kui viiteloendur on loendamas, siis lisatakse talle väärtus 1. Kui viiteloendur on oma piirini jõudnud ('stall_limit'), tehakse taas LEDide lülitus ning viiakse viiteloendur tagasi algusesse. Tulemusena oodatakse 8 tiksu niisama ning kahel järgneval tiksul lülitatakse LEDe vaheldumisi. Eeltehtud tingimuslause kindlustab selle, et LEDid ei alustaks olles mõlemad sama väärtusega.
Et kirjutatud koodi tulemust visuaalselt näha, tuleb valminud meetod mingil hetkel välja kutsuda. Selleks asendame meetodis 'Ticker' rea
Switch(pin1, value1);
reaga
Pulser(pin1, value1, pin2, value2);
Teoreetiliselt võib anda meetodile ette ka muutujad järjekorras (pin2, value2, pin1, value1), siinkohal on erinevus vaid selles, kumba LEDi kasutatakse pulsi andmiseks ning kumba vastandpulsi nägemiseks. Lisaks sõltub see LEDide algväärtustest.
Kui nüüd programm käivitada, kasutades taas rohelise noolega 'Remote Machine' nuppu, peaks üks LED vilkuma tihedamini kui teine ning mõlemad ei tohiks põleda samaaegselt. Katsetamise mõttes võib rakenduse peatada, vahetada meetodile muutujate andmise järjekorra ära, ning rakenduse uuesti käivitada.
Nõnda on võimalik õppida selgeks, mis on servo mootorite juhtimise taga olev loogika ning kuidas seda koodis kirjeldada. Põhimõtteliselt oleks võimalik nüüd teha mingile servole sobilikud draiverid, mis lihtsustaksid tulevikus Windows 10 operatsioonisüsteemiga Raspberryl servode juhtimist. Servode juhtimist tuleb tunda, et ehitada liikuvate osadega masinaid, nagu näiteks Microsofti näiteprojektiks tehtud õhuhokirobotit.