আমার মাইক্রোকন্ট্রোলার এলইডি প্রোগ্রামটি কাজ বন্ধ করার কারণ কী?


11

সুতরাং, আমি প্রোগ্রামিং এ সম্পূর্ণ এবং নূতন। আমি আরডুইনোসে কিছু প্রাথমিক জিনিস করেছি (আক্ষরিকভাবে এলইডি টগল করা এবং একটি এলসিডির উপর কিছু প্রদর্শন করা) এবং আমি নিজে সি-তে প্রোগ্রাম কীভাবে শেখানোর চেষ্টা করছি আমি বাণিজ্য দ্বারা একটি হার্ডওয়্যার ইঞ্জিনিয়ার, তবে এটি আমাকে বিরক্ত করে যে আমি পারছি না ফার্মওয়্যার / সফ্টওয়্যার দিকের যে কোনও একটি করুন এবং এটি শেখানোর জন্য কোনও সন্ধ্যা কোর্স নেই এবং আমি আমার ক্যারিয়ারের বিকল্পগুলি এগিয়ে নিতে চাই। আমি বুঝতে চেষ্টা করছি যে এই কয়েকটি কমান্ড কীভাবে একসাথে চলে যায় এবং এমন একটি বিষয় নিয়ে চলে এসেছি যে এটি কেন কাজ করছে না আমি কেবল তার মাথা পেতে পারি না।

সুতরাং, আমি একটি ইনপুট এবং একটি আউটপুট আছে। আমার আউটপুটটি একটি FET এর গেটটি টগল করছে যা একটি LED চালু করে। ইনপুটটি একটি এন্ড গেট থেকে আসছে। সুতরাং, আমার এলইডি সর্বদা চালু থাকে, এবং আমি যখন এআরএন গেট থেকে একটি ইনপুট সিগন্যাল পাই (2 শর্ত পূরণ করা হয়েছে) আমি আউটপুট (এলইডি টগল) কম যেতে চাই (এলইডি বন্ধ করুন। আউটপুটটিও এর সাথে সংযুক্ত থাকায় অ্যান্ড ইনপুটগুলির মধ্যে একটি, এটি নীচে ইনপুট সিগন্যালটিকেও ঘুরিয়ে দেবে।

আমি কী করতে চাই: আমি কেবল ইনপুটটি 'শর্ত পূরণ' হিসাবে পড়তে এবং LED বন্ধ করতে চাই। এটি তখন 1 সেকেন্ডের জন্য বন্ধ রাখতে হবে এবং এটি আবার চালু হবে। যদি ইনপুট আবার উচ্চে চলে যায়, প্রক্রিয়াটি পুনরাবৃত্তি করে। আমি অন্যান্য ও গেটের ইনপুট হিসাবে স্যুইচ করতে একটি সাধারণ ধাক্কা ব্যবহার করছি এবং মাপ করেছি যে বোতামটি টিপলে আউটপুট (এমসিইউ ইনপুট) বেশি যায়, তবুও এলইডি টগল (আউটপুট) বন্ধ হবে না। আমার কোডটি (আমার মনে হয়) বেশ জঘন্য সরল, তবে স্পষ্টত আমি ঠিক কিছু বুঝতে পারি না কারণ এটি ঠিক কাজ করছে না।

সুতরাং আমি এই কোডটি ব্যবহার করছি:

#include "mbed.h"

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

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

এবং আমার কাছে এটি যৌক্তিক বলে মনে হয়। স্বাভাবিক অবস্থায়, আউটপুটটি উচ্চ হয়। যদি ইনপুটটি অ্যান্ড গেট থেকে সংকেত পায় তবে এলইডি 1 সেকেন্ডের জন্য বন্ধ হয়ে যাবে, তারপরে আবার চালু করুন।

এটি কীভাবে যুক্তিযুক্ত উপায় বলে মনে হচ্ছে আমি এটি ভুল করেছি এবং আমি বুঝতে পারি না কেন এটি কাজ করে না?

যদি এটি সহায়তা করে তবে আমি নিউক্লিও F103RB ব্যবহার করছি। আমি যখন 'পলক' কোডটি ব্যবহার করি এবং ঠিক তার মতোই এলইডি চালু এবং বন্ধ করি তখন এটি ঠিক কাজ করে, আমি যখন "যদি" বিবৃতিটি ভুল করি তখন ঠিক যুক্ত হয়।

এটি সরলিকৃত সার্কিট:

পরিকল্পিত

এই সার্কিটটি অনুকরণ করুন - সার্কিটল্যাব ব্যবহার করে স্কিম্যাটিক তৈরি করা হয়েছে

পিএস আমি জানি যে আমি সেগুলি স্কিমেটিকতে যুক্ত করিনি, তবে এবং গেটগুলির ইনপুট এবং আউটপুটটিতে পুলডাউন প্রতিরোধক রয়েছে।


আপনি যদি সরাসরি "IN শর্ত পূরণ করে" রাখেন তা কি কাজ করে?
ট্রানজিস্টর

এটা না. আমি বোতামটি সরাসরি আইএন-তে আটকে দিয়েছিলাম এবং এখনও কাজ করি না
কৌতূহলী

1
ইনপুট ভেরিয়েবলগুলি অস্থির হিসাবে চিহ্নিত করা ভাল ধারণা, বা সংকলক কোডটি বাইরে থেকে পরিবর্তন করা হচ্ছে না তা ধরে নিয়ে কিছু অদ্ভুত অপ্টিমাইজেশন করতে পারে।
ডার্ক ব্রুয়েরে

3
@ ডির্কব্রুয়ের: আপনি আশা করবেন যে এর সংজ্ঞাটি DigitalInইতিমধ্যে অন্তর্ভুক্ত রয়েছে volatile
এমএসএলটাররা

3
পরের বারের জন্য কেবল একটি ইঙ্গিত: আপনি সিপিইউ (বা মাইক্রোকন্ট্রোলার) চালু করার সময় বাটনটি চেপে ধরে রাখার চেষ্টা করুন। এখন কি হয়?
একটি সিভিএন

উত্তর:


26

আমি ভাবতাম যে আপনার কোডের চারপাশে একটি লুপের দরকার হবে -

while(1)
{

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

আপনার বোতামটি চাপ দেওয়ার সুযোগ পাওয়ার আগে আপনার কোডটি শেষ হয়ে যাবে এবং প্রস্থান হবে। যদি বিবৃতিটি বারবার চলতে থাকে তবে আপনার কিছুক্ষণ প্রয়োজন।


আমার কি আলাদা করে তোলে? আমি 'যখন' দেখতে পাব তবে কী করে? সমস্ত প্রশ্নের জন্য ক্ষমা চাই তবে আমি সত্যিই শূন্য জ্ঞান দিয়ে শুরু করছি!
কৌতুহল

1
@ কুরিয়াস আপনার বোতামটি টিপানোর সুযোগ পাওয়ার আগে আপনার কোডটি শেষ হয়ে যাবে এবং বেরিয়ে যাবে। যদি বিবৃতিটি বারবার চলতে থাকে তবে আপনার কিছুক্ষণ প্রয়োজন। আপনি সাধারণত যে মাইক্রোকন্ট্রোলার প্রোগ্রামিং করছেন সে সম্পর্কে কিছু আলাদা না হলে সাধারণত এটি হয় the
হ্যান্ডি হুই

9
"কীভাবে সে কাজ করেছে তা আপনি ব্যাখ্যা করতে পারেন" - শর্তটি শূন্যের দিকে না ফেরা পর্যন্ত কিছুক্ষণের মধ্যে সমস্ত কিছু পুনরায় হয়ে যায়। কী অবস্থা, আপনি জিজ্ঞাসা করতে পারেন; এটি "যখন" -শব্দের পরে বন্ধনীগুলির অংশ এবং আপনি দেখতে পাচ্ছেন শর্তটি 1 তে সেট করা হয়েছে, তাই এটি কখনই শূন্য নয় এবং এভাবে অনির্দিষ্টকালে পুনরাবৃত্তি হয়। লুপ ছাড়াই কোডটি একবারে কার্যকর করা হয় এবং এর পরে সফ্টওয়্যারটি সমাপ্ত হয়, তবে সেই সময়ের সাথে লুপটি কোডটি বারবার কার্যকর করা হয় যতক্ষণ না আপনি হার্ডওয়ারটি চালু না করেন।
জুরজি

14
আপনার ত্রুটি সম্ভবত আরডুইনো এমবেডে যাওয়া থেকে শুরু হয়েছিল। আরডুইনোতে আপনি সাধারণত আপনার অ্যাপ্লিকেশন কোডটি রেখে দেন loop()তবে আরডুইনো ফ্রেমওয়ার্কটি এমন কোড যুক্ত করে যা মোটামুটি আচরণ করে int main() { setup(); while(1) { loop(); } }
ris8_allo_zen0

1
@ করিয়াস ইউর্স কাজ করেছে। দুর্ভাগ্যক্রমে এটি একবার চালানো হয়েছিল, ততক্ষনে আপনি যখন এটি চালিত করেছিলেন। এটি চালাতে সম্ভবত একটি মাইক্রোসেকেন্ড নিয়েছিল, এবং এটিই ছিল। আপনি যদি ইনপুটটি পরীক্ষা করে চালিয়ে যাওয়া এবং আউটপুট সেট করতে চান তবে এটি চালিয়ে যাওয়ার জন্য আপনাকে এটি বলার প্রয়োজন। "যখন (কিছু_শর্ত)" ততক্ষণ চলবে "" কিছু_শক্তি "যতক্ষণ সত্য, সি ভাষার অর্থ যার অর্থ শূন্য নয়। সুতরাং "যখন (1)" চিরকাল ইনপুট চেক করে রাখে বা কমপক্ষে যতক্ষণ তা চালিত হয় for
গ্রাহাম

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()এমবেড লাইব্রেরি আরম্ভের কোড 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)। দ্বিতীয়টি মূর্তিমানিক সি, তবে পূর্ববর্তীটি "সর্বদা সত্যের কাছে মূল্যায়ন করবে" হিসাবে একজন মানুষের কাছে আরও স্পষ্ট। যে কোনও শালীন সংকলক উভয় ভেরিয়েন্টের জন্য একই বাইনারি কোড তৈরি করতে হবে।
একটি সিভিএন

2
@ মাইকেলKjörling আমি এটি মানুষের কাছে আরও সুস্পষ্টরূপে দ্বিমত পোষণ করব। আপনার মস্তিষ্ক যেমন চরিত্রের পরিবর্তে আকৃতি অনুসারে শব্দগুলি পড়েন তেমনি একজন অভিজ্ঞ প্রোগ্রামারের কাছে এই প্রতিমাগুলি প্রতিটি স্বতন্ত্র বিবৃতি কী করছে তা ব্যাখ্যা করার পরিবর্তে ধারণাগুলিতে সরাসরি অনুবাদ করে। অভিব্যক্তিমূলক নির্মাণ থেকে দূরে সরে আপনি লোককে আপনার কোডের সাথে বোঝার জন্য প্রয়োজনের চেয়ে কম স্তরের সাথে যুক্ত করতে বাধ্য করেন; যা একটি বৃহত কোড ভিত্তিতে অযথা মানসিক কাজ যোগ করে।
চুউ

1
@ চিউ "একজন মানুষের দ্বারা [যিনি অভিজ্ঞ প্রোগ্রামার নন]"
ব্যবহারকারী 253751

2

অন্যদের দ্বারা সঠিকভাবে উল্লিখিত হিসাবে, একটি লুপ আপনার কোডটি বারবার চালানোর অনুমতি দেয়। তবে whileলুপের প্রয়োজন ছাড়াই আরডুইনোর জন্য এটি করার একটি অন্তর্নির্মিত উপায় রয়েছে । এটি loopফাংশনটি দ্বারা সম্পন্ন হয় - আপনার সমস্যার জন্য এর প্রয়োগযোগ্যতা আপনি আরডুইনো আইডিই ব্যবহার করেন কিনা তার উপর নির্ভর করে।

এটি দেখতে কিছু দেখতে হবে:

#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=379368.0


হ্যাঁ। আমি মূলত একটি আরডুইনোতে জিনিসগুলি দিয়েছিলাম, নিউক্লিও এবং এমবেড আইডিইতে স্যুইচ করার সময় আমি বুঝতে পারি না কেন এটি কাজ করে না!
কৌতূহলী

1
এই উত্তরটি আরডুইনো সিস্টেমটি ব্যবহারের উপর নির্ভর করে। mbed একটি ভিন্ন পদ্ধতি / লাইব্রেরি সেট করা হয় এবং loop()এবং setup()যাও Arduino থেকে ফাংশন হয় না অধিকাংশ সিস্টেমের মধ্যে ব্যবহৃত। রেফারেন্সের জন্য, আরডিনো সহজভাবে main()এরকম কিছু সংজ্ঞা দেয় :void setup(); void loop(); int main() { setup(); while (true) loop(); }
ক্যামেরন ট্যাকলাইন্ড

0

আপনি যদি সমাবেশের সাথে পরিচিত না হন তবে এটি আপনার আরামদায়ক অঞ্চলে আরও কিছুটা হতে পারে:

int প্রধান () {

//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

আমি সমাবেশের সাথে মোটেই পরিচিত নই আমি ভীত!
কৌতূহলী

আমি এটি জানি কিন্তু এটি সম্পর্কে thats!
কৌতূহলী

@ জেরোয়েন 3 আপনি যে প্রশ্নের সাথে লিঙ্ক করেছেন তার উত্তর "গোটো কয়েকটি জায়গায় উপযুক্ত", "গোটো সঠিকভাবে ব্যবহার করা হলে কিছুই ভুল হয় না" এবং "নিজের মধ্যে গোটোতে কোনও ভুল নেই" দিয়ে উত্তর দেওয়া হয়। আমি একমত যে ব্যতিক্রমী ভাষায়, ভাষাগুলি অতিমাত্রায় ব্যবহারযোগ্য তবে বিশেষত সি-তে এর ব্যবহার রয়েছে।
glglgl

@glglgl: উপরে উল্লিখিত চুউ হিসাবে কোডটি পাঠযোগ্য হবে। goto** দৃ *়ভাবে ** সম্ভবত ব্যতিক্রম বাদ দিয়ে "এখানে যাদু চলছে" পরামর্শ দেয় goto cleanup;। এখানে উদাহরণ হিসাবে, পাঠককে এই চমকপ্রদ প্রশ্নটি ছেড়ে দেওয়া হবে "এত বিশেষ যে আপনি while(1) { }এখানে ব্যবহার করেন নি ???"।
এমসাল্টাররা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.