前回、Arduino UNOを使いデジタル端子からの入力(タクトスイッチのオンオフ判定)をやってみました。
今回はこれまでまだ使っていないアナログ入力端子(A0~A5)を使いアナログ値を読み取ってみたいと思います。
アナログ値の入力にはセンサーからの入力などいろいろと考えられますが、今回は可変抵抗器(ボリュームなどで使われる)を使いその電圧の変化を読み取り、それに応じてLEDの明るさを変化させたりをやってみたいと思います。
またArduinoのアナログ入力端子には10ビット分解能のADコンバーターが搭載されています。
Arduinoが取得したアナログ値から実際に入力されている電圧の計算もやってみたいと思います。
可変抵抗(ポテンショメーターなど)はジョイスティックなどにも使われており、電子工作ではサーボモーターを動かす制御に使えたりと幅が広がりそうです。
目次
【Arduino】可変抵抗器を使いアナログ入力値を読み取る!
今回の目標
デジタル入力で出来るHIGH(5V)またはLOW(0V)の判別に比べ、アナログ入力を使えばアナログの電圧値を取り込む事ができます。(Arduinoの場合0〜5Vの範囲で)
Arduinoのアナログ入力端子(A0~A5)にはアナログの電圧を取り込みその取り込んだ電圧値を数値化(デジタル)に変換するADC(アナログーデジタル コンバーター)機能が備わっています。
Arduino(こちらではArduino UNOで説明していきます)のアナログ入力端子は10ビットの分解能を持っています。
つまり2の10乗で1024(0~1023)までの数値として入力電圧を読み取る事が出来ます。
Arduinoの入力端子にかかる電圧0~5Vを0〜1023の数字に数値化するという事です。(AD変換)
この読み取った数値を利用してLEDの点灯スピードを変えたり、サーボモーターの回転角度を指示したりいろいろと利用する事ができます。
またセンサーのオフセット値の調整などにも使われます。
アナログ入力の読み取りにはanalogRead関数を使います。
今回これを使いアナログ値の読み取りを行い、またそのアナログ値から実際に入力端子に掛かっている電圧を計算してみたいと思います。
そして可変抵抗を使いLEDの明るさ調整もやってみたいと思います。
可変抵抗器とは?
可変抵抗器とは回転させる事により抵抗値が変化するというもので、ラジオなどに使われているボリューム(ツマミ?)などがそれにあたります。
ポテンショメーターなどと呼ばれたりもしますが、全て回転させる事により内部の抵抗値を変化させるパーツとなります。
電子基板などによく使われているドライバーで回すタイプの「半固定抵抗」などもありますが、基本的に構造は同じです。
今回、Arduinoスターターキットに入っていたこちらの可変抵抗を使ってみます。
抵抗値は10kΩの可変抵抗となり最小で0Ωから最大に回すと10kΩまで抵抗値が変化します。
可変抵抗の足は3ピンとなっています。
両端のピンがVcc(5V)とGNDを繋ぐもの、そして真ん中のピンが抵抗値の増減により変化した電圧(抵抗による分圧)が取り出せる端子となりArduinoのアナログ端子に入力します。
回路記号を見ると分かりやすいですね!
回転させることにより接点の位置が変わり抵抗値が変化するという事です。
抵抗値を読み取るのではなく抵抗値の変化による電圧の値を読み取っているのがポイントです!
それでは実際に動かしてみましょう。
可変抵抗からの数値を読み取る!
まずは可変抵抗から得られる値をArduinoで読み取りその数値をシリアルモニタで確認してみましょう。
回路はこんな感じで組みます。
可変抵抗の両端のピンをArduinoの5V・GND端子に繋ぎ、真ん中のピンをアナログ入力端子に繋ぐだけです。
簡単ですね!
アナログ入力端子はA0~A5までの6本使えますが、今回はA0ピンに繋いでやっていきます。
そしてスケッチはこちらを用意しました。
読み取った可変抵抗器からのアナログ値を変数VOLUMEに格納しそれをシリアルモニタに出力、PC画面で入力値を確認出来るスケッチとなります。
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 | // Arduino入門編⑥ アナログ入力 可変抵抗からの入力値を読み取る // https://burariweb.info const int INPUT_PIN = A0; // 入力ピンをA0に固定 int VOLUME; // 変数を整数型で宣言 void setup(){ Serial.begin(9600); // シリアル通信の開始 } void loop(){ VOLUME = analogRead(INPUT_PIN); // アナログ値の読み取り Serial.print("Volume: "); // シリアルモニタに出力 Serial.println(VOLUME); delay(100); } |
簡単なスケッチとなりますが少し解説しておきます。
はじめて出てきた関数としてanalogRead関数があります。
指定したアナログピンからアナログ値を読み取る関数となります。
読み取った数値は10ビット分解能0~1023の数字に変換(AD変換)されます。
analogRead 関数
指定したアナログピンから値を読み取る。
アナログ入力ピン(A0~A5)を指定します。
10ビットのAD変換機が搭載されており0~5Vの入力電圧を0~1023の値に変換して読み取ります。
(書式)analogRead(pin);
pin:読み取るピン番号をA0~A5で指定。(0~5表記でも可)
Serial.begin(speed);
シリアル通信を有効にします。
シリアル通信のデータ転送レート(bps)を指定。
(300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200bps)
Serial.print(data) ;
データをシリアルポートへ出力します。
つまりPCのシリアルモニタに出力し表示させます。
シリアルモニタを立ち上げ可変抵抗を回すと最小の位置で0となり最大の位置で1023となるのが確認できると思います。(動作が反対になる場合は5VとGND端子を入れ替えて下さい。)
またシリアルプロッタを使えば視覚的に数値の変化が分かりやすくなります。
シリアルモニタ・シリアルプロッタは、Arduino IDEの[ツール]からそれぞれ立ち上げることができます。
アナログピンにかかる実際の電圧値を計算してみる
先程のスケッチで可変抵抗を動かしていくとアナログ入力端子からは最小0から最大1023までの数値として得られる事が分かりました。
Arduinoのアナログ入力端子は10ビットの分解能を持つAD変換器(アナログーデジタル変換)を搭載しているいう話を先程お話ししました。
つまりArduinoのアナログ端子に入力された電圧0~5Vの数値を10ビット(2の10乗=1024)でAD変換し0~1023までの数値に変換されたという事になります。
今回の場合だと、可変抵抗器により変化した電圧(抵抗の分圧により得られた電圧)0~5Vの電圧が0~1023の数字に変換されArduinoに取り込まれたという事です。
この数値を利用してLEDの点灯スピードを変えたり明るさを変えたり、サーボモーターの角度調整に使ったりできるわけですね!
うぅ〜ん、でもなぜAD変換なんて面倒なことをやっているのか?
なんて思われた方もいるかと思います。
はじめてだと少し話が難しいかもしれませんね!
簡単に言うとArduinoはマイコンなのでコンピューターと同じくデジタルしか扱う事ができません。
入力される電圧は4.21Vや3.58Vなど小数点以下に数字が続くアナログな数値です。
このままのアナログ値では扱えないのでArduinoで扱えるデジタル値に変換してあげる必要があります。
これがAD変換になりますがArduinoはマイコンに内蔵されたAD変換器を使いアナログピンの電圧を計測し変換する事ができます。
アナログピンの入力電圧が0Vの時は0、5Vの時は1023というスケールで表現するという事です。
つまり0~5Vの電圧値を細かく等分して(1024分割)それを0~1023という数字に置き換えたという事ですね。
そのため分解能は、5V / 1024 =約0.0049Vという事になります。
これが分かれば実際に入力ピンに掛かっている電圧値を求める事が出来ます。
仮にArduinoのアナログ入力ピンから得られる値(analogRead関数で得られた値)が100だとすると上記に当てはまると、
100×分解能(5/1024)となり
実際には0.49Vだという事が計算出来ます。
このようにanalogRead関数によって得られた値(0~1023)に約0.049V(5/1024)を掛ければ実際の電圧値に変換する事が出来るという事になります。
(実際の電圧値)=(アナログ値)×(基準電圧 5V)/ 1024(分解能)
それでは先程のスケッチを少し修正して入力ピンに掛かっている実際の電圧値もシリアルモニタに表示させてみましょう。
最初のスケッチに上記の計算式を追加してみました。
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 | // Arduino入門編⑥ アナログ入力端子の電圧値を計算 // https://burariweb.info const int INPUT_PIN = A0; // 入力ピンをA0に固定 int VOLUME; // 変数を整数型で宣言 float VOLTAGE; // 変数を浮動小数点型で宣言 void setup(){ Serial.begin(9600); // シリアル通信の開始 } void loop(){ VOLUME = analogRead(INPUT_PIN); // アナログ値の読み取り VOLTAGE = VOLUME * 5.0/1024.0; // 読み取ったアナログ値を電圧(V)に変換 Serial.print("Volume: "); Serial.print(VOLUME); // シリアルモニタに出力 Serial.print(" Volt: "); Serial.print(VOLTAGE); Serial.println(" V"); delay(100); } |
少しスケッチを解説しておきます。
まず冒頭の変数の宣言ですが、これまで整数型はintを使ってきました。
今回新しく出てきたfloatは浮動小数点を持つ数値のデータ型となり小数が扱えるようになります。(電圧表示で4.45Vなど小数点以下の数字を扱うので)
5 6 7 | const int INPUT_PIN = A0; // 入力ピンをA0に固定 int VOLUME; // 変数を整数型で宣言 float VOLTAGE; // 変数を浮動小数点型で宣言 |
float (浮動小数点型)
浮動小数点を持つ数値のデータ型となり小数が扱えるようになります。
アナログ的な値が必要なときに使います。
【アナログ入力ピンに実際に掛かる電圧を計算】
アナログピンの電圧 =(analogRead関数により得られた値) × 5(V) / 1024 により計算しています。
19 20 | VOLUME = analogRead(INPUT_PIN); // アナログ値の読み取り VOLTAGE = VOLUME * 5.0/1024.0; // 読み取ったアナログ値を電圧(V)に変換 |
それではスケッチを動かしシリアルモニタを確認して下さい。
可変抵抗が最小では入力値0で電圧0V、最大時では入力値1023で電圧5.0Vなのが確認出来ます。
analogRead関数を使いアナログ値の読み取りや実際にこの数値が何を意味するのか理解できれば今回の目標は達成です。
折角なのでもう少しやってみましょう!
可変抵抗を使いLEDの明るさを調整してみる
上記analogRead関数により得られる数値の意味が分かればこの数値を使いいろいろと試せそうです。
これまでの復習としてアナログ出力(PWM)を使って可変抵抗をスライドさせLEDの明るさを調整させてみたいと思います。
LEDを追加で接続しました。
接続にはPWM出力が使える9番ピンを利用しています。
PWMに関してはこちらも参考にしてみて下さい!
こちらのスケッチを用意しました。
今回やったanalogRead関数でのアナログ値の読み取り、そしてその値を利用してこれまでやってきたPWM制御でLEDを任意の明るさに点灯させるというものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // Arduino入門編⑥ 可変抵抗器でLEDの明るさを調整 // https://burariweb.info const int INPUT_PIN = A0; // 入力ピンをA0に固定 const int LED_PIN = 9; // LEDを9番ピンに固定 int VOLUME; // 変数を整数型で宣言 void setup(){ pinMode(LED_PIN, OUTPUT); // 9番ピンを出力に設定 } void loop(){ VOLUME = analogRead(INPUT_PIN); // アナログ値の読み取り analogWrite(LED_PIN, VOLUME/4); // PWMでLEDを点灯 delay(100); } |
簡単なスケッチとなりますが、1点だけ注意ポイントがあります。
PWMでLEDを点灯させるanalogWrite関数内に変数VOLUMEの値を4で割っています。
19 20 | VOLUME = analogRead(INPUT_PIN); // アナログ値の読み取り analogWrite(LED_PIN, VOLUME/4); // PWMでLEDを点灯 |
これは以前の記事の復讐になりますが、analogWrite関数を使ったPWM出力は8ビットの分解能、つまり2の8乗256(0~255)で指定するという話を以前ご紹介しました。
しかしアナログ入力により得られる値はさらに分解能が高く10ビット(0~1023)となっています。
この値を調整するために4で割っています。
アナログ入力ピンから得られた値(0~1023)を4で割ってPWM出力で指定できる0~255の数値にスケールを合わせているという事です。
そして実際にスケッチを動かしたのがこちらの動画となります。
サーボモーターの制御に関してはまだご紹介していませんが、一緒に動かしてみました。
可変抵抗を回し抵抗値を増減させることによりLEDの明るさやサーボモーターの可動角度が変化しています。
サーボライブラリを使う場合、9番10番ピンでanalogWriteによるPWM出力が使えなくなるためです。
【追記】Arduinoを使い簡単な抵抗値測定器を作ってみました!
今回、可変抵抗器を使い抵抗による分圧でArduinoのアナログ端子に入力された電圧をシリアルモニタに表示させてみました。
同様な方法で繋いだ未知の抵抗値の測定をする事もできます。
簡易的な抵抗値の測定器として使えますね!
今回使った関数(コマンド)まとめ
関数 | 使用方法 |
analogRead(pin); | 指定したアナログピンから値を読み取る。アナログ入力ピン(A0~A5)を指定。 10ビットのAD変換が搭載されており0~5Vの入力電圧を0~1023の値に変換して読み取ります。(書式)analogRead(pin); pin:読み取るピン番号(Arduino UNOの場合0~5またはA0~A5で指定) |
Serial.begin(speed); | シリアル通信を有効にします。 シリアル通信のデータ転送レート(bps)を指定します。 (300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200bps)(書式例)Serial.begin(9600); |
Serial.print(data) ; | データをシリアルポートへ出力します。 つまりPCのシリアルモニタに出力し表示させます。 |
今回使ったパーツ
Arduino UNO
Arduinoはオープンソースのハードウェアなので正規品以外にも互換品が多数メーカーから販売されています。
互換品でも正規品と比べて特に問題なく使用でき数百円程度で購入が可能なのでArduino学習用としていいですね!
Arduino互換ボードは多数販売されていますが、個人的にElegoo製のArduino互換ボードは非常にいい印象を受けます。
Arduino スターターキット
これからArduino学習を進めていくにあたりArduino UNO(互換品)やブレッドボード、ジャンパーピンなどがセットになったスターターキットが販売されています。
私はGeekcreit製のスターターキットを使っていますが、ELEGOO製のものは国内Amazonなどでも購入可能で人気があるようです。(セット内容はほぼ同じです!)
そしてELEGOOのサイトからスターターキット用サンプルスケッチのダウンロードも可能です。(Geekcreitのキットでも使えます)
参考 チュートリアルダウンロードELEGOO基本的にこれからこのセットで出来るものから紹介していこうと考えていますが、かなり多くのことが出来ます。
電子工作を始めるにはまずブレッドボードやジャンパーピン、メインとなるArduino UNOやサーボ、LEDなどの基本的なパーツがないと実際に動かすことが出来ませんが、個々にパーツを購入して回路を組んでとなるとかなりの手間がかかります。
スターターキットがあればArduinoの初歩的なことはかなりの数こなすことが出来るのでオススメです!
そこからスキルアップに伴い個別でセンサーなど必要なものを増やしていくのがいいと思います。
今回使った可変抵抗はArduinoスターターキットに含まれていました。
可変抵抗器
上記Arduinoスターターキットにも付属していましたが、もちろん個別で購入することも可能です。
形状や抵抗値など様々なものが販売されていますが、今回使った同型10kΩのものを記載しておきます。
今回のポイント
- Arduino UNOのアナログ入力ピンは10ビット分解能のAD変換器を搭載している!
- アナログ入力(analogRead関数)で得られる数値は0~1023の数値に変換される(AD変換)
- 実際に入力されている電圧値は、(得られた数値) × 分解能(5V / 1024)で計算できる!
最後に!
今回、analogRead関数を使い可変抵抗のアナログ値の読み取りが出来るようになりました。
可変抵抗器が使われたパーツとして電子工作でよく使われるものといえばこのようなジョイスティックでしょうか。
サーボモーターで動かすロボットなどの操作に使うと面白そうですね!
このようなアナログジョイスティックには2つの可変抵抗器が内部に搭載されています。
つまりX軸方向とY軸方向の2つという事ですね。
今回の内容が理解出来ていれば単に可変抵抗器の数が増えているだけなので制御は簡単です。
またスティックの押し込み判定も出来るタイプのものですが、これも前回やったデジタル入力の話が理解出来ていれば簡単です。
次回、アナログ入力とデジタル入力の復習としてこのジョイスティックを使ってみたいと思います。
サーボモーターに関してはまだご紹介出来ていませんが、こんな感じでジョイスティックを使いサーボモーターを制御したり出来るようになります。(動画ではM5StickCを使っていますが!)
[…] 前回、Arduino UNOを使い可変抵抗器からのアナログ値の読み取りをやってみました。 […]