とある科学の備忘録

とある科学の備忘録

CやPythonのプログラミング、Arduino等を使った電子工作をメインに書いています。また、木製CNCやドローンの自作製作記も更新中です。たまに機械学習とかもやってます。

【Arduino】アナログ出力(PWM)とは?

アナログ出力でできること

前回、LEDを点滅させるプログラムを書きました。
shizenkarasuzon.hatenablog.com


しかし、このプログラムは、明かりを点けるか消すかのどちらかしかできないという制約がありました。
明るさを調節する機能が欲しいところです。

この課題を解決してくれるのが、「PWM」と呼ばれる「アナログ出力」の方式です。

アナログ出力とデジタル出力

「アナログ出力」と「デジタル出力」の違いは何でしょうか。
簡単に言うと、「デジタル出力」は、ONかOFFの2通りのみ、「アナログ出力」はその間の値も連続してとれる

前回の記事でのLED点滅は、LEDが点灯している状態(出力ON)と、LEDが消灯している状態(出力OFF)の二つの状態しかありませんでした。
しかし、今から行おうとしていることは、「LEDが点灯している状態」と「LEDが消灯している状態」の間の、「LEDがちょっとだけ微妙についている状態」も表現しよう、というものです。
f:id:pythonjacascript:20181104003400j:plain
このように、ONとOFFの間の「微妙な値」を連続的に調節できるような出力を「アナログ出力」と言います。

 

PWMとは

アナログ出力の方法として、PWMというものがあります。この記事では、最終的にPWMを使ってLEDの明るさを制御するので、ここではPWMについてちょっとした解説を行います。

PWMによるアナログ出力の方法を一言で表すと、「高速でON-OFFを切り替えれて、そのONとOFFの時間の比率を変更し、出力を調整する」出力方法です。

前回の記事では1秒ごとにLEDを点滅させていましたが、その点滅の周波数を増やしていって、LED のチカチカが感じられなくなる値まで高速で点滅させるとします。

すると、通常の50%程度の明るさで光るようになったはずです。これは、「LEDが点灯している時間」:「LEDがOFFの時間」 = 1 : 1 だからです。十分高速に点滅させることでLED から瞬きが消え、目の「残像」機能が明るさの平均値をとっているのです。
f:id:pythonjacascript:20181104003442j:plain

なので、LEDが点いている時間を4 分の1 にすると、明るさは25%となります。また、「LEDがONの時間」:「LEDがOFFの時間」=3:1にすると、75%の明るさで光っているように見えます。


プログラムを書く

PWM出力をArduinoで行うには、analogWrite 関数を使用します。いままでデジタル出力を行う時は、

digitalWrite(13, HIGH); //13ピンをON(電圧がHIGH)にする

のように書いてきたと思います。これと同じで、9ピンのアナログ出力を調整するには、

analogWrite(9, 128);  //9番ピンで50%のアナログ出力を行う

と書きます。

analogWrite関数の第一引数には、PWM出力を行うピン番号を指定します。PWMによるアナログ出力が可能なピンは、ピン番号9、10、11 です。

また、第二引数には、アナログ出力の強さを指定します。0~255の間で設定するので、0を入力すると出力は0%になり、255を入力して100%、128を入力すると50%になります。つまり、上のプログラムは9番ピンで50%のアナログ出力を行う、という意味です。


回路を組む

以下のような回路を組んでください。
f:id:pythonjacascript:20181104010356j:plain
9ピンからPWM出力をして、その結果をLEDの明るさとして判断します。


サンプルプログラム

以下のプログラムをArduinoに書き込んで実行して下さい。

#define LED 9  // LED を接続したピン
int i =0; //カウントアップとダウンに使用

void setup(){
    pinMode(LED, OUTPUT); // LED のビンの出カに設定
}

void loop(){
    for(I = 0; i< 255; i++){ // だんだん明るく
        analogWrite(LED, i);// LED の明るさをセット
        delay (10); // 10ミリ秒停止。analogWrite()は一瞬なのでこれがないと変化が目に見えない
    }
    for(i=255; i>0 i--){ // だんだん暗く
        analogwrite(LED, i); // LED の明るさをセット
        delay (10);
    }
}

実行結果:

LEDがだんだん明るくなる→だんだん暗くなる→..を繰り返すと思います。