मेरे माइक्रोकंट्रोलर एलईडी कार्यक्रम के कारण काम करना बंद हो गया है?


11

इसलिए, मैं प्रोग्रामिंग में एक पूर्ण और पूर्ण नौसिखिया हूं। मैंने Arduinos पर कुछ बुनियादी सामान किया है (शाब्दिक एलईडी एलईडी और एक एलसीडी पर कुछ प्रदर्शित करना) और मैं स्वयं को सिखाने की कोशिश कर रहा हूं कि कैसे सी में प्रोग्राम करना है। मैं व्यापार द्वारा एक हार्डवेयर इंजीनियर हूं, लेकिन यह मुझे परेशान करता है कि मैं नहीं कर सकता फर्मवेयर / सॉफ्टवेयर साइड में से कोई भी करें और इसे पढ़ाने के लिए शाम के पाठ्यक्रम नहीं हैं, और मैं अपने करियर के विकल्पों को आगे बढ़ाना चाहता हूं। मैं यह समझने के लिए संघर्ष कर रहा हूं कि इनमें से कुछ कमांड एक साथ कैसे चलते हैं और इस मुद्दे पर चले गए हैं कि मैं अपना सिर इधर-उधर नहीं कर सकता कि यह काम क्यों नहीं कर रहा है।

इसलिए, मेरे पास एक इनपुट और एक आउटपुट है। मेरा आउटपुट एक FET के गेट को टॉगल करता है जो एक एलईडी चालू करता है। इनपुट एक AND गेट से आ रहा है। तो, मेरी एलईडी हमेशा चालू रहती है, और जब मुझे AND गेट से इनपुट सिग्नल मिलता है (2 स्थितियां पूरी हो गई हैं) मैं चाहता हूं कि आउटपुट (एलईडी टॉगल) LOW पर जाए (LED को बंद करें। चूंकि आउटपुट भी जुड़ा हुआ है) AND इनपुट्स में से एक, यह इनपुट सिग्नल LOW को भी चालू कर देगा।

मैं क्या करना चाहता हूं: मैं सिर्फ इनपुट को 'शर्तों के अनुसार' के रूप में पढ़ना चाहता हूं और एलईडी बंद कर देता हूं। फिर इसे 1 सेकंड के लिए बंद होना चाहिए, और वापस चालू करना चाहिए। यदि इनपुट उच्च फिर से जाता है, तो प्रक्रिया दोहराती है। मैं दूसरे और गेट इनपुट के रूप में स्विच करने के लिए एक साधारण पुश का उपयोग कर रहा हूं और मापा है कि बटन दबाए जाने पर आउटपुट (MCU इनपुट) उच्च हो जाता है, फिर भी एलईडी टॉगल (आउटपुट) बंद नहीं होगा। मेरा कोड है (मुझे लगता है) बहुत लानत है, लेकिन स्पष्ट रूप से मुझे कुछ ठीक से समझ नहीं आ रहा है क्योंकि यह अभी काम नहीं कर रहा है।

तो यह वह कोड है जिसका मैं उपयोग कर रहा हूं:

#include "mbed.h"

DigitalIn ip(D7);
DigitalOut op(D8);

int main() {
    if (ip == 1){
        op = 0;
        wait (1.0);
        op = 1;
    }else{
        op = 1;
    }
}

और मेरे लिए, यह तर्कसंगत लगता है। सामान्य स्थिति में, आउटपुट उच्च है। यदि इनपुट को AND गेट से सिग्नल मिलता है, तो LED 1 सेकंड के लिए बंद हो जाएगी, फिर से चालू करें।

ऐसा क्या है जो मैंने गलत किया है क्योंकि ऐसा करने के लिए तार्किक तरीका दिखता है और मैं बस यह नहीं समझ सकता कि यह काम क्यों नहीं करता है?

यदि यह मदद करता है, तो मैं Nucleo F103RB का उपयोग कर रहा हूं। जब मैं 'ब्लिंक' कोड का उपयोग करता हूं और इस तरह एलईडी को चालू और बंद करता हूं, तो यह ठीक काम करता है, यह सिर्फ तब होता है जब मैं 'इफ' स्टेटमेंट जोड़ता हूं कि यह गलत हो जाता है।

यह सरलीकृत सर्किट है:

ढांच के रूप में

इस सर्किट का अनुकरण करें - सर्किटलैब का उपयोग करके बनाई गई योजनाबद्ध

पीएस मुझे पता है कि मैंने उन्हें योजनाबद्ध में नहीं जोड़ा था, लेकिन इनपुट और आउटपुट पर AND गेट्स में पुलडाउन रेसिस्टर्स होते हैं।


क्या यह काम करता है यदि आप "शर्तों को सीधे" में डालते हैं?
ट्रांजिस्टर

ऐसा नहीं होता। मैंने बटन को सीधे IN में चिपका दिया और फिर भी काम नहीं किया
Curious

1
इनपुट चर को अस्थिर के रूप में चिह्नित करना एक अच्छा विचार है, या संकलक कुछ अजीब अनुकूलन कर सकता है यह मानकर कि यह कोड के बाहर से नहीं बदला जा रहा है।
डिर्क ब्रुअरे

3
@DirkBruere: आपको उम्मीद है कि DigitalInपहले से ही परिभाषा शामिल है volatile
MSalters

3
अगली बार के लिए बस एक संकेत: जब आप सीपीयू (या माइक्रोकंट्रोलर) को चालू करते हैं (या रीसेट करते समय) बटन दबाए रखें। अब क्या होता है?
बजे एक CVn

जवाबों:


26

मैंने सोचा होगा कि आपको अपने कोड के आसपास एक लूप की आवश्यकता होगी -

while(1)
{

    if (ip == 1){
       op = 0;
       wait (1.0);
       op = 1;}
    else {
       op = 1;}
}

इससे पहले कि आपके पास बटन दबाने का मौका हो आप कोड समाप्त और बाहर हो जाएंगे। यदि आपको कथन को बार-बार चालू रखने के लिए समय चाहिए।


क्या है कि मेरा अलग है? मैं can जबकि ’देख सकता हूं लेकिन वह क्या करता है? सभी प्रश्नों के लिए क्षमा याचना लेकिन मैं वास्तव में शून्य ज्ञान के साथ शुरू कर रहा हूँ!
उत्सुक

1
@curious बटन को दबाने का मौका देने से पहले आपके पास कोड समाप्त और बाहर हो जाएगा। यदि आपको कथन को बार-बार चालू रखने के लिए समय चाहिए। यह सामान्य रूप से मामला है, जब तक कि आपके द्वारा प्रोग्रामिंग किए जा रहे माइक्रोकंट्रोलर के बारे में कुछ अलग न हो।
हैंडीहोवी

9
"क्या आप बता सकते हैं कि क्यों काम किया" - थोड़ी देर के लूप में सब कुछ दोहराया जाता है जब तक कि स्थिति शून्य तक नहीं हो जाती। क्या हालत है, आप पूछ सकते हैं; "जबकि" के बाद कोष्ठकों में वह हिस्सा है -कीवर्ड और जैसा कि आप देख सकते हैं, स्थिति 1 पर सेट है, इसलिए यह कभी भी शून्य नहीं है और इस प्रकार अनिश्चित काल तक दोहराया जाता है। लूप के बिना कोड को केवल एक बार निष्पादित किया जाता है और जिसके बाद सॉफ्टवेयर समाप्त हो जाता है, लेकिन लूप कोड के साथ बार-बार निष्पादित किया जाता है जब तक कि आप हार्डवेयर को चालू नहीं करते।
ज्यूरी

14
आपकी त्रुटि शायद Arduino से mbed जाने से उपजी है। Arduino में आप आमतौर पर अपना एप्लिकेशन कोड डालते हैं loop(), लेकिन Arduino फ्रेमवर्क में वह कोड जुड़ता है जो लगभग समान व्यवहार करता है int main() { setup(); while(1) { loop(); } }
उदय 17_लालो_जन ०

1
@Curious तुम्हारा काम किया। दुर्भाग्य से यह ठीक एक बार भाग गया, तुरंत जब आपने इसे चालू किया। शायद इसे चलाने के लिए एक माइक्रोसेकंड लिया गया था, और वह यह था। यदि आप चाहते हैं कि यह इनपुट की जाँच करता रहे और आउटपुट सेट करता रहे, तो आपको इसे करते रहने के लिए कहना होगा। "जबकि (some_condition)" तब तक चलता है जब तक "some_condition" सही होता है, जिसका C भाषा में अर्थ होता है गैर-शून्य। तो "जबकि (1)" इनपुट को हमेशा के लिए जाँचता रहता है, या कम से कम जब तक यह वैसे भी संचालित होता है।
ग्राहम

21
#include "mbed.h"

DigitalIn ip(D7);
DigitalOut op(D8);

int main() {
    if (ip == 1){
        op = 0;
        wait (1.0);
        op = 1;
    }else{
        op = 1;
    }
    // and now the program ends? What to do?
}

प्रोसेसर निर्देश को क्रमिक रूप से निष्पादित करता है । यह एक छलांग के साथ शुरू होता हैmain() की Mbed पुस्तकालय initialisation कोड के भीतर से DigitalInऔर DigitalOut
फिर तुलना करता है ip == 0, के भीतर निर्देश चलाता है {}और फिर main()समाप्त होता है ... कोई और निर्देश नहीं ... यह क्या करता है?

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

अब, इसे कैसे ठीक करें?

int main() {
    // Add a while(1) infinite loop
    while(1){
        if (ip == 1){
            op = 0;
            wait (1.0);
            op = 1;
        }else{
            op = 1;
        }
    }
    // Program never gets here
}

स्पष्टीकरण के लिए बहुत-बहुत धन्यवाद। जबकि लूप ने इसे काम करने में सक्षम बनाया। दुर्भाग्य से मैं आपको अभी तक +1 नहीं दे सकता क्योंकि मेरा प्रतिनिधि बहुत कम है, लेकिन मैं प्रतिक्रिया और स्पष्टीकरण की बहुत सराहना करता हूं
जिज्ञासु

अहा! मेरे सवाल पर उस तीसरे उत्थान ने मुझे आपके जवाब को वोट करने दिया! धन्यवाद फिर से
जिज्ञासु

1
@ गंभीर यदि आप चाहते हैं कि यह आपके लिए स्पष्ट हो, तो प्रोग्रामर, आप while(1 == 1)सिर्फ इसके बजाय कुछ लिख सकते हैं while(1)। उत्तरार्द्ध मुहावरेदार सी है, लेकिन पूर्व मनुष्य के लिए अधिक स्पष्ट है क्योंकि "हमेशा सच का मूल्यांकन करेगा"। किसी भी सभ्य संकलक को दोनों वेरिएंट के लिए एक ही बाइनरी कोड का उत्पादन करना चाहिए।
बजे एक CVn

2
@ MichaelKjörling मैं असहमत हूँ यह एक मानव के लिए अधिक स्पष्ट है। जैसे आपका मस्तिष्क चरित्र के बजाय उनके आकार से शब्दों को पढ़ता है, एक अनुभवी प्रोग्रामर के लिए ये मुहावरे प्रत्येक व्यक्तिगत कथन की व्याख्या करने के बजाय सीधे अवधारणाओं पर अनुवाद करते हैं। मुहावरेदार निर्माणों से दूर जाकर आप लोगों को अपने कोड के साथ संलग्न करने के लिए मजबूर करते हैं जो कि समझ से कम आवश्यक है; जो एक बड़े कोड आधार पर बहुत सारे अनावश्यक मानसिक कार्यों को जोड़ता है।
चुउ

1
@Chuu "एक मानव द्वारा [जो एक अनुभवी प्रोग्रामर नहीं है]"
user253751

2

जैसा कि दूसरों द्वारा सही उल्लेख किया गया है, एक लूप आपके कोड को बार-बार चलाने की अनुमति देगा। हालांकि, एक whileलूप की आवश्यकता के बिना Arduino के लिए ऐसा करने का एक अंतर्निहित तरीका है । यह loopफ़ंक्शन द्वारा किया जाता है - आपकी समस्या के लिए इसकी प्रयोज्यता इस बात पर निर्भर करती है कि आप Arduino IDE का उपयोग करते हैं या नहीं।

यह कुछ इस तरह दिखना चाहिए:

#include "mbed.h"

DigitalIn ip(D7);
DigitalOut op(D8);

void setup() {
    // any code before loop is run
}

void loop() {
    if (ip == 1){
        op = 0;
        wait (1.0);
        op = 1;
    }else{
        op = 1;
    }
}

आपका मुख्य कार्य अब छिपा हुआ है और संकलित होने पर ही आपके कार्यक्रम में जोड़ा जाता है। यहाँ इस पर एक अच्छी चर्चा है: http://forum.arduino.cc/index.php?topic=37936.2.0


हाँ। मैंने मूल रूप से एक arduino पर चीजें कीं, जिसमें यह भी शामिल है जब नाभिक पर स्विच किया गया और आईडीई आईडीई मैं समझ नहीं सका कि यह काम क्यों नहीं किया!
जिज्ञासु

1
यह उत्तर Arduino सिस्टम का उपयोग करने पर निर्भर करता है। mbed एक अलग प्रणाली / पुस्तकालयों का सेट है और loop()और setup()Arduino से कार्यों कर रहे हैं नहीं सबसे प्रणालियों में इस्तेमाल किया। संदर्भ के लिए, Arduino बस main()कुछ इस तरह परिभाषित करता है :void setup(); void loop(); int main() { setup(); while (true) loop(); }
कैमरून टैक्लिंड

0

यदि आप असेंबली से परिचित हैं, तो यह आपके कम्फर्ट ज़ोन में भी थोड़ा अधिक हो सकता है:

मुख्य प्रवेश बिंदु() {

//A label or function similar to assembly

label:

    if (ip == 1){

        op = 0;

        wait (1.0);

        op = 1;

    }else{

        op = 1;

    }

// Goto used same as "jmp" in assembly

goto label;

// Program never gets here

}


3
कृपया विधानसभा के ऊपर किसी भी भाषा में गोटो का उपयोग न करें
जेरोएन 3

मैं विधानसभा से बिल्कुल भी परिचित नहीं हूँ मुझे डर है!
जिज्ञासु

मुझे पता है, लेकिन इसके बारे में है!
जिज्ञासु

@ Jeroen3 आपके द्वारा लिंक किए गए प्रश्न का उत्तर "कुछ ही स्थानों पर उचित है", "गोटो के साथ कुछ भी गलत नहीं है यदि इसे ठीक से उपयोग किया जाता है" और "अपने आप में गोटो के साथ कुछ भी गलत नहीं है"। मैं इस बात से सहमत हूं कि अपवाद वाली भाषाओं में, गोटो शानदार है, लेकिन विशेष रूप से सी में, इसके उपयोग हैं।
ग्लोगल

@glglgl: जैसा कि चू ने ऊपर बताया है, कोड को पठनीय होना चाहिए। goto** जोरदार ** से पता चलता है "जादू यहाँ चल रहा है", संभवतः के अपवाद के साथ goto cleanup;। यहां उदाहरण में, पाठक को गूढ़ प्रश्न के साथ छोड़ दिया जाएगा "ऐसा क्या खास है जो आपने while(1) { }यहां इस्तेमाल नहीं किया ???"।
एमएसल्टर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.