बहुत लंबा विलंब () संभव है?


9

मैं एक खोलने और बंद करने की कोशिश कर रहा हूँ छोटा दरवाजा जो हर 12 घंटे में खुल या बंद होना चाहिए। मैं सोच रहा था कि क्या मैं 12 घंटे की देरी () (43 200 000 000) के साथ एक छोटी सी लूपिंग स्क्रिप्ट बना सकता हूं; मेरा अनुमान? हालाँकि, मुझे नहीं पता कि यह संभव है और / या सिफारिश योग्य है। कुछ प्रतिक्रिया / विकल्प (यदि आवश्यक हो) अच्छा होगा :)


ठीक है, मुझे लगता है कि देरी में अधिकतम 65535 has है, लेकिन अब मुझे एक विकल्प की आवश्यकता है ...
फ्रेड पन्नेकोक

4
अधिक परिपक्व समय में, MCU- अकेले सिस्टम आमतौर पर समय-समय पर एक बाधा को आग देने के लिए MCU के एक हार्डवेयर टाइमर चैनल को प्रोग्रामिंग करके किया जाता है, और फिर इनकी गिनती करता है - जिससे प्रोसेसर इस बीच अन्य काम कर सकता है, और संचयी रूप से सटीक है घड़ी का क्रिस्टल।
क्रिस स्ट्रैटन

3
देरी का उपयोग करने से एक बहुत मामूली ओवरहेड त्रुटि बढ़ जाएगी। एक ज्ञात अच्छी अवधि में समय के लिए एक रुकावट का उपयोग करना बेहतर होता है और फिर वहां से गिनती होती है। यहाँ मेरी व्यक्तिगत वेबसाइट पर अवधारणा का एक प्रमाण है: blog.linformatronics.nl/213/electronics/…
jippie

1
यदि यह पूरी तरह से समय पर नहीं होना है, तो आप सुबह और शाम को एक संवेदक की तरह एक अपरंपरागत चीजों का उपयोग कर सकते हैं।
द गाइ हैट ​​विथ द हाट

हां, मैंने इसके बारे में सोचा था, हालांकि मेरे पास केवल एक हल्का डिटेक्टर हिस्सा है और मुझे यकीन नहीं है कि इसे मौसम से कैसे बचाया जाए (थोड़ा दरवाजा बाहर है)
फ्रेड पन्नेकोक

जवाबों:


10

वास्तविक समय घड़ी विधि सबसे सटीक तरीका है, लेकिन अन्यथा उपयोग करें millis

unsigned long startMillis = millis();
while (millis() - startMillis < LONG_DELAY_MS);

इससे लगभग देरी हो जाएगी। 4294967295ms (2 ^ 32-1) या 49 दिन, जिसके बाद टाइमर के मूल्य तक पकड़ जाएगाstartMillis


1
केवल उपयोग करने में क्या गलत है delay(LONG_DELAY_MS)? Arduino कार्यान्वयन अहस्ताक्षरित देशांतर स्वीकार करता है। मैं भी नहीं पूरी तरह से आप वाकई कोड सही जब काम करता हूँ millis()wraps के आसपास है, और से छोटी हैstartMillis
Gerben

यदि मैं सही हूँ तो प्रतीक्षा करते समय विलंब आपके arduino को पूरी तरह से निष्क्रिय बना देता है। मुझे नहीं पता कि यह कैसे कार्य करेगा जब मिलिस वापस 0.
फ्रेड

@ गुडबर्न गुड, इसे उत्तर के रूप में डालें!
ज्यामितीय

2
@FredPannekoek ओवरफ्लो ठीक काम करेगा, इसलिए जब तक अहस्ताक्षरित लंबी का उपयोग किया जाता है।
ज्यामितीय

1
@ 23ars Arduino के सफल होने का मुख्य कारण इसका आसान उपयोग करने वाला हार्डवेयर अमूर्त पुस्तकालय है, यदि आप पुस्तकालयों के कार्यों के विरुद्ध हैं तो आप स्वयं को कुछ हद तक सीमित कर रहे हैं। वैसे भी, टिप्पणियों का कार्य उत्तर को बेहतर बनाना है, यदि आपके पास बेहतर समाधान है, तो अपना उत्तर लिखें। ;)
जियोमेट्रिकल

7

delay()इसके उपयोग हैं, लेकिन लंबे समय से देरी के लिए यह अच्छा नहीं है। यह केवल xघड़ी चक्र के लिए कुछ नहीं करने के लिए माइक्रोकंट्रोलर को बताता है। उस समय के दौरान, आपका Arduino कुछ और नहीं कर सकता है।

आपका सबसे अच्छा शर्त एक रियल टाइम क्लॉक (आरटीसी) नामक चीज़ का उपयोग करना होगा। ये चिप्स विशेष रूप से समय का ध्यान रखने के लिए बनाए गए हैं, और आप इन्हें आसानी से अपने Arduino से जोड़ सकते हैं। यहाँ एक उदाहरण है कि आप ऐसा कैसे कर सकते हैं।


+1 - आरटीसी समाधान विशेष रूप से अच्छा है यदि आप एमसीयू से अधिक सटीकता चाहते हैं तो आपको दे सकते हैं।
रिकार्डो

1
@ रिकार्डो - एक आरटीसी एक घड़ी की क्रिस्टल के साथ एक एमसीयू की तुलना में अधिक सटीक होने की संभावना नहीं है, जो समय-समय पर बाधा उत्पन्न करने के लिए अपने हार्डवेयर टाइमर का उपयोग करता है; यह आम तौर पर आपको मिलने वाली बिजली हानि और शायद कैलेंडर योजनाओं के बारे में कुछ ज्ञान देता है।
क्रिस स्ट्रैटन

1
Afaik uno अपनी घड़ी के लिए एक क्वार्ट्ज बिट सिरेमिक सिरेमिक गुंजयमान यंत्र का उपयोग नहीं करता है, इस प्रकार एक आरटीसी से बहुत कम सटीकता के साथ।
jfpoilpret

@ क्रिशस्ट्रटन - राइट। मुद्दा लेना। अगर ओपी को दिन के समय दरवाजा खोलना या बंद करना है तो आरटीसी बहुत बेहतर विकल्प होगा।
रिकार्डो

7

आप वॉचडॉग का उपयोग कर सकते हैं और प्रतीक्षा करते हुए और बिजली बचाने के दौरान अपनी एमसीयू नींद ले सकते हैं।

लेकिन ध्यान दें कि आप केवल बिजली बचाएंगे यदि आपका बोर्ड भी इसे बचाता है। इसका मतलब है कि आपके पास सामान्य नियामकों के बजाय कम अर्ध-वोल्टेज वोल्टेज नियामक होना चाहिए जो सबसे आम Arduino बोर्डों को सुसज्जित करते हैं, जैसे कि Uno। अन्यथा, इससे कोई फर्क नहीं पड़ता कि आपका एमसीयू ऊर्जा बचाता है यदि आपका बोर्ड नहीं करता है।

यहाँ कोड है (अप्राप्त):

#include <avr/sleep.h>
// This variable is made volatile because it is changed inside an interrupt function
volatile int sleep_count = 0; // Keep track of how many sleep cycles have been completed.
const int interval = 720; // Interval in minutes between waking and doing tasks.
const int sleep_total = (interval*60)/8; // Approximate number of sleep cycles 
// needed before the interval defined above elapses. Not that this does integer math.

void setup(void) {
    watchdogOn(); // Turn on the watch dog timer.
    // Disable the ADC by setting the ADEN bit (bit 7) to zero.
    ADCSRA = ADCSRA & B01111111;
    // Disable the analog comparator by setting the ACD bit (bit 7) to one.
    ACSR = B10000000;
    // Disable digital input buffers on all analog input pins by setting bits 0-5 to one.
    DIDR0 = DIDR0 | B00111111;
}

void loop(void) {
    goToSleep(); // ATmega328 goes to sleep for about 8 seconds
    // and continues to execute code when it wakes up
    if (sleep_count == sleep_total) {
        // CODE TO BE EXECUTED PERIODICALLY
    }
}

void goToSleep() {
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode.
    sleep_enable(); // Enable sleep mode.
    sleep_mode(); // Enter sleep mode.
    // After waking from watchdog interrupt the code continues
    // to execute from this point.
    sleep_disable(); // Disable sleep mode after waking.
}

void watchdogOn() {
    // Clear the reset flag, the WDRF bit (bit 3) of MCUSR.
    MCUSR = MCUSR & B11110111;
    // Set the WDCE bit (bit 4) and the WDE bit (bit 3) of WDTCSR. 
    WDTCSR = WDTCSR | B00011000; 
    // Set the watchdog timeout prescaler value to 1024 K 
    // which will yeild a time-out interval of about 8.0 s.
    WDTCSR = B00100001;
    // Enable the watchdog timer interupt.
    WDTCSR = WDTCSR | B01000000;
    MCUSR = MCUSR & B11110111;
}

ISR(WDT_vect) 
{
    sleep_count ++; // keep track of how many sleep cycles have been completed.
}

मेरे द्वारा कॉपी किया गया कोड इस पृष्ठ से है: लो-पावर अरुडिनो वॉचडॉग टाइमर का उपयोग करना


1

क्या आपके पास एक नींद (अहस्ताक्षरित इंट सेकंड) उपलब्ध है?

यदि नहीं, तो यह आपको बहुत देर करने की अनुमति देगा ():

for (unsigned int bigloop=0; bigloop<65535; bigloop++)
{
   for (unsigned int smallloop=0; smallloop<65535; smallloop++)
   {
      for (unsigned int tinyloop=0; tinyloop<65535; tinyloop++)
      {
         delay(65535);
      }
   }
}

अगर मैं टॉम की तरह एक आरटीसी प्राप्त करने का प्रबंधन नहीं करता तो मैं यह कोशिश कर सकता था। मदद के लिए धन्यवाद!
फ्रेड पाननेकोक

1

यह काम करेगा:

longDelayInSeconds = 120; //two minutes;   
while (p < longDelayInSeconds) {

        delay(1000);
        p++;

}

4
सबसे अच्छा समाधान और ओपी ने 12 घंटे नहीं, 2 मिनट के लिए कहा।
मदिवाड

1

जब मैं बीच में सामान नहीं करना चाहता तो मैं लूप का उपयोग करता हूं:

for (int Hours = 0; Hours < 12; Hours++) {            //Creates 12 hours
  for (int Minutes = 0; Minutes < 60; Minutes++) {    //Creates 1 hour
    for (int Seconds = 0; Seconds < 60; Seconds++) {  //Creates 1 minute
      delay(1000);                                    //Creates 1 second
    }
  }
}

4
यह स्पष्ट करना कि यह एक साधारण से बेहतर कैसे है delay(43200000)

1
खैर स्टार्टर के लिए यह संशोधित करना आसान होगा कि आप कब तक इंतजार करना चाहते हैं। बस प्रत्येक घंटे, मिनट और सेकंड के लिए संख्या को मिलिसेकंड में बदलने की आवश्यकता के बिना बदल दें।
१६:
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.