こんにちは、「メカのりまき」です。
この記事では、Arduinoのアナログ入力を使用する方法とポテンショメータ(可変抵抗器)について、説明したいと思います。
この記事では、アナログ入力の動作を確認するために、PCとシリアル通信を行ったり、ブザーで音を鳴らしたりしますので、それらについての知識も必要となります。
以下のリンク先の記事で、シリアル通信やブザーの使い方について説明していますので、シリアル通信やブザーの使い方が分からないという方は、先に以下のリンク先の記事をご覧になることをお勧めします。
また、この記事は「Arduino IDE」の基本的な使い方を、理解していることを前提とした記事となっています。
「Arduino IDE」の使い方は以下のリンク先の記事で説明していますので、「Arduino IDE」の使い方が分からない方は、以下のリンク先の記事を是非ご覧になってください。
目次
本記事で使用するもの
本記事で私が使用した物は以下の通りです。
- 「Arduino IDE2.0.3」をインストールしたPC(Windows11)
- USBケーブル
- Arduino Uno R3(ELEGOO UNO R3でも可)
- ブレッドボード
- 抵抗器
- ポテンショメータ(可変抵抗器)
- パッシブブザー
- ジャンパーワイヤー
「Arduino Uno R3」の互換ボードであれば、「ELEGOO UNO R3」以外のボードでも、本記事と同様な手順で動作可能だと思われますが、動作検証はしていないので、その点はご了承ください。
以下のリンクのスターターキットを購入した場合、上記で述べた使用するものは、PC以外すべて入手することができます。
Arduinoをまだ購入していないという方やArduinoで動かすことができるたくさんのパーツが欲しいという方は、購入を検討してみてください。
アナログ入力の説明
「Arduino Uno R3」では、脇にA0~A5と書かれたものを「アナログ入力ピン」と呼びます。
この「アナログ入力ピン」は、デジタル入出力をする以外にも、接続先の電位がGNDとどれだけ差があるかを数値化する「アナログ入力」を行うことができます。
「デジタル入力」では、接続先の電位が「HIGH」であるか「LOW」であるかの2パターンでしか測定できなかったのに対し、「アナログ入力」では、接続の電圧(GNDとの電位差)を細かく分割して読み取ることができます。
例えば「Arduino Uno R3」の場合、デフォルトの設定だと、0~5[V]の電圧を0~1023の値(1024パターン)に変換して読み取ることができます。
図で表すと以下のようになります。
「アナログ入力」を利用するときは、以下のような文をスケッチに記述します。
1 |
analogRead(A0); |
上記の文では、A0ピンに接続した部分の電圧を調べ、0~1023の値を割り当てます。
電圧と読み取った値の関係は、0~5[V]を1024パターンで分割するため、
5[V]÷1024=約0.0049[V]
ごとに値が1変化するような関係となっています。
ここで、5[V]の部分を参照電圧、1024の部分を分解能と呼びます。
「analogRead()」で読み取った値を、電圧に変換したい場合は、
電圧=5[V]÷1024×(読み取った値)
と計算しますが、この計算には誤差が生じるということを頭の隅に置いておく必要があります。
例えば上記の式に、「analogRead()」で読み取れる一番大きな値である1023を当てはめてみると、
電圧=5[V]÷1024×1023=約4.9951[V]
となり、5[V]にはなりません。
なぜかというと、「analogRead()」の値は、0~5[V]を1024パターンで分割したときに割り当てられたものであり、4.9951[V]も5[V]も同じ1023という値として扱われるからです。
つまり、「analogRead()」で読み取った値が同じでも、電圧にバラツキがあるため、読み取った値から計算して電圧に変換する際には誤差が生じるということになります。
誤差の範囲は、参照電圧(上記の場合は5[V])や分解能(上記の場合は1024)によって変わり、以下のような式で求めることができます。
誤差の範囲 = 参照電圧 ÷ 分解能
大雑把に電圧を測定したい場合は特に気にする必要はありませんが、センサのデータをアナログでやり取りを行うような場合や電圧を精密に測定したい場合は、参照電圧や分解能についても気にする必要が出てくるかもしれないので、こういった誤差が存在するということを覚えておくことをお勧めします。
アナログ入力を試す
まずは、「GNDピン」、「5Vピン」、「3.3Vピン」を「A0ピン」に接続して、アナログ入力の動作確認をしていただこうと思います。
スケッチを書き込む
以下のスケッチを書き込んでください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//アナログ入力で読み取った値を入れる変数 int value; //計算した電圧を入れる変数 float voltage; void setup() { //A0ピンを入力ピンとして設定する(デフォルト設定なので省略しても良い) pinMode(A0,INPUT); //シリアル通信の初期処理を行う Serial.begin(9600); } void loop() { //A0ピンで電圧を読み取り変数に入れる value=analogRead(A0); //アナログ値から電圧を計算する(参照電圧を5[V],分解能を1024とする) voltage=5.0/1024*value; //analogReadで読み取った値と計算した電圧をシリアルモニタに出力させる Serial.print("Value: "); Serial.print(value); Serial.print(" Voltage: "); Serial.print(voltage,4); Serial.println(" [V]"); //測定の間隔を250[ms]空ける delay(250); } |
動作の確認
スケッチの書き込みが終わりましたら、次は動作の確認を行っていただこうと思います。
以下の図のように、A0ピンとGNDピンを接続してください。
接続が終わりましたら、次はシリアルモニタを開き、Arduinoからの出力を確認してください。
すると、A0ピンの接続先は0V(GNDと同じ電位)であるため、0[V]と表示されているのが確認できます。
次は、A0ピンと5Vピンを以下の図のように繋いでください。
すると、A0ピンの接続先は5V(GNDより5V高い電位)であるため、バラツキや誤差はありますが、5[V]付近の値が表示されているのが確認できます。
最後に、A0ピンと3.3ピンを以下の図のように繋いでください。
すると、バラツキや誤差はありますが、3.3[V]付近の値が表示されているのが確認できます。
スケッチの解説
スケッチの全体としては、以下の図のような流れで、処理を行っています。
シリアル通信や変数宣言について、もう少し詳しく知りたい方は以下のリンク先の記事で説明していますので、是非ご覧になってください。
基本的には、これまで説明してきた、アナログ入力の読み取りや電圧の計算などを、そのままスケッチにまとめただけとなりますが、注意しなくてはならない点が2点あります。
計算の型変換
22行目の電圧を計算する部分で、「5」ではなく「5.0」と記述していますが、これにはちゃんとした理由があります。
22 |
voltage=5.0/1024*value; |
実は上記の「5.0」を「5」に変更すると、計算結果は常に「0」となってしまいます。
試しに、「5.0」を「5」に変更したスケッチを書き込んで、動作の確認をしてみてください。
変更を加えると電圧値が常に0.0000[V]と表示されるのが確認できると思います。
ではなぜ、そのようなことが起こるのか順番に説明したいと思います。
まず、計算に使用している小数点の含まない数値は「int型」として扱われます。
そして、「int型」同士の計算は小数点が含まれるような計算であったとしても、「int型」に変換されるというルールがあるため、小数点以下が切り捨てられた結果となります。
つまり、「5.0」を「5」に変更した場合、以下のような流れで計算されてしまうため、計算結果が「0」になってしまうということになります。
「int型」同士の計算結果は「int型」に変換されてしまいますが、片方が「float型」の場合、計算結果は「float型」に変換されます。
よって、「5」か「1024」のどちらかを「float型」として扱われるように、小数点を含んだ状態で記述すれば問題を解決することができます。
Serial.print()の桁数
28行目で電圧の計算結果を出力する際に以下のような文を記述しています。
28 |
Serial.print(voltage,4); |
上記の文では「voltage」後に、カンマで区切り「4」という数字が記述されています。
この「4」は小数点以下の桁数を指定するものであり、上記の場合は、小数点以下の数字が4桁になるように四捨五入され表示されます。
数字を記述していない場合は、小数点以下の数字は、2桁までの表示になりますが、数字を付け加えることにより、さらに細かい数字を見ることができます。
抵抗器を使ってアナログ入力を試す
上記では、0[V]、5[V]、3.3[V]の3パターンの動作を確認していただきました。
次は、抵抗器を利用することで、接続先の電圧を調節して、アナログ入力の動作を確認していただこうと思います。
回路を作成する
以下のような回路を作成してください。
ここで、抵抗器1と抵抗器2は電気抵抗が330[Ω]、220[Ω]のものを使用します。
手持ちに同じ電気抵抗の抵抗器が無ければ、別のものを使用しても構いません。
ただし、抵抗器の電気抵抗の合計が小さいと回路に大きな電流が流れてしまうので、電気抵抗の合計が500[Ω]以上になるような組み合わせにすることをお勧めします。
動作の確認
抵抗器1と抵抗器2に電気抵抗が330[Ω]、220[Ω]のものを使用した場合は、以下のように2.0[V]付近の値が表示されます。
抵抗器の組み合わせによってはこの値が変化します。
回路の解説
上記の動作確認で、何らかの電圧が測定されたと思います。
ここでは、上記で測定した電圧と抵抗器の関係について、計算をしてみたいと思います。
まず、直列回路の性質とオームの法則より、回路に流れる電流は以下のように計算ができます。
そして、抵抗器2に加わっている電圧はオームの法則より、以下のように計算することができます。
よって、A0ピンで読み取れる値は、5÷(R1+R2)×R2[V]に対応する値が表示されるということになります。
例えば、抵抗器1と抵抗器2に電気抵抗が330[Ω]、220[Ω]のものを使用した場合は、
5÷(330+220)×220=2.0[V]
になります。
ポテンショメータの説明
ポテンショメータ(可変抵抗器)は、つまみを回すことにより、内部の電気抵抗の大きさを変更することができる部品で以下のような見た目をしています。
ポテンショメータを記号で表すと以下のようになります。
ポテンショメータの端子は3つあり、内部では以下の図のように繋がっています。
ポテンショメータは抵抗器を2つ直列に接続した回路にとても似ています。
ただし、ポテンショメータはつまみを回すことにより、内部の電気抵抗の大きさを調節することができます。
つまり、先ほど作成した回路の抵抗器の部分をポテンショメータに置き換えれば、つまみを調節することにより、真ん中のピンについての電圧を調節することができるということになります。
ポテンショメータを試す
先ほどの回路の抵抗器をポテンショメータに置き換えて、ポテンショメータの動作確認をしていただこうと思います。
回路を作成する
以下のような回路を作成してください。
動作の確認
シリアルモニタの表示を確認しながら、ポテンショメータのつまみを回してみてください。
すると、つまみの回転に応じて、シリアルモニタに表示されている、値が変化していくのが確認できます。
値が変化しない場合は、ポテンショメータがブレッドボードにしっかりと差し込まれているかなどを確認してみてください。
回路の解説
A0ピンで測定する電圧は、抵抗器を直列に接続した回路と同じ理論で計算することができます。
回路全体の電気抵抗はポテンショメータの電気抵抗のみで常に一定となります。
例えば、10[kΩ]のポテンショメータの場合、全体の電気抵抗は常にR1+R2=10[kΩ]となります。
抵抗器を直列に接続した回路と異なる点は、つまみの回転に応じてR1とR2の大きさが変更される点のみです。
つまみを最大まで回した場合、A0ピンが読み取る電圧は以下のようになります。
ポテンショメータで音を制御する
つまみの回転に応じて、アナログ入力で読み取る値が変更されるのが確認できましたら、最後に、ポテンショメータを使って音を制御する方法について説明をしたいと思います。
回路を作成する
以下のような回路を作成してください。
スケッチを書き込む
回路が作成できましたら、以下のスケッチを書き込んでください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
//アナログ入力で読み取った値を入れる変数 int value; //ブザーに接続するピンを指定する変数 int buzzer=2; void setup() { //A0ピンを入力ピンとして設定する(デフォルト設定なので省略しても良い) pinMode(A0,INPUT); //ブザーに接続したピンを出力ピンに設定 pinMode(buzzer,OUTPUT); } void loop() { //A0ピンで電圧を読み取り変数に入れる value=analogRead(A0); //読み取った値に応じて、音を鳴らす if(value<128){ tone(buzzer,262,125); }else if(value<256){ tone(buzzer,294,125); }else if(value<384){ tone(buzzer,330,125); }else if(value<612){ tone(buzzer,349,125); }else if(value<740){ tone(buzzer,392,125); }else if(value<868){ tone(buzzer,440,125); }else if(value<996){ tone(buzzer,492,125); }else if(value<1024){ tone(buzzer,523,125); } //測定の間隔を250[ms]空ける delay(250); } |
動作の確認
スケッチと回路が正しければ、以下の動画のように、つまみの回転に応じて、音の高さが変わっていくのが確認できます。
スケッチの解説
スケッチの全体としては、以下の図のような流れで、処理を行っています。
スケッチの内容は、先ほどのスケッチのシリアルモニタへ出力させる部分を、「if文」で条件を分けて、「tone関数」により、決まった高さの音をブザーで鳴らすように変更したものとなっています。
また、「if文」の条件には、「analogRead()」で読み取った値のみを使用しており、電圧の計算は行っていません。
ピアノの音階と振動数(tone関数の値)の関係はおおよそ(小数点以下を四捨五入した場合)、以下のようになっています。
音階名 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
ド | 33 | 65 | 131 | 262 | 523 | 1047 | 2093 |
ド# | 35 | 69 | 139 | 277 | 554 | 1109 | 2217 |
レ | 37 | 73 | 147 | 294 | 587 | 1175 | 2349 |
レ# | 39 | 78 | 156 | 311 | 622 | 1245 | 2489 |
ミ | 41 | 82 | 165 | 330 | 659 | 1319 | 2637 |
ファ | 44 | 87 | 175 | 349 | 698 | 1397 | 2794 |
ファ# | 46 | 93 | 185 | 370 | 740 | 1480 | 2960 |
ソ | 49 | 98 | 196 | 392 | 784 | 1568 | 3136 |
ソ# | 52 | 104 | 208 | 415 | 831 | 1661 | 3322 |
ラ | 55 | 110 | 220 | 440 | 880 | 1760 | 3520 |
ラ# | 58 | 117 | 233 | 466 | 932 | 1865 | 3729 |
シ | 62 | 123 | 247 | 494 | 988 | 1976 | 3951 |
「tone関数」について、よく分からないという方は、以下のリンク先の記事で詳しく説明していますので、是非ご覧になってください。
また、「if文」がよく分からないという方は、以下のリンク先の記事で説明していますので、是非ご覧になってください。
Arduinoのアナログ入力を使用する方法とポテンショメータ(可変抵抗器)についての説明は以上となります。
ポテンショメータを利用すると、自分の手で物を操作することができるため、直観的に物を操作したいときに役に立ちます。
是非、自分の手で何か物を操作したい場合は、今回学んだポテンショメータのことを思い出してみてください。
次回は、Arduinoでサーボモータを動かす方法について説明したいと思います。
本記事はここまでです。ご清覧ありがとうございました。
広告
楽天モーションウィジェットとGoogleアドセンス広告です。
気になる商品がございましたら、チェックをしてみてください。