11月25日発売 書籍『Arduinoと3Dプリンタでロボットを作ろう』を出させて頂きました!

【Arduino入門編⑦】ジョイスティックの制御方法!デジタル・アナログ入力の解説です!

前回、Arduino UNOを使い可変抵抗器からのアナログ値の読み取りをやってみました。

Arduino UNOのアナログ入力端子には10ビット分解能のADC(アナログーデジタルコンバーター)が内臓されており、入力端子の電圧0~5Vを0~1023の数値として読み込む事が出来るのが分かりました。

今回これを使い2軸アナログジョイスティックからの数値を読み取ってみたいと思います。

アナログジョイスティックからの入力値を読み取る!

今回の目標

前回の応用、そしてこれまでの復習としてアナログジョイスティックからの入力値を読み取りLED点灯制御に使ってみたいと思います。

前回、可変抵抗器からのアナログ値の読み取りをやってみました。
今回使う2軸アナログジョイスティックはX軸方向とY軸方向で2つの可変抵抗器が内蔵されており、個別でそれぞれの値を読み取る事で制御が可能となります。
前回の応用&これまでの復習的な内容となります。

【Arduino入門編⑥】可変抵抗を使いアナログ値を読み取る。アナログ値から実際に入力されている電圧を計算。アナログ入力端子の解説です!

またジョイスティックにはセンタークリック機能があり押し込み判定が出来るものを今回使っています。
こちらもこれまでやってきたデジタル入力を使えば判定は簡単です。

ジョイスティックを使った制御が出来るようになるとサーボモーターを使ったロボット?みたいなものを動かしたりと、これからいろいろと使えそうです。
またプレステのコントローラーにあるアナログパッドを使ってBluetoothで動かす、なんて事も出来そうです。

サーボモーターの制御に関してはまだこちらで詳しくご紹介していないので、触り程度で紹介し、ジョイスティックからのアナログ値を取得し今回はPWMでLEDの明るさ制御する事をメインでやっていきたいと思います。

これまでのアナログ入力・デジタル入力の復習的な内容となりますが、それぞれ理解が深まればと思います。

アナログジョイスティックとは?

今回こちらのよく見かける安価な2軸タイプのアナログジョイスティックを使ってみます。
X軸方向・Y軸方向のアナログ値の読み取りに加え、センタークリック機能によりスティックを押し込むことによるON/OFF判定も出来るようになっています。
Arduinoのスターターキットにも同封されているものです。(後ほどご紹介)

内部構造は簡単で、X軸方向(横)とY軸方向(縦)にそれぞれ可変抵抗器が使われていてスティックにはプッシュスイッチも内蔵されています。

前回、可変抵抗器のアナログ値の取得をやってみました。
基本的にやり方は同じです。
先述のように2つの可変抵抗器が内蔵されているだけなので個別でそれぞれのアナログ値をアナログ入力端子から取得するだけです。

また押し込む事によりON/OFFの判定も出来ますが、これはデジタル入力端子から取得できます。
ただ単純な接点の短絡&開放のスイッチのため、接点が開放(OFFの時)の時に端子が浮いた状態(何も繋がれていない状態)となるので、動作を安定させるため入力側に何かしら電圧がかかりON/OFF判定出来るようにプルアップさせてあげる必要があります。

プルアップ・プルダウンについても以前ご紹介しました。
このあたりも踏まえ、これまでの復習として理解が深まればと思います。

そしてジョイスティックの接続は以下の5本の端子を接続します。
それぞれ、Vcc(+5V)・GND・VRx・VRy・SW端子となっています。

接続ピン詳細
GNDArduinoのGNDに接続
+5VArduinoの5V出力端子に接続
VRxX軸方向の読み取り(アナログピン)
VRyY軸方向の読み取り(アナログピン)
SWセンタークリックON/OFF(デジタルピン)

※こちらのジョイスティックにはX軸方向・Y軸方向の検知に10kΩの可変抵抗器が使われています。

ジョイスティックの動作原理

今回使うアナログジョイスティックにはX軸方向・Y軸方向検知用に10kΩの可変抵抗器が使われています。
そして何も押されていない状態では自動的にセンターポジションに戻る構造となっています。

スティックを倒すことにより内部の可変抵抗器の抵抗値が変化してその抵抗の分圧によりアナログ入力端子に0~5Vの電圧値が入力されます。
その電圧値をArduinoのAD変換(アナログーデジタルコンバーター)機能により0~1023のデジタル値に変換され入力値となります。

MEMO
スティックを動かすことにより内部の可変抵抗器の値が変化し0~5Vの範囲で電圧が変化します。
その電圧をanalogRead関数を使いデジタル値(0~1023)に変換して読み取るということです。

そしてセンターポジションではX軸方向・Y軸方向のアナログ値はおおよそ0~1023の真ん中の512が読み取られるということです。

しかし実際には可変抵抗器の精度により取得できるアナログ値はそれより少しズレた値となるようです。
また、数値も前後少しずつ変化し揺らぎみたいなものも発生するようです。
このあたり実際に使う時に少し補正してあげる必要がありそうです。

そしてセンタークリック機能は単純なON/OFFのプッシュスイッチと同じで、その判定にはdigitalRead関数が使われます。
その際にスイッチが押されていない状態(宙に浮いた状態)ではデジタル入力の場合動作が不安定となるため、押されていない状態では常にHIGHが入力されるようにプルアップさせる必要があり、押した状態でLOWとなるようにGNDに接続する形となります。
プルアップさせるのでON/OFFが反転している点がポイントですね。

スティック状態(digitalRead関数で読み取った値)
押されていない状態HIGHを検出
押した状態LOWを検出

それでは実際に回路を組んで試してみましょう。

ジョイスティックから取得した入力値をシリアルモニタで確認

まずはジョイスティックから取得したX軸方向・Y軸方向のアナログ値とプッシュスイッチの状態を取得しシリアルモニタで確認してみたいと思います。

X軸方向・Y軸方向の読み取りはアナログ入力ピンを使い、プッシュスイッチはデジタル入出力ピンを使って状態を読み取ります。

5V・GNDをArduino UNOから取り、VRx・VRyをアナログ入力ピンに接続(今回VRxをA0、VRyをA1に接続しました)、SWをデジタル入出力ピン(今回D2ピンを使いました)に接続します。

プッシュスイッチが押されていない状態(浮いた状態)を防ぐため、pinMode関数でD2ピンをプルアップして常にHIGH状態、そして押された状態ではGNDに繋がるようになっています。

プルアップ・プルダウンに関してはこちらを参考にしてみて下さい。

【Arduino入門編⑤】プルアップ・プルダウンって何?デジタル入力の解説です!

接続はこのようになります。
簡単ですね!
今回使ったジョイスティックとは下記回路図とピン配列が少し違いますが対応した箇所に接続して下さい!

VRx(ジョイスティック) → A0(Arduino)
VRy(ジョイスティック) → A1(Arduino)
SW(ジョイスティック) → D2(Arduino)

そしてスケッチはこちらを使用します。
前回のアナログ入力について理解出来ていれば簡単です。

アナログ入力に関してはこちらを参考にして下さい。

【Arduino入門編⑥】可変抵抗を使いアナログ値を読み取る。アナログ値から実際に入力されている電圧を計算。アナログ入力端子の解説です!
それでは上記スケッチを動かしシリアルモニタを立ち上げジョイスティックから取得した値を確認してみましょう。

シリアルモニタを立ち上げるとこのようにジョイスティックから取得したX軸方向・Y軸方向のアナログ値、そしてプッシュスイッチの状態が表示されます。

ジョイスティックは何も押されていない状態ではセンターに戻る仕様なので先述したように本来アナログ入力値(0~1023)のちょうど真ん中の512くらいになるはずですが・・・少しバラツキがありますね!

そしてスティックをX軸方向・Y軸方向に動かしてみると、それぞれ最小0〜最大1023の範囲におさまっている事が確認できます。

また押し込みスイッチはプルアップされて接続しているので押されていない状態ではHIGH(1)、押されるとLOW(0)となる事も確認できます。

これらが確認&理解出来れば今回の目標は達成です。
簡単でしたね!

ここからこの入力された値を使いサーボモーターなどを動かしてみると視覚的に分かりやすいのですが、サーボモーターの制御に関してはまだ詳しくご紹介していないので後日詳しく出来ればと思います。

これまでやってきた事で分かりやすいのはLEDの点灯でしょうか?
アナログ値の取得が出来たので、ジョイスティックを動かし上下左右に対応したLEDの明るさを制御してみたいと思います。

ジョイスティックを使いLEDの点灯強度を制御する

ジョイスティックで取得した入力値を視覚化するため簡単な回路を組んでみました。
スティックを倒す向きと強さに応じて対応したLEDの明るさが変化し、プッシュスイッチが押されると真ん中の青色LEDが点灯するイメージです。(LEDの電流制限抵抗は今回150Ωのものを使っています)

LEDをそれぞれの出力ピンに繋いだだけの単純な回路となりますが、少し配線が面倒ですね!

スティックを倒す向きと強度によりその方向のLEDの点灯する明るさが変化します。
先程のスケッチに追加してこんな感じで書いてみました。

アナログ出力(PWM)によりLEDの点灯強度を変えています。
PWM制御に関してはこちらの記事を参考にしてみて下さい。

【Arduino入門編③】PWM制御でLEDをゆっくり点灯&消灯させてみる!アナログ出力(PWM)の解説その①

上記スケッチについて少し解説しておきます。
センター付近のバラツキがあるのでこれを少し補正しています。
OFFSETという変数を作りセンター付近の判定をあまくしています。
本来のセンターポジションでのアナログ値は512が理想的ですが少しズレていて値もフラフラと定まらないので前後5%のオフセットを取ってこの範囲は誤差として無視する(LEDが光らないように)ようにしています。

今回のようにLEDの点灯では問題はあまりないと思いますが、例えばサーボモーターを使い同様の方法で動かそうとすると数値のバラツキでカタカタ動いてしまう場合があるので少し補正してあげる方がいいかもしれません!

大まかなスケッチの流れを少し解説しておきます。
例えばX軸方向を考えると何も押されていないセンター付近でのアナログ入力値は512(実際は少しズレていますが)、そして右に倒していくと最大で1023(512〜1023まで変化)、左に倒していくと最小の0(512〜0に変化)になります。

これを利用しanalogWrite関数を使いPWM出力(デューティー比0~255)にレンジを合わせてあげれば点灯強度を変えられるという事になります。

MEMO
analogWrite関数を使ったデューティー比は0~255の範囲で指定!
今回4本の赤色LED(上下左右)はPWM出力ができる3・5・9・10番ピンを使っています。

ここでこのスケールを合わせるために便利なmap関数を使っています。
このmap関数を使いそれぞれスティックの向きに応じたアナログ値をanalogWrite関数で出力できるPWM(0〜255)の範囲でレンジを調整しています。

具体的には、例えば左に倒していくとX軸方向のアナログ値は512⇒0と変化します。
これをLEDが徐々に明るくなるようにanalogWrite関数で出力する際の値を0⇒255の範囲にmap関数を使い調整しています。(実際にはセンター付近にオフセット5%を考慮しています。)

map 関数
数値をある範囲から別の範囲に変換します。

 

(書式)map(vaue, a, b, X, Y);

 

変数valueのaからbまでの範囲の値をXからYの範囲の値に変換する。
範囲を指定するパラメータは負の数を扱う事も出来ます。
また計算の結果、小数が生じる場合は切り捨てられます。
あくまで返り値は整数となります。

それでは実際にスケッチを動かしてみて下さい。
スティックの向きに応じそれぞれ対応したLEDが点灯しスティックの傾きにより明るさが強弱変化します。
そしてスティックを押し込むと青色LEDが点灯するのも確認出来ます。

またこちらはM5StickCを使っていますが同様の制御によりサーボモーターを動かしています。
詳しくは後日ご紹介出来ればと思います。

【追記】ジョイスティックコントローラーを作ってみました!

Arduinoのテスト環境であると便利なジョイスティックコントローラーを3Dプリントパーツで作ってみました!

Arduinoで動くもののテストをする場合、コントローラーという形状にしておくと操作性もイメージしやすくプログラムの修正などにも役立つと思います。

3Dプリントパーツでジョイスティックコントローラーを作る!電子工作用途で便利に使えます。【STLデータ公開】

本記事でご紹介したジョイスティックの使い方やポテンショメーターを使ったこちらの記事を参考に組めばテスト環境で便利に使えるかと思います。

【Arduino入門編⑥】可変抵抗を使いアナログ値を読み取る。アナログ値から実際に入力されている電圧を計算。アナログ入力端子の解説です!

【追記】ジョイスティックシールドが便利です!

Arduinoを使って何か動かしたい場合にジョイスティックやタクトスイッチを使うことはよくあります。

今回ご紹介したアナログジョイスティックですが、Arduinoとの接続自体は簡単ですが結構多くの配線を接続する必要があります。
テストで動かしたい場合など、ワイヤーの脱落などもよく起こることからジョイスティックシールドを使うようになりました。

ジョイスティック以外にも6つのタクトスイッチが使え、シールドなのでArduinoボードに接続するだけで使えるようになり配線をシンプルにする事ができます。

また無線モジュール(nRF24L01)との組み合わせで簡易的なコントローラーとして使うことも出来るので便利となります!

【Arduino】ジョイスティックシールドを使ってみる!無線モジュール(nRF24L01)とのコンビで便利に使えます!

【追記】nRF24L01を使ったArduino無線コントローラーを製作!

Arduinoのアナログ入力/ジョイスティックの制御は、製作物を動かす際や様々なArduinoのテスト動作などでもよく使われます。

本記事を読んで頂いている方は、Arduinoを使った電子工作を始めたばかりの方だと思います。
気付けば私もArduinoを使った電子工作を始めて2年程が立ちました。

ある程度Arduinoの扱いにも慣れてきましたが、Arduinoは後発となるESP系のマイコンボードなどと比べると標準で無線機能が搭載されていません。

そのためこのようなArduinoを使った無線コントローラーを製作しました!
無線で操作できる物理コントローラーが1台あると、Arduinoを使った製作物を動かす際やちょっとした無線の動作テストなどで非常に便利に使えます。

【電子工作】Arduinoを使った無線コントローラー(送信機)製作ノート①!KiCadの基板設計から基板発注(JLCPCB)までの話(nRF24L01)

今回使ったパーツ

Arduino UNO

Arduinoはオープンソースのハードウェアなので正規品以外にも互換品が多数メーカーから販売されています。
互換品でも正規品と比べて特に問題なく使用でき数百円程度で購入が可能なのでArduino学習用としていいですね!

Arduino互換ボードは多数販売されていますが、個人的にElegoo製のArduino互換ボードは非常にいい印象を受けます。

【ELEGOO Arduino Uno】Arduino完全互換ボードの中ではダントツのクオリティーですね!

Arduino スターターキット

これからArduino学習を進めていくにあたりArduino UNO(互換品)やブレッドボード、ジャンパーピンなどがセットになったスターターキットが販売されています。

私はGeekcreit製のスターターキットを使っていますが、ELEGOO製のものは国内Amazonなどでも購入可能で人気があるようです。(セット内容はほぼ同じです!)

そしてELEGOOのサイトからスターターキット用サンプルスケッチのダウンロードも可能です。(Geekcreitのキットでも使えます)

参考 チュートリアルダウンロードELEGOO

基本的にこれからこのセットで出来るものから紹介していこうと考えていますが、かなり多くのことが出来ます。
電子工作を始めるにはまずブレッドボードやジャンパーピン、メインとなるArduino UNOやサーボ、LEDなどの基本的なパーツがないと実際に動かすことが出来ませんが、個々にパーツを購入して回路を組んでとなるとかなりの手間がかかります。

スターターキットがあればArduinoの初歩的なことはかなりの数こなすことが出来るのでオススメです!
そこからスキルアップに伴い個別でセンサーなど必要なものを増やしていくのがいいと思います。

今回使ったアナログジョイスティックはELEGOO製Arduinoスターターキットには含まれているようです。

アナログジョイスティック

今回使用したアナログジョイスティックは個別でも販売されています。
Arduinoを使い何かを動かす場合、使用頻度が高いパーツの1つになります。
学習用に手元にあると便利です!

LEDセット

ArduinoのスターターキットにもLEDは20個ほど入っています。
LEDはArduinoを使っていろいろ回路を組んで試す際に非常によく使うパーツになります。
個別で購入するよりセットになっているものは非常にお安く1セット持っていると便利だと思います。(200個ほど入っています)

今回使った関数(コマンド)まとめ

 pinMode(pin,mode);

Arduino UNOが持っているデジタルピン(D0~D13)やアナログピン(A0~A5)の入出力設定をします。

 

pin:設定したいピンの番号
mode:入力[INPUT]・出力[OUTPUT]。プルアップを有効にする場合[INPUT_PULLUP]

analogRead(pin);

指定したアナログピンから値を読み取る。(A0~A5)
Arduino UNOには10ビットのAD変換器が搭載されており、0~5Vの入力電圧を0~1023の値に変換して読み取ります。

 

pin:読み取るピン番号(Arduino UNOの場合0~5またはA0~A5で指定)

digitalRead(pin);

指定したピンの値(HIGH or LOW)を読み取ります。(D0~D13)
事前にpinMode関数で入力(INPUT)に設定しておく必要があります。

map
数値をある範囲から別の範囲に変換します。

 

(書式)map(vaue, a, b, X, Y);

 

変数valueのaからbまでの範囲の値をXからYの範囲の値に変換する。
範囲を指定するパラメータは負の数を扱う事も出来ます。
また計算の結果、小数が生じる場合は切り捨てられます。
あくまで返り値は整数となります。

今回のポイント

  • アナログジョイスティックはX軸方向・Y軸方向のスティック読み取りに可変抵抗器がそれぞれ使われていてアナログ入力(analogRead関数)でその値を読み取る事が可能!
  • センタークリックの判定はデジタル入力(digitalRead関数)でその値を読み取る事が可能!(プルアップで使用)

最後に!

アナログジョイスティックを使えばサーボモーターなどで動くロボットを制御したりといろいろ楽しめそうですね!

今回はアナログ入力とデジタル入力の復習的な内容となりましたが、次回サーボモーターを動かしてみたいと思います。

サーボモーターを動かすにはPWM制御が使われています。
PWMでは周期的にパルスを出力しそのパルス幅によりサーボモーターの回転角度を制御しています。
実際にはサーボライブラリを使う事により簡単に動かす事が出来ますが、これまでやってきたPWM制御について分かっていれば理解もより深まると思います。

そしてもう少し先になりますがジャイロセンサーを使ってサーボモーターの制御などさせてみると面白そうですよね!

その他 Arduino入門編 記事一覧
【Arduino入門編㉛】INA219モジュールで電圧・電流を計測する基本的な方法! 【Arduino入門編㉚】マイコンのデジタル端子(I/O)不足を解消!『I/Oエキスパンダー(MCP23017)』の基本的な使い方! 【Arduino入門編㉙】SPI通信の基礎知識!SPIで使われる信号線や接続方法などについて! 【Arduino入門編㉘】ソフトウェアシリアルを使ってみる! 【Arduino入門編㉗】赤外線(IR)モジュールを使いリモコンの信号を読み取り送受信する方法! 【Arduino入門編㉖】UARTシリアル通信の基礎知識!Arduino間でのデータのやり取りなどをやってみる! 【Arduino入門編㉕】ステッピングモーターを動かしその基礎を理解する!(28BYJ-48 & ULN2003) 【Arduino入門編㉔】Arduinoで7セグメントLEDを制御してみよう!(スタティック制御 / ダイナミック制御) 【Arduino入門編㉓】PCA9685 16チャンネルPWMサーボモータードライバを使って複数のサーボモーターを同時に制御してみる!(最大16台) 【Arduino入門編㉒】ArduinoでDCモーターを制御する。【L298Nデュアルモータードライバ】 【Arduino入門編㉑】温湿度センサー(DHT11)を使い温度と湿度を計測する! 【Arduino入門編⑳】Arduino Uno R3ボードのピン配列&基本機能まとめ! 【Arduino入門編⑲】RTC(リアルタイムクロック)モジュールDS3231を使いシンプルな時計を作る![I2C通信] 【Arduino入門編⑱】I2C通信の基礎!LCDディスプレイに文字を表示させてみる![後編] 【Arduino入門編⑰】LCDディスプレイに文字を表示させてみる![前編][1602 LCDモジュール] 【Arduino入門編⑯】サーボモーターをジョイスティックやシリアルモニタから動かしてみる! 【Arduino入門編⑮】Arduino Unoへの電力供給(外部電源)および電源出力端子の使い方!【追記】 【Arduino入門編⑭】センサーシールド(Sensor Shield)を使ってみる! 【Arduino入門編⑬】テスト環境に便利!Arduino拡張ボード(シールド)プロトタイプシールドを使ってみる! 【Arduino入門編⑫】光センサー(Cdsセル)をアナログ入力ポートで読み取り制御に使ってみる!

3 COMMENTS

大木

あ、すみません。勘違いしてました。その列は横につながっていないですね。
申し訳ございません。

返信する
大木

つい先日から始めたばかりの初心者です。
この配線図だと横の列(アルファベットの列)で他の部品とつながってしまうように思えるのですが、
大丈夫な理由は何でしょうか?

返信する

コメントを残す