- Kas ir daudzuzdevumu veikšana?
- Kāpēc izlaist kavēšanos () Arduino?
- Kāpēc izmantot milis ()?
- Nepieciešamās sastāvdaļas
- Ķēdes shēma
- Arduino UNO programmēšana daudzuzdevumu veikšanai
Vairākuzdevumu ir novedusi datorus revolūciju, ja viena vai vairākas programmas var darboties vienlaicīgi, kas palielina efektivitāti, elastīgumu, pielāgošanās spējas un produktivitāti. Iegultās sistēmās mikrokontrolleri var apstrādāt arī daudzuzdevumus un vienlaikus veikt divus vai vairākus uzdevumus, neapturot pašreizējās instrukcijas.
Šeit šajā apmācībā mēs uzzināsim, kā Arduino veic daudzuzdevumu veikšanu ar Arduino millis funkciju. Parasti aizkaves () funkcija Arduino tiek izmantota periodiskam uzdevumam, piemēram, LED mirgo, taču šī aizkaves () funkcija uz noteiktu laiku aptur programmu un neļauj veikt citas darbības. Tātad šajā rakstā ir paskaidrots, kā mēs varam izvairīties no delay () funkcijas izmantošanas un aizstāt to ar milis (), lai vienlaikus veiktu vairākus uzdevumus un padarītu Arduino par Multitasking kontrolieri. Pirms sīkāk sāksim ar daudzuzdevumu nepietiekamu novērtēšanu.
Kas ir daudzuzdevumu veikšana?
Daudzuzdevumi vienkārši nozīmē vairāku uzdevumu vai programmu izpildi vienlaikus vienlaikus. Gandrīz visās operētājsistēmās ir daudzuzdevumi. Šāda veida operētājsistēmas ir pazīstamas kā MOS (daudzuzdevumu operētājsistēma). MOS var būt mobilā vai galddatora operētājsistēma. Labs piemērs daudzuzdevumu veikšanai datoros ir tas, ka lietotāji vienlaikus izmanto e-pasta lietojumprogrammu, interneta pārlūku, multivides atskaņotāju, spēles un ja lietotāji nevēlas izmantot lietojumprogrammu, kas darbojas fonā, ja tā nav aizvērta. Galalietotājs vienlaikus izmanto visas šīs lietojumprogrammas, taču OS šo jēdzienu uztver nedaudz atšķirīgi. Apspriedīsim, kā OS pārvalda daudzuzdevumus.
Kā redzams attēlā, centrālais procesors dala laiku trīs vienādās daļās un piešķir katru daļu katram uzdevumam / lietojumprogrammai. Lielākajā daļā sistēmu šādi tiek veikts daudzuzdevumu veikšana. Arduino Multitasking koncepcija būs gandrīz vienāda, izņemot to, ka laika sadalījums būs nedaudz atšķirīgs. Tā kā Arduino darbojas zemā frekvencē un operatīvā atmiņa, salīdzinot ar klēpjdatoru / mobilo / personālo datoru, katram uzdevumam piešķirtais laiks arī būs atšķirīgs. Arduino ir arī delay () funkcija, kas tiek plaši izmantota. Bet pirms sākšanas pārrunāsim, kāpēc mums nevienā projektā nevajadzētu izmantot delay () funkciju.
Kāpēc izlaist kavēšanos () Arduino?
Ja tiek apsvērta Arduino atsauces dokumentācija, ir divu veidu kavēšanās funkcijas: pirmā ir aizkave (), bet otra - aizkaveMikrosekundes (). Abas funkcijas ir identiskas attiecībā uz kavēšanos. Vienīgā atšķirība ir tāda, ka ar delay () funkciju nodotais parametrs vesels skaitlis ir milisekundēs, ti, ja mēs ierakstām aizkavi (1000), tad aizkave būs 1000 milisekundes, ti, 1 sekunde. Līdzīgi ar funkciju delayMicroseconds (), nodotais parametrs ir mikrosekundēs, ti, ja mēs rakstām delayMicroseconds (1000), tad aizkave būs 1000 mikrosekundes, ti, 1 milisekundes.
Šeit nāk punkts, abas funkcijas pārtrauc programmu uz laiku, kas pagājis kavēšanās funkcijā. Tātad, ja mēs piešķiram 1 sekundes aizkavi, tad procesors nevar pāriet uz nākamo instrukciju, kamēr nav pagājusi 1 sekunde. Līdzīgi, ja aizkave ir 10 sekundes, programma apstājas uz 10 sekundēm, un procesors neļaus izpildīt nākamos norādījumus, kamēr nav pagājušas 10 sekundes. Tas kavē mikrokontrollera darbību ātruma un instrukciju izpildes ziņā.
Labākais piemērs, lai izskaidrotu kavēšanās funkcijas trūkumu, ir divu spiedpogu izmantošana. Apsveriet, ka mēs vēlamies pārslēgt divas gaismas diodes, izmantojot divas spiedpogas. Tātad, ja tiek nospiesta viena spiedpoga, atbilstošajam LED vajadzētu mirgot 2 sekundes, līdzīgi, ja tiek nospiests otrais, tad LED vajadzētu mirgot 4 sekundes. Bet, kad mēs izmantojam aizkavi (), ja lietotājs nospiež pirmo pogu, programma apstājas uz 2 sekundēm un, ja lietotājs nospiež otro pogu pirms 2 sekunžu kavēšanās, tad mikrokontrolleris nepieņem ievadi, jo programma ir apstāšanās posmā.
Arduino oficiālajā dokumentācijā tas skaidri pieminēts funkcijas Piezīmes un brīdinājumi par kavēšanos () aprakstā. Varat to pārbaudīt, lai padarītu to skaidrāku.
Kāpēc izmantot milis ()?
Lai pārvarētu kavēšanās izmantošanas radīto problēmu, izstrādātājam jāizmanto funkcija milis (), kuru ir viegli izmantot, tiklīdz esat pieradis, un tā izmantos 100% CPU veiktspēju, neradot kavēšanos instrukciju izpildē. milis () ir funkcija, kas tikai atgriež milisekundes, kas pagājušas kopš Arduino dēļa darbības uzsākšanas, nesasaldējot programmu. Pēc aptuveni 50 dienām šis laika skaitlis pārpildīsies (ti, atgriezīsies uz nulli).
Tāpat kā Arduino ir delayMicroseconds (), tam ir arī mili () mikroversija kā micros (). Atšķirība starp mikros un milis ir tāda, ka mikroshēmas () pārpildīsies pēc aptuveni 70 minūtēm, salīdzinot ar milis (), kas ir 50 dienas. Tātad atkarībā no lietojumprogrammas varat izmantot milis () vai mikros ().
Aizkavēšanās () vietā tiek izmantots milis ():
Lai izmantotu milis () laika noteikšanai un aizkavēšanai, jums jāreģistrē un jāuzglabā laiks, kurā notikusi darbība, lai sāktu laiku, un pēc tam ik pa laikam jāpārbauda, vai ir pagājis noteiktais laiks. Tātad, kā norādīts, saglabājiet pašreizējo laiku mainīgajā.
neparakstīta garā strāvaMillis = milis ();
Mums ir nepieciešami vēl divi mainīgie, lai uzzinātu, vai ir pagājis nepieciešamais laiks. Mēs esam saglabājuši pašreizējo laiku mainīgajā currentMillis, taču mums arī jāzina, kad kad sākās laika periods un cik ilgs ir periods. Tātad intervāls un previousMillis ir deklarēta. Intervāls mums pateiks laika aizkavi un previosMillis saglabās pēdējo reizi, kad notikums ir noticis.
neparakstīts garš iepriekšējaisMillis; neparakstīts ilgs periods = 1000;
Lai to saprastu, ņemsim vienkārša mirgojoša LED piemēru. Periods = 1000 mums paziņos, ka gaismas diode mirgos 1 sekundi vai 1000 ms.
const int ledPin = 4; // LED tapas numurs savienots int ledState = LOW; // izmanto, lai iestatītu LED stāvokli neparakstīts ilgi previousMillis = 0; // glabās pēdējo reizi, kad gaismas diode mirgo const long period = 1000; // periods, kurā mirgot ms void setup () { pinMode (ledPin, OUTPUT); // iestatīt ledpin kā izvadi } void loop () { neparakstīta garā strāvaMillis = milis (); // saglabājiet pašreizējo laiku, ja (currentMillis - previousMillis> = periods) {// pārbaudiet, vai 1000ms ir pagājis iepriekšējāMillis = currentMillis; // saglabājiet pēdējo reizi, kad mirgot LED, ja (ledState == LOW) {// ja gaismas diode ir izslēgta, ieslēdziet to un otrādi ledState = HIGH; } cits { ledState = ZEMS; } digitalWrite (ledPin, ledState); // iestatiet LED ar ledState atkal mirgot } }
Šeit paziņojums
Pārtraukumi Arduino darbojas tāpat kā citos mikrokontrolleros. Arduino UNO dēlī ir divas atsevišķas tapas pārtraukumu piestiprināšanai GPIO tapās 2 un 3. Mēs to esam detalizēti aplūkojuši Arduino pārtraukumu apmācībā, kur varat uzzināt vairāk par pārtraukumiem un to izmantošanu.
Šeit mēs parādīsim Arduino daudzuzdevumus, vienlaikus rīkojoties ar diviem uzdevumiem. Uzdevumi ietvers divu gaismas diode mirgošanu ar dažādu laika aizturi, kā arī spiedpogu, kas tiks izmantota LED ieslēgšanas / izslēgšanas stāvokļa kontrolei. Tātad vienlaikus tiks veikti trīs uzdevumi.
Nepieciešamās sastāvdaļas
- Arduino UNO
- Trīs gaismas diodes (jebkura krāsa)
- Pretestības (470, 10k)
- Džemperi
- Maizes dēlis
Ķēdes shēma
Ķēdes shēma Arduino Millis () fuction izmantošanas demonstrēšanai ir ļoti vienkārša, un tai nav daudz pievienojamu komponentu, kā parādīts zemāk.
Arduino UNO programmēšana daudzuzdevumu veikšanai
Lai programmētu Arduino UNO daudzuzdevumu veikšanai, būs nepieciešama tikai loģika, kas nosaka, kā darbojas milis (), kas ir paskaidrots iepriekš. Pirms sākat programmēt Arduino UNO daudzuzdevumu veikšanai, ieteicams atkal un atkal mirkšķināt LED, izmantojot milis, lai padarītu loģiku skaidru un padarītu sevi ērti ar miliem (). Šajā apmācībā pārtraukums tiek izmantots arī ar milis () vienlaikus daudzuzdevumu veikšanai. Poga būs pārtraukums. Tāpēc ikreiz, kad tiek ģenerēts pārtraukums, ti, tiek nospiesta spiedpoga, gaismas diode ieslēgsies ON vai OFF stāvoklī.Programmēšana sākas ar tapu numuru deklarēšanu vietās, kur ir pievienotas gaismas diodes un spiedpoga.
int led1 = 6; int led2 = 7; int toggleLed = 5; int spiedpoga = 2;
Tālāk mēs uzrakstām mainīgo, lai saglabātu gaismas diožu statusu turpmākai izmantošanai.
int ledState1 = ZEMS; int ledState2 = ZEMS;
Tāpat kā paskaidrots iepriekš mirgojošajā piemērā, tiek deklarēts, ka mainīgie par periodu un iepriekšējiem miljoniem salīdzina un rada kavēšanos gaismas diodēm. Pirmais gaismas diode mirgo ik pēc 1 sekundes un vēl viena LED mirgo pēc 200ms.
neparakstīts garš iepriekšējaisMillis1 = 0; konst garais periods1 = 1000; neparakstīts garš iepriekšējaisMillis2 = 0; konst garais periods2 = 200;
Lai radītu atkārtošanās aizkavi, tiks izmantota vēl viena milisa funkcija, lai izvairītos no vairākkārtējas spiedpogas nospiešanas. Būs līdzīga pieeja kā iepriekš.
int debouncePeriod = 20; int debounceMillis = 0;
Šīs trīs mainīgie tiks izmantoti, lai uzglabātu statusu spiedpogu kā pārtraukt, pārslēgšanas LED un spiediet pogu stāvoklī.
bool buttonPushed = false; int ledChange = LOW; int lastState = AUGSTS;
Definējiet piespraudes darbību, kura tapa darbosies kā INPUT vai OUTPUT.
pinMode (led1, OUTPUT); pinMode (led2, OUTPUT); pinMode (toggleLed, OUTPUT); pinMode (spiedpoga, INPUT);
Tagad definējiet pārtraukuma tapu, pievienojot pārtraukumu ar ISR definīciju un pārtraukuma režīmu. Ievērojiet, ka, deklarējot funkciju attachInterrupt (), ieteicams izmantot digitalPinToInterrupt (pin_number) , lai tulkotu faktisko digitālo tapu uz konkrēto pārtraukuma numuru.
attachInterrupt (digitalPinToInterrupt (pushButton), pushButton_ISR, CHANGE);
Pārtraukšanas apakšprogramma ir rakstīta, un tā mainīs tikai buttonPushed karodziņu. Ņemiet vērā, ka pārtraukuma apakšprogrammai jābūt pēc iespējas īsākai, tāpēc mēģiniet to uzrakstīt un samaziniet papildu norādījumus.
void pushButton_ISR () { buttonPushed = true; }
Cikls sākas ar milisu vērtības saglabāšanu mainīgajā currentMillis, kas glabā pagājušā laika vērtību katru reizi, kad cilpa atkārtojas.
neparakstīta garā strāvaMillis = milis ();
Kopā ir trīs funkcijas, veicot daudzuzdevumus, mirgot vienu gaismas diode vienā sekundē, mirkšķināt otro LED pie 200 ms un, ja tiek nospiesta spiedpoga, izslēdziet izslēgšanas / ieslēgšanas LED. Tāpēc mēs uzrakstīsim trīs daļas, lai veiktu šo uzdevumu.
Pirmais ir pagājis pārslēgšana LED stāvokli pēc katras 1 sekundi, salīdzinot Millis.
ja (pašreizējaisMillis - iepriekšējaisMillis1> = periods1) { iepriekšējaisMillis1 = pašreizējaisMillis; ja (ledState1 == LOW) { ledState1 = HIGH; } cits { ledState1 = ZEMS; } digitalWrite (led1, ledState1); }
Līdzīgi, otrkārt, tas pārslēdz LED ik pēc 200 ms, salīdzinot pagājušos milis. Paskaidrojums jau ir paskaidrots iepriekš šajā rakstā.
ja (pašreizējaisMillis - iepriekšējaisMillis2> = periods2) { iepriekšējaisMillis2 = pašreizējaisMillis; ja (ledState2 == LOW) { ledState2 = HIGH; } else { ledState2 = LOW; } digitalWrite (led2, ledState2); }
Visbeidzot, buttonPushed karodziņš tiek uzraudzīts, un pēc 20ms atlēciena kavēšanās ģenerēšanas tas vienkārši pārslēdz LED stāvokli, kas atbilst spiedpogai, kas pievienota kā pārtraukums.
if (buttonPushed = true) // pārbaudiet, vai ISR tiek izsaukts { if ((currentMillis - debounceMillis)> debouncePeriod && buttonPushed) // ģenerēt 20ms atlēciena aizkavi, lai izvairītos no vairākkārtējas nospiešanas { debounceMillis = currentMillis; // saglabājiet pēdējo atlēciena aizkaves laiku, ja (digitalRead (pushButton) == LOW && lastState == HIGH) // nomainiet indikatoru pēc tam, kad ir nospiesta poga { ledChange =! ledChange; digitalWrite (toggleLed, ledChange); lastState = ZEMS; } else if (digitalRead (pushButton) == HIGH && lastState == LOW) { lastState = HIGH; } buttonPused = false; } }
Tas pabeidz Arduino millis () apmācību. Ņemiet vērā, ka, lai ierastu ar milis (), vienkārši praktizējiet šīs loģikas ieviešanu dažās citās lietojumprogrammās. Varat to arī paplašināt, lai izmantotu motorus, servomotorus, sensoru un citas perifērijas ierīces. Ja rodas šaubas, lūdzu, rakstiet uz mūsu forumu vai komentāru zemāk.
Pilns kods un video, lai parādītu milis funkcijas izmantošanu Arduino, ir sniegts zemāk.