2008-09-30 10 views
6

क्या आपके पास एक स्विच इनपुट से निपटने के लिए नियमित रूप से आसान आसान है?सरल बहस नियमित

यह किसी भी ओएस के बिना एक साधारण बेयर धातु प्रणाली है।

मैं एक विशिष्ट गणना के साथ लूपिंग निर्माण से बचना चाहता हूं, क्योंकि प्रोसेसर की गति में उतार-चढ़ाव हो सकता है।

उत्तर

10

मुझे लगता है कि आप के बारे में यह यहाँ बहुत कुछ सीख सकता है: http://www.ganssle.com/debouncing.pdf

आपका सबसे अच्छा शर्त हार्डवेयर यदि संभव हो तो यह करने के लिए हमेशा होता है, लेकिन वहाँ के रूप में अच्छी वहाँ में सॉफ्टवेयर पर कुछ विचार कर रहे हैं। TFA से

सरल उदाहरण कोड:

#define CHECK_MSEC 5 // Read hardware every 5 msec 
#define PRESS_MSEC 10 // Stable time before registering pressed 
#define RELEASE_MSEC 100 // Stable time before registering released 
// This function reads the key state from the hardware. 
extern bool_t RawKeyPressed(); 
// This holds the debounced state of the key. 
bool_t DebouncedKeyPress = false; 
// Service routine called every CHECK_MSEC to 
// debounce both edges 
void DebounceSwitch1(bool_t *Key_changed, bool_t *Key_pressed) 
{ 
    static uint8_t Count = RELEASE_MSEC/CHECK_MSEC; 
    bool_t RawState; 
    *Key_changed = false; 
    *Key_pressed = DebouncedKeyPress; 
    RawState = RawKeyPressed(); 
    if (RawState == DebouncedKeyPress) { 
     // Set the timer which allows a change from current state. 
     if (DebouncedKeyPress) Count = RELEASE_MSEC/CHECK_MSEC; 
     else Count = PRESS_MSEC/CHECK_MSEC; 
    } else { 
     // Key has changed - wait for new state to become stable. 
     if (--Count == 0) { 
      // Timer expired - accept the change. 
      DebouncedKeyPress = RawState; 
      *Key_changed=true; 
      *Key_pressed=DebouncedKeyPress; 
      // And reset the timer. 
      if (DebouncedKeyPress) Count = RELEASE_MSEC/CHECK_MSEC; 
      else Count = PRESS_MSEC/CHECK_MSEC; 
     } 
    } 

}

+0

वास्तव में यह लगभग 10 मिनट के सवाल पूछने के बाद पाया। काफी हंडी मैं एचडब्ल्यू समाधान से सहमत हूं ... अगर केवल ... – Benoit

+0

@ बेनोइट: अच्छा, मुझे जवाब दें! ;) – GEOCHET

1

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

1

आप इसके साथ दूर मिल सकता है, हार्डवेयर में सबसे अच्छा समाधान के बीच कोई राज्य के साथ स्विच करने के लिए दो अलग-अलग राज्यों है। यही है, एक एसपीडीटी स्विच का उपयोग करें, जिसमें प्रत्येक ध्रुव फ्लिप/फ्लॉप की आर या एस लाइनों को खिला रहा है। उस तरह से वायर्ड, फ्लिप/फ्लॉप का उत्पादन अस्वीकार किया जाना चाहिए।

+0

मैं मानता हूं कि एचडब्ल्यू बेहतर होगा लेकिन यह पासा में नहीं है। – Benoit

+0

यदि कोई ऐसा व्यक्ति है जो कोई व्यक्ति स्विच कर रहा है, तो हार्डवेयर डिबॉन्गिंग होने पर भी आपको इसे हमेशा अस्वीकार करने की आवश्यकता होती है। लोगों के हाथ हिलाते हैं, वे बटन पर पर्याप्त या बहुत अधिक बल का उपयोग नहीं करते हैं, या बकवास बटन में प्राप्त हो गया है - वे * यांत्रिक रूप से * उस तरह उछाल बना सकते हैं, जिससे आपका एसपीडीटी विश्वासपूर्वक रिपोर्ट करेगा। हार्डवेयर debouncing महान है, हालांकि, और यदि कुछ और नहीं है, तो आप अपने बाउंस समय को बहुत छोटा रखने और एक और अधिक प्रतिक्रियाशील कीबोर्ड प्राप्त करने देता है। –

2

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

9

सरल समाधान अक्सर सबसे अच्छे होते हैं, और मुझे पता चला है कि केवल हर एन मिलसेकंड (स्विच के आधार पर 10 और 50 के बीच) स्विच स्विच को पढ़ना हमेशा मेरे लिए काम करता है।

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

इसे लागू करने के लिए, आपको अपने सिस्टम पर एक साधारण आवधिक टाइमर इंटरप्ट की आवश्यकता होगी (कोई आरटीओएस समर्थन नहीं मानते), लेकिन यदि आप इसे नंगे धातु पर प्रोग्रामिंग करने के लिए उपयोग करते हैं, तो इसे व्यवस्थित करना मुश्किल नहीं होना चाहिए।

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

+0

मैं मानता हूं कि एक स्थिर अवधि पूरी तरह से ठीक काम करती है - मैं अक्सर "मैं वहां हूं" से बहस करने के लिए अपने प्रदर्शन रीफ्रेश चक्र का उपयोग करता हूं और यह ठीक काम करता है। आप यहां वास्तविक "डिबॉन्स तर्क" खो रहे हैं, हालांकि - जब तक आप हमेशा राज्य परिवर्तन पर ट्रिगर नहीं करते हैं, जो हर बार काम नहीं करेगा। –

+3

@ टॉम, पूरा बिंदु वहां है * है * कोई बहस तर्क नहीं: आपको इसकी आवश्यकता नहीं है। स्विच 'बाउंस' वास्तव में केवल एक आर्टेफैक्ट है जो यांत्रिक संपर्क क्लोजर को तेजी से नमूना करने के लिए डिज़ाइन किया गया था, इसे संचालित करने के लिए बनाया गया था। नमूना दर को छोड़कर, आप समस्या को दूर करते हैं। (और हाँ, वीडियो रीफ्रेश आवृत्ति सबसे अच्छे स्विच के लिए स्पॉट पर है) – Roddy

+0

बहुत रोचक, मैंने इस तरह से इस बारे में सोचा नहीं था। कुछ scribbling के बाद, मेरा मानना ​​है कि आप सही रूप से सही हैं अगर मतदान अवधि आपके हार्डवेयर से सबसे लंबे समय तक बहस चक्र के बीच है और सबसे छोटी बटन प्रेस की आधा लंबाई है जिसे आप स्वीकार करेंगे, जब तक आप स्वीकार करने के इच्छुक हैं (कभी-कभी) दो पूर्ण मतदान चक्रों की देरी। (60 हर्ट्ज की स्क्रीन रीफ्रेश दर के लिए, उदाहरण के लिए <9ms का बाउंस चक्र इंगित करता है।) मुझे गड़बड़ होनी चाहिए, मैंने आपको चिह्नित किया - और स्पष्ट रूप से मैं इसे बदल नहीं सकता। :-(यदि आप अपना जवाब थोड़ा बदलते हैं, तो मैं इसे फिर से चिह्नित कर सकता हूं। –

2

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

लेकिन, सबसे अच्छी सलाह है कि आप अपने दोस्ताना हार्डवेयर डिजाइनर से मूल्य को "लच" दें और जब आप इसे प्राप्त करते हैं तो आप इस मूल्य को साफ़ करने की अनुमति दें।

+0

यह मेरे लिए सही नहीं लगता है। निश्चित रूप से वे जिस क्रम में आते हैं वह महत्वपूर्ण है? उदाहरण के लिए, यदि आपका शिफ्ट रजिस्टर कहता है ऊपर नीचे, निश्चित रूप से आप "बाउंस के बीच में" हैं और आपको एक और अवधि का इंतजार करना होगा? –

0

जो मैं आमतौर पर करता हूं उसके पास इनपुट रजिस्टर की चौड़ाई तीन या तो चर होती है। प्रत्येक मतदान, आमतौर पर एक बाधा से, नए नमूने के लिए रास्ता बनाने के लिए मूल्यों को एक स्थानांतरित करता है।फिर मेरे पास तर्कसंगत और नमूने सेट करके और उलटा तार्किक-या साफ़ करने के द्वारा गठित एक विवादित चर है। यानी (अपरीक्षित, स्मृति से)

input3 = input2; 
input2 = input1; 
input1 = (*PORTA); 

debounced |= input1 & input2 & input3; 
debounced &= (input1 | input2 | input3); 

यहाँ एक उदाहरण है:

debounced xxxx है (जहां 'एक्स' है "जो कुछ भी")

input1 = 0110, 
input2 = 1100, 
input3 = 0100 
उपरोक्त जानकारी के साथ

,

हमें केवल 2 से 1, और बिट 0 से 0 स्विच करने की आवश्यकता है। शेष अभी भी "बाउंसिंग" हैं।

debounced |= (0100); //set only bit 2 
debounced &= (1110); //clear only bit 0 

नतीजा यह है कि अब = debounced x1x0

+0

मैंने आपके एल्गोरिदम को दिलचस्प पाया (जो मैं ढूंढ रहा हूं उसके करीब)। मैंने इसे अस्वीकार करने के लिए संपादित किया ~ ', जो मुझे लगता है गलत था – JACH

0

एंबेडेड गुरु जैक Ganssle इस विचार का एक बहुत प्रदान की है। इस विषय पर उनके 26 पृष्ठ के पीडीएफ (A Guide to Debouncing) इस विषय पर मैंने सबसे अच्छा पढ़ा है।

0

ganssle.com से एल्गोरिदम में एक बग हो सकता है। मैं छाप निम्न पंक्ति

static uint8_t Count = RELEASE_MSEC/CHECK_MSEC; 

आदेश सही ढंग से प्रारंभिक प्रेस Debounce में

static uint8_t Count = PRESS_MSEC/CHECK_MSEC; 

पढ़ना चाहिए है।

0

हार्डवेयर स्तर बुनियादी debouncing दिनचर्या खाते में एक भौतिक कुंजी (या स्विच के) व्यवहार के बाद के खण्ड लेने के लिए है पर:

कुंजी quietly- बैठे> उंगली कुंजी को छूता है और डाउन- धक्का शुरू होता है> कुंजी पहुँच यात्रा और उंगली के नीचे इसे पकड़ना शुरू होता है-> उंगली कुंजी को जारी करने लगती है और वसंत कुंजी बैक अप को दबाता है-> उंगली रिलीज कुंजी और कुंजी तब तक कंपन करती है जब तक यह

इन सभी चरणों में धातु के स्क्रैपिंग और रगड़ के 2 टुकड़े शामिल होते हैं और एक-दूसरे के खिलाफ बंपिंग, वोल्टेज को ऊपर और नीचे 0 से अधिकतम मिलीसेकंड की अवधि के दौरान, इसलिए बिजली के शोर के रास्ते में हर कदम होता है:

(1) शोर, जबकि कुंजी को छुआ नहीं जा रहा है, नमी, कंपन, तापमान परिवर्तन इत्यादि जैसे पर्यावरण संबंधी मुद्दों के कारण शोर।कुंजी संपर्कों

(2) शोर की वजह से के रूप में कुंजी को दबाए

दबाया जा रहा है

(3) शोर कुंजी

नीचे आयोजित किया जा रहा है के रूप में (4) कुंजी के रूप में शोर है

में वोल्टेज परिवर्तन के कारण जारी किया जा रहा

(5) जारी किया जा रहा

यहाँ के बाद कुंजी कंपन न के रूप में शोर एल्गोरिथ्म है जिसके द्वारा हम मूल रूप से लगता है कि कुंजी एक व्यक्ति द्वारा दबाया जा रहा है है:

+०१२३५१६४१०

, कुंजी है, जो "दबाया जा सकता है" किया जा सकता है, "निश्चित रूप से दबाया जाता है", "निश्चित रूप से दबाया नहीं है" की स्थिति पढ़ें "दबाया हो सकता है नहीं किया जा" (हम वास्तव में यकीन है कि कभी नहीं कर रहे हैं)

पाश जबकि कुंजी "हो सकती है" दबाया जाता है (यदि हार्डवेयर से निपटना है, तो यह कुछ थ्रेसहोल्ड मान से अधिक वोल्टेज नमूना है), जब तक कि "निश्चित रूप से नहीं" दबाया जाता है (थ्रेसहोल्ड वोल्टेज से कम) (यह प्रारंभ होता है, शोर के लिए प्रतीक्षा quiesce, की परिभाषा "हो सकता है" और "निश्चित रूप से" कुंजी जब तक "हो सकता है", जबकि कुंजी है "निश्चित रूप से" दबाया विशिष्ट अनुप्रयोग पर निर्भर)

पाश है, दबाया

जब कुंजी "हो सकती है" दबाया जाता है, तो कुंजी की स्थिति को लूपिंग और नमूना शुरू करना, और दबाए जाने की कुंजी कितनी देर तक चलती है - यदि कुंजी वापस "शायद नहीं" या "निश्चित रूप से नहीं है" "कुछ निश्चित समय से पहले दबाए गए राज्य को, प्रक्रिया को पुनरारंभ करें - एक निश्चित समय (मिलीसेकंड की संख्या) जिसे आपने चुना है (आमतौर पर विभिन्न मानों के साथ प्रयोग करके) आप तय करते हैं कि नमूना मान अब शोर के कारण नहीं होता है, लेकिन बहुत संभावना कुंजी वास्तव में एक मानव उंगली से नीचे आयोजित किया जा रहा के कारण होता है और आप मान "दबाया" वापस


while(keyvalue = maybepressed){ 
//loop - wait for transition to notpressed 
sample keyvalue here; 
maybe require it to be "notpressed" a number of times before you assume 
it's really notpressed; 
} 
while(keyvalue = notpressed){ 
//loop - wait for transition to maybepressed 
sample keyvalue 
again, maybe require a "maybepressed" value a number of times before you 
transition 
} 
while(keyvalue=maybepressed){ 
    presstime+=1; 
    if presstime>required_presstime return pressed_affirmative 
    } 
} 
return pressed_negative 
संबंधित मुद्दे