ডিজিটাল ইনপুট আউটপুট অপারেশন, Loop ও If Else এর উদাহরণ

এই পর্বে যা যা লাগবে:

  • Arduino Board
  • Breadboard
  • Jumper Wire
  • 10KOhm Resistor – ১টি
  • 220Ohm Resistor – ১টি
  • USB Cable - ১টি
  • Pushbutton - ১টি
  • Single-Color LED - ১টি

Loop (লুপ) ব্যবহার করে ডিজিটাল আউটপুটের উদাহরণ:

গত পর্বে আমরা দেখেছিলাম Led ব্লিঙ্কিং কীভাবে করে। সেটাও কিন্তু ডিজিটাল আউটপুট। আমরা ডিজিটাল আউটপুট আরেকবার ঝালাই দেওয়ার জন্য For loop ব্যবহার করে দেখব কীভাবে ডিজিটাল আউটপুটের তৈরি করা যায়।

আর হ্যাঁ, আগের পর্বের সার্কিট ডায়াগ্রামটা ফলো করলেই হবে

প্রোগ্রামটা দেখে নেওয়া যাক:

int ledPin = 13;

void setup()
{
    pinMode(ledPin, OUTPUT);
}

void loop()
{
    for (int i = 100; i

Line 1, 3, 5, 8 এর ব্যাখ্যা পূর্বের পোস্টে দেওয়া আছে।

Line 10:

for (int i = 100; i <= 1000; i = i + 100){
// Statements goes here
}

এইখানে লুপ ব্যাবহার করা হয়েছে। আমাদের অনেক সময় একই কাজ বারবার করতে হয়। একই কাজ বারংবার করার প্রক্রিয়াই হল লুপ। যদি আমাকে বলা হয় C তে তোমার গ্রুপের নাম ১০০ বার লিখ, সাধারণ চিন্তায় আমি দুইভাবে লিখতে পারি।

printf("Electroscholars"); // 1st one
printf("Electroscholars");
.................
.................
printf("Electroscholars"); // The 100th one

অথবা

int i;
for (i = 0; i < 100; i = i + 1)
{
  printf("Electroscholars");
}

এভাবে, আমাদের ১০০ লাইনের কোডটি মাত্র ৪ লাইনে সমাপ্ত হল। যদি লুপের স্ট্রাকচার না বুঝে থাকেন তাহলে নিচের অংশটি পড়ে ফেলুন।

For লুপের স্ট্রাকচার:

  • for লুপের স্ট্রাকচার শুরু হয় একজোড়া First Bracket দিয়ে, First Bracket এ ৩টি অংশ দুইটি ‘;’ – সেমিকোলন দ্বারা ভাগ করা থাকে

  • প্রথম ‘;’ এর আগের অংশকে Initialization, প্রথম ‘;’ এর পরে এবং পরের ‘;’ এর আগের অংশকে Condition ও পরের ‘;’ এর পরের অংশকে Increment বলা হয়

  • first bracket ক্লোজড করার পর Second Bracket বা Curly Braces থাকে। এই Second Bracket এর মধ্যে যেসব স্টেটমেন্ট / ফাংশন ইত্যাদি থাকবে তা Loop এর শর্ত ও ইনক্রিমেন্ট অনুযায়ী ততবার রান করানো হয়।

For লুপ যেভাবে কাজ করে:

  • লুপটি প্রথমেই তার ভ্যারিয়েবলে একটি মান বসিয়ে নেয় (Initialization) [উপরের উদাহরণে যেমন, i = 0। দ্রষ্টব্য, C++, Java, Arduino ইত্যাদি ল্যাঙ্গুয়েজে প্রথম ব্র্যাকেটের ভিতর-ই ভ্যারিয়েবল তৈরি করা যায়, মানে for (int i = 0; i < 100; i = i + 1) Java, C++ ইত্যাদি ল্যাঙ্গুয়েজে কাজ করবে কিন্তু C তে নয়।

  • এরপর সেই মানটি শর্তানুযায়ী চেক করে দেখে সেই ভ্যারিয়েবল শর্তটি মানছে কিনা [Condition]

  • যদি শর্ত মানে তাহলে সে এবার কোন ‘Increment’ না করে সরাসরি Curly Braces এর স্টেটমেন্টগুলো রান করতে থাকে

  • স্টেটমেন্টগুলো সব রান হয়ে গেলে এবার সে তার ভ্যারিয়েবল এর মান ইঙ্ক্রিমিনেন্ট শর্তানুযায়ী বাড়ায়।

  • বাড়ানোর পরে আবারও চেক করে সেটা শর্ত মানছে কিনা শর্ত মানলে সে লুপের স্টেটমেন্টে আবার প্রবেশ করে রান করানোর জন্য ভ্যারিয়েবলের মান যদি বাড়তে বাড়তে / কমতে কমতে এমন এক পর্যায়ে চলে যায় যেখানে সে আর শর্ত মানে না তখন আর লুপের স্টেটমেন্টগুলো রান করানোর চেষ্টা করে না

লুপের ব্যাপারটি আশা করি কিছুটা হলেও বোঝা গেল। এবার দেখা যাক প্রোগ্রামটি কি বলছে?

প্রোগ্রামটির Walkthrough!:

  • ledPin নামের ইন্টিজার টাইপের ভ্যারিয়েবল তৈরি করে 13 নাম্বারটি তার মধ্যে রাখ
  • void setup() ফাংশনে: ledPin কে আউটপুট হিসেবে সেট কর
  • void loop() ফাংশনে (এই ফাংশন একটি Infinite Loop এর উৎকৃষ্ট উদাহরণ):
  • ফর লুপে i নামের ভ্যারিয়েবল তৈরি করে 100 সংখ্যাটি তার মধ্যে রাখ, i কি 1000 এর চেয়ে ছোট? (যদি ছোট হয় তাহলে লুপে প্রবেশ করবে না হলে করবে না)
  • হ্যাঁ
  • লুপে প্রবেশ কর!
  • ledPin এ ৫ ভোল্ট দাও
  • 100 মিলিসেকেন্ড অপেক্ষা কর
  • ledPin থেকে ৫ ভোল্ট সরাও
  • 100 মিলিসেকেন্ড অপেক্ষা কর
  • এবার i এর মান আরও ১০০ বাড়াও (=২০০ হল)
  • এখন i কি ১০০০ এর ছোট? হ্যাঁ, তাহলে লুপে প্রবেশ কর
  • ledPin এ ৫ ভোল্ট দাও
  • 200 মিলিসেকেন্ড অপেক্ষা কর
  • ledPin থেকে ৫ ভোল্ট সরাও
  • 200 মিলিসেকেন্ড অপেক্ষা কর
  • এবার i এর মান আরও ১০০ বাড়াও (=৩০০ হল)

…. …. …. এভাবে i এর মান ১০০০ হলেও কাজ করবে কিন্তু যখন ১১০০ হয়ে যাবে তখন লুপে প্রবেশ করবে না, তখন সে void loop এর একদম প্রথমে চলে যাবে এবং তখন তার কাছে এই for লুপটি নতুন লুপ মনে হবে তাই সে আবার i এর মান ১০০ সেট করবে।

এভাবে যত সময় যাবে জ্বলা নেভার সময় বাড়তে থাকবে একসময় যখন for লুপের শর্ত মানবে না তখন void loop এর প্রথম থেকে চলা শুরু করবে।

Proteus সিম্যুলেশন:

alt text

ডিজিটাল Input Reading নিয়ে কিছু কথা:

ডিজিটাল ইনপুটের জন্য আগের সার্কিটটাকে একটু মডিফাই করে ব্যবহার করব। আমি যেটা করতে চাইছি সেটা হচ্ছে, একটি পুশ বাটন থাকবে আর্ডুইনোর সাথে, সেটাকে প্রেস করলে একটি led জ্বলবে। খুবই সাধারণ একটি প্রজেক্ট কিন্তু ডিজিটাল রিডিং সম্পর্কে জানার জন্য যথেষ্ট। সার্কিটের জন্য কোড লেখার আগে কিছু জিনিস জানা জরুরি।

এখানে পুশবাটনটি কানেক্ট করলেই হবে না বরং তার সাথে একটি Pull Down* রেজিস্ট্যান্স কানেক্ট করতে হবে। Push Button এর এক পাশে 5V সাপ্লাই দেওয়া হয় আর আরেক পাশ আর্ডুইনো বা অন্য কোন কম্পোনেন্টের সাথে যুক্ত করা হয়। যখন বাটনটি পুশ করা হয় তখন 5V ও অপরপাশ Short হয়ে যায় তাই সরবরাহকৃত 5V অপর প্রান্তে পৌঁছে যায়। এভাবে আমরা যখন বারংবার রিডিং চেক করে দেখব পিনে 5V পাচ্ছে কিনা, সেই শর্ত দিয়ে আমরা আর্ডুইনোর মাধ্যমে কাজ করতে পারি।

এখন আমরা চিন্তা করি, পুশবাটনটির সাথে কোন Pull Down রেজিস্ট্যান্স নেই। তাহলে কি হবে? আপাত দৃষ্টিতে সমস্যা হওয়ার কথা না কারণ আর্ডুইনো তো 5V টলারেন্ট আর আমরা তার থেকে ভোল্টেজ নিয়ে তাকেই সাপ্লাই দিচ্ছি পুশবাটনটির মাধ্যমে, তাই আর্ডুইনোর কিছু হবে না। কিন্তু যখন এক পাশ 5V এর সাথে যুক্ত থাকবে [Unpressed অবস্থায়] এবং আমরা রিডিং চেক করব তখন Unexpected Noise এর সৃষ্টি হবে যেটা রিডিংকে Fluctuate করবে।

সমস্যা শুধু সেটাই না, আমরা ব্রেডবোর্ডে 5V Supply Rail তৈরি করব যেখানে আমরা 5V সাপ্লাই দিব, যখন 5V দরকার হবে তখন সেখান থেকে 5V নিয়ে কম্পোনেন্টে দিব। ধরা যাক, পুশবাটন আর্ডুইনোর সাথে কানেক্টেড এবং পুশবাটনে 5V সাপ্লাই দেওয়া ও Push Button এর একটি প্রান্ত গ্রাউন্ডে ও সেই গ্রাউন্ড থেকে একটি জাম্পার দিয়ে আর্ডুইনোতে কানেক্ট করা হবে এবং একটি Led রেজিস্ট্যান্সসহ 13 নাম্বার পিনে কানেক্টেড। গ্রাউন্ড থেকে তাহলে দুটা কানেকশন যাচ্ছে, একটি সরাসরি গ্রাউন্ড অপরটি আর্ডুইনোতে, পুশবাটন চাপ দিলে এবার কারেন্ট কোথায় ফ্লো করবে? বেশিরভাগ কারেন্ট আর্ডুইনোতে না গিয়ে গ্রাউন্ডে চলে যাবে অর্থাৎ রিডিং পাওয়ার পর্যাপ্ত কারেন্ট সে পাবে না। তাই আমরা একটি Pull Down রেজিস্ট্যান্স ব্যবহার করছি।

Pull Down রেজিস্ট্যান্সের কারণে কারেন্টকে আবারও একই সিদ্ধান্ত নিতে হবে,

  • হয় সে হাই রেজিস্ট্যান্স লাইন দিয়ে গ্রাউন্ডে যাবে
  • অথবা অপেক্ষাকৃত অল্প রেজিস্ট্যান্স লাইন দিয়ে আর্ডুইনোতে যাবে

Ohm বলে গেছেন সে ২য় অপশনটি বেছে নিবে :P। তারমানে আমরা আর্ডুইনোতে এবার পর্যাপ্ত কারেন্ট পাচ্ছি রিডিং চেক করার জন্য। Resistance ব্যবহার করার কারণে কিছু ভোল্টেজ ড্রপ হবে অবশ্যই কিন্তু আর্ডুইনোর Digital Reading এর জন্য পুরোপুরি 5V এর দরকার হয় না :)

সার্কিট ডায়াগ্রাম:

alt text

আর্ডুইনো প্রোগ্রাম:

int led = 13;
int button = 3;

void setup()
{
    pinMode(led, OUTPUT);
    pinMode(button, INPUT);
}

void loop()
{
    if (digitalRead(button) == HIGH)
    {
        digitalWrite(led, HIGH);
    }
    else
    {
        digitalWrite(led, LOW);
    }
}

প্রোগ্রাম Walkthrough:

আগের লাইনের ব্যাখ্যা পূর্বের পোস্টগুলোতে দেওয়া আছে।

Line 7:

পুশবাটন থেকে আমরা রিডিং নিচ্ছি, তাই এটা ইনপুট। এখন এটি যে পিনের সাথে কানেক্টেড ঠিক সেই কারণে সেটাকে Input হিসেবে সেট করতে হবে।

Line 12:

if else অত্যান্ত গুরুত্বপূর্ন একটি কনডিশনাল ফ্লো কন্ট্রোল। এখানে যেটি করা হয়, প্রথমে আমরা একটি নির্দিষ্ট স্টেটমেন্ট সিলেক্ট করি। যদি সেটা True হয় তাহলে এই কাজটা করবে, সেটা False হলে আরেকটি কাজ করবে। এটা ঠিক করার জন্য if else দরকার।

if (booleanCheck == True)
{
   doThis();
} else {
   doThat();
}

যেমন, আরেকটি উদাহরণ:

if (6 < 7)
{
    printf("This is Electroscholars!");
} else {
    printf("Program will NEVER print this!");
}

6 সর্বদাই 7 এর চেয়ে ছোট, তারমানে 6 < 7 == True। এর অর্থ প্রোগ্রামটি রান করলে “This is Electroscholars” প্রিন্ট হবে বাকি অংশ প্রিন্ট হবে না।

আমরা if এর মধ্যে নতুন একটি ফাংশন digitalRead দেখতে পাচ্ছি। digitalRead এর আর্গুমেন্ট ইন্টিজার টাইপ ও রিটার্ন টাইপ বুলিয়ান। অর্থাৎ সে আর্গুমেন্টে কোন পিন সেটা গ্রহণ করে এবং আউটপুটে হ্যাঁ/না, 1/0, HIGH, LOW রিটার্ন করে।

তাহলে যদি button Read করে LOW পায় অর্থাৎ ভোল্টেজ না পায় তাহলে সে led তে ভোল্টেজ দিবে না। বাটন প্রেস না করলে ভোল্টেজ পাবে না তাই আর led ও জ্বলবে না।

এখানে else এর আড়ালে আছে if (digitalRead(button) == LOW), if এর পরে else থাকলে তার কন্ডিশন হয় if এর উল্টা। অর্থাৎ, বাটনে থেকে HIGH রিড করলে led জ্বলবে।

এটার সিম্যুলেশন করলে পুশ বাটন চাপ দিলে led জ্বলে ঠিকি কিন্তু আর সেটা নিভে না। এটার সিম্যুলেশনগত প্রবলেম আছে, তাই সিম্যুলেট করে দেখালাম না। এটা আপনাদের বাড়ির কাজ। বাস্তবে কোডটি কাজ করবে, সমস্যা নেই।

নোট:

Pull Up Resistor, Pull Down Resistor

alt text

নিচের ছবিগুলো দেখলেই ধারণা পরিষ্কার হবে। Pull Down Resistor এর ক্ষেত্রে সুইচের সাথে গ্রাউন্ড না হয়ে VCC হবে।

alt text alt text alt text alt text

আরও জানার জন্য ভিসিট দিন এই লিঙ্কে