# পালস উইডথ মড্যুলেশন পরিচিতি

## যা যা লাগবে:

* `Arduino` \[Predictable! Isn’t it? :P]
* `Breadboard`
* `Jumper`
* `Led`
* `Resistor` \[Recommended 100Ohm, but 220/330 Will work too]

## PWM সম্পর্কে আলোচনা:

এতক্ষণে আপনারা ডিজিটাল ইনপুট আউটপুট দেখলেন, এবার দেখাব অ্যানালগ আউটপুট কিভাবে আর্ডুইনোর মাধ্যমে তৈরি করা যায়। ডিজিটাল আউটপুটের ক্ষেত্রে আমরা দেখেছি কোন পিনে আমরা `digitalWrite()` ফাংশনটি প্রয়োগ করলেই `5V` যাচ্ছে। কিন্তু আমাদের অনেক সময় শুধু `5V` দিলে হয় না, কম ভোল্টেজ হলে সুবিধা হয়। ডিজিটাল `I/O Led` ব্লিংকিং কিংবা মোটর ঘুরানোর জন্য যথেষ্ট, কিন্তু মনে করুন আপনার মোটরটির স্পিড কন্ট্রোল কিংবা Led এর ব্রাইটনেস কন্ট্রোল করার দরকার হল, তাহলে কী করবেন? যেহেতু `5V` অ্যাপ্লাই করলে মোটরটি ফুল স্পিডে ও `Led` টি ফুল ব্রাইটনেসে জ্বলবে তাই তার জন্য একটা ব্যবস্থা নেওয়া জরুরি।

যখন আপনি এই সমস্যায় ভুগছেন, ঠিক তখনই `PWM` করা লাগবে। এটা দ্বারা ভোল্টেজ কমানো হয় না, একটি সাইকেলে ভোল্টেজ কতক্ষণ দেব কি দেব না সেটা নির্ধারণ করাই `PWM` এর কাজ! `PWM` এর আরক নাম `DAC [Digital to Analog Conversion]`, এটি `DAC` থেকে `PWM` নামেই বেশি পরিচিত। যেহেতু `PWM` এর মাধ্যমে ভোল্টেজ আমরা টাইম ধরে দেই ও দেই না, তাই এটা প্রায় অ্যানালগ আউটপুট দেয়।

`PWM` সিগনাল জেনারেট করার জন্য আমরা `analogWrite(int pin, int value)` ফাংশনটি ব্যবহার করি, `analogWrite` এর প্রথ্ম আর্গুমেন্ট `pin` নির্দেশ করে কত নাম্বার পিনে সিগনাল দিতে হবে এবং `value` নির্দেশ করে কত ভ্যালুর `PWM` সিগনাল দিতে হবে। একটা কথা মাথায় রাখতে হবে, `value` এর মান `8-bit` এর মধ্যে সীমাবদ্ধ রাখতে হবে বা `0 থেকে 2^8 – 1` বা `0 – 255` পর্যন্ত ভ্যালুর মান হতে পারে, এর চেয়ে বেশি হলে কাজ করবে না।

আর হ্যাঁ, আর্ডুইনোর সব পিন `PWM Signal` জেনারেট করতে পারে না, `UNO` এর ক্ষেত্রে যেসব পিনের আগে `‘~’` চিহ্নটি আছে কেবল ওই পিনগুলোই `PWM Signal` জেনারেট করতে পারবে, যেমন `3, 5, 6, 9, 10, 11` পিনগুলো `UNO` এর `PWM` পিন। কোন মোটর স্পিড কন্ট্রোল বা `Led` এর ব্রাইটনেস কন্ট্রোলিংয়ের জন্য আপনাকে অবশ্যই সেই ডিভাইস/কম্পোনেন্টগুলো এই পিনগুলোতে কানেক্ট করতে হবে।

## সার্কিট ডায়াগ্রাম:

**সার্কিটটা হুবহু তৃতীয় পরিচ্ছদের এর মত, তফাৎ হচ্ছে এখানে** `3` **নাম্বার পিনকে** `Led` **এর সাথে কানেক্ট করা হয়েছে।**

![alt text](http://i.imgur.com/7CYwEP3.png)

## প্রোগ্রাম:

```
const int led = 3;
void setup()
{
    pinMode(led, OUTPUT);
}
void loop()
{
  for (int i = 0; i < 256; i++){
    analogWrite(led, i);
    delay(10);
  }

  for (int i = 255; i >= 0; i--){
    analogWrite(led, i);
    delay(10);
  }
}
```

## প্রোগ্রাম Walkthrough:

```
*    একটি ধ্রুব তৈরি কর led নামে এবং তার মধ্যে 3 সংখ্যাটি জমা কর
*    led কে আউটপুট হিসেবে চিহ্নিত কর
*    ফর লুপ বানাও, নতুন ইন্টিজার লোকাল* ভ্যারিয়েবল i কে Initialize করে 0 জমা কর; লুপটি ততক্ষণ রান করবে যতক্ষণ i, 256 এর চেয়ে ছোট থাকে; প্রতিবার লুপ চালানোর পর i এর মান 1 করে বাড়াবে
*    led তে i এর ভ্যালু অনুযায়ী analogWrite এর মাধ্যমে analog সিগনাল জেনারেট কর
*    ১০ মিলিসেকেন্ড অপেক্ষা কর
*    i এর মান 1 বাড়াও, i কি 256 এর ছোট? যদি হ্যাঁ হয় তাহলে লুপে ঢুক; না হলে লুপে না ঢুকে পরের স্টেটমেন্ট রান করো
*    i একটি লোকাল ভ্যারিয়েবল নাও যার মধ্যে 255 জমা কর; i কি ০ এর সমান বা বড়? হ্যাঁ হলে লুপে প্রবেশ কর, না হলে প্রবেশ কোরো না; প্রতি লুপ চালানোর পর i এর মান ১ করে কমাবে
*    led তে i ভ্যালু অনুযায়ী analogWrite এর মাধ্যমে analog সিগনাল জেনারেট কর
*    ১০ মিলি সেকেন্ড অপেক্ষা কর
*    …. …. … void loop() এর মধ্যকার জিনিস বারংবার চলতেই থাকবে
```

## প্রোটিয়াস সিম্যুলেশন:

![alt text](http://i.imgur.com/M8IN85M.gif)

## নোট:

### লোকাল ভ্যারিয়েবল ও গ্লোবাল ভ্যারিয়েবল:

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

গ্লোবাল ভ্যারিয়েবল কোন সাধারণত ফাংশনে থাকে না একে প্রোগ্রামের যেকোন জায়গায় ডিক্লেয়ার করা যায়। গ্লোবাল ভ্যারিয়েবলগুলো একবার ডিক্লেয়ার করলেই হয়, দুই বা ততোধিকবার করতে গেলেই প্রোগ্রাম রান করবে না আমরা উপরের প্রোগ্রামটি `i` কে গ্লোবাল হিসেবে ডিক্লেয়ার করেও কাজটি সম্পন্ন করতে পারি। যেমন:

```
int i;
... ... ....
void loop()
{
    for (i = 0; i < 256; i++){ /*  code */ }
    for (i = 255; i >= 0; i--) { /* code */ }
}
```

### Duty Cycle:

#### এটি সম্পর্কে Wikipedia কী বলছে?

> A duty cycle is the percentage of one period in which a signal is active. A period is the time it takes for a signal to complete an on-and-off cycle.

অর্থাৎ, `Duty Cycle` হল এমন একটি টার্ম, কোন একটি সিগনালের ক্ষেত্রে `Duty Cycle` এর মান জানলে আপনি তৎক্ষণাৎ বলে দিতে পারবেন একক পর্যায়কালে সিগনালটি কতক্ষণের জন্য `On` ছিল আর কতক্ষণের জন্য `Off` ছিল। আমরা যেহেতু `DC` এর আলোচনা করছি তাই `On` মানে ধরে নেব `5V` আছে এবং `Off` মানে ধরে নেব `0V`। নিচের এনিমেশন দেখলে ধারণা পাওয়ার কথা:

![alt text](http://upload.wikimedia.org/wikipedia/commons/0/02/PWM_duty_cycle_with_label.gif)

সূত্র: [উইকিপিডিয়া](http://en.wikipedia.org/wiki/Duty_cycle)

## PWM এ আমরা আসলে কি করছি?

> PWM করে আমরা আসলে `Duty Cycle` কন্ট্রোল করছি। যখন আমি `analogWrite(pin, 255)` আর্গুমেন্ট দিচ্ছি তার মানে এটি ওই পিনে `100% duty cycle` এর সিগনাল দিবে তার মানে আমরা বলতে পারি, `digitalWrite(led, HIGH) == analogWrite(led, 255)`। কী? ব্যাপারটা Confusing লাগছে? কনফিউশনের দরকার নেই, এবার আপনিই ভাবুন, আমি যদি পর্যায়কালের ৫০% সময় ভোল্টেজ দিতে চাই ও বাকি ৫০% সময় ভোল্টেজ অফ রাখতে চাই তাহলে আমি `analogWrite` এ কত `Value` পাস করব? ঠিক ধরেছেন, `127`।
>
> তার মানে, যদি ভোল্টেজের পর্যায়কাল `2 millisecond` হয় তাহলে ১ম মিলিসেকেন্ডে ৫ ভোল্ট থাকবে কিন্তু ২য় মিলিসেকেন্ডে ০ ভোল্ট থাকবে। আবার ৩য় মিলিসেকেন্ডে ভোল্টেজ থাকবে, ৪র্থ মিলিসেকেন্ডে থাকবে না.. … …।

## সচরাচর জিজ্ঞাস্য প্রশ্ন \[F. A. Q]:

#### প্রশ্ন:

`PWM` যদি ভোল্টেজ না-ই কমায় তাহলে স্পিড বা ব্রাইটনেস কমে কীভাবে? এগুলো কী ভোল্টেজের উপর নির্ভরশীল নয়?

#### উত্তর:

`PWM` এ যত `Low Duty Cycle` হয় আমরা তত `Dim Light` পর্যবেক্ষণ করি। আসলে `Dim Light` এর জন্য দায়ী `PWM` নয়, আপনার চোখ! হ্যাঁ, `Arduino` এর `Square Wave` এর ফ্রিকোয়েন্সি প্রায় `490Hz` এর মত। তার মানে, এটি প্রতি সেকেন্ডে 490 বার 5V থেকে 0V এ পরিবর্তিত হয়ে থাকে। আমরা জানি, `T = 1 / f`। তারমানে, আর্ডুইনোর পর্যায়কাল প্রায় `0.002 Second`। এই কারণেই `duty cycle` কম দিলে `dim` দেখায় কারণ এটি এতটাই তাড়াতাড়ি ব্লিংকিং করে যে আপনার চোখ সেটা ধরতে পারে না। তারমানে আপনার চোখ আপনাকে বুঝায় যে `led` এর ব্রাইটনেস কমছে। আসলে led ফুল ব্রাইটনেসেই জ্বলে যা আপনি ধরতে পারেন না।
