arduino
समय प्रबंधन
खोज…
वाक्य - विन्यास
अहस्ताक्षरित लंबी मिली ()
अहस्ताक्षरित लंबे माइक्रो ()
शून्य देरी (अहस्ताक्षरित लंबी मिलीसेकंड)
शून्य विलंबमाइक्रोसेकंड (अहस्ताक्षरित लंबे माइक्रोसेकंड)
उस वर्ग के कंस्ट्रक्टर और ऑपरेटरों के लिए elapsedMillis हेडर देखें। संक्षेप में:
- elapsedMillis elapsedMillisObject; किसी वस्तु को समय से ट्रैक करने के लिए बनाया गया था या किसी अन्य समय में स्पष्ट रूप से निर्धारित बिंदु के बाद से
- elapsedMillisObject = 0; "अब से" ऑब्जेक्ट द्वारा ट्रैक किए गए समय को रीसेट करें
- अहस्ताक्षरित लंबा डेल्टा = elapsedMillisObject; हमें ट्रैक किए गए समय को देखने दें
- elapsedMillisObject + = और - = ये काम उम्मीद के मुताबिक हुआ
टिप्पणियों
ब्लॉकिंग बनाम नॉन-ब्लॉकिंग कोड
बहुत सरल रेखाचित्रों के लिए, delay()
और delayMicroseconds()
का उपयोग करके अवरोधक कोड लिखना उपयुक्त हो सकता है। जब चीजें अधिक जटिल हो जाती हैं, तो इन कार्यों का उपयोग करने में कुछ कमियां हो सकती हैं। इनमें से कुछ हैं:
- सीपीयू समय बर्बाद करना: अधिक जटिल रेखाचित्रों को सीपीयू की आवश्यकता हो सकती है जबकि एक एलईडी ब्लिंकिंग अवधि की समाप्ति की प्रतीक्षा कर रहे हैं।
- अप्रत्याशित देरी: जब
delay()
को सबरूटीन्स में कहा जाता है जिसे स्पष्ट रूप से नहीं कहा जाता है, उदाहरण के लिए आपके द्वारा शामिल पुस्तकालयों में। - अनुपलब्ध घटनाएँ जो देरी के दौरान होती हैं और एक बाधा हैंडलर द्वारा नियंत्रित नहीं की जाती हैं, उदाहरण के लिए पराग बटन दबाया जाता है: एक बटन 100 एमएस के लिए दबाया जा सकता है, लेकिन यह
delay(500)
द्वारा छाया हो सकता है।
कार्यान्वयन का विवरण
millis()
आमतौर पर एक हार्डवेयर टाइमर पर निर्भर करता है जो 1 kHz से बहुत अधिक गति से चलता है। जब millis()
कहा जाता है, तो कार्यान्वयन कुछ मूल्य देता है, लेकिन आप नहीं जानते कि वास्तव में कितना पुराना है। यह संभव है कि "चालू" मिलीसेकंड बस शुरू हो गया, या यह उस फ़ंक्शन कॉल के ठीक बाद समाप्त हो जाएगा। इसका मतलब है कि, जब millis()
से दो परिणामों के बीच अंतर की गणना करते हैं, तो आप लगभग शून्य और लगभग एक मिलीसेकंड के बीच कुछ भी बंद कर सकते हैं। यदि उच्च परिशुद्धता की आवश्यकता है, तो micros()
उपयोग करें।
elapsedMillis
के स्रोत कोड को elapsedMillis
पता चलता है कि यह समय में दो बिंदुओं की तुलना करने के लिए वास्तव में millis()
का उपयोग करता है, इसलिए यह इस प्रभाव से भी ग्रस्त है। फिर से, एक ही पुस्तकालय से उच्च परिशुद्धता के लिए वैकल्पिक elapsedMicros
।
देरी के साथ ब्लिंकिंग को रोकना ()
एलईडी ब्लिंक बनाने के सबसे सीधे तरीके में से एक है: इसे चालू करें, थोड़ा इंतजार करें, इसे बंद करें, फिर से प्रतीक्षा करें, और अंतहीन दोहराएं:
// set constants for blinking the built-in LED at 1 Hz
#define OUTPIN LED_BUILTIN
#define PERIOD 500
void setup()
{
pinMode(OUTPIN, OUTPUT); // sets the digital pin as output
}
void loop()
{
digitalWrite(OUTPIN, HIGH); // sets the pin on
delayMicroseconds(PERIOD); // pauses for 500 miliseconds
digitalWrite(OUTPIN, LOW); // sets the pin off
delayMicroseconds(PERIOD); // pauses for 500 milliseconds
// doing other time-consuming stuff here will skew the blinking
}
हालांकि, अपशिष्ट सीपीयू चक्रों के ऊपर उदाहरण में किया गया इंतजार, क्योंकि यह अतीत में जाने के लिए एक निश्चित बिंदु के इंतजार में लूप में बैठता है। यही कारण है कि गैर-अवरुद्ध तरीके, millis()
या elapsedMillis
का उपयोग करते हुए, बेहतर करते हैं - इस अर्थ में कि वे हार्डवेयर की क्षमता से अधिक नहीं जलाते हैं।
ElapsedMillis पुस्तकालय (और वर्ग) के साथ गैर-अवरुद्ध ब्लिंक
ElapsedMillis लाइब्रेरी एक ही नाम के साथ एक वर्ग प्रदान करती है जो उस समय का ट्रैक रखता है जो इसे बनाया गया था या एक निश्चित मूल्य पर सेट किया गया था:
#include <elapsedMillis.h>
#define OUTPIN LED_BUILTIN
#define PERIOD 500
elapsedMillis ledTime;
bool ledState = false;
void setup()
{
// initialize the digital pin as an output.
pinMode(OUTPIN, OUTPUT);
}
void loop()
{
if (ledTime >= PERIOD)
{
ledState = !ledState;
digitalWrite(OUTPIN, ledState);
ledTime = 0;
}
// do other stuff here
}
आप उदाहरण में देख सकते हैं कि एलईडी पिन पिन टॉगल होने पर ledTime
ऑब्जेक्ट को शून्य असाइन किया गया है। यह पहली नज़र में आश्चर्य की बात नहीं हो सकती है, लेकिन अधिक समय लेने वाली चीजें होने पर इसका प्रभाव पड़ता है:
ऐसी स्थिति पर विचार करें जहां 750 मिली सेकेंड के बाद ledTime
और PERIOD
बीच तुलना की जाती है। फिर शून्य से ledTime
सेट करने का मतलब है कि सभी टॉगल ऑपरेशन निम्नलिखित 250 एमएस "देर से" होंगे। , तो इसके विपरीत में, PERIOD
से घटाया गया था ledTime
, एलईडी एक छोटी सी अवधि देखना होगा और उसके बाद जैसे कि कुछ हुआ निमिष जारी है।
मिलिस के साथ गैर-अवरुद्ध ब्लिंक ()
यह arduino डॉक्स से एक उदाहरण के बहुत करीब है:
// set constants for blinking the built-in LED at 1 Hz
#define OUTPIN LED_BUILTIN
#define PERIOD 500 // this is in milliseconds
int ledState = LOW;
// millis() returns an unsigned long so we'll use that to keep track of time
unsigned long lastTime = 0;
void setup() {
// set the digital pin as output:
pinMode(OUTPIN, OUTPUT);
}
void loop() {
unsigned long now = millis();
if (now - lastTime >= PERIOD) // this will be true every PERIOD milliseconds
{
lastTime = now;
if (ledState == LOW)
{
ledState = HIGH;
}
else
{
ledState = LOW;
}
digitalWrite(OUTPIN, ledState);
}
// now there's lots of time to do other stuff here
}
इस तरह से millis()
का उपयोग करना - गैर-अवरुद्ध तरीके से समय-समय पर संचालन - एक ऐसी चीज है, जिसकी काफी बार जरूरत होती है, इसलिए इसके लिए elapsedMillis
लाइब्रेरी का उपयोग करने पर विचार करें।
उपाय करें कि बीता हुआ लम्बा और एलैप्सिडिमिक्रोस का उपयोग करने में कितना समय लगता है
#include <elapsedMillis.h>
void setup() {
Serial.begin(115200);
elapsedMillis msTimer;
elapsedMicros usTimer;
long int dt = 500;
delay(dt);
long int us = usTimer;
long int ms = msTimer;
Serial.print("delay(");Serial.print(dt);Serial.println(") took");
Serial.print(us);Serial.println(" us, or");
Serial.print(ms);Serial.println(" ms");
}
void loop() {
}
इस उदाहरण में, एक elapsedMillis
ऑब्जेक्ट और एक elapsedMicros
ऑब्जेक्ट का उपयोग यह मापने के लिए किया जाता है कि किसी चीज़ को कितनी देर तक लिया गया था, उन्हें बनाने से ठीक पहले जिस अभिव्यक्ति को हम समय पर निष्पादित करना चाहते हैं, और उसके बाद उनके मान प्राप्त कर रहे हैं। वे थोड़ा अलग परिणाम दिखाएंगे, लेकिन मिलीसेकंड परिणाम एक मिलीसेकंड से अधिक नहीं होगा।
बिना देरी के 1 से अधिक कार्य ()
यदि आपके पास अलग-अलग अंतराल में बार-बार निष्पादित करने के लिए 1 से अधिक कार्य हैं, तो इस उदाहरण का उपयोग प्रारंभिक बिंदु के रूप में करें:
unsigned long intervals[] = {250,2000}; //this defines the interval for each task in milliseconds
unsigned long last[] = {0,0}; //this records the last executed time for each task
void setup() {
pinMode(LED_BUILTIN, OUTPUT); //set the built-it led pin as output
Serial.begin(115200); //initialize serial
}
void loop() {
unsigned long now = millis();
if(now-last[0]>=intervals[0]){ last[0]=now; firstTask(); }
if(now-last[1]>=intervals[1]){ last[1]=now; secondTask(); }
//do other things here
}
void firstTask(){
//let's toggle the built-in led
digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN)?0:1);
}
void secondTask(){
//say hello
Serial.println("hello from secondTask()");
}
प्रत्येक 15 सेकंड में निष्पादित करने के लिए एक और कार्य जोड़ने के लिए, चर intervals
और last
विस्तार करें:
unsigned long intervals[] = {250,2000,15000};
unsigned long last[] = {0,0,0};
फिर नया कार्य निष्पादित करने के लिए एक if
स्टेटमेंट जोड़ें। इस उदाहरण में, मैंने इसे thirdTask
नाम दिया।
if(now-last[2]>=intervals[2]){ last[2]=now; thirdTask(); }
अंत में समारोह घोषित करें:
void thirdTask(){
//your code here
}