2011-04-01 20 views
6

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

वर्तमान में, हम रोलिंग/मूविंग औसत का उपयोग कर रहे हैं। हालांकि, पिछले 15 रीडिंग में, परिणाम अभी भी बहुत अधिक उतार-चढ़ाव करता है।

चिकनाई एल्गोरिदम के बारे में पढ़ने में, ऐसा लगता है कि बी-स्प्लिंस, कर्नेल फ़िल्टर, या कुछ अन्य चिकनाई एल्गोरिदम आदर्श होंगे। हालांकि, मुझे एक साधारण उदाहरण नहीं मिल रहा है जो गणित या कुछ ऐसे में numpy या आंतरिक कार्यों का उपयोग नहीं करता है।

कोई भी सरल-से-कार्यान्वित फ़ंक्शन के बारे में जानता है जो इससे मदद कर सकता है? यह एक सी ++ प्रोजेक्ट है (क्यूटी 4.5 का उपयोग करके) केवल न्यूनतम पुस्तकालयों के साथ। मैं पूर्णांक डोमेन में रहना पसंद करूंगा (3300-4200 से मिलीवॉल्ट में वोल्टेज दिखा रहा हूं)।

TIA माइक

उत्तर

6

अच्छा, यह बताने में थोड़ा मुश्किल है कि आपको अपनी स्थिति पर विनिर्देशों के बिना क्या चाहिए। उदाहरण के लिए, आपका सेंसर नमूना दर क्या है, और सेंसर उतार-चढ़ाव और शोर कैसा है जिसे आप विशेषता को हटाने की कोशिश कर रहे हैं?

हालांकि, यदि आप पहले से ही औसत लागू हो रहे हैं, तो मैं इसके बजाय एक चलती औसत कोशिश करने की सिफारिश कर सकता हूं। (औसत एन औसत के बजाय नमूनों का औसत।) इससे आपके आउटपुट से सामान्य से बड़े शॉर्ट टर्म अबाउटेशन के प्रभाव को कम किया जाएगा।

यदि आप काम करने वाले पैरामीटर पा सकते हैं, तो यह एक अलग-अलग समय-रहित फ़िल्टर के कुछ रूपों का उपयोग करने के लिए सीपीयू और मेमोरी आवश्यकताओं के लिए प्राथमिक होगा। ये लागू करने में काफी आसान हैं, और केवल मौजूदा आउटपुट मान और वर्तमान इनपुट की गणना करने के लिए वर्तमान इनपुट के ज्ञान की आवश्यकता है। उदाहरण के लिए:

Y = Y[n-1] + A * (X - Y[n-1]) 

(। कहाँ Y वर्तमान आउटपुट है, Y[n-1] पिछले गणना उत्पादन है, और X अपने नवीनतम सेंसर पढ़ने है)

A प्रभावी रूप से कम पास फिल्टर के समय स्थिर है, लेकिन यह अलग समय है, इसलिए यह नमूना दर पर निर्भर करता है। विशेष रूप से, A = dt/tau, जहां dt सेकेंड में आपकी नमूना अवधि है, और tau लगातार समय-समय पर स्थिरता के समान है।

+0

यह एकदम सही था। गणना करने के लिए तेज़, आसान। मेरे गुणांक को समझने के लिए थोड़ा सा लगा, लेकिन महान काम करता है। –

+0

@ माइक: मैटलैब जैसे टूल (और फ्रीमैट और ऑक्टेव जैसे फ्री क्लोन) में विशिष्ट बैंडविड्थ आवश्यकताओं के लिए आईआईआर फ़िल्टर गुणांक की गणना करने की सुविधा है। यद्यपि इस मामले में केवल एक गुणांक के साथ, एक अनुभवजन्य दृष्टिकोण संभवतः पर्याप्त है (और शायद मैटलैब सीखने से तेज़)। आपकी चलती औसत विधि एफआईआर फ़िल्टर का एक साधारण उदाहरण है (सभी गुणांक बराबर 1 के साथ)। – Clifford

+0

धन्यवाद, मैं वास्तव में क्या देख रहा था, यह मेरा समारोह Arduino के लिए इस आधार पर है: // compresor पूर्णांक कंप्रेसर (पूर्णांक संकेत, पूर्णांक lastSignal) { पूर्णांक परिणाम = lastSignal + 0.2 * (संकेत - lastSignal) ; वापसी परिणाम; } – Macumbaomuerte

1

आप बस करने के लिए एक तिरछा सीमा लागू करने के विचार किया है मूल्य?

new_val = Read_From_HW(); 
diff = new_val - prev_val; 

if (diff > SKEW_LIMIT) 
    diff = SKEW_LIMIT; 
else if (diff < -SKEW_LIMIT) 
    diff = -SKEW_LIMIT; 

reported_val = prev_val + diff; 
prev_val = reported_val; 
0

मुझे पता है कि यह सीधे आपके प्रश्न का उत्तर नहीं देता है, लेकिन औसत बार मदद करेगा? दूसरे शब्दों में, केवल एक मतलब के बजाय 15 सेकंड विंडो कहने पर न्यूनतम/अधिकतम/माध्य/औसत दिखाएं।

1

सिग्नल प्रोसेसिंग तकनीकों और जटिल गणित में बहुत गहरा होना संभव होगा, लेकिन आपको खुद से पूछना होगा कि यह वास्तव में आवश्यक है या नहीं?

यदि यह डिस्प्ले एक साधारण तात्कालिक संख्यात्मक आउटपुट है, जो लगातार ग्राफ या डेटा लॉग (यानी आपको सिग्नल का पुनर्निर्माण करने की आवश्यकता नहीं है) के बजाय "संकेत केवल" के लिए उपयोग किया जाता है, तो यह अक्सर पूरी तरह से स्वीकार्य होगा बस एक चलती औसत की बजाय आवधिक औसत लें। चूंकि इसके लिए कोई इतिहास संग्रहण की आवश्यकता नहीं है, इसलिए आप जितनी चाहें उतने नमूने औसत कर सकते हैं, और यह प्रदर्शन अद्यतन की आवश्यक आवृत्ति द्वारा निर्धारित किया जाएगा।

यह चालाक नहीं है, लेकिन यह अक्सर कार्य के लिए पर्याप्त है। यहां एक उदाहरण और इसके उपयोग का परीक्षण सिमुलेशन है।

class cPeriodicMean 
{ 
    public : 
     cPeriodicMean(int period) : m_mean(0), 
             m_period(period), 
             m_count(0), 
             m_sum(0) 
     { 
      // empty 
     } 

     void addSample(int sample) 
     { 
      m_sum += sample ; 
      m_count++ ; 
      if(m_count == m_period) 
      { 
       m_mean = m_sum/m_period ; 
       m_count = 0 ; 
       m_sum = 0 ; 
      } 
     } 

     int getMean() 
     { 
      return m_mean ; 
     } 

    private : 
     int m_mean ; 
     int m_period ; 
     int m_count ; 
     int m_sum ; 
} ; 

// Test Simulation 
#include <cstdlib> 
#include <cstdio> 
#include <windows.h> // for Sleep to simulate sample rate 
int main() 
{ 
    // Average over 100 samples 
    cPeriodicMean voltage_monitor(100) ; 

    for(;;) 
    { 
     // Simulate 4000mV +/- 50mV input 
     int sample = 4000 + (std::rand() % 100) - 50 ; 
     voltage_monitor.addSample(sample) ; 

     // Simulate 100Hz sample rate 
     Sleep(10) ; 

     // Current output 
     int millivolts = voltage_monitor.getMean() ; 
     printf("\r%d millivolts ", millivolts) ; 
    } 
} 

इस तकनीक भी है कि चिकनी उत्पादन का उत्पादन लेकिन एक ही आवृत्ति पर परिणाम उत्पन्न अपने चलती औसत फिल्टर करने के लिए इनपुट के रूप में समय-समय पर मतलब उत्पादन का उपयोग किया जाएगा होगा की एक शोधन। यदि आप 100 नमूना अवधि के साथ अपने दूसरे नमूने प्रति 100 उदाहरणों का उपयोग करना चाहते थे, और फिर इसे अपने 15 नमूना चलने वाले औसत के माध्यम से रखें, तो आप 15 सेकंड के नमूने डेटा का उपयोग करेंगे जबकि अभी भी हर सेकेंड परिणाम प्राप्त होगा, थोड़ी अतिरिक्त मेमोरी के साथ उपयोग।

स्पष्ट रूप से आप अपनी आवश्यक आवृत्ति पर आवश्यक परिणामों को प्राप्त करने के लिए अवधि, चलती औसत लंबाई और नमूना दर बदल सकते हैं। मेरा सुझाव है कि आप उस अवधि के लिए जितने नमूने ले सकते हैं, जिसके लिए आपको अपडेट की आवश्यकता है, फिर जब तक आप बर्दाश्त करना चाहते हैं तब तक चलती औसत बनाएं।

0

यह वास्तव में मुझे हार्डवेयर समस्या की तरह लगता है। क्या यह ली-आईओ या एनआईएमएच बैटरी है? निर्वहन वक्र कैसा दिखता है? बैटरी कोशिकाओं और आपके एडीसी के बीच क्या घटक हैं? विभिन्न डिजिटल फ़िल्टर को लागू करने के लिए चलाने से पहले इन चीजों को जानने के लिए को की आवश्यकता है।

-1

यदि आपके पास जवाब नहीं है तो यह को रोबोट 3pi जैसे रोबोट पर प्रिंट करने का एक अच्छा तरीका है।

{ 
    int bat = read_battery_millivolts(); 

    clear(); 
    print_long(bat); 
    print("mV"); 
    lcd_goto_xy(0,1); 
    print("Press B"); 

    delay_ms(100); 
} 

+0

पुराने प्रश्नों का उत्तर देते समय सावधान रहें जिनके पास बहुत सारे उत्तर हैं, खासकर जब उनमें से एक स्वीकार किया जाता है। आपको यह बताने की जरूरत है कि मौजूदा उत्तर किसी भी मौजूदा से बेहतर क्यों है। – APC