4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Tinkercad Circuits で Arduino 入門5~PWM出力~

Last updated at Posted at 2020-05-03

概要

第5回目です。前回は、Arduino(アルディーノ)の デジタル入力機能 について勉強しました。今回は、PWM出力(疑似アナログ出力)について、Tinkercad Circuit(Arduino&電子回路シミュレータ)を利用して勉強していきます。

今回のArduinoプログラムには、新しい要素として 変数繰り返し が登場します。

アナログ出力とは

デジタル出力は、第2回 で学習したように「$1$(=HIGH)」または「$0$(=LOW)」の 2値 に対応する電圧を出力する機能でした。Arudino UNO の場合は「$1$(HIGH)が $5\mathrm{V}$ 電圧」に、「$0$(LOW)が$0\mathrm{V}$(GNDレベル)電圧」に対応していました。

ちなみに、RaspberryPimbedArduino Due のデジタル入出力(GPIO:General-Purpose Input/Output)は「$1$(HIGH)が $3.3\mathrm{V}$ 電圧」に、「$0$(LOW)が $0\mathrm{V}$(GNDレベル)電圧」に対応します。電子工作用(ホビー用途)のマイコンの多くでは、だいたいは $5\mathrm{V}$ 系か、$3.3\mathrm{V}$ 系となっています。一方で、$1.8\mathrm{V}$ 系を採用している低消費電力タイプのマイコンも存在します。これらのデジタル入出力に用いる電圧レベルを ロジックレベル といいます。

  • ロジックレベルが異なるモジュール(マイコンやセンサなど)を組み合わせる場合、レベルの変換のための回路(ロジックレベルコンバータレベルシフタ とよばれます)が、必要になります。

さて、デジタル出力に対して アナログ出力 とは、一定の範囲内で連続した電圧を出力できる機能 になります。例えば、$0\mathrm{V}$ から $5\mathrm{V}$ の範囲内で、$2.3\mathrm{V}$ や $4.5\mathrm{V}$、$0.2\mathrm{V}$ などの任意の電圧を出力する機能になります。アナログ出力 を使えば、LED に対して 点灯/消灯 だけではなく、調光(明るさの調節)ができるようになります。

とても便利な機能なのですが、一般的なマイコン(Arduino、RaspberryPi、mbed、PICなど)には、通常、この「アナログ出力機能」は備わっていません

PWM出力(疑似アナログ出力)

PWMとは、Pulse Width Modulation の略称で、日本語では「パルス幅変調」と呼ばれます。これを利用することで、**疑似的なアナログ出力が可能**になります。

次に示すのは、周期が $1000 \mu\mathrm{s}$、デューティ比が $60 %$ の PWM信号 です。
2020-05-01_19h43_46.png

HIGH(=$5\mathrm{V}$)と LOW(=$0\mathrm{V}$)の 2値の出力 が短い時間で切り替わっていることが分かります。ただし、ランダムに切り替わるわけではなく、規則性をもって HIGHLOW が切り替わっています。具体的には、HIGH出力の時間 $T_{H}$ が $600 \mu\mathrm{s}$、LOW出力の時間 $T_{L}$ が $400 \mu\mathrm{s}$ で繰り返されています。

このとき、次式で計算される値を デューティ比 $D$ といいます。

$$D = \frac{T_{H}}{T_{H}+T_{L}}\times 100=\frac{600\times10^{-6}}{600\times10^{-6}+400\times10^{-6}} = 60 %$$

また、$T_{H}+T_{L} = 600\mu + 400\mu = 1000\mu\mathrm{s}$($=1\mathrm{ms}$)が周期 $T$、その逆数が 周波数 $f = 1/T = 1000\mathrm{Hz}$($=1,\mathrm{kHz}$)になります。

ところで、上記の PWM出力 について平均電圧を計算してみると、$5\mathrm{V} \times 60% =3\mathrm{V} $ になることが分かります。このことから、デューティ比 $60%$ のPWM出力は、疑似的な $3\mathrm{V}$ のアナログ出力として扱うことができます。実際に、この PWM出力 を LED に与えると、(人間の目には)$3V$ を与えたときに相当する明るさで点灯しているように見えます

ただし、注意しなければならないのは、PWM出力の周波数 です。もし、周波数が $0.1\mathrm{Hz}$ だと、周期は $T=1/f=1/0.1= 10,\mathrm{s}$ となり、もはや $6$ 秒点灯と $4$ 秒消灯 の単なる繰り返しです。

なお、$D=0%$ のとき、PWM出力は デジタルLOW出力(=$0\mathrm{V}$)と同じです。また、$D=100%$ のときは、デジタルHIGH出力(=$5\mathrm{V}$)と同じです。

ArduinoによるPWM出力(方法1)

①ポート出力をHIGHに設定、②$T_{H}$ 秒だけ待機、③ポート出力をLOWに設定、④$T_{L}$ 秒だけ待機、という処理を繰り返す方法で、Arduino から PWM信号 を出力してみます。
2020-05-01_23h12_54.png

通常のデジタル出力と比較するために、デジタル8番ポート(D8)からは固定で HIGH を出力してデジタル6番ポート(D6)からはデューティ比 $30%$ のPWM を出力して、それぞれで、LED を光らせてみましょう。

Tinkercad にログインして、次のように回路を構成します。回路を構成する際は、LED の極性に注意してください。また、電流制限抵抗には $330\Omega$ を使用してください。

次にコードエディタ(ショートカットキーは [E] )を起動し、ブロックモードでロジックを構成して、シミュレーションを実行(ショートカットキーは [S] )してみましょう。ロジックでは「$0.3\mathrm{ms}$($=300\mu \mathrm{s}$)間のHIGH出力」と「$0.7\mathrm{ms}$間のLOW出力」を交互に与えるために、無限ループを構成しています。
2020-05-01_23h07_39.png

シミュレーションを実行してみると、少し分かりずらいですが、PWM出力(デューティ比$30%$)の6番ポートに接続している LED のほうが やや暗い こと が確認できたと思います。

  • 回路例はこちら(Tinkercadに移動します)。

しかし、この方法では、PWM出力をつくる部分でプログラムがループしてしまうために(そこから先にプログラミングが進まなくなってしまうために)、他の処理(例えば、デジタル入力をチェックするなど)を組み合わせることが難しくなってしまいます。そのため、通常、この方法は使われません。

ArduinoによるPWM出力(方法2)

Arduinoでは、analogWrite(...) という関数を使って、より簡単に(ループを構成せずに)**PWM出力(=疑似アナログ出力)**が可能です。ブロックプログラムの場合は、次のように「ピン X を Y に設定」というブロックを使用します。
2020-05-01_23h52_59.png

このブロックはデジタル出力ブロックに似ていますが、高(HIGH)/低(LOW) でなはなく、デューティ比(数値)を設定します
2020-05-01_23h14_42.png

ただし、設定する数値は、0 から 255 までの整数 で与えます。0 を設定するとデューティ比 $0%$、255 を設定するとデューティ比 $100%$、128を設定するとデューティ比が約 $50%$ の PWM信号が出力されます。

逆に、デューティ比 $30%$ のPWM信号を出力したければ、$255\times 0.3 = 76.5$ なので、$76$ か $77$ を指定します(誤差の範疇なのでどちらでもOKです)。
2020-05-03_12h02_46.png

また「ピン X を 0 に設定」を実行すれば(デューティ比$0%$になるので) PWM 出力は停止します。

このように便利な機能なのですが、analogWrite(...) による PWM出力 は「3561011 番のデジタル出力ポート(ピン)」でしか使用できないという制約があります。ボードには 「」 が印字されています。
2020-05-01_23h36_49.png

analogWrite(...) の機能を使って、さきほどと同じようにLEDを点灯させてみましょう。プログラミングを以下のように書き換えてシミュレーションをしてみてください。回路例はこちら(TinkerCadに移動します)。
2020-05-01_23h41_23.png

補足:オーバーフロー

analogWrite(...) つまり「ピン X を XXX に設定」で設定可能な数値は、「0」~「255」まで整数値( $0$ を含めての $255$ なので、$256$ 段階=$2$の$8$乗段階)になります。もし、$256$ 以上の値、例えば「$270$」とかをアナログ出力に与えると、それは $270-256$ で「$14$」を与えたことになってしまいます($14$ になると PWM出力が約 $5%$ となるので、LED出力は相当に暗いです)。このような現象を**オーバーフロー(桁あふれ)**といいます。詳しく知りたい場合は「オーバーフロー 数値 コンピュータ」などで検索してみてください。

補足:analogWrite(...) によるPWM出力の周波数

analogWrite(...) による PWM出力の周波数は基本的に固定です。5番と6番ポートは $980\mathrm{Hz}$、その他は $490\mathrm{Hz}$ になります。これは、Tinkercadオシロスコープモジュール 使って確認することもできます。
2020-05-02_11h07_00.png

9番ポートからデューティ比 $50%$ で PWM 出力して、それをオシロスコープモジュールで観測してみます。シミュレーションを実行すると、次のように約 $500\mathrm{Hz}$($490\mathrm{Hz}$)になっていることが確認できます。回路例はこちら(Tinkercadに移動します)。
2020-05-02_11h14_49.png

なお、周波数を変更することも可能ですが、初心者向けではありません。気になる方は以下が参考になると思います。

演習10:電子ホタル(1匹)~準備~

次のような回路を構成し、PWM出力を利用して、LEDが ゆっくりとした明暗の変化を繰り返す ような電子ホタルをつくりたいと思います。
2020-05-02_11h54_04.png

まずは、作成例をコピーして動作を確認しましょう。こちら をクリックすると、サンプルに飛ぶので、その画面内の「コピーして編集」をクリックします。自分の領域に複製が作成されるので、シミュレーションを実行して動作を確認しましょう。

この「複製して動作確認まで」が演習10です。

演習11:電子ホタル(1匹)~プログラムの読解~

演習10 で複製した回路のコードを確認してみましょう。プログラムには、新たな要素として「変数」と「繰り返し」が登場しています。しかし、**「繰り返し」のブロックの表記(和訳)が残念なことになっていて、正直、英語に切り替えたほうが分かりやすい**です。以下は、C言語での while(a<=10){ ... } に対応するブロックですが(高校生以上なら)英語のほうが分かりやすいですよね。
2020-05-03_08h32_00.png

言語は、Tinkercad のダッシュボードの最下部から変更可能です。必要に応じて英語に切り替えてください(英語モードにしたとき、ブラウザの翻訳はオフにしておきましょう)。
2020-05-02_12h20_33.png

コードエディタを開いてブロックあるいはコードを読み解いてみてください。また、次の課題12ではゼロから作成してもらうので、眺めるだけではなくで、1ブロックずつ意味を考えながら読み解きましょう。

プログラム内のパラメータ(10015 などの数値)を変更して、動作がどのように変わるか予測・確認することも理解の助けになります。
2020-05-02_11h48_17.png

ソースコードを、直接、見たほうが分かりやすいかもしれません。

電子ホタル(1匹).ino
int i = 0;

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

void loop() {
  i = 0;
  while (i < 255) {
    analogWrite(9, i);
    delay(100); // Wait for 100 millisecond(s)
    i = (i + 15);
  }
  while (i > 0) {
    analogWrite(9, i);
    delay(100); // Wait for 100 millisecond(s)
    i = (i - 15);
  }
}

(別解)

上記のプログラムは、次式のように三角関数($\sin$)を使ってもっとスマートに構成することができます。

$$ d =\big(, \sin(2\pi\times\frac{i}{36}) + 1.0 , \big) \times 127.5 $$

ここで、$i$ を $0,1,2,\cdots,34,35$ と変えていけば、$d$ は $0$ から $255$ の範囲で次のように変化します。例えば、$i=9$ のとき、$d=(\sin(\frac{\pi}{2})+1)\times 127.5 = 255$ になります。
ダウンロード.png

これを次のようにプログラム上に実装すれば、同様に電子ホタルが作成できます(ブロックでは $\pi$ が定数として利用できないので、$2\pi\simeq 6.28$ としています)。
2020-05-03_09h16_29.png

演習12:電子ホタル(1匹)~作成~

演習11と同じものを、ゼロから(回路を含めて最初から)構成してみましょう。見本のコードを眺めて理解したつもりでも、実際に手を動かしてみると「??」となることは多々あります。必ず実際に作成してみましょう。

なお、この課題では変数を利用する必要があります。次の手順で変数を組み込みます。

  1. 変数のグループのなかにある「新しい変数」をクリックします。
    2020-05-02_18h09_48.png
  2. ダイアログが表示されるので、変数名を入力します。日本語は避けましょう。

    2020-05-02_18h12_17.png
  3. 作成した変数を削除したい場合は、右クリックして「変数 x を削除」を選択します。
    2020-05-02_18h13_49.png

演習13:電子ホタル(2匹以上)~作成~

LED を 2つ以上 に増やし、なおかつ、それらの点灯タイミングがズレるようにしてみましょう。
2020-05-03_10h24_51.png

  • 解答例はこちら(TinkerCadに移動します)。

    • $\sin(\omega t) $ と $\sin(\omega t+\theta) $ の関係を利用して変数1つで対応する方法。
  • 解答例(別解)はこちら(TinkerCadに移動します)。

    • 三角関数を使わずに変数4つで対応する方法(お勧めしない)。
  • 3Hの学生さんは、最低でも 30分 は自分で粘ってから解答例を見るようにしてください。数分で諦めるのは早過ぎできす。また、解答例をみて理解したあとも、必ず自分で動かして同じようにロジックを構成してみましょう(「檸檬」という漢字が「読めること」と「書けること」は違うのと同じ理屈です)。

補足:LEDを直列接続して同時点灯させる回路

演習13 とは直接的には関係ありませんが、LEDを直列接続して同時点灯させる回路 を説明しておきます(第3回 で学習した 単体LED を点灯させる方法を理解している前提の説明です)。

直列接続した $2$ 個の LED を点灯させる場合、電流制限抵抗 $R$ は次のように決めます。

$$ R \ge \frac{V_{\mathrm{CC}}-2\times V_{F}}{I_F} ,,[\Omega]$$

例えば、LEDの特性が $V_{F}=2.0,\mathrm{V}$、$I_{F}=20,\mathrm{mA}$ で、電源電圧$V_{\mathrm{CC}}=5,\mathrm{V}$ であれば、$ R \ge (5-2\times 2)/0.02=50,\Omega$(下記では余裕を持たせて $100\Omega$ としています)。
2020-05-03_10h46_25.png

また、直列接続した $n$ 個の LED を点灯させる場合、電流制限抵抗 $R$ は次のように決めます。なお、電源電圧 $V_{\mathrm{CC}}$ は、少なくとも $nV_{F}$ 以上にする必要があります

$$ R \ge \frac{V_{\mathrm{CC}}-nV_{F}}{I_F} ,,[\Omega]$$

例えば、$V_{F}=2.0,\mathrm{V}$、$I_{F}=20,\mathrm{mA}$、$V_{\mathrm{CC}}=12,\mathrm{V}$ であれば、$ R \ge (12-5\times 2)/0.02=100,\Omega$(下記では余裕を持たせて $200\Omega$ としています)。
2020-05-03_10h46_25.png

ところで、Arduino の デジタル出力は $5,\mathrm{V}$ なので上記のように、5つものLEDを直接接続することはできません。その場合、次のように トランジスタ(NPN) を使って回路を構成します。
2020-05-03_11h16_30.png

なお、ベース抵抗(図内の $10k\Omega$ の抵抗)には、ちゃんとした設計法があるのですが、それについては省略します(電子回路の授業や、実験実習で習うハズです)。気になる人は「トランジスタ スイッチング ベース抵抗 設計」をキーワードにググってください。

  • 回路例はこちら(TinkerCadに移動します)。

なお、デジタル $6$ 番ポートから PWM出力 をさせていても、問題なく動作します。

さらに、次のように並列化することで、さらに多くの LED を点灯させることができます(電源の電流負荷が2倍になっていることに注意してください)。
2020-05-03_11h48_10.png

EX演習2:クリスマスイルミネーション

トランジスタを使ったスイッチング回路も組み合わせて多数のLEDが点灯するクリスマスイルミネーションの回路とプログラムをつくってみましょう。

次回

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?