Nem vagyok Arduino szakértő, annak ellenére, hogy sokáig nálam volt a lemez, alig vizsgáltam. Azok az idők, amikor már használtam, a már létrehozott kód másolásának és beillesztésének eszközeként jelent meg, de nem érdekelt különösebben a működésének megismerése, hanem egyszerűen azzal a szándékkal, hogy működőképessé és hasznos legyen számomra. Idén karácsonykor kissé hangoltam a betlehemet néhány LED-del és egy HC-SR04 ultrahang érzékelővel. És megálltam megfigyelni, hogy mit kell tenni.
Csak különböző dolgokat akartam csinálni két LED-mel ugyanabból a jelből. Hoppá. Gyorsan rábukkantam arra, ami szerintem lesz az egyik első korlátozás, amellyel találkozol, amikor elkezded kavarogni az Arduinóval. És nem kell túl bonyolulttá tenni. Csak néhány LED-ről beszélek, rájössz, hogy nem csinálhatod helyesen azt, amit akarsz.
Tisztázzuk a kezdetektől fogva az Arduino-ban nem létezik multitasking, két munkát nem lehet párhuzamosan feldolgozni. De vannak olyan technikák, amelyekkel olyan gyorsan lehet hívni, hogy úgy tűnik, hogy egyszerre működnek.
Részletesebben elmondom az esetet. Karácsonykor felállítottam egy betlehemet, és azt akartam, hogy bizonyos betlehemek világítsanak, amikor a lányaim meglátogatják. Semmi bonyolult. Csak azt akartam, hogy a led-lámpák két ága másképp működjön, mint a közelségérzékelő értéke.
Azt akartam, amikor valaki 10 cm-nél közelebb ért
- A csillagokhoz jutó fények egyik ága 10 másodpercig világít
- Hogy a másik, aki bemegy a házakba, 10 másodpercig marad, de mivel elváltak a kiságytól.
Egyszerű, igaz? mivel ez nagy problémákat okozhat neked. Mivel az Arduino nem képes multitaskingra, egyik parancsot a másik után hajtja végre.
Megcsináltam a felszerelés a HC-SR04 ultrahangos érzékelővel és 2 LED, mindegyik egyenértékű lenne a Betlehem egyik ágával. Az első rész nem túl vicces, mivel az ultrahang-érzékelő beállítását és működését kell konfigurálni a LOOP-ban, de ezt több ezer helyen megtalálhatja. Mint egy másik nap, ha többet tudakozok, készítek egy különlegességet, most itt vagy (sajnálom, hogy nem tettem fel krediteket, de nem emlékszem, honnan vettem)
HC-SR04 kód az Arduino-n
int ledPin1 = 8; int ledPin2 = 7; távolsági; hosszú idő; hosszú áramidő; hosszú időzítés; void setup () {// inicializálja a LED_BUILTIN digitális tűt kimenetként. pinMode (ledPin1, OUTPUT); pinMode (ledPin2, OUTPUT); Soros kezdet (9600); pinMode (3, OUTPUT); / * a 9. tű aktiválása kimenetként: az ultrahangos impulzushoz * / pinMode (2, INPUT); / * a 8. tű aktiválása bemenetként: ultrahang visszapattanási idő * /} // a ciklusfunkció újra és újra fut örökre void loop () {digitalWrite (3, LOW); / * Az érzékelő stabilizálása miatt * / késleltetésMikroszekundum (5); digitalWrite (3, HIGH); / * az ultrahangos impulzus küldése * / delay mikroszekundum (10); idő = pulzusIn (2, HIGH); / * Funkció a bejövő impulzus hosszának mérésére. Méri az ultrahangos impulzus küldése és az érzékelő visszapattanása közötti időtartamot, vagyis attól kezdve, amikor a 12. érintkező megkezdi a visszapattanást, HIGH, amíg abbahagyja ezt, LOW, a bejövő impulzus hosszát * / távolság = int (0.017 * idő); / * képlet a teljes távolság kiszámításához * / / * Monitorozás centiméterben a soros monitoron * / Serial.println ("Távolság"); Soros.println (távolság); Soros.println ("cm"); késés (1000);
Ezzel az ultrahang-érzékelő által mért távolságot felülvizsgálják és tárolják
LEDS működési megoldás
Az első dolog, ami eszembe jut, az, hogy el kell kezdeni a késéseket. Nem tudom, miért, de minden kezdő gondolkodik a késésen (), és ez nagymértékben korlátozza a lehetőségeket, mert a delay () használata közben a tábla nem működik tovább, ezért ebben a felfüggesztési időben nem tehet mást. A megoldás millis () használata
Itt találtam az if és a számlálók alapján egyszerű megoldást. Ahogy egy tanárom szokta mondani, bármit be lehet programozni sok IF-vel egymás után. De az igazság természetesen nem túl elegáns.
// ha a távolság kisebb 10-nél, bekapcsoljuk a két LED-t vagy elágazást, és millis () értékkel kezdjük el számolni az időt (if <távolság <10) {digitalWrite (ledPin1, HIGH); digitalWrite (ledPin2, HIGH); aktuális idő = millisz (); } // ha a távolság nagyobb, mint 10, ellenőrizzük a bekapcsolása óta eltelt időt, és ha nagyobb, mint a jelzett, akkor kikapcsoljuk a LED1-et, ha (távolság> 10) {timepast = millis () - currenttime ; digitalWrite (ledPin1, LOW); // ha a távolság nagyobb, mint 10000, akkor kikapcsoljuk a LED2-t, ha (timepast> 10000) {digitalWrite (ledPin2, LOW); }}}
Ennek a kódnak az a célja, hogy az Arduino folyamatosan végrehajtja ezt a három IF-t, hogy olyan gyorsan átmenjen rajtuk, hogy úgy tűnik, hogy több dolgot is csinál egyszerre. De mint már tudjuk, folytatja a mondatok végrehajtását egyesével.
Miután a távolságot megmérte és eltárolta a változóban távolság, az if-eket kiértékelik:
- Az első ellenőrzi, hogy a távolság kisebb-e a kívánt 10 centinél. Ha igen, bekapcsoljuk a két LED-et, és milliszámmal () kezdjük el számolni az időt
- és a másodikra mennénk, ha a távolság nagyobb, mint 10 cm. Ha megfelel, kiszámoljuk az eltelt időt, és kikapcsoljuk az 1-es ledet, amely csak a távolságtól függ.
- A harmadikhoz mennénk, ha ellenőrizzük, hogy telt-e el több mint 10 másodperc a számláló aktiválása óta, és ha igen, kapcsoljuk ki a 2-es csapot
- És így megy tovább a hurok. És újra.
Végül, és bár a megoldás működött, számomra egyértelmű volt, hogy ezt a problémát biztosan sokan tapasztalták, és hogy ortodox megoldásnak kell lennie. Elkezdtem keresni, és találtam egy jót (ami biztosan nem az egyetlen) a fiúktól Adafruit és objektum-orientált programozás. Ez meghatározott osztályú objektumok létrehozásából áll, hogy gyors hívásokat kezdeményezzenek, és ne kelljen több százszor megismételni a kódot programunkban.
Ami végül "ugyanaz", mint az én megoldásom az + + számlálókkal, de sokkal elegánsabb, és ez sokkal olvashatóbb és sokkal hatékonyabb kódot nyújt.
A multitasking kezelése elkerülhetetlenül időgazdálkodáshoz vezet Arduino-ban. Eleinte ez nem szerepelt a cikkben, de szerintem nagyon érdekes.
Arduino és időfunkciók
Ahogy már kommentáltam Azt hiszem, nagy függőség van késéssel () , valószínűleg azért, mert az induló emberek ezt a funkciót látják az összes példában, amelyeket általában villogástól bármelyik lámpáig vagy a LED-ek be- és kikapcsolásáig manipulálnak.
A késleltetésnek van egy nagyon nagy problémája, mégpedig az, hogy ha egy ideig a delay()-t hívjuk, akkor minden leáll. A tábla nem olvas semmilyen érzékelőt, nem folytatja a mondatok végrehajtását, és egyáltalán nem csinál semmit, csak várja meg a megadott időt, és természetesen ha a táblát egynél több dologra akarjuk használni ugyanakkor ez nem életképes.
Rá kell néznünk millisz () még a delayMicroseconds()-hoz És van micros() is, ami visszaadja a program futása óta eltelt mikroszekundumok számát
Késedelem nélkül pislogjon
Remek példa a működésére futtassa a mitikus Blinket, de késedelem nélkül. A fő különbség az, hogy megfeledkezik a delay () funkcióról, és millis () értéket használ a műveletek közötti eltelt idő számításához.
Az Arduino megszakításainak ismerete segíthet a programok bizonyos fokú többfeladatos végrehajtásában.
Szia Leandro, nagyon köszönöm. Nem ismerem a megszakítások témáját. Kivizsgálom, hogy megnézzem :)
VAN egy menetrend-funkció, amely TÖBB HETŐSÉGET LEHET MEGADNI