एक ही पिन पर एकाधिक Arduino इंटरप्ट




embedded debouncing (2)

निम्नलिखित कोड में, ISR2 क्यों कभी नहीं चला?

const int in = 19;
const int LED = 9;
int flag;
void setup() {
    pinMode(in, INPUT_PULLUP);
    pinMode(LED, OUTPUT);
    attachInterrupt(digitalPinToInterrupt(in), ISR2, RISING);
    attachInterrupt(digitalPinToInterrupt(in), ISR1, FALLING);

}
void  loop() {
    if (flag) {delay (100); flag = false;}// debounce
}
void ISR1(){
    digitalWrite(LED, LOW);
    // Turn Off the motor, since, Limit Switch was engaged
    flag = true;
}
void ISR2(){ // Limit Switch was disengaged. 
    digitalWrite(LED, HIGH);
    delay(100); // Debounce, so I do not receive spurious FALLING edges from this.
}

क्या Arduino आपको एक ही पिन पर दो इंटरप्ट्स संलग्न करने की अनुमति नहीं देता है भले ही इंटरप्ट विभिन्न कार्यक्रमों के लिए क्रमादेशित हो?

मेरे सेटअप में, पिन 19 को गति नियंत्रण सेटअप में उपयोग की जाने वाली सीमा स्विच से एक संकेत मिलता है जब सीमा स्विच व्यस्त होता है, तो पिन में LOW संकेत मिलता है इस प्रकार, मैं पहले एक बढ़त के किनारे देख रहा हूं जिसके बाद मेकैनिकल बाउंस की वजह से बढ़त के किनारों और FALLING किनारों को देखते हैं। मैं इस मामले में ठीक से debouncing संभाल

हालांकि, कल्पना कीजिए कि सीमा स्विच कुछ समय के लिए लगे हुए राज्य में बैठे थे, और फिर मैं मोटर को रिवर्स कर देता हूं जिससे सीमांत स्विच बंद हो जाता है, यह एक बढ़त के किनारे भेजता है, जिसके बाद FALLING और RISING किनारों पर RISING । मुझे इन किनारों की अनदेखी करने की आवश्यकता है क्योंकि कुछ भी खतरे में नहीं है। ISR2 को पहली बार बढ़त के किनारे पर कब्जा करने के उद्देश्य से लिखा गया था जब सीमा स्विच छूट जाता है, और उसके बाद यह तर्क देता है कि निम्नलिखित FALLING किनारों पर ध्यान न दिया जाए। लेकिन अब जब ISR2 कभी नहीं बुलाया जाता है, तो मैं इस स्थिति से कैसे निपट सकता हूँ?

पीएस मेरा माइक्रोकंट्रोलर एटीएमएजी 2650 है, यह एक आर्डिनो मेगा बोर्ड है।


आप क्यों कह रहे हैं कि यह कभी नहीं बुलाया जाता है? मुझे लगता है कि इसे कहा जाता है, लेकिन आप इसे ध्यान नहीं देते क्योंकि नेतृत्व में इसकी स्थिति बदलती नहीं है (क्योंकि वहां बाउंस है)।

वैसे भी, आप इसे सही ढंग से शुरू नहीं कर रहे हैं चलिए एक उदाहरण करते हैं: आप एंडस्टॉप को हिट करते हैं। ISR1 को बुलाया जाता है, इसलिए flag सच है। ठीक है, अगले लूप पर मोटर बंद हो जाएगा। लेकिन ... अब स्विच बाउंस है ISR2 को बुलाया जाता है, और आईएसआर से निकलने से पहले इसमें delay कार्य 100ms के लिए इंतजार करता है परिणाम: आपने 100 सेकंड तक मोटर स्टॉप फ़ंक्शन को देरी कर दी।

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


ISR2 कभी नहीं चलता है क्योंकि किसी इंटरप्ट स्रोत के लिए केवल एक इंटरप्ट सर्विस रूटीन हो सकता है और आप ISR1 को इस इंटरप्ट के लिए Sercice routine के रूप में बदल दिया है। अगर आपने ISR2 से पहले अपना कोड और ISR1 संलग्न किया है, तो आप ISR2 रन देख सकते हैं लेकिन ISR1 नहीं।

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

हालांकि आप पहले किनारे के लिए अंतराल प्राप्त करने के बाद दूसरे किनारे के लिए अंतराल को पुन: कॉन्फ़िगर करने में सक्षम हो सकते हैं और संक्रमण को रद्द कर सकते हैं। इस तरह आपका कोड एक आईएसआर के लिए आगे और पीछे कॉन्फ़िगर करेगा और दूसरे को पिंग-पँग करेगा।