ハードウェア知識ゼロでも大丈夫。「Gravity」で始める電子工作入門
こんにちは、ちゃちゃまるです。
先日CodeZineさんで紹介した ハードウェアの知識ゼロでもボードにセンサーをつなげられる「Gravity」シリーズ について、さらに詳しく使い方を説明していきたいと思います!
※この記事は主に初心者の方・他のマイコンボードを使ってはみたが挫折してしまった方向けです。
「Gravity」のおさらい
「Gravity」とは中国・上海のハードウェア系企業であるDFRobotが作ったコネクタの規格、またそのコネクタを搭載したセンサー等を指します。
簡単に言うと、開発ボードとコントローラー(ボタンなど)やセンサー(音センサーなど)を統一された規格でつなぐことができるシリーズです。つなぐ部分やコネクタ自体が色分けされているので、直感的に配線ができ、簡単に自分の思う通りのものができます。
本記事ではGravity: Stater Kit for Arduinoを題材にしています。
開発環境を整える
Gravityのコントローラーやセンサーを使うには、PCにIDE(書き込み用アプリケーション)を用意し、PCとマイコンボードをつなげる必要があります。まずは開発環境から整えていきましょう!
- Macbook Air Early 2014
- OS X El Capitan v10.11.6
- Arduino IDE v1.6.12
Arduino IDEをインストール
Arduino - Softwareから「Arduino IDE」をダウンロードしてインストールします。
「Download the Arduino IDE」からお使いのOSを選択してください。
Arduino IDEはドネーションウェア(ユーザーが任意の利用料を開発者に寄付するライセンス形態のソフトウェア)なので、寄付金額を選択する画面に移動します。今回はグレーで書かれている「JUST DOWNLOAD」をクリックしてダウンロードを開始します。
Arduino IDEを起動
Arduino IDEをダウンロード後初回起動すると、上のような画面がでてきます。このテキストエリアにコードを書いていきます。
OSの言語を日本語以外に設定している場合、メニューバーの「Arduino」内の「Preferences」からArduino IDEの言語設定を変更できます。反映するにはOKを押した後アプリの再起動が必要です。
基本的なArduino IDEの流れとしては、まずエディア部分にコードを書き、検証ボタンでコードを検証、その後「マイコンボードに書き込む」ボタンでマイコンにプログラムを送ります。エラーやメッセージなどはコンパイラ画面に出力されます。
PCとマイコンボードをつなげる
PCとマイコンボードをつないで、PCからArduino IDE経由でプログラムを書き込めるようにします。
USBでDFRduinoとPCをつないだら、「ツール」から「Arduino/Genuino UNO」を選択するだけです。DFRduinoはArduinoと全く同じ(下で詳しく解説します)なので、これでボードと接続できました。
マイコンボードにプログラムを書き込む
Arduino IDEではプログラムを書いたファイルのことを「スケッチ」と呼ぶのですが、実はアプリにいくつものスケッチサンプルが内蔵されています。
上の「スケッチ例」を見るとかなりの量があります。今回は「01.Basics」内の「Blink」というスケッチを呼び出してみましょう。「Blink」をクリックすると自動的にプログラムが書かれたウィンドウが出てきます。
たくさんの文字が書かれていますが、実際のプログラムは色がついている部分です(/* */
で囲まれている部分や//
と行の先頭にあるのはコメントなので、実際の挙動には関係しません)。ここに書く言語はC言語ベースのArduino言語です。C言語自体の記述方法(if
文やfor
文など)はここでは解説しませんので、他のサイトを参考にしてください。
さて、ここで本来なら「検証」ボタンを使ってプログラムに間違いがないかチェックするのですが、今回はサンプルスケッチを使っているのでエラーは出ません。一応画面左上の「検証」(チェックマークのボタン)を押してみましょう。
「コンパイルが完了しました。」と同時に色々出てきました。このような画面が出たらとりあえず「プログラムの検証は成功した」と認識していれば大丈夫です。ちなみに「コンパイル」とは、人間が理解できるプログラミング言語からコンピュータが理解できる機械語へとプログラムを変換することを指します。
コンパイルが完了したので、いよいよマイコンボードに書き込みましょう。「検証」の隣にある「マイコンボードに書き込む」(矢印マークのボタン)をクリックします。
DFRduino UNOは上の赤で囲った部分がLEDとなっていて、さきほどのスケッチを書き込むとここが周期的に光ったり消えたりします。
マイコンボードに書き込んだプログラムは、Arduino IDEで新しいスケッチを書き込まない限り動き続けます。LEDのチカチカを止めたいときは「ファイル」から「新規ファイル」を開いて、空のスケッチを書き込みます。
シールドを取り付ける
「シールド」とは、マイコンボードの機能を拡張させるアドオンボードのことを指します。今回使うマイコンボードの「DFRduino UNO R3」はArduino互換(Arduinoと全く同じ動きをするもので、作っている会社・団体が違うだけ)なので、まだこのままではGravityシリーズのセンサーやコントローラーを使うことはできません。そこで、このボードに重ねる形でGravity用シールド「I/O Sensor Expansion Shield v7.1」を乗せます。
このI/O Sensor Expansion Shield v7.1を詳しく見てみると、ピン(金属の出っ張っている部分)が「黒・赤・緑」や「黒・赤・青」に色分けされています。これがまさに、知識ゼロでもGravityで遊ぶことができる理由です(後ほど配線をする際にこの色分けの恩恵を受けます)。この後のチュートリアルでは常にシールドをマイコンボードに乗せた状態で使います。
プログラムの実行
いよいよプログラムを実際に書いて実行していきましょう!
デジタル信号を取得する
何かのデータを取得する際、センサーから送られてくる信号には「デジタル」と「アナログ」の二種類があります。デジタル信号は値が「0」もしくは「1」で、アナログ信号の場合は値が「0」から「1023」の1024段階で、センサーから送られています。信号を取得するモジュールのことをインプットデバイスと呼びます。
使うパーツ:
- DFRduino UNO + I/O Sensor Expansion Shield v7.1
- Digital Push Button Module(以下ボタン)
実行編
では手始めに、ボタンが押されているかどうかを確認するプログラムを動かしてみましょう!
まずは配線をします。ボタンに付属のコネクタを指し、もう片方をシールドのD側2番ピン(以下図参照)に、コネクタとピンの色が合うように挿してください。
ボタンに付属している「黒・赤・緑」のコネクタは、デジタル信号を送るときに使います。今回はボタンが押されているか押されていないか、の2パターンの値が送られてきます。センサーやコントローラーの基盤の上に「D」や「A」と書かれていますが、これらもそれぞれデジタルかアナログかを示しています。
次に、D側2番ピンにつながっているボタンが押されているかどうかを検知するプログラムをArduino IDEのエディタ部分に書きます。
void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}
void loop() {
int buttonState = digitalRead(2);
Serial.println(buttonState);
delay(1);
}
「検証」と「ボードに書き込み」ボタンの列の右端の「シリアルモニタ」ボタン(虫眼鏡のアイコン)をクリックします。ここにSerial.println()
の括弧内の値が表示されるようになります。
プログラム解説編
Arduino IDEで作成するプログラムは大きくvoid setup()
とvoid loop()
の2つに分けることができます。setup()
に続く中括弧({}
)の中は一度だけ実行され、loop()
内のコードは繰り返し実行されます。
Serial.begin(9600);
はシリアル通信の際データの転送速度を9600で指定しています。これはシリアルモニタを使用するのに必要です。おまじない的なものと解釈してもらって大丈夫です(笑)
pinMode()
はどのピンを使ってどのようにデータを使うかを示しています。括弧内の一つ目にはピン番号を、二つ目にはINPUT
(データを取得する)もしくはOUTPUT
(データを送信する)を指定します。今回の場合、D側2番ピンからデータ(ボタンが押されたかどうか)を取得したいので、pinMode(2, INPUT);
となります。ちなみにD側2番ピンの場合2
、A側2番ピンの場合A2
と書きます。
以上がsetup()
になります。次はloop()
内を見ていきます。
digitalRead()
を使うと、括弧内で指定したピンの値を読み取ることができます。今回は2番ピンを読み取りたいのでdigitalRead(2)
ですね。この値をbuttonState
に入れておきます。
Serial.println()
は括弧内の値をシリアルモニタに映します。Serial.println(buttonState);
の場合、buttonState
、つまりボタンが押されているかどうかを0
または1
でシリアルモニタに表示します。
delay()
は括弧内の時間実行を遅らせます。時間の単位はミリ秒(1000分の1秒)です。delay(1);
をloop()
の最後に書くことによって、このプログラムを1ミリ秒ごとに実行するよう指定できます。
アナログ信号を取得する
次はアナログ信号(0から1023までの値)を取得して、シリアルモニタで表示させてみましょう!こちらも先程と同様、センサーをインプットデバイスとして使います。
使うパーツ:
- DFRduino UNO + I/O Sensor Expansion Shield v7.1
- Analog Rotation Sensor(以下回転センサー)
実行編
付属しているアナログ用(黒・赤・青)のコネクタで回転センサーとシールドのA側0番ピンをつなげます。
次に以下のプログラムをエディタにコピーします。
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(1);
}
作成したスケッチを検証後ボードに送信します。シリアルモニタを開いて回転センサーのツマミを回すと、0から1023の値が回転角度に合わせて表示されると思います。
プログラム解説編
前回はdigitalRead()
を使いましたが、今回はアナログの値を取得したいのでanalogRead()
を使います。括弧内にはピン番号を入れます。
記事がとんでもなく長くなってしまうので、既出のコードは解説しません。分からない方はお手数ですが上に戻って確認してください m(._.)m
LEDをチカチカさせる
LEDを周期的にチカチカ光らせてみます。今回はピンにつないだものから値を取得するのではなく、値をピンにつないだものに送信します。このようなモジュールをアウトプットデバイスと呼びます。
使うパーツ:
- DFRduino UNO + I/O Sensor Expansion Shield v7.1
- Digital Piranha LED-R(以下赤LED)
実行編
赤LEDをシールドのD側13番につなげてください。
プログラムは以下の通り。
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
}
検証→ボードに書き込みで、LEDが1秒周期でチカチカし始めます。
プログラム解説編
digitalWrite()
は、括弧内の一つ目に指定したピンにHIGH
もしくはLOW
の値を送ることができます。HIGH
は「1」、LOW
は「0」となります。
また、プログラム内で13番ピンの情報を何回か使うので、最初にint ledPin = 13;
と変数に入れておいてあげると、後々ピンの番号を変更したいときに便利です。
人感ライトを作る
ここの辺りから電子工作っぽい感じになりますよ!次はインプットデバイスとアウトプットデバイスを同時に使い、一つのモジュールから値を取得して、その値を別のモジュールに送るような仕組みを作ってみます!
使うパーツ:
- DFRduino UNO + I/O Sensor Expansion Shield v7.1
- PIR Sensor(以下人感センサー)→インプットデバイス
- Digital Piranha LED-R(以下赤LED)→アウトプットデバイス
実行編
人感センサーで動きを確認したら、赤LEDを点灯します。どちらもデジタルで良さそう(動いている・動いていない、点灯している・点灯していない、のそれぞれ2つの状態しかない)なので、人感センサーをD側2番ピンに、赤LEDをD側13番ピンにつなげます。
プログラムは以下の通り。
int sensorPin = 2;
int ledPin = 13;
int sensorState = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(sensorPin, INPUT);
}
void loop() {
sensorState = digitalRead(sensorPin);
if (sensorState == HIGH) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}
検証→ボードに書き込んでみましょう。人感センサーに向かって動いたり手を振ったりするとLEDが付くはずです。
プログラム解説編
今回は変数を3つ作りました。ピン番号などは変数で管理すると、可読性も上がりピンの変更などもしやすいのでオススメです。最後に宣言したsensorState
は、人感センサーで読み取った値が入ります。
digitalRead()
で読み取った値はHIGH
またはLOW
でかえってきます。なのでsensorState == HIGH
やsensorState == LOW
としてあげると、HIGH
のとき、LOW
のとき、と条件によって別々の挙動を指定することができます。
まとめると、digitalRead()
で人感センサーからの値によって、赤LEDにdigitalWrite()
でオンオフを指定しています。
音でLEDをつける
だんだん慣れてきましたか?今度は音センサーを使って、一定の音量を超えたらLEDが光る仕組みを作りましょう!
使うパーツ:
- DFRduino UNO + I/O Sensor Expansion Shield v7.1
- Analog Sound Sensor(以下音センサー)→インプットデバイス
- Digital Piranha LED-R(以下赤LED)→アウトプットデバイス
実行編
音センサーの基盤上に「A」と書かれているので、シールドのA側0番ピンに指します。赤LEDはいままで通りD側なので、D側13番に指します。
いままではD側何番、A側何番、と指定してきましたが、実はD側・A側さえ合っていれば基本何番でも大丈夫です。いくつものモジュールを近いピン番号にくっつけすぎるとごちゃごちゃするので、適当に間隔を空けて配線すると楽ですよ。
まずは以下のコードをエディタに入力してみてください。
int soundPin = A0;
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop(){
int soundState = analogRead(soundPin);
Serial.println(soundState);
}
このプログラムを検証して実行すると、音センサーが返したアナログの値がシリアルモニタに出てきます。今回は音が「ある一定以上の音量になった場合」LEDを光らせたいので、その「ある一定」を見つける必要があります。周りの環境によって返ってくる音量の値が変わるので、自分がこれ以上音が鳴ったら光らせたい!という値を見つけてください。
「ある一定」の数値が決まったらそれを反映させつつ以下のプログラムにします。先程まで使っていたコードは先頭に//
をつけることで無視することができます。
int soundPin = A0;
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
// Serial.begin(9600);
}
void loop(){
int soundState = analogRead(soundPin);
// Serial.println(soundState);
if (soundState > 「ある一定」の数値) {
digitalWrite(ledPin, HIGH);
delay(10000);
} else {
digitalWrite(ledPin, LOW);
}
}
もう一度検証→ボードに書き込むと、周りの音が一定ラインを超えるとLEDが光るようになります!
LEDをゆっくりと点灯させる
序盤にLEDを点灯させるのをすでにやりましたが、今度はゆっくりと点灯させます。勘の良い方は「LEDにアナログの値を書き込めないのではないか」と気づくと思います。ゆっくり点灯ということはおそらくanalogWrite()
を使うことは予想できますが、LEDはいままでdigitalWrite();
で値を送っていたのでできないのではないか、と。
そこでPWN(Pulse Width Modulation・パルス幅変調)を使います。ググってみると何やら難しい話が出てきますが、簡単に言うとデジタル信号で擬似的にアナログデータを送ることができます。
PWMに対応しているピンは、今回のシールド上ではD側のアスタリスク(*
)が付いている3番、5番、6番、9番、10番、11番です。
使うパーツ:
- DFRduino UNO + I/O Sensor Expansion Shield v7.1
- Digital Piranha LED-R(以下赤LED)→アウトプットデバイス
実行編
赤LEDをシールドのD側10番につなげます。PWM対応なのを確認してください。
プログラムは以下の通り。
int ledPin = 10;
void setup() {
pinMode(ledPin,OUTPUT);
}
void loop(){
for (int value = 0 ; value < 255; value++) {
analogWrite(ledPin, value);
delay(5); }
for (int value = 255; value >0; value--){
analogWrite(ledPin, value);
delay(5); }
}
検証→ボードに書き込みで、ゆっくりLEDがついて、ゆっくりLEDが消えるようになります。プログラム自体はシンプルなので、解説は割愛します。
お疲れ様でした!
ここまでかなり長い道のりでしたね!この記事を書くのにも結構時間かかりました(笑)
この記事を通して、インプットデバイスから値を取得して、アウトプットデバイスに値を渡す、という処理をできるようになりました。これさえできるようになれば、後は好きなモジュールを使って作りたいものを作るだけです!
この記事で学んだことだけでできるプロジェクトの一例として、流れている音楽の大きさを赤・青・緑のLEDで表すなんてのはどうでしょうか。音センサーから値を取ってきて、いくつ以上の値で緑LEDを光らせて、いくつ以上で青を、いくつ以上で赤を…… と指定すればできそうですね!PWMを使うことで、さらに細かく音の大きさが表わせそうです。
2017年2月23日開催の 今度こそ挫折しない!知識ゼロからの電子工作ハンズオンイベントに来てくださっている方で、チュートリアルを早く終わってしまった方もぜひやってみてください!
それではまた!お疲れ様でした!