Arduino समय का उपयोग कर मिलिस () सही या सही नहीं है?


9

मैं कुछ डेटा रिकॉर्ड करने के लिए Arduino का उपयोग कर रहा हूं। मेरे Arduino स्केच में मैंने millis()फ़ंक्शन का भी उपयोग किया ताकि मैं उस समय का ट्रैक रख सकूं जिस पर मेरे द्वारा मापी जाने वाली प्रत्येक वैल्यू ली गई है। हालाँकि, मैंने देखा कि समय सही नहीं है। उदाहरण के लिए वास्तविक जीवन में 30 सेकंड केवल 10 सेकंड (उदाहरण के लिए) के रूप में सामने आते हैं।

क्या मैं यह कहने में सही हूं कि Arduino देरी फ़ंक्शन का उपयोग करते हुए समय को प्रभावित करता है millis()? दूसरे शब्दों में, मुझे लगता है कि मेरे पास 50ms की देरी है, क्या इसका मतलब यह है कि millis()फ़ंक्शन उस अवधि के लिए भी रुकता है और फिर कनेक्शन की अवधि के लिए जारी रहता है और इसी तरह? मैंने इस पर ध्यान दिया जब मैंने कुछ डेटा की साजिश रचने की कोशिश की और पाया कि मेरे डेटा में चोटियों की आवृत्ति बहुत बार दी गई थी जो समय बीत चुका था। इसलिए मैं जानना चाहता हूं कि क्या यह समय के इस बेमेल के लिए तर्क है और यदि हां, तो मैं इसे कैसे ठीक करूं ताकि मैं प्रत्येक नमूने के समय को रख सकूं?

यहाँ कुछ संदर्भ देने के लिए मेरा वर्णन है:

#include <eHealth.h>    

unsigned long time;
// The setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);  
}

// The loop routine runs over and over again forever:
void loop() {

  float ECG = eHealth.getECG();
  time = millis();
  Serial.print(time);
  Serial.print(" ");
  Serial.print(ECG, 5); 
  Serial.println("");    

  delay(50);
}

क्या आप आधिकारिक Uno बोर्डों में से एक का उपयोग कर रहे हैं?
पीटर ब्लूमफील्ड

1
निर्मित मूल्यों के बजाय वास्तविक समय (एक धारावाहिक मॉनीटर कि टाइमस्टैम्प लाइनों आदर्श है) शायद यह पता लगाने में मदद करेगा कि क्या हो रहा है।
इग्नासियो वाज़केज़-अब्राम्स

3
की संगणना millis()बाधित है, इसलिए delay()इसे प्रभावित नहीं करना चाहिए।
माइक्रोथियॉन

मेरे पास एक ही समस्या है, लेकिन केवल जब मैं इसे (मिली ()) जटिल कोड में एकीकृत करता हूं। मुझे लगता है कि कोड की जटिलता इसकी सटीकता को प्रभावित करती है जिस तरह से यह कोड की जटिलता के साथ देरी में अधिक से अधिक हो जाता है। क्या इससे बचने का कोई तरीका है? शायद अलग RTC मॉड्यूल का उपयोग कर?
जोसिप 7171

जवाबों:


10

millis()बाधित है, इसलिए delay()इसे प्रभावित नहीं करेगा, कम से कम एक ATmega आधारित बोर्ड पर नहीं।

यह कहना millis()बिलकुल सही नहीं है। टाइमर का प्रत्येक टिक ठीक 1ms नहीं है, लेकिन 1.024ms है। यह त्रुटि धीरे-धीरे जमा होती है जब तक कि सुधार नहीं किया जाता है। इसे TIMER0_OVF (टाइमर 0 ओवरफ्लो) इंटरप्ट हैंडलर के कार्यान्वयन में देखा जा सकता है।

अशुद्धि का एक अन्य स्रोत स्वयं थरथरानवाला / क्रिस्टल है, जो कि वास्तव में 16 मेगाहर्ट्ज नहीं है। हालांकि यह बहुत करीब है, और जब तक तापमान बहुत अधिक नहीं बदलता है, अपेक्षाकृत स्थिर है।

ऊपर का मतलब है कि आप का उपयोग करते समय लगभग 1ms बाहर हो सकता है millis()। यह आपकी समस्या की तरह नहीं है।

एक और संभावित मुद्दा यह होगा कि क्या getECG()कर रहा है - यह बहुत धीमा हो सकता है।

float eHealthClass::getECG(void)
    {
        float analog0;
        // Read from analogic in. 
        analog0=analogRead(0);
        // binary to voltage conversion
        return analog0 = (float)analog0 * 5 / 1023.0;   
    }

analogRead() धीमी है, लेकिन इस तरह एक पाश को प्रभावित करने के लिए इतना धीमा नहीं है।

एक और समस्या जो मैंने लोगों को देखी है वह यह है कि जब वे घड़ी की गति को बदलते हैं, लेकिन सही ढंग से बोर्ड नहीं बदलते हैं। इसका मतलब है कि millis()कार्यान्वयन में उपयोग किए गए स्थिरांक गलत हैं और समय गलत हैं।

यदि आप वास्तव में हर 50ms के मूल्यों को पढ़ना चाहते हैं, तो इसे लागू करने का एक बेहतर तरीका निम्नलिखित है

static long lastUpdate;

if (millis() - lastUpdate > 50)
{
    lastUpdate = millis();
    //Do stuff
}

हमें वास्तव में आपके द्वारा प्राप्त किए जा रहे टाइमस्टैम्प को देखने की आवश्यकता होगी। यदि आप वास्तव में 30 को 10 के रूप में दिखा रहे हैं, तो काम पर कुछ और है।


2
कृपया ध्यान दें कि, ऊनो के लिए, घड़ी क्रिस्टल-चालित नहीं है, लेकिन सिर्फ एक सिरेमिक रेज़ोनेटर का उपयोग करता है जो क्रिस्टल की तुलना में कम सटीक है।
jfpoilpret


रेज़ोनेटरों में एक प्रारंभिक प्रारंभिक सहिष्णुता (अक्सर 0.5-2%) और खराब तापमान स्थिरता होती है, लेकिन यदि आप उनका उपयोग करते समय टाइमिंग लूप को कैलिब्रेट करते हैं, तो वे तब तक ठीक हो सकते हैं जब तक तापमान चलता नहीं है।
साइबर्ग रिबन

2
मिलिस () अभी भी एक टाइमर पर काम करता है जो हर 1.024ms पर टिक करता है, लेकिन जब भी त्रुटि मीटर चर बहुत अधिक हो जाता है, तो उन्होंने वेतन वृद्धि के रूप में त्रुटि मुआवजा जोड़ा। मुझे लगता है कि यह वास्तव में रोमन ब्लैक का एल्गोरिथ्म है। तो समय बिल्कुल 1ms के करीब होना चाहिए। github.com/arduino/Arduino/blob/master/hardware/arduino/cores/…
अनंत काल

अभी भी दिलचस्पी रखने वालों के लिए, मैंने जो टिप्पणी JRobert के उत्तर पर पोस्ट की है, उसे देखें, मैं अपने जवाब के साथ जवाब नहीं देना चाहता था क्योंकि मेरे पास एक नहीं है, मैंने सिर्फ समस्या को दोहराया है।
user3284376

2

यदि किसी महत्वपूर्ण अंश eHealth.getECG()कॉल की अवधि के लिए इंटरप्ट को बंद कर दिया जाता है , तो millis()गिनती पीछे रह सकती है। अन्यथा, millis()आपके द्वारा वर्णित 3x त्रुटियों की तुलना में अधिक सटीक समय वापस करना चाहिए।

आपने कहा कि आपका नमूना संकेत आपकी अपेक्षा से अधिक आवृत्ति में दिखाई देता है, जो कि आपकी नमूना दर आपके इच्छित उद्देश्य से कम होने पर हो सकती है। क्या आप एक 20Hz नमूना दर मान रहे हैं? आपका लूप 50ms से अधिक लंबा हो सकता है, जिसे आप मुद्रित समय में देखेंगे, लेकिन उन्हें अभी भी घड़ी का समय ट्रैक करना चाहिए। यदि आपने उसका हिसाब नहीं दिया है, लेकिन 50ms / नमूना मान लिया है, तो आपको डेटा की स्पष्ट गति दिखाई देगी।

यदि यह समस्या नहीं है, तो अगला चरण आउटपुट के टॉगल करने के दौरान होगा loop(), और परिणामी वर्ग तरंग की आवृत्ति को आवृत्ति मीटर के साथ मापें (कुछ सस्ती DVM यह कर सकते हैं) या 'गुंजाइश। एक ही काम एक खाली के साथ करो loop()। पहला प्रयोग आपका वास्तविक नमूनाकरण दर या अंतराल होगा; दूसरा आपको बताएगा कि क्या millis()(यानी, टाइमर 0 आवृत्ति) वह है जो आपने अपेक्षित किया था।


1
मैं इसके साथ आगे भी खेलता रहा हूं और यह महसूस करता रहा हूं कि यह मुद्दा Arduino के साथ नहीं है, अधिकांश भाग के लिए मिलिस () फ़ंक्शन बहुत अच्छी तरह से काम करता है, कुछ मान बिल्कुल 8ms (देरी) के अलावा नहीं हैं, लेकिन क्या आपने कहा है कि उम्मीद की जानी चाहिए। मैंने जो 3x त्रुटि बताई है, वह उन चीजों के बारे में है, जो मैं डेटा प्राप्त करने के लिए उपयोग कर रहा हूं। कोई भी विचार जो इसका परिणाम हो सकता है, मैं पायथन के पीयर्सियल का उपयोग कर रहा हूं और यह नरक के रूप में धीमा है।
user3284376

मैं आपको 1/2 @ 'के अनुमान से अधिक देने के लिए आपके कार्यान्वयन के बारे में पर्याप्त नहीं जानता, लेकिन क्या पाइथन की तरफ से नमूने गिराने के लिए काफी धीमा है?
JRobert

0

मुझे भी। मैं यह जोड़ सकता हूं कि यदि रुकावटें बंद हो जाती हैं, तो मापा गया समय "वास्तविक समय" है। वैसे भी, मुझे समझ में नहीं आता कि यह देरी क्यों हुई, क्योंकि यदि लूप बहुत लंबा लगता है, वैसे भी मिलिस () को वास्तविक समय मान वापस करना चाहिए (केवल प्रत्येक मूल्य के बीच अधिक दूरी के साथ)


1
"वही यहाँ" का क्या उल्लेख है? उत्तर अपने दम पर खड़े होने चाहिए, क्योंकि StackExchange चीजों को फिर से आदेश दे सकता है (एक मंच के विपरीत)। इसलिए "यहाँ भी" का अर्थ कुछ भी हो सकता है, जो इस बात पर निर्भर करता है कि आपका उत्तर / प्रश्न किस उत्तर के नीचे है।
निक गैमन

यह पोस्ट एक टिप्पणी के रूप में अधिक उपयुक्त होगी, हालांकि (माना जाता है) आपके पास पर्याप्त प्रतिष्ठा की कमी है।
ग्रीनऑनलाइन

क्षमा करें, जब आप कुछ उत्तर देते हैं, तो यह स्पष्ट है कि यह मुख्य पोस्ट का संदर्भ दे रहा है, अन्यथा यह एक टिप्पणी होगी
user48711
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.