Arduino szimulátor

Tartalom:

  • Bonyolult algoritmusok kipróbálása, fejlesztése Arduino szimulátorban
  • Az UnoArduSim program letöltése és telepítése
  • A program használata, gyakorlati mintapéldák a használat megtanulásához
  • Program debug lehetőségek, változó tartalmak
  • Nyomógomb, LED, LCD kijelző stb. használata a szimulátorban
  • Valós idejű működés, idő múlása a lépésenkénti végrehajtás alatt

——————————————————————-

Aki programot ír, annak biztosan előfordul olyan esete, amikor elveszik a saját programjában, és az teljesen mást csinál mint amit szeretne. Ezeknek a „megőrült” programoknak az okozója a készítő, az átgondolatlanság, és a rossz struktúra. Vagyis önmagunk. De ha ez megtörtént, akkor a hibát ki kell javítani, és ez időnként nem egyszerű. A baj az Arduino-val van! A program az Arduino-ban fut és mivel nincs üvegből a tokozása és megfelelő méretű nagyítónk sincs kéznél, nem láthatjuk a programban használt változók értékét. Így aztán nyomon követhetetlen, hogy az IF utasításokban éppen hol tévelyeg a programunk. Az egyedüli segédeszközünk, ha valahogyan információt juttatunk ki a chip-ből. Használhatunk erre egy LED-et, vagy egy LCD kijelzőt, de a legegyszerűbb a soros port. Azonban nagyon lelassítja a programot és a fejlesztési időt is, ha a programsorok közé kell beírogatni további sorokat, amik más sem csinálnak csak megjelenítik a változók értékét.

Milyen csodálatos dolog lenne, ha valamilyen módon láthatóvá tennénk a változókat program futás közben! Erre az egyik lehetőség, hogy vegyünk egy fejlettebb mikrovezérlőt. Reményeim szerint erre lesz jó a SAMD21 ARM Cortex processzorral szerelt alaplap, ami teljesen megegyezik méretben, és programozási környezetben az Arduino UNO-val, csak éppen a mikrovezérlője támogatja a program debug-ot, azaz segíti a lépésenkénti végrehajtást, és a változók megjelenítését a fejlesztő eszközben. Ehhez persze az Arduino IDE programot is le kell cserélni egy Arduino Pro Ide nevű programra. Az alaplapot már megrendeltem. Azonban amíg ez meg nem érkezik, maradnak a gyengébb megoldások. És persze ennek is lesznek hátrányai, mert ez a vezérlő, és így az alaplap kivezetései is 3.3V-os rendszerben működnek. Egy csomó modul nem fog vele közvetlenül működni, csak szintillesztővel.

A programhibák megkeresésére, és a fejlesztés támogatására jelenleg egyetlen segédeszközt találtam, az Arduino szimulátor programokat. Elég sok programot megnéztem, egyik rosszabb és használhatatlanabb, mint a másik. Én persze lelkes amatőrként az ingyenes programokat kerestem. Az alább ismertetett UnoArduSim program már megüti a használhatóság határát. Egy alkalommal már kimentett a bajból, amiért hálával tartozom, de nem szeretem. Csak rosszat tudok róla mondani, viszont nincs más. Működési elvéből és felépítéséből adódóan nem lehet benne egy az egyben futtatni a problémás kódunkat. Az Arduino-hoz led, nyomógomb szervó TFT és karakteres LCD és még néhány dolog kapcsolható hozzá, de ezek nagyon általánosak, és nem pont olyanok mint amiket a gyakorlatban használni szoktam. Pl. a karakteres LCD kijelző nem I2C konverterrel működik (nem ilyet szimulál), hanem direktben kell sok Arduino lábat elhasználva bekötni. Van ugyan egy I2C buszos lehetőség, de ehhez egy olyan könyvtárat használ, ami nekem nem esett kézre, a legtöbb megszokott LCD függvény nem működött, vagy nem úgy, ahogyan megszoktam. Pl. nem fogadta el a backlight() illetve a noBacklight() függvényeket. Így leginkább arról lehet szó, hogy a kritikus programrészeket kimásoljuk, némi környezeti átalakítást végzünk rajta (pl. a hőmérő modul lekérdezését egy konkrét hőmérséklettel helyettesítjük) és így keressük meg a hibát. Amit aztán majd az eredeti programban is ki fogunk tudni javítani, ha ebben a környezetben megtaláltuk.

Ha mindezeket a korlátozásokat és kényelmetlenségeket elfogadjuk, akkor egész jó kis program. Minden tiszteletem az alkotóé! Ha jól értelmeztem a weboldalt, akkor egyedül írta az egészet. Van hozzá dokumentáció is, el lehet vele boldogulni.

Itt lehet letölteni: https://www.sites.google.com/site/unoardusim/


Pontosabban itt lehetett letölteni! Úgy tapasztaltam, hogy a weboldal már megszűnt. Esetleg még fellelhetők verziók a neten. Szerencsére nekem van egy legutolsó állapotom, amit még lehet használni. Innen lehet letölteni! Csak ki kell bontani, és elindítani az unoardusim.exe programot!


Telepíteni nem kell, a kibontást követően másoljuk oda a kapott könyvtárat, ahová csak szeretnénk. Keressük meg az „UnoArduSim.exe” programot, ezt kell futtatni. Ugyanebben a könyvtárban találunk használhatóan részletes használati útmutatót pdf formátumban. Így néz ki ha elindítjuk a programot:

Ezen a kinézeten sokat lehet egyszerűsíteni, ha az éppen felesleges alkatrészeket kikapcsoljuk (lásd később). Használata ingyenes. Láthatóan még jelenleg is fejleszti a készítő, rendszeresen jelennek meg új verziók. Az alap problémák sajnos a program kialakításában vannak, de ezeken lépjünk túl.

Nagy előnye a programnak, hogy a szimuláció során lépésről lépésre követhetjük a program működését, és az összes változó értékét látjuk minden pillanatban.

A képernyő felépítése:

A képernyő jól áttekinthető, de sajnos az Arduino alaplap és a kapcsolódó alkatrészek tervező felülete nagyon primitív, és program futás közben zavaros a látvány. Pl. ha több LED is szerepel a programban, azokat könnyű összekeverni. A fent látható példában a klasszikus Blink programot helyeztem el, ami ugyebár a futtatáshoz mindössze egy LED-et igényel. Úgy konfiguráltam, hogy a képernyőn csak az Arduino alaplap és egy LED legyen látható. Az alkatrészek mindegyike egy négyzet alakú kicsi keret, amibe bezsúfolta az alkotó a paramétereket. Jelen esetben a LED kis négyzetében a 13-as szám azt jelenti (én írtam be), hogy a LED-et a 13-as Arduino lábra kötöttük. Az R betű, hogy piros színnel világít. Még beállíthatnánk, hogy magas vagy alacsony szintnél világítson, és kész is vagyunk. Tehát ez nem egy grafikusan beállítható program. Számokkal, betűkkel kell paraméterezni, de egy kicsi grafikával megtámogatott. A képen a LED éppen világít, mert a fut a program, és magas szint van a 13-as kivezetésen. Ezt a piros „1” is jelzi számunkra a kivezetés mellett. Nem is kellett volna LED a kimenetre. A beépített LED az Arduino-n sárgán világít.

Lássuk sorban a használat lépéseit. Ehhez először a file menüben be kell töltenünk a programot. Esetleg kattintsunk duplán a program nyomkövető felületre, és megjelenik egy editor, amibe be is írhatjuk, vagy Ctrl+C és Ctrl+V-vel bemásolhatjuk a szükséges részeket:

A használat rettenetesen fapados, de legalább a nyelvi elemeket külön színezi. Jobbra középen a fekete sávban találunk egy kis összefoglalót a használható constansok, függvényok utasítások csoportosított listájával. Hasznos szolgáltatás. A logikai kifejezésekben nem ismeri az and or stb. szavakat & és | jeleket fogad csak el. Az Arduino IDE által hiba nélkül lefordított programokat nem mindig „eszi” meg, kell kicsit változtatni. Az a C++ nyelv másik változata lehet. Nem értek ennyire hozzá, de nagyjából elboldogultam a hibaüzenetek alapján.
Nagyon bosszantó, hogy az utasítások lezárására nem lehet a „;”-t kitenni, mert a billentyűzetről nem fogadja el. Sem a laptopomon, sem az asztali gépemen nem működik, és nem sikerült rájönnöm mi az oka. Szerencsére lemásolható egy másik sor végéről, és Ctrl+V-vel be lehet illeszteni.
Ha módosítunk a programon, akkor a „Save” menüponttal menthetjük. Ha ebbe az editorba másoljuk a programot valahonnan, akkor is érdemes előtte még a főmenü file menüjében egy „mentés másként”-el megcsinálni az állományt, különben ez a save egy alapértelmezett állományban fog menteni a program indítási könyvtárába. A Compile lefordítja a programot. Ha hibát talál, akkor az az alsó zöld sávban jelzi. Minden hibát ki kell javítani, és az Accept gombbal betölteni a programot a főképernyőre. Ekkor jön a futtatás. Ehhez a felső sorban van egy csomó kis ikon, ezeket inkább a menüből mutatom:

Kis próbálkozással rá lehet jönni, melyik mit csinál. A legfontosabb az F4 gomb a billentyűzeten, amivel soronként lehet végrehajtani a programot. Egy sorba csak egy utasítást írjunk, és akkor ez tényleg teljesül is. Ha csak simán futtatni akarjuk a programot, ahhoz az F9 kell. Ha egy kijelölt pontig szeretnénk, ha elfutna a program F4 nyomkodás nélkül, akkor tegyük a kérdéses program sorra a jelölést, azaz kattintsunk rá (sötét lesz a teljes sor), és nyomjuk meg az F7 billentyűt.
Persze egérrel is lehet kattogtatni a megfelelő ikonokon, de az lehet, hogy másra fog kelleni, mert valamivel a nyomógombokat és egyéb alkatrészeket is kezelni kell esetleg.

Egy csomó alkatrészt kirakhatunk a képernyőre, és ezeket a Configure / I/ODevices  menüpontban tudjuk beállítani:

Az egyes kis kockákba beírhatjuk, hogy abból az izé-ből éppen hányat szeretnénk használni. Én ezek közül a „Text LCD (I2C)” nevűt használtam információ megjelenítésre, ezért ezt szeretném részletesebben megmutatni:

Így néz ki. Szerencsére minden be van rajta alapból állítva, bár ha szoftveresen megírjuk az I2C működést, akkor feltehetőleg van értelme az A4 és A5 Arduino-n alapértelmezett kivezetéseket átállítani más kivezetésre. Most rögvest pipáljuk be a Backpack jelölőt, és kattintsunk duplán az ablakra a folytatáshoz:

Itt már csak a kijelző típusát kell kiválasztani, ami most legyen 2×16 karakteres. És ekkor már látható a kijelző. Ezt az ablakot a program futtatása előtt előre ki kell nyitni, és akkor indítani a szimulációt. A kijelzőre íráshoz csak a programhoz mellékelt könyvtár használható. Ezt a futtatható program (ahová másoltuk a kibontott könyvtárat) „Include_3rdParty” alkönyvtárában találjuk. Sokat vesződtem vele, mire kiszedtem, illetve megértettem a leírásból, mit kell csinálni, hogy működjön. Itt egy példa program, ez elinduláshoz pont elegendő:

#include <Wire.h>
#include <Adafruit_LiquidCrystal.h>
Adafruit_LiquidCrystal lcdx(0); // set the LCD address to 0x20(Cooperate with 3 short circuit caps) 
                                //for a 16 chars and 2 line display

void setup()
{
  lcdx.begin(16,2);
  lcdx.setCursor(0,0);
  lcdx.print("Poba");
}

void loop()
{
}

A futás eredménye:

Tulajdonképpen nem sok mindenre kell használni az LCD kijelzőt, hiszen a program futása közben az összes változó értéke programsorról programsorra végigkövethető. Nyilván a „kinézet” tervezéséhez hasznos lehet főleg a nagyobb mérető kijelzőkön. Azonban a TFT kijelző egyértelműen hasznos, megtervezhető és kipróbálható a grafikus megjelenés, mielőtt az Arduino-ba töltenénk. Ezt még nem használtam, így nincs vele tapasztalatom. Másik roppant hasznos dolog, hogy vannak általános I2C modulok, valamint shift regiszter stb. amiken nyomonkövethető az információ áramlása. Egy shift regiszterben pl. programsoronként láthatjuk, milyen bitek lépnek be a regiszterbe. Ezek mind jól jönnek fejlesztés során. Amit még fontosnak tartok megemlíteni, hogy a változók értékét futás közben át lehet írni. Ehhez csak annyit kell tenni, hogy a stop gombbal leállítjuk a programot, duplán kattintunk a változóra, a megjelenő abalakban beírjuk az új értéket, és megnyomjuk az Accept gombot, majd a kis „X”-el kilépünk az abalakból

A programot lehet folytatni immár az új vátozó értékkel akár lépésenként, akár folyamatos futtatással. Érdekes lehetőség ez a hibakeresésben, vagy akár egy programrész működésének finomításában.

Még egy nagyon fontostulajdonságra derült fény nemrégiben! A szélsebességmérőm programját tökéletesítettem, és ehhez használtam a szimulátort. Az Arduino egyik bemenetére kötöttem a részegységek között található impulzus generátort. Ennek periódus idejét s kitöltési tényezőjét is külön-külön be lehet állítani, így tökéletes volt számomra. Ráadásul futás közben is lehet állítani ezeket az értékeket, a szimulációt nem is kell megállítani. A szélsebességet egy „v” nevű változóba számítottam ki, amit a változó értékek között lehet látni, tehát a szélsebesség közvetlenül leolvasható volt a szimulátorról. Ekkor derült ki számomra, hogy a szimulátor valós időben működik. Bár ez a leírásban is benne volt, ha vettem volna a fáradságot és előre elolvasom, előre kiderül. A PC teljesítménye nagyságrendekkel nagyobb, mint egy ATMega328 chip teljesítménye, így bőven belefér, hogy a változók értékét is kiírja a képernyőre, plusz egy-egy utasítás végrehajtási ideje a valóságos végrehajtási idővel legyen azonos. Tehát minden úgy zajlott időben is, mint a valóságban.

Természetesen a program elsőre nem sikerült tökéletesen, és ezért lépésről lépésre kellett végrehajtani. Aggódtam, hogy mi történik e közben az időmérésekkel, és az impulzus generátor által generált impulzussal. Jelentem ez is tökéletes! Amikor végrehajtok egy-egy lépést, csak a tényleges program sor végrehajtásának idejéig megy előre az idő, amíg bámulom a képernyőt, áll minden. Az impulzusgenerátor sem generálja az impulzusokat a programtól függetlenül. Amikor a programsorok végrehajtásának idejéből összejön annyi idő, ami egy fel és lefutó él között szükséges, akkor fog csak a kimenete váltani.

Okulásul itt az általam kipróbált program. Kevésbé lényeges, hogy mit csinál, de jól mutatja be a valós idő múlását a szimulátorban.

float t_ido;    //segéd változó az átlagos körül fordulási idő számításához
long ido_5s=0;  //5 másodperc után állónak tekintem a szélkereket, ha nem volt impulzus, ahhoz kell ez a segédváltozó
long ido1=0;    //a fél másodperc alatt történt impulzusok teljes ideje
int n_imp=0;    //ebben tárolom a felfutó élek darabszámát
float v=0;      //kiszámított szélsebesség =egy fordulat a szélsebességmérőn 2,5km/h (gyártói adat)
long tmp;       //segédváltozó idő múlásának megjelenítéséhez

void setup()
{
  pinMode(2,INPUT);    //2-es kivezetéshez kötöttem az impulzus generátort
}

void loop()
{
  t_ido=0;
  ido_5s=millis();                 //innen számoljuk az 5 sec időt
  ido1=0;                          //két felfutó él között eltelt idő
  n_imp=0;                         //felfutó élek száma
  do {
    while (digitalRead(2)==0) {    //keressük a felfutó élet ezzel a ciklussal
      if (ido_5s+5000<millis()) {  //ha 5 másodperc alatt sincs semmi, akkor áll
        //adas(0);
        v=0;
        ido_5s=millis();           //újra kezdjük az 5 sec mérését, és várjuk tovább a felfutó élet
                                   //5 másodperc múlva újra megkapjuk, hogy még mindig 0 a sebesség
      }
    }
    //megjött a felfutó él
    if (n_imp==0) { ido1=millis();n_imp++;tmp=millis();}    //ha ez az első felfutó él, akkor elindítjuk az időmérést
    else {
      if (ido1+500<millis()) {               //ha eltelt 500msec az első felfutó él óta, és jött legalább még egy impulzus,
                                             //akkor lehet sebességet számolni és továbbítani
        t_ido=(float)(millis()-ido1)/n_imp;  //átlagos körül fordulási idő számítása (min fél másodperces időszakokra átlagolok)
        v=(float)2.5*1000/t_ido;             // ez az utolsó fél másodperc átlagos szélsebessége
        break;                               //kilépünk és újrakezdünk mindent
      }
      n_imp++;

    }
    ido_5s=millis();                         //innen figyeljük megint az 5sec időt, 
                                             //ha letelik, és incs lefutó él, akkor 0 a sebesség
    tmp=millis();                            //csak az idő múlását követem, ezért olvasom be tmp-be millis() értékét. 
                                             //A program működésében nincs szerepe, de így látom a szimulátorban az idő múlását
    while (digitalRead(2)==1) {              //keresni kezdem a lefutó élet ezzel a ciklussal (addig fut, amíg a bemenet HIGH
      if (ido_5s+5000<millis()) {            //ha 5 másodperc alatt sincs semmi, akkor áll a szélkerék, és v=0
        v=0;
        ido_5s=millis();                     //újra kezdjük az 5 sec mérését, és várjuk tovább a felfutó élet
                                             //5 másodperc múlva újra megkapjuk, hogy még mindig 0 a sebesség
      }
    }
    tmp=millis();                            //csak az idő megjelenítéséhez a szimulátorban
    //megjött a lefutó él 
  } while (true);                            //Főciklus újra indul, várjuk a felfutó élet
}

És egy fotó a szimulátorról futás közben. Ha az Arduino kivezetésre kattintunk, a bemenet állapota idődiagrammon is követhető, ezt is bekapcsoltam:

Elég sok negatív megjegyzésem volt az elején, de végül is egész jól használható program.

Mennyire volt hasznos amit olvastál? Értékelés után szövegesen is leírhatod megjegyzéseidet és véleményedet!

Kattints egy csillagra az értékeléshez!

Szövegesen is leírhatod véleményedet! Ha kérdésed van, ne felejtsd el megadni az email címedet!