# ডিজিটাল ইনপুট আউটপুট ও লুপ

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

* `Arduino Board`
* `Breadboard`
* `Jumper Wire`
* `10KOhm Resistor` – ১টি
* `220Ohm Resistor` – ১টি&#x20;
* `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<= 1000; i = i + 100)
    {
        digitalWrite(ledPin, HIGH);
        delay(i);
        digitalWrite(ledPin, LOW);
        delay(i);
    }
}
```

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

### Line 10:

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

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

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

অথবা

```cpp
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](http://i.imgur.com/NbIOh3K.gif)

## ডিজিটাল 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](http://i.imgur.com/v1Ejkt5.png)

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

```
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` দরকার।

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

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

```cpp
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](http://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Pullup_Resistor.png/220px-Pullup_Resistor.png)

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

![alt text](http://i.imgur.com/7vhlbUf.png) ![alt text](http://i.imgur.com/AEnUktj.png) ![alt text](http://i.imgur.com/sQMmib1.png) ![alt text](http://i.imgur.com/BlieQX5.png)

আরও জানার জন্য ভিসিট দিন এই [লিঙ্কে](http://playground.arduino.cc/CommonTopics/PullUpDownResistor)।


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://arduino.howtocode.dev/basic_ideas/digitalio.loop.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
