目次
本記事で使用するもの
以下のリンクのスターターキットを購入した場合、上記で述べた使用するものは、PC以外すべて入手することができます。
Arduinoをまだ購入していないという方やArduinoで動かすことができるたくさんのパーツが欲しいという方は、購入を検討してみてください。
ジョイスティックの説明
ジョイスティックは、スティックを傾けることで、方向の入力が可能な部品です。
また、スティックを押し込むことで、スイッチの役割も果たすジョイスティックもあります。
上記で紹介したスターターキットの中には以下の写真のようなジョイスティックが入っています。
上記のジョイスティックは、x軸とy軸の動きを検知するために、二つのポテンショメータを利用しています。
この2つのポテンショメータは、「GND」、「+5V」と書かれた線に繋がっており、さらに、それぞれのポテンショメータの真ん中の線が「VRx」、「VRy」という線に繋がっています。
よって、「GND」、「+5V」を、Arduinoの「GNDピン」、「5Vピン」に繋いだ状態にし、「VRx」、「VRy」の電圧をアナログ入力で読み取ることで、各方向にどれだけスティックが傾いているかを読み取ることができます。
ここで、ポテンショメータやアナログ入力について、良く分からないという方は、以下のリンク先の記事で説明していますので、是非、ご覧になってください。
また、上記のジョイスティックは、スイッチも備わっており、スティックを押し込むことにより、スイッチの「ON」、「OFF」を切り替えることができます。
スイッチは「GND」と「SW」という線に繋がっているため、「GND」をArduinoの「GNDピン」に繋ぎ、「SW」の電圧をプルアップ付きのデジタル入力で読み取ることにより、スイッチの状態を読み取ることができます。
ここで、スイッチやプルアップ付きデジタル入力について、良く分からないという方は、以下のリンク先の記事で説明していますので、是非、ご覧になってください。
ジョイスティックを試す
では、初めに以下の画像のように、スティックの状態をシリアルモニタへ出力させる方法について、説明したいと思います。
空のスケッチを書き込む
回路を作成する前に、空のスケッチ(「ファイル」タブの「New Sketch」をクリックしたときに出てくる何の処理も書かれていないスケッチ)を書き込みます。
そうすることにより、前に書き込んだスケッチが、新しく作成しようとしている回路に影響を及ぼすことを防げます。
新しい回路を作成するときは、いつもこの作業をやっておくと、安全に回路を作成することができます。
回路を作成する
以下のような回路を作成してください。
アナログスティックの接続は、操作をしやすくするため、以下のように「オス-メス」のジャンパーワイヤーを使って接続しています。
(上記で紹介したスターターキットでは「オス-メス」のジャンパーワイヤーが10本くっついた状態で入っていますが、手で簡単に1本ずつに分けることができます。)
スケッチを書き込む
回路の作成が終わりましたら、以下のようなスケッチを書き込んでください。
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 43 |
//x軸方向の値 int x_value; //y軸方向の値 int y_value; //スイッチの状態を見る変数(押されていない:1 押されている:0) bool switch_flag; void setup() { //VRxに繋いだピン(A0)をを入力ピンとして設定する(デフォルト設定なので省略しても良い) pinMode(A0,INPUT); //VRyに繋いだピン(A1)をを入力ピンとして設定する(デフォルト設定なので省略しても良い) pinMode(A1,INPUT); //SWに繋いだピン(2)をプルアップ付きの入力ピンとして設定する pinMode(2,INPUT_PULLUP); //シリアル通信の初期処理を行う Serial.begin(9600); } void loop() { //x軸方向とy軸方向の値を取得する x_value=analogRead(A0); y_value=analogRead(A1); //スイッチの状態を取得する switch_flag=digitalRead(2); //x軸方向とy軸方向の値、スイッチの状態を表示する Serial.print("X: "); Serial.print(x_value); Serial.print(" Y: "); Serial.print(y_value); Serial.print(" SW: "); Serial.println(switch_flag); delay(100); } |
スケッチの書き込みが終わりましたら、シリアルモニタを開き、入力部分の右に表示されている設定が「9600baud」、自動スクロールが「ON」になっているのを確認して、スティックを倒したり、押し込んだりしてみてください。
スケッチと回路が正しければ、シリアルモニタに表示されている値が、スティックの動きに応じて変化していくのが確認できます。
スケッチの解説
このスケッチは、各ポテンショメータの電圧をアナログ入力で、スイッチの状態をプルアップ付きのデジタル入力で測定し、測定した値をシリアルモニタで表示させているものとなります。
スイッチの状態については、プルアップ付きのデジタル入力で測定しているので、スイッチが押し込まれていないとき「1」、押し込まれていないとき、「0」が表示されます。
アナログ入力は、電圧を0~1023(1024パターン)に変換して読み取ることができます。
アナログ入力ピンに接続した「VRx」、「VRy」は、スティックの位置に応じて、電圧が変化するので、スティックを動かすとアナログ入力で読み取った値が変化するという仕組みとなっています。
ここで、スティックから手を離した際の位置(中央の位置)の場合、1024パターンの半分の位置である「511」もしくは「512」となることが予想されますが、以下のように実際には少しずれた値が表示されます。
よって、中央を基準にどれだけスティックを傾けているのかを、検知したい場合は、測定した値が上記の中央の値からどれだけ離れているかを計算する必要があります。
次に節で説明するジョイスティックで複数のLEDを制御する方法では、中央を基準にどれだけスティックを傾けているのかを検知して、それに応じてLEDの点灯を制御するものとなっているので、上記の中央の値を利用します。
この中央の値は、スティックの種類が同じであっても、個体差により変わってくるので、引き続き説明をご覧になる方は、ご自分のスティックの中央の値「X:~」、「Y:~」をメモしておいてください。
ジョイスティックで複数のLEDを制御する
続いて、以下の動画のように、ジョイスティックを使って、複数のLEDを制御する方法について、説明をしたいと思います。
回路を作成する
以下のような回路を作成してください。
配線が多いため、回路図がごちゃごちゃしていますが、各LEDのアノード(+)側を、Arduinoのデジタル入出力ピンやアナログ入力ピンに、LEDのカソード(-)側を、抵抗器を介してGNDに繋げています。
線が密集していますので、隣り合うLEDや抵抗器の線が、接触してしまわないように注意してください。
ここで、抵抗器の電気抵抗の高さは、LEDの順電圧と順電流から計算で求めます。
以下に、直列に繋げる抵抗器の電気抵抗の高さを計算するツールを用意しましたので、ご活用ください。
回路で使用する抵抗器は、上記のツールで求めた電気抵抗よりも少し高い電気抵抗のものを使用します。
上記のツールが行っている電気抵抗の計算方法については、以下のリンク先の記事で説明していますので、気になる方はご覧になってください。
ここで、電気抵抗の計算が行えない場合は、電気抵抗が高いもの(大体1[kΩ])から順番に接続していき、ちょうど良い明るさになるものを探していきます。
その際、電気抵抗を低いものにすれば、その分点灯が明るくなるのですが、電気抵抗が低すぎるもの(大体100[Ω]を下回るくらい)の場合、LEDの寿命を縮めてしまったり、破壊してしまったりすることがあるので注意してください。
今回、私はすべて220[Ω]の抵抗器を使用しています。
(真上からLEDを見ると結構眩しいです。眩しすぎると感じた場合は、電気抵抗の大きな抵抗器に変更するなどして明るさを調整してみてください。)
スケッチを書き込む
以下のようなスケッチを書き込んでください。
ここで、11行目、12行目の値は、先程のスケッチで確認したスティックが中央のときの値に変更してください。
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
//x軸方向の値 int x_value; //y軸方向の値 int y_value; //スイッチの状態を見る変数(押されていない:1 押されている:0) bool switch_flag; //スティックから手を放しているときの値 int x_offset=527; int y_offset=517; //各色のLEDに接続されているピンを配列でまとめる int Yellow_LED[3]={3,4,5}; int Red_LED[3]={6,7,8}; int Green_LED[3]={9,10,11}; int Blue_LED[3]={A3,A4,A5}; void setup() { //VRxに繋いだピン(A0)をを入力ピンとして設定する(デフォルト設定なので省略しても良い) pinMode(A0,INPUT); //VRyに繋いだピン(A1)をを入力ピンとして設定する(デフォルト設定なので省略しても良い) pinMode(A1,INPUT); //SWに繋いだピン(2)をプルアップ付きの入力ピンとして設定する pinMode(2,INPUT_PULLUP); //LEDに接続しているピンを出力ピンとして設定する for(int i=0;i<3;i++){ pinMode(Yellow_LED[i],OUTPUT); pinMode(Red_LED[i],OUTPUT); pinMode(Green_LED[i],OUTPUT); pinMode(Blue_LED[i],OUTPUT); } } void loop() { //全てのLEDを消灯 for(int i=0;i<3;i++){ digitalWrite(Yellow_LED[i],LOW); digitalWrite(Red_LED[i],LOW); digitalWrite(Green_LED[i],LOW); digitalWrite(Blue_LED[i],LOW); } //スイッチの状態を取得する switch_flag=digitalRead(2); //スイッチが押されたているときと押されていないときで処理を分岐する if(switch_flag==0){ //スイッチが押されている時、真ん中から広がるようにLEDを点灯 //真ん中付近のLEDを点灯 digitalWrite(Yellow_LED[0],HIGH); digitalWrite(Yellow_LED[2],HIGH); digitalWrite(Red_LED[0],HIGH); digitalWrite(Red_LED[2],HIGH); digitalWrite(Green_LED[0],HIGH); digitalWrite(Green_LED[2],HIGH); digitalWrite(Blue_LED[0],HIGH); digitalWrite(Blue_LED[2],HIGH); delay(250); //真ん中付近のLEDを消灯 digitalWrite(Yellow_LED[0],LOW); digitalWrite(Yellow_LED[2],LOW); digitalWrite(Red_LED[0],LOW); digitalWrite(Red_LED[2],LOW); digitalWrite(Green_LED[0],LOW); digitalWrite(Green_LED[2],LOW); digitalWrite(Blue_LED[0],LOW); digitalWrite(Blue_LED[2],LOW); //端にあるLEDを点灯 digitalWrite(Yellow_LED[1],HIGH); digitalWrite(Red_LED[1],HIGH); digitalWrite(Green_LED[1],HIGH); digitalWrite(Blue_LED[1],HIGH); delay(250); }else{ //スイッチが押されていないとき、スティックの傾きでLEDの点灯を制御 //x軸方向とy軸方向の値を取得する x_value=analogRead(A0); y_value=analogRead(A1); //x軸方向の値に応じて黄、緑のLEDの点灯を制御 if(x_value<x_offset-300){ digitalWrite(Green_LED[1],HIGH); }else if(x_value<x_offset-100){ digitalWrite(Green_LED[0],HIGH); digitalWrite(Green_LED[2],HIGH); } if(x_value<x_offset+100){ //何もしない }else if(x_value<x_offset+300){ digitalWrite(Yellow_LED[0],HIGH); digitalWrite(Yellow_LED[2],HIGH); }else{ digitalWrite(Yellow_LED[1],HIGH); } //y軸方向の値に応じて赤、青のLEDの点灯を制御 if(y_value<y_offset-300){ digitalWrite(Red_LED[1],HIGH); }else if(y_value<y_offset-100){ digitalWrite(Red_LED[0],HIGH); digitalWrite(Red_LED[2],HIGH); }else if(y_value<y_offset+100){ //何もしない }else if(y_value<y_offset+300){ digitalWrite(Blue_LED[0],HIGH); digitalWrite(Blue_LED[2],HIGH); }else{ digitalWrite(Blue_LED[1],HIGH); } //明るさ調整用の待機 delay(5); } } |
スケッチと回路が正しければ、先程の動画のように、スティックの状態に応じて、LEDの点灯が変化することが確認できます。
点灯しないLEDがある場合は、LEDの向きが間違っていたり、ピンや抵抗器を差す位置がずれていたりしている可能性が高いので、まずは、接続を確認してみてください。
スケッチの解説
今回のスケッチでは、スティックの状態を検知するためのピンに加えて、「デジタル入出力ピン」を9本、「アナログ入力ピン」を3本、出力ピンとして設定し、LEDを制御しています。
「アナログ入力ピン」は名前のせいで、入力しかできないピンだと思われることがありますが、出力も行うことができます。
LEDに接続しているピンの番号は、15~18行目のように配列を使って各色ごとにまとめています。
アナログ入力ピンの番号を指定する「A~」って、文字なのに、整数を入れる「int型」で良いのかと思われる方もいらっしゃると思いますが、実はこの「A~」というのは、「uint8_t型」の変数で、コンパイルの初めに、ボードの種類に合わせた整数が入れられています。
この「A~」の変数宣言は裏で行われていることなので、普段目にすることはできませんが、スケッチ内で、新しく「A~」という名前の変数を宣言しようとすると、「その変数の名前はすでに使われていますよ」というエラーが表示されます。
話は逸れましたが、続いて「void loop()」内の処理について、説明していきたいと思います。
「void loop()」内の処理では、まず、全てのLEDを消灯させ、その後、スイッチの状態に合わせて処理を分岐させています。
ここで、スイッチが押されているとき、真ん中付近のLEDから広がるようにLEDの点灯、消灯を行い、スイッチが押されていないときは、スティックの傾きに応じてLEDを点灯、消灯させています。
処理の分岐を行っている「if文」について、良く分からないという方は、以下のリンク先の記事で説明していますので、是非、ご覧になってください。
スイッチが押されていない場合、スティックの傾きに応じてLEDの点灯、消灯を行うために、また別のif文で処理を分岐させています。
if文の条件式は、読み取ったアナログ入力の値が、中央の値からどれだけずれているかを見ており、これにより、どのLEDを点灯させるかを決めています。
スティックを同じ位置で固定した場合、「void loop()」の初めでLEDを消灯しているので、LEDは素早く点滅している状態になりますが、その点滅は人間の目で確認できるようなものではありません。
しかし、点灯している時間と消灯している時間が同じくらいの場合、LEDの明るさは少し暗く見えてしまうので、「delay(5)」により点灯している時間を延ばし、明るく見せているということをしています。
ジョイスティックを使って、複数のLEDを制御する方法についての説明は以上となります。
終わりに
ジョイスティックの使い方について、ご理解いただけたでしょうか。
今回説明したジョイスティックは、ポテンショメータ2つとスイッチ1つという、割と単純な部品の組み合わせでしたが、それだけでも色々なものを操作することができるすごく面白い部品だと思います。
ジョイスティックで何を操作するのかというのも、自由なので、色々な組み合わせを楽しんでみてください。
次回の記事では、光の強さを測定するときなどに利用する「フォトレジスタ」というものの使い方について説明したいと思います。
本記事はここまでです。ご清覧ありがとうございました。
広告
楽天モーションウィジェットとGoogleアドセンス広告です。
気になる商品がございましたら、チェックをしてみてください。