Arduino Mills pulkstenis no sākuma. Arduino vairākuzdevumu veikšana ar Millis funkciju. Izmantojot arduino aizkaves funkciju
Sveiks Andrej. Jūsu pieeja uzkrāto zināšanu un pieredzes bagāžas nodošanai ir ļoti interesanta. Tas ļoti palīdz uzsākt darbu. Nu, man, sākot apgūt arduino, ir vēlme progresēt. Turklāt ar ārēju palīdzību es to varu izdarīt ātrāk. Tātad: sākumā mans uzdevums bija izveidot robotu, kas kustas pa līniju. Izdarīja - viss kārtībā. Bet tālāk, sniedzot viņam papildu iespējas, viņš nesaprata, kāpēc viņš pārtrauca pareizi reaģēt uz līniju. Es uzgāju šo rakstu un sapratu, kāpēc.
Tagad man jums ir jautājums: zemāk esošajā skicē un gatavs, ņemot vērā problēmas ar kavēšanos, vai man ir jāpārslēdzas uz mili visur, kur šī funkcija ir pieejama? Ja tā, tad es saprotu, ka gandrīz visa skice būs jāpārtaisa? Un nav līdz galam skaidrs, kā attāluma mērīšanā izmantot mili? Paldies.
//Robots ar baltu līniju sekojošu funkciju
// ********************* Iestatiet motora vadus ************************* *
int Motor LeftSpeed = 5; // Kreisais (A) Motors SPEED - ENA
int MotorLeftForward = 4; // Kreisais (A) motors FORWARD - IN1
int MotorLeftBack = 3; // Kreisais (A) Motors BACK - IN2
int MotorRightForward = 8; // Pa labi (B) Motors FORWARD - IN3
int MotorRightBack = 7; // Pa labi (B) Motors BACK - IN4
int MotorRightSpeed = 9; // Labā (B) motora ĀTRUMS - ENB
// *********************Instalējiet ultraskaņas sensoru izejas************************ ****
intrigPinL = 14; // kreisā sprūda ultraskaņas sensora izejas numura iestatīšana
int echoPinL = 15; // kreisā atbalss ultraskaņas sensora izejas numura iestatīšana
intrigPinC = 10; // centrālā trigera ultraskaņas sensora izejas numura iestatīšana
int echoPinC = 11; // centrālā eho ultraskaņas sensora izejas numura iestatīšana
intrigPinR = 12; // labās sprūda ultraskaņas sensora izejas numura iestatīšana
int echoPinR = 13; // labā atbalss ultraskaņas sensora izejas numura iestatīšana
// ********************* Līnijas sensoru izeju iestatīšana *******************
const int LineSensorLeft = 19; // kreisās līnijas sensora ieeja
const int LineSensorRight = 18; // labās līnijas sensora ievade
intSL; // kreisā sensora statuss
intSR; // labā sensora statuss
// ********************* Gaismas un skaņas signālu izejas iestatīšana ****************
int Gaisma = 2; // gaismas signāla izejas numura iestatīšana
int Zumm = 6; // iestatīt skaņas signāla izvades numuru
int ledState = LOW; // iestatiet gaismas diodes stāvokli uz šo mainīgo
garš iepriekšējaisMillis = 0; // saglabā LED diodes pēdējās ieslēgšanas laiku
garš intervāls = 300; // intervāls starp LED ieslēgšanu/izslēgšanu (0,3 sekundes)
// ********************* Mainīga attāluma mērīšana ar sensoriem***************
unsigned int impulseTimeL=0;
neparakstīts int impulseTimeC=0;
neparakstīts int impulseTimeR=0;
garais distL=0; // attālums, ko mēra kreisais ultraskaņas sensors
garš distC=0; // attālums, ko mēra centrālais ultraskaņas sensors
garais dist.R=0; // attālums, ko mēra labais Uz sensors
// ****************************** IESTATĪŠANA *********** ***** **************
Serial.begin(9600); // sākt seriālo portu (ātrums 9600)
//*************** Iestatiet motora kontaktus********************
pinMode (MotorRightBack, OUTPUT); // Pa labi (B) Motors ATPAKAĻ
pinMode(MotorRightForward, OUTPUT); // Pa labi (B) Motors UZ PRIEKŠU
pinMode (MotorLeftBack, OUTPUT); // Kreisais (A) Motors ATPAKAĻ
pinMode(MotorLeftForward, OUTPUT); // Kreisais (A) Motors UZ PRIEKŠU
kavēšanās (ilgums);
//*************** Iestatiet sloksnes sensora kontaktus******************
pinMode (LineSensor Left, INPUT); // definējot kreisās līnijas sensora tapu
pinMode (LineSensorRight, INPUT); // definējot labās līnijas sensora tapu
// ***************Ultraskaņas sensoru izvades režīmu iestatīšana****************************
pinMode(trigPinL, OUTPUT); // kreisās trigas ultraskaņas sensora izejas darbības režīma iestatīšana
pinMode(echoPinL, INPUT); // kreisā atbalss ultraskaņas sensora izejas darbības režīma iestatīšana
pinMode(trigPinC, OUTPUT); // centrālā trigera ultraskaņas sensora izejas darbības režīma iestatīšana
pinMode(echoPinC, INPUT); // centrālā eho ultraskaņas sensora izejas darbības režīma iestatīšana
pinMode(trigPinR,OUTPUT); // labās sprūda ultraskaņas sensora izejas darbības režīma iestatīšana
pinMode(echoPinR, INPUT); // labā atbalss ultraskaņas sensora izejas režīma iestatīšana
// ************** Iestatīt kontaktus gaismas un skaņas signāliem**************************** **** *****
pinMode (Zumm, OUTPUT); // skaņas signāla izejas darbības režīma iestatīšana
pinMode (gaisma, OUTPUT); // gaismas signalizācijas izejas darbības režīma iestatīšana
// ******************** Pamata kustību komandas ******************
void forward (int a, int sa) // FORWARD
analogWrite(MotorRightSpeed, sa);
analogWrite(MotorLeftSpeed, sa);
tukšums pa labi (int b, int sb) // ROTATE RIGHT (viena puse)
digitalWrite(MotorRightBack, LOW);
digitalWrite (MotorLeftBack, LOW);
digitalWrite(MotorLeftForward, HIGH);
analogWrite(MotorLeftSpeed, sb);
tukšums pa kreisi (int k, int sk) // KREISĀS GRIEZES (viena puse)
digitalWrite(MotorRightBack, LOW);
digitalWrite (MotorRightForward, HIGH);
analogWrite(MotorRightSpeed, sk);
digitalWrite (MotorLeftBack, LOW);
void stopp(int f) // STOP
digitalWrite(MotorRightBack, LOW);
digitalWrite (MotorRightForward, LOW);
digitalWrite (MotorLeftBack, LOW);
digitalWrite(MotorLeftForward, LOW);
// ************************** Attāluma mērīšana******************** *
void izmdistL () // attāluma mērīšana ar kreiso ultraskaņas sensoru
digitalWrite(trigPinL, HIGH);
digitalWrite(trigPinL, LOW); // 10 mS impulss līdz ultraskaņas sensora izvadei attāluma mērīšanai
impulssTimeL = impulssIn(echoPinL, HIGH); // nolasīt attālumu no ultraskaņas sensora
distL=impulseTimeL/58; // Konvertēt uz centimetriem
void izmdistC () // attāluma mērīšana ar centrālo ultraskaņas sensoru
digitalWrite(trigPinC, HIGH);
digitalWrite(trigPinC, LOW); // 10 mS impulss līdz ultraskaņas sensora izvadei attāluma mērīšanai
impulssTimeC = impulssIn(echoPinC, HIGH); // nolasīt attālumu no ultraskaņas sensora
distC=impulseTimeC/58; // Konvertēt uz centimetriem
void izmdistR () // attāluma mērīšana ar centrālo ultraskaņas sensoru
digitalWrite(trigPinR, HIGH);
digitalWrite(trigPinR, LOW); // 10 mS impulss līdz ultraskaņas sensora izvadei attāluma mērīšanai
impulssTimeR = impulssIn(echoPinR, HIGH); // nolasīt attālumu no ultraskaņas sensora
distR=impulseTimeR/58; // Konvertēt uz centimetriem
// ********************************** CILPA *********** ***** **************
// ********************* LĪNIJAS sekošanas režīms ********************* ***
// *********************gaismas un skaņas signāli*******************
tonis (Zumm,900); // ieslēdz skaņu 900 Hz
tonis (Zumm,900); // ieslēdz skaņu 800 Hz
neparakstīta garā strāvaMillis = millis();
if (currentMillis - previousMillis > intervāls) // pārbaudīt vai ir pagājis nepieciešamais intervāls, ja ir pagājis tad
previousMillis = pašreizējaisMillis; // saglabāt pēdējo pārslēgšanās laiku
if (ledState == LOW) // ja gaismas diode ir izslēgta, tad mēs to iedegam un otrādi
ledState = AUGSTS;
digitalWrite (gaisma, ledState); // iestatiet izvades stāvokļus, lai ieslēgtu vai izslēgtu LED
// ************************** Attāluma mērīšana******************** ******
Serial.println(distL);
Serial.println(distC);
Serial.println(distR);
if (distL>50 && distC>50 && distR>50) // ja izmērītais attālums ir lielāks par 50 centimetriem - aiziet
SL=digitalRead(LineSensorLeft); // nolasa signālu no kreisās joslas sensora
SR=digitalRead(LineSensorRight); // nolasa signālu no labās joslas sensora
// ************************* Sekojot melnajai līnijai ******************* ****
// ROBOTS uz joslas - ejam taisni
ja (SL == LOW & SR == LOW) // BALTS — BALTS — iet taisni
uz priekšu(10, 100);// UZ PRIEKŠU(laiks, ātrums)
// ROBOTS sāk pārslēgties no joslas - mēs taksējam
cits, ja (SL == LOW & SR == HIGH) // MELNS — BALTS — pagriezieties PA kreisi
pa kreisi (10, 100);// pagriezieties PA kreisi (laiks, ātrums)
cits, ja (SL == AUGSTS & SR == LOW) // BALTS — MELNS — pagriezieties PA labi
pa labi (10, 100); // pagriezieties PA labi (laiks, ātrums)
// FINISH - ROBOTS redz joslu ar abiem sensoriem
cits, ja (SL == AUGSTS & SR == AUGSTS) // MELNS — MELNS — STOP
stop(50); // STOP
else // ja izmērītais attālums ir mazāks vai vienāds ar minimālo, apstājieties
Funkcija millis() ļauj skaitīt laiku, kas pagājis kopš pašreizējās programmas palaišanas. Funkcija atgriež vērtību “neparakstīta garā” formātā un ļauj skaitīt vērtības līdz 50 dienām no programmas palaišanas brīža. Pēc šī laika atpakaļskaitīšana atsāksies. Šis ir funkcijas millis() izmantošanas piemērs:
neparakstīts ilgu laiku; void setup()( Serial.begin(9600); ) void loop()( Serial.print("Ieslēgšanas laiks: "); laiks = millis(); // saglabā laika vērtību Serial.println(time); // nosūtīt informāciju, izmantojot seriālā porta aizkavi (1000);)
Iepriekš minētajā piemērā katra otrā informācija par laiku, kas pagājis kopš programmas palaišanas, tiks nosūtīta porta monitoram. Tā kā laiks tiek mērīts milisekundēs, katra nākamā vērtība atšķirsies par 1000. Nolasīšanas precizitāte ir atkarīga no Arduino kvarca rezonatora stabilitātes.
micros() funkcija
Funkcija micros () ir līdzīga funkcijai millis (), atšķirība ir mērījuma precizitātē. Izmantojot funkciju micros(), mēs iegūstam laiku, kas pagājis kopš pašreizējās programmas sākuma mikrosekundēs. Skaitīto mikrosekunžu skaitītājs tiks atiestatīts pēc 70 minūtēm. Šis ir funkcijas micros() izmantošanas piemērs:
neparakstīts ilgu laiku; void setup()( Serial.begin(9600); ) void loop()( Serial.print("Laiks kopš sākuma: "); laiks = mikros(); Serial.print(time); Serial.println(" ms " ); kavēšanās (1000); )
Tāpat kā piemērā ar funkciju millis(), arī šeit katra otrā informācija par izmērīto laiku tiks nosūtīta uz porta monitoru, vienīgā atšķirība ir tāda, ka šajā gadījumā laiks tiek mērīts mikrosekundēs.
delay() funkcija
Funkcija delay() ļauj apturēt pašreizējās programmas izpildi uz parametrā norādīto laiku. Komandas sintakse ir šāda:
//komandu aizkave(500); //aizkavēšanās uz 0,5 s //aizkavēšanās(1000); //aizkavēšanās par 1 s
Laiks ir norādīts milisekundēs (1 s = 1000 ms). Šī parametra tips var būt "unsigned long", kas svārstās no 0 līdz 4294967295. Tālāk ir parādīts komandas delay() izmantošanas piemērs:
#define ledPin 13 void setup() ( pinMode(ledPin,13); ) void loop() ( digitalWrite(ledPin, HIGH); //ieslēdziet LED aizkavi (500); //gaidiet 500 ms (0,5 sek) digitalWrite( ledPin ,LOW); // izslēgt LED aizkavi (1000); // gaidīt 1000 ms (1 s))
Iepriekš minētajā piemērā gaismas diode iedegas uz 0,5 sekundēm, pēc tam nodziest uz 1 sekundi un tā tālāk, līdz Arduino tiek izslēgts.
delayMicroseconds() funkcija
Funkcija delayMicroseconds() ir funkcijas delay() variācija. Atšķirība ir laika noteikšanas skaitā un precizitātē. Funkcija delay() ļauj skaitīt laiku ar 1 milisekundes precizitāti, savukārt delayMicroseconds() ar 1 mikrosekundes precizitāti.
Vērtība, ko var norādīt parametrā, ir diapazonā no 0 līdz 16383. Lai iegūtu ilgākus laika intervālus, izmantojiet funkciju delay() vai vairākas reizes izmantojiet delayMicroseconds().
#define outPin 8 void setup() ( pinMode(outPin, OUTPUT); // kontakts 8 kā izeja ) void loop() ( digitalWrite(outPin, HIGH); // pin 8 high delayMicroseconds(50); // pauze 50 mikrosekundes digitalWrite(outPin, LOW); // pin 8 zema aizkaveMicroseconds(50); // pauze 50 mikrosekundes )
Šis piemērs ģenerē kvadrātveida vilni ar 100 mikrosekundes periodu un 50% polsterējumu.
Arduino latentumam ir ļoti svarīga loma. Bez tiem nevar darboties pat visvienkāršākais Blink piemērs, kas mirgo gaismas diode pēc noteikta laika. Bet lielākā daļa iesācēju programmētāju maz zina par laika aizkavi un izmanto tikai Arduino aizkavi, nezinot šīs komandas blakusparādības. Šajā rakstā es detalizēti runāšu par pagaidu funkcijām un to izmantošanas iespējām Arduino IDE izstrādes vidē.
Arduino ir vairākas dažādas komandas, kas ir atbildīgas par darbu ar laiku un pauzēm:
- kavēšanās ()
- kavēšanās mikrosekundes ()
- millis()
- mikros ()
Tie atšķiras pēc precizitātes, un tiem ir savas īpašības, kas jāņem vērā, rakstot kodu.
Izmantojot arduino aizkaves funkciju
Sintakse
Arduino aizkave ir vienkāršākā komanda, un to visbiežāk izmanto iesācēji. Faktiski tā ir aizkave, kas pārtrauc programmas darbību uz iekavās norādīto milisekundžu skaitu. (Vienā sekundē ir 1000 milisekundes.) Maksimālā vērtība var būt 4294967295 ms, kas ir aptuveni vienāda ar 50 dienām. Apskatīsim vienkāršu piemēru, kas ilustrē šīs komandas darbību.
Void setup() ( pinMode(13, OUTPUT); ) void loop() ( digitalWrite(13, HIGH); // signāla kontakts 13 liela aizkave (10000); // pauze 10000ms vai 10 sekundes digitalWrite13, LOW); // nosūtīt zemu signālu uz pin 13 delay(10000); // pauze 10000 ms vai 10 sekundes)
Metodē uzstādīt mēs paredzam, ka tapa 13 tiks izmantota kā izeja. Programmas galvenajā daļā vispirms uz tapu tiek pielietots augsts signāls, pēc tam mēs veicam 10 sekunžu aizkavi. Šobrīd šķiet, ka programma ir apturēta. Tad tiek dots zems signāls un atkal aizkave un viss sākas no jauna. Rezultātā mēs iegūstam, ka tapa tiek piegādāta pārmaiņus, tad 5 V, tad 0.
Jums ir skaidri jāsaprot, ka pauzes laikā, izmantojot aizkavi, programma tiek apturēta, lietojumprogramma nesaņems datus no sensoriem. Tas ir lielākais trūkums, izmantojot Arduino aizkaves funkciju. Šo ierobežojumu var apiet, izmantojot pārtraukumus, taču mēs par to runāsim atsevišķā rakstā.
Aizkaves piemērs ar mirgojošu LED
Diagrammas piemērs, lai ilustrētu, kā darbojas aizkaves funkcija.
Jūs varat izveidot ķēdi ar LED un rezistoru. Tad mēs iegūstam standarta piemēru - mirgojošu LED. Lai to izdarītu, uz tapas, kuru mēs norādījām kā izeju, jums ir jāpievieno gaismas diode ar pozitīvu kontaktu. Mēs savienojam gaismas diodes brīvo kāju caur aptuveni 220 omu rezistoru (var būt nedaudz vairāk) ar zemi. Jūs varat noteikt polaritāti, ja paskatās uz tā iekšpusi. Lielā kauss iekšpusē ir savienots ar mīnusu, un mazā kāja ir savienota ar plusu. Ja jūsu LED ir jauns, tad polaritāti varat noteikt pēc vadu garuma: gara kāja ir plus, īsa kāja ir mīnuss.
delayMicroseconds funkcija
Šī funkcija ir pilnīgs aizkaves analogs, izņemot to, ka tās mērvienības ir nevis milisekundes, bet mikrosekundes (1000000 mikrosekundes 1 sekundē). Maksimālā vērtība būs 16383, kas ir vienāda ar 16 milisekundēm. Izšķirtspēja ir 4, kas nozīmē, ka skaitlis vienmēr būs četrinieks. Fragmenta piemērs izskatītos šādi:
DigitalWrite(2, AUGSTS); // nosūtīt pin 2 liela kavēšanāsMicroseconds(16383); // pauze 16383µs digitalWrite(2, LOW); // nosūtīt zemu signālu uz pin 2 delayMicroseconds(16383); // pauze 16383µs
Problēma ar delayMicroseconds ir tieši tāda pati kā ar aizkavi - šīs funkcijas pilnībā "uzkarina" programmu un tā burtiski uz brīdi sastingst. Šobrīd nav iespējams strādāt ar portiem, nolasīt informāciju no sensoriem un veikt matemātiskas darbības. Mirgotājiem šī opcija ir piemērota, taču pieredzējuši lietotāji to neizmanto lieliem projektiem, jo šādas kļūmes tur nav vajadzīgas. Tāpēc daudz labāk ir izmantot tālāk aprakstītās funkcijas.
miss funkcija aizkaves vietā
Funkcija millis () ļaus jums bez kavēšanās veikt arduino aizkavēšanos, tādējādi apejot iepriekšējo metožu trūkumus. Millis parametra maksimālā vērtība ir tāda pati kā aizkaves funkcijai (4294967295 ms vai 50 dienas).
Izmantojot millis, mēs neapturam visas skices izpildi, bet vienkārši norādām, cik ilgi arduino ir vienkārši “apiet” tieši tas koda bloks, kuru mēs vēlamies apturēt. Atšķirībā no kavēšanās, milis pats par sevi neaptur neko. Šī komanda vienkārši atgriež mums no mikrokontrollera iebūvētā taimera milisekundes, kas ir pagājušas kopš sākuma. Ar katru zvanu uz cilpu Mēs paši izmērām laiku, kas pagājis kopš pēdējā mūsu koda izsaukuma, un, ja laika starpība ir mazāka par vēlamo pauzi, mēs kodu ignorējam. Tiklīdz starpība kļūst lielāka par vēlamo pauzi, mēs izpildām kodu, iegūstam pašreizējo laiku, izmantojot tos pašus mili un atceramies to - šis laiks būs jaunais atskaites punkts. Nākamajā ciklā atpakaļskaitīšana jau būs no jaunā punkta, un mēs atkal ignorēsim kodu, līdz jaunā atšķirība starp mili un mūsu iepriekš saglabāto vērtību atkal sasniegs vēlamo pauzi.
Lai aizkavētu bez kavēšanās ar millis, ir nepieciešams vairāk koda, taču tas var mirgot LED un apturēt skici, neapturot sistēmu.
Šeit ir piemērs, kas skaidri ilustrē komandas darbību:
neparakstīts ilgs laiks; // Mainīgais atskaites punkta saglabāšanai void setup() ( Serial.begin(9600); ) void loop() ( /* Šeit sākas delay() analogā izpilde. Aprēķiniet starpību starp pašreizējo momentu un iepriekšējo saglabāts atskaites punkts. Ja atšķirība ir lielāka par Ja nē, neko nedariet */ if (millis() - laiks > 10000)( // 10000 vietā aizstājiet nepieciešamo pauzes vērtību timing = millis(); Serial. println ( "10 sekundes") ;)))
Pirmkārt, mēs ieviešam laika mainīgo, kas saglabās milisekundes. Pēc noklusējuma mainīgā vērtība ir 0. Programmas galvenajā daļā mēs pārbaudām nosacījumu: ja milisekundes kopš mikrokontrollera sākuma mīnus laika mainīgajam ierakstītais skaitlis ir lielāks par 10000, tad darbība tiek veikta, lai izvadītu ziņojumu porta monitoram, un mainīgajam tiek ierakstīta pašreizējā laika vērtība. Programmas darbības rezultātā ostas monitorā ik pēc 10 sekundēm tiks parādīts ziņojums 10 sekundes. Šī metode ļauj bez kavēšanās mirgot LED.
mikros funkcija aizkaves vietā
Šī funkcija var arī aizkavēt, neizmantojot aizkaves komandu. Tas darbojas tieši tāpat kā mili, bet tas neskaita milisekundes, bet gan mikrosekundes ar izšķirtspēju 4 µs. Tā maksimālā vērtība ir 4294967295 mikrosekundes jeb 70 minūtes. Pārpildes gadījumā vērtība tiek vienkārši atiestatīta uz 0, neaizmirstiet to.
Kopsavilkums
Arduino platforma sniedz mums vairākus veidus, kā īstenot aizkavēšanos mūsu projektā. Ar aizkavi jūs varat ātri apturēt skices izpildi, bet tajā pašā laikā bloķēt mikrokontrollera darbību. Komandas millis izmantošana ļauj atbrīvoties no Arduino aizkaves, taču tas prasa nedaudz vairāk programmēšanas. Izvēlieties labāko metodi atkarībā no jūsu projekta sarežģītības. Parasti vienkāršās skicēs un ar kavēšanos, kas mazāka par 10 sekundēm, tiek izmantota aizkave. Ja darbības loģika ir sarežģītāka un nepieciešama liela aizkave, tad aizkaves vietā labāk izmantot millis.
Ja vēlaties "pauzēt" mikrokontrolleri, jums vienkārši jāievada kavēšanās instrukcija pareizajā programmas vietā. Taču tas kļūst par īstu šķērsli, mēģinot veikt citas darbības, piemēram, izsekot pogas klikšķiem. Šajā gadījumā ir jāīsteno sava veida daudzuzdevumu veikšana.
Jā, tas jūsu programmām pievienos dažas koda rindiņas, taču tas savukārt padarīs jūs par pieredzējušāku programmētāju un palielinās jūsu Arduino potenciālu. Lai to izdarītu, jums vienkārši jāiemācās izmantot Millis funkciju.
Jāsaprot, ka aizkaves funkcija aptur jūsu Arduino programmas izpildi, neļaujot tai šajā laika periodā darīt neko citu. Tā vietā, lai uz noteiktu laiku apturētu visu programmu, mēs iemācīsimies saskaitīt, cik daudz laika ir pagājis pirms darbības pabeigšanas. Tas, protams, tiek darīts, izmantojot funkciju millis () un dažus drauga mainīgos, lai saglabātu mūsu datus. Lai lietas būtu viegli saprotamas, mēs sāksim ar pirmo apmācības skici ar nosaukumu "Mirkšķināšana", taču šajā gadījumā mēs mirgosim LED bez kavēšanās.
Šīs programmas sākums ir tāds pats kā jebkurai citai standarta Arduino programmai. Vispirms tiek deklarēti visi nepieciešamie mainīgie un I / O līnijas (piemēram, LED 13. rinda). Šeit mums ir nepieciešams arī vesels skaitlis, lai saglabātu LED pašreizējo stāvokli. Tas tiks iestatīts uz LOW, jo gaismas diodes sākotnējais stāvoklis ir izslēgts. Pēc tam mēs deklarējam mainīgo "previousMillis" tipa "unsigned long". Atšķirībā no "int", garie neparakstītie mainīgie ir 32 biti, tas ir paredzēts mainīgajiem, kuru vērtība var kļūt ļoti liela - kā potenciālo laiku mēs varam gaidīt, līdz tiek veikta darbība. Mainīgais previousMillis tiks izmantots, lai saglabātu laiku, kad LED pēdējo reizi mirgoja. Ir arī "const long" tips, tas ir arī 32 bitu, bet tas nemaina vērtību, tas ir, tas ir paredzēts konstantēm (šajā gadījumā intervāla konstantei). Mēs iestatīsim to uz 1000 un izmantosim kā pauzes laiku, mērot milisekundēs.
const int ledPin = 13; // definēt gaismas diodes izvadi // Mainīsies mainīgie: int ledState = LOW; // ledState izmanto, lai noteiktu LED stāvokli bez paraksta long previousMillis = 0; // saglabāt laiku, kad LED pēdējo reizi tika atjaunināts // konstantes nemainīsies: const long interval = 1000; // mirgojošs intervāls milisekundēs void setup() ( // izvades līnijas 13 pinMode(ledPin, OUTPUT) iestatīšana)
Tad mēs ieejam bezgalīgā cilpā. Atcerieties, ka kavēšanās vietā mēs vēlamies skaitīt, cik daudz laika ir pagājis kopš mūsu pēdējās mirkšķināšanas, mūsu gadījumā 1000 ms. Ja norādītais laiks ir pagājis, ir pienācis laiks mainīt mūsu LED stāvokli.
Pirmkārt, mēs iestatīsim neparakstīto garo "currentMillis" uz "millis()", kas norāda pašreizējo laiku milisekundēs. Tas mums palīdzēs noskaidrot, vai starpība starp pašreizējo un iepriekšējo laiku ir pārsniegusi 1000 ms. Lai to izdarītu, mēs sakām: "Ja pašreizējais laiks, atskaitot iepriekšējo mirgošanas reizi, kad mūsu LED mirgo, ir lielāks vai vienāds ar mums piešķirto vērtību 1000 ms, saglabājiet pēdējo mirgošanas laiku kā iepriekšējo." Tas mums palīdzēs atcerēties, cik daudz laika ir pagājis kopš pēdējās mirkšķināšanas nākamajā cilpas atkārtojumā. Pēc tam, ja LED stāvoklis ir LOW, padariet to HIGH, pretējā gadījumā padariet to LOW. Pēc tam izmantojiet komandu digitalWrite, lai izdrukātu pašreizējo stāvokli LED.
void loop() ( unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= intervāls) ( // saglabāt pēdējās LED stāvokļa maiņas laiku previousMillis = currentMillis; // ja gaismas diode ir izslēgta, ieslēdziet to, un otrādi if (ledState == LOW) ( ledState = HIGH; ) else ( ledState = LOW; ) // LED izeja digitalWrite(ledPin, ledState); ) )
Pirmā lieta, ar ko saskaras iesācējs, kurš apgūst Arduino, ir nepatīkamais kavēšanās () funkcijas īpašums - programmas izpildes bloķēšana. Daudzos interneta piemēros šī funkcija tiek izmantota, taču praktiskā pielietošana kaut kā liek domāt, ka labāk iztikt bez tās.
Kā jau iesācējam pienākas, izgudroju velosipēdu un pats izveidoju nebloķēšanas aizkaves ieviešanu. Uzdevums bija šāds:
- Nodrošiniet pseido daudzuzdevumu veikšanu, lai dažādi notikumi notiktu savā laikā, ar saviem intervāliem un nebloķētu viens otru.
- Bija ērti to lietot.
- To varētu veidot kā bibliotēku un viegli iekļaut citos projektos bez copy-paste.
Rezultāts ir šāds.
#iekļauts
Metode Now() atgriež patieso vērtību, ja intervāls ir pagājis. Šajā gadījumā atpakaļskaitīšana sākas no jauna ar tādu pašu intervālu. Tas ir, Tagad () katru reizi, kad "pārlādē" automātiski.
Klasiskā LED mirgošana var būt uzreiz sarežģīta līdz diviem mirgošanas gadījumiem. Piemēram, gaismām, kas savienotas ar tapām 12 un 11, vajadzētu mirgot attiecīgi ar 1 s un 777 ms intervālu.
#iekļauts
Ciklā varat darīt ko citu, gaismas diožu mirgošana nebloķēs šī koda izpildi.
Ir skaidrs, ka tas nav pilnīgs aizkaves (), kas aptur pavedienu uz noteiktu laiku, aizstāšana, jums vienmēr ir jāraksta programma kā MFA (ierobežots automātikas mehānisms). Tas ir, saglabājiet stāvokli un, atkarībā no tā, dodieties uz pareizo vietu kodā.
Vecā versija:
Darbība1(); kavēšanās (1000); darbība2(); kavēšanās (500); darbība3(); ...
Jauna iespēja:
Baita stāvoklis=0; SmartDelayd(); ... slēdzis (stāvoklis) ( 0. gadījums: action1(); d.Set(1000000UL); stāvoklis=1; pārtraukums; 1. gadījums: if (d.Now()) ( action2(); d.Set(500000UL) ; stāvoklis=2; ) pārtraukums; 2. gadījums: if (d.Now()) (darbība3(); d.Stop(); stāvoklis=0; ) pārtraukums; ) ...
Metode Set(interval) iestata jaunu intervālu un atgriež veco. Jūs varat vienkārši apskatīt intervālu, izmantojot Get() metodi;
Stop() pārtrauc apstrādi, un Now() vienmēr atgriež false.
Start() atsāk un Now() sāk darboties kā parasti.
Ja jums ir nepieciešams palēnināt laika skaitīšanu, bet neapturēt to pilnībā, tad ir Gaidīšanas () metode. Piemēram, ja LED 12 mirgo un, nospiežot pogu, tā nemirgo, vienkārši pievienojiet tālāk norādīto kodu cilpai () piemērā ar divām diodēm iepriekš:
If (digitalRead(9)) led12.Wait(); ...
Tātad ar augstu signāla līmeni 9. posmā diode pie 12 nemirgos un turpinās, kad tur parādīsies 0.
Piemēram, ja ekrāns tiek zīmēts ar šādu “taimeri” un pogas tiek apstrādātas paralēli, iespējams, ka ekrāns vai daļa ir jāpārzīmē uzreiz pēc pogas nospiešanas, nevis jāgaida, līdz beigsies intervāls. Šim nolūkam tiek izmantota metode Reset(), pēc kuras nākamais Now() izsaukums atgriezīsies true. Piemēram:
SmartDelay displejs (1000000UL); void loop() ( ja (btClick()) display.Reset(); // noklikšķinājis uz pogas, mums jāzīmē ekrāns. if (display.Now()) screenRedraw(); // uzzīmējiet ekrānu. )
No kļūdām redzu tikai to, ka netiek ņemta vērā mikrosekunžu skaitītāja pārpilde, bet pretējā gadījumā, jā, mums ir jātīra kods. Man nepatīk, kā domāšanas laikā tiek darīts Reset().