マイクロビットを使ってみた(その5)
皆さんこんにちは!「マイクロビットを使ってみた」の5回目です。前回予告したとおりアナログ入力やPWM出力について説明します。今まで説明した範囲ではマイクロビット本体とPCが有ればほぼ試してみる事が出来ましたが、今回の実験を行うには外部にくっつける物がチョット必要です。
左の写真は実験で使う教育用玩具です。アナログ入力の実験を行うためのジョイスティック付きコントローラーと、PWM出力の実験を行うためのサーボモーターが付いた2輪式の自動車です。
今回は上に示したおもちゃを使ってアナログ入力とPWM出力について説明したいと思います。IoTシステムではセンサー情報を良く扱いますが、サーミスターのような温度センサーや電池電圧などのアナログ値を送る事も多いです。山間部や離島などで使われるシステムでは商用電源が無い為に太陽電池(や風力発電)+充電式バッテリー何てシステムも多いようです。このような場合は電池電圧のセンシングも重要です。残量に応じて動作モードを変更するとか、センターに警告を上げるとか。IoTシステムを構築する際は気にしなくてはならない事が結構有ります。こちらのページを参考になさってください。
それでは実験を始めましょう!
準備
今回のプログラムを使って実際に動かしてみるには1回目の記事で紹介したもの以外に以下のものが必要です。
・ジョイスティック 1台
アナログ入力の実験では上の写真のジョイスティックを使います。右側の写真はジョイスティックにマイクロビットを取り付けたところです。これはスイッチエデュケーション様で取り扱っている「micro:bit用ジョイスティック付きコントローラーキット」と言う物になります。RING2(P2)の端子を出力端子に設定し、これの”0″又は”1″で、左右の選択を行い、RING0(P0)とRING1(P1)でX方向、Y方向のアナログ値を読み込みます。レバーを上下左右に動かす事により0~3V(電源電圧)までの電圧がアナログ端子に出力されます。
・実験用自動車 1台
こちらもスイッチエデュケーション様で取り扱っているもので、「bitPak:Drive」と言う名前の付いている2輪式の自動車です。現在では在庫限りとなっている様ですが、似たようなものが幾つか有りますので興味の有る方は調べてみてください。
この自動車は普通のモーターの代わりに回転サーボモーターと言われるものを使って動かしています。これはPWM信号を受けると、その信号の幅に応じて回転速度や回転方向が決まるものです。左右のサーボモーターの速度や回転方向を制御して自由自在に走らせる事ができます。
・単四型乾電池 5本
ジョイスティックを動かすには単四型乾電池が2本必要です。また、自動車側には単四型乾電池が3本必要です。まあ、ジョイスティック側はPCと接続したままにしておけば電池を使わなくて済みますが。。。自動車側はサーボモーターを動かす都合上、絶対に乾電池が必要です!USBコネクタを挿しておいても動きません。念のため。
追加で必要な物は以上です。購入するとなると、それなりに費用がかかります。記事を読んでみて「動かしたい!」って思った方は購入されてみてはいかがでしょうか?上に紹介したものだけでなく、調べれば色々な実験キットも見つかると思います。それでは実験を始めましょう。
実験
1.アナログ入力を使う
ジョイスティックを使ってアナログ入力の動きを確認しましょう。以下のプログラムはジョイスティックの動きに応じてLEDの点灯位置を移動させるプログラムです。ここでは左側のジョイスティックを対象にしています。右側のジョイスティックの動きを確認したいときはプログラム中の”P2″の値を”0″から”1″に変更すれば動作を確認する事が出来ます。
マイクロビットのアナログ入力端子は、入力された電圧に応じて0~1023の値が出力されるようになっています。この値を読み取るには「アナログ値を読み取る」と言う部品を使い、読み取りたい端子を指定すればOKです。予め「変数を追加する」でXとYを変数として使えるようにしておいてください。
ではプログラムの説明を行います。プログラムが起動すると、お約束のハートマークを点けています。その後「ずっと」の枠内でぐるぐる回り続けます。
最初に左側のジョイスティックを選択するためにP2端子を”0″に設定します。これには「デジタルで出力する 端子」と言う部品を使います。出力する端子は右側の下向き矢印を押すと選択する事が出来ます。その後X軸の値をP0端子から読み取り、これをLEDの座標に収まる様、0~4の範囲にマップ(割り当て)します。同様にY軸の値もP1端子から読み込むのですが、LEDのY座標は上が0で下が4になっているのに対してジョイスティックは上が数字の大きい方(1023側)になっていますので、そのままマップするとLEDの動きが逆になってしまいます。そのために”4″からマップした数値を引き、ジョイスティックの動きとLEDの動きが同じになるようにしています。
さて、今のプログラムでは読み取ったアナログ電圧を5段階に分割(マップ)してLED上に表示させましたが、実際に読み取ったアナログ値は幾つになっているのか気になりませんか?以下のプログラムは1秒毎に読み取ったアナログ値をそのままUSB経由でターミナルソフトに表示させるプログラムです。ターミナルソフトの設定は三回目の記事に出ています。(COMポートの番号はお使いの環境に合わせてください)
左図が実際に動かした結果です。モノには必ずバラつきが有りますので、お使いの物と同じ結果が出るとは限りませんが、手持ちのジョイスティックでは、X軸は0とか1023には達しませんでした。最小/最大値は3/1022でした。Y軸の最大値は1023になりましたが、最小値はやはり0にはならず3でした。
実用的なプログラムを作るときにはバラつきも考慮して、0で動くとか、1023になったら動くと言ったようなプログラムは作らないようにする事ですね。そうしないと、たまたま手元に有ったセットで動いても別のセットでは動かなくなる可能性が高いです。モノ作りは常にバラつきとの戦いです。
さて、アナログ入力の使い方は大体分かったと思います。では、両方のジョイスティックの値を読み込みたいときはどうすれば良いでしょうか?先のプログラムでP2の値を変えれば右と左を変更する事が出来ると言いましたが、具体的にはどうするのでしょうか?X、Yの値をそれぞれ一つの端子で読み込むため厳密には左右同時に読み込む事は出来ませんが、殆ど気にならない時間で交互に数値を読み込む事により”ほぼ”同時に左右の値を読み込むことができます。以下にプログラムを示します。このプログラムでは500mS毎に値を読み込んでターミナルソフトに表示しています。(先ほどのプログラムを動かした結果、1秒毎だとチョット遅い気がして。。。)
上のプログラムは左右のジョイスティックの値をほぼ同時に読み込み、ターミナルソフト上に表示するプログラムです。以下に動作結果を示します。
右図が上のプログラムを動かした結果です。値によって桁数が変わるので少し見にくいですがご容赦ください。
プログラムとしては、まず左側のジョイスティックの値を読み込むためにP2端子を”0″に設定し、端子状態が安定するまでチョットだけ(10mS)待ち、それからP0(X)とP1(Y)を読み込みつつ、ターミナルソフトに表示を行い、その後右側のジョイスティックの値を読むためにP2端子を”1″に設定し直してから左側と同じ作業を行っています。このようにして、左右のジョイスティックが同時に使えている様に見せることができます。
さっきの実験結果は読み取った数値の桁数が変わると列がズレてしまって読み辛かったですね。本筋からはチョット脱線しますが列を合わせる方法(一例です。他にも良いやり方があるかも知れません。)を紹介します。今回読み取る数値は0~1023です。つまり最大で4桁ですので、これより桁数が少ない場合は” “(スペース)で埋めれば良いのです。以下に左側のジョイスティックだけを読み取った時のプログラムに桁を整列させる機能を追加したものを示します。
このプログラムを使うときはXとY及びLENと言う名前で変数を三つを追加しておいてください。XとYには取得したアナログ値が入っています。LENには取得したX又はYが何桁の数字かを入れます。(正確にはXやYと言う数字を一旦文字列に変換する部品を使って文字列にしてからその長さを調べる部品を使っています。数字が何桁かを調べる部品は無さそうですが、文字列が何文字かを調べる部品が有ったので、予め数字を文字列に変換してから使いました。目的そのものの部品は無くても、部品を組み合わせれば希望する機能を実現する事が出来ます。)
このプログラムを実行した結果を以下に示します。
取得したアナログ値の桁数に関わらず、列が一致しているので非常に読みやすくなっていますね。同じような考え方で作れば左右のジョイスティックの値を取得した場合にも使えます。
先に説明したスペースで埋める部分は緑の「もし ~ ならくりかえし」の部品を使っています。最初に数字の桁数を”LEN”と言う変数に入れ、LENが4を超えるまでスペースをターミナルソフト上に足して行きます。スペースを出力する度にLENにも”1″を足して行きますので、LENが4を超えればスペースを足すのを止め、その後ろに取得したアナログ値を出力します。この様にして桁を合わせているのでターミナルソフト上の出力結果が見やすくなっています。
以上でアナログ入力の使い方の説明を終わります。ジョイスティックと組み合わせることにより、ボタンでのオン/オフ動作と違ってきめ細かい調節が必要な動作もさせる事が出来るようになりましたね。
2.PWM出力について
PWM出力の説明は、サーボモーターの説明と並行して行います。PWMとは”Pulse Width Modulation”の略語で、日本語では「パルス幅変調」と呼ばれます。一定周期の中で”1″の時間幅(パルス幅)を変化させると平均化した場合、直流電圧に変換できますので直流出力の手段として使われたり、今回のサーボモーターの様に受信側(=サーボモーター)でパルス幅に応じて動作を決めたりする用途に使われます。
そのサーボモーターですがパルス幅に応じて角度が決定される一般的なサーボモーターと、今回の実験で用いる連続回転サーボモーターと言われるものが有りますのでそれぞれについて説明します。
(1)一般的なサーボモーター
左の写真はSG90と言う型式のサーボモーターです。ホビー用途などに良く使われています。お馴染みの秋月電子様でも取り扱っています。(SG90の商品紹介ページ)
このサーボモーターはPWM信号のパルス幅に応じてアームの角度が決まるようになっています。SG90の仕様書を見ると
電源電圧 | 3.3V~6V |
PWM周期 | 20mS |
可動範囲 | ±90° |
パルス幅(0°) | 1.45mS |
パルス幅(-90°) | 0.5mS |
パルス幅(90°) | 2.4mS |
と、なっています。実際にサーボモーターを動かすには制御用のPWM信号を送ってあげる他にモーターを動かす為の電源も供給してあげないといけませんので、チョット面倒です。実験するためにこのような回路をつくりました。詳細はコチラ→サーボモーター駆動回路
注:この実験に使うサーボモーターの回転角は±90°ですが、ラジコンに使われるようなサーボモーターでは±60°の回転角だったりするものもあるようです。その様なサーボモーターに±90°の指示を与えると無理にそこまで移動しようとしてサーボモーターに過負荷がかかり、破壊する事もある様です。実験の際は仕様を良く確認してください。
マイクロビットでサーボモーターを動かすには「サーボモーター」のリストの中にある部品を使います。が、新規にプロジェクトを作った時には「サーボモーター」のリストは無いと思います。Bluetoothの部品を使える様にした時と同様に、「高度なブロック」をクリックして出てくる「拡張機能」を押し、”servo”を検索窓に入れて部品を探してください。見つかった”servo”を追加すればプロジェクトの中でサーボモーターを動かす為の色々な部品が使える様になります。
左図がサーボモーターのリストをクリックした時に出てくる部品の一覧です。通常の回転角を決めるサーボモーターを動かすには「servo (端子) 角度( ) °」の部品を使い、任意の数値を入れたり、変数を入れたりして制御します。
この角度指定の機能を使ってサーボモーターSG90を動かしてみました。テスト用のプログラムを以下に示します。
このプログラムでは、最初に角度を90°に指定し、その後Aボタンを押すと5°ずつ角度が増え、Bボタンを押すと5°ずつ角度が減ります。また、その時の角度をUSB経由でターミナルソフトに表示しますので、ボタンを押した回数を数えてなくても大丈夫です。このプログラムを使って代表的な角度を設定した時のPWM波形とサーボモーターの回転位置を観測したものを以下に示します。
(注:サーボモーターの仕様書には可動範囲が-90°~+90°となっていますが、マイクロビットの部品では範囲指定が0°~180°となっています。)
この結果を見ると、周期は20mSでSG90の仕様と合っています。マイクロビットの部品の中には周期を決める為の部品が有りませんでしたので、”servo”出力を選んだ段階で周期は20mSに決められているのでしょうね。さて、肝心のパルスの幅ですが、上のオシロの画面ではパルス幅に対して時間軸が長すぎて正確には観測出来ていないようです。別途詳細に観測した結果では、0°指定時には0.504mS、90°指定時は1.51mS、180°指定時は2.52mSでした。SG90の仕様とはチョットだけ異なるようですが、見た目では指定の角度どおりにサーボモーターが動いている様に見えました。通常のサーボモーターで角度指定をしたいときはこの部品を使えばOKですね。
(2)連続回転サーボモーター
右の写真が今回の実験で使う連続回転サーボモーターです。Feetech社のFS90Rと言う型式のものです。右の写真は今回の実験で使う「bitPak:Drive」の車輪の部分を抜き出して撮ったものですが、サーボモーター単品は秋月電子様でも扱っていました。(360°連続回転サーボ(ローテーションサーボ) FS90Rの商品紹介ページ)
さて、この連続回転サーボモーターは先の一般的なサーボモーターと違い、パルス幅に応じて回転方向や回転速度が決まる様になっています。マイクロビットの部品の中に「servo (端子) 回転速度( )%」と言う部品があり、これを使うと速度と回転方向の制御が出来ます。
連続回転サーボモーターの速度指定範囲は左図の様に-100%~(+)100%の範囲となっています。一般的なサーボモーターと同様に、速度指定は数値でも変数でもOKです。
先ほどの一般的なサーボモーターと同様に、テストプログラムを作って指定した速度とPWM波形の関係を調べてみました。使ったプログラムは以下のとおりです。
このプログラムでは最初に停止状態(速度0%)にしておき、Aボタンを押すと速度を+10%、Bボタンを押すと-10%となるように作りました。以下に指定速度とPWM波形の関係を示します。
このサーボモーターは速度指定を変更しても回転しているか止まっているかの違いだけなので写真は載せていません。(スチル写真では全部止まって見えるだけですので。)0%で停止、マイナス方向で上から見て時計方向に回転、パルス幅が狭いほど早く回転し、プラス方向を設定すると反時計方向に回転してパルス幅が広いほど速く回転しました。
観測したPWM波形を見ると、先ほどの一般的なサーボモーターの時に観測した波形と同じ波形でした。0~180°の角度指定と-100%~(+)100%の速度指定は単に数字を置き換えているだけで有る事が判ります。「サーボモーター」の部品の中には”パルス幅の設定”と言う部品も有りますので、角度やスピードで設定する以外にもPWMのパルス幅を指定して制御する事もできます。
(3)周期を変える裏ワザ
チョット大袈裟に書いていますが、表からちゃんと見えてます。表現がPWMになっていないだけです。先ほど説明した様に”servo”の部品を選んだ段階で周期は20mSになってしまい変更する手段は無いようです。ホビー用として一般的に売っているサーボモーターは大体周期が20mSなのでこれでも大丈夫ですが、何か特殊な部品が有り周期が10mSじゃないとダメですなんて場合が有ったらどうしましょう。こんな時は以下の様な手を使えば大丈夫です。
左のプログラム(って言うほどでは有りませんが。)は周期を10mSに設定し、パルス幅を大体5mSにした例です。PWMの説明の冒頭に平均化して直流出力に使う例を挙げましたが、このプログラムはそれを応用しています。
アナログで出力する時は”0″を設定すると0Vに、”1023″を設定すると3V(電源電圧)になります。丁度中間の512に設定すれば1.5Vの電圧が出る仕組みです。(但し、ローパスフィルターを使って平均化すればの話ですが。)
上の波形がプログラムの実行結果です。見て判るように、「アナログで出力する」と言う部品を使っても、純粋にアナログ電圧が出てくる訳ではありません。”平均化すれば”アナログ電圧になるだけで、端子からはPWM波形が出ているだけです。ですから、周期が20mS以外の部品が有った場合はパルス幅の計算がチョット面倒にはなりますが、この部品を使って任意の周期のPWM波形を作る事が出来ます。一つ注意ですが、「アナログ出力 パルス周期を設定する」の部品は先に「アナログで出力する」の部品を置いておかないと有効にならないようです。実験に使ったプログラムは二行しか有りませんが逆にすると周期が20mSになってしまいます。
周期を設定する部品にマウスを合わせると左の様な注意書きが出て来て、周期を設定する対象ピンがアナログ出力になっていないとこの操作は無効になると出てきます。よって順番が重要なようです。(個人的には周期を設定してから出力させたいですが、仕様なので仕方ないですね。)
以上でPWM出力とサーボモーターの使い方の説明を終わります。
3.自動車を組み立てて動かそう
今までの説明でアナログ入力の使い方、PWM出力の使い方とサーボモーターの動かし方が分かったと思いますので自動車を組み立てて動かしましょう。ジョイスティック側からは自動車の左右のサーボモーターに対して前進/後進及び速度を無線で送り、自動車側は無線で受信した速度データをサーボモーターに伝えます。自動車の組み立て方はメーカーさんのサイトの真ん中辺りに動画がありますので、そちらを参考にして組み立ててください。ここではプログラムの事について説明します。
(1)ジョイスティック側
ジョイスティック側のプログラムは以下の仕様で作ります。
- 左右のジョイスティックを使い、左輪/右輪それぞれの速度を無線で送る。
- 速度の範囲と操作の関係は、手を離した状態で中立(速度ゼロ)、向こう側一杯に押すと前進一杯となり、速度+100、手前一杯に引くと後進一杯で速度-100となる。(無線で送る数字の範囲は-100~+100の整数値)
- 左右のジョイスティックの状態をLEDに表示する。表示方法は以下のとおり。
- 左側はX座標”0″の列に、右側はX座標”4″の列に表示する。
- Y座標は中立状態で”2″、前進一杯で”0″、後進一杯で”4″とする。(-100~+100を座標の0~4にマップする。)
- 状態の更新は100mS間隔とする。(ジョイスティックの読み込みと無線送信)
- (お約束で)プログラムが起動するとハートマークが500mSだけ点灯する。(起動確認)
左右のジョイスティックを使いますので、上の方の説明に有りますようにP2を切り替えながら使う事になります。また、二つの情報を無線で送りますので四回目の記事で説明した複数の数字を無線で送る方法を使います。LEDの点灯方法は二回目の記事で説明していますし、四回目の記事では数値をマップして希望する範囲に収まるようにする方法も説明しています。ここまで来ると、殆どの要素が説明済みであるので後はそれらを組み合わせるだけですね。この様にして作ったプログラムが以下のものです。
ここまで記事を読んでこられた方には特に説明は要らないかと思います。みんな今まで使ってきた部品ばかりです。あえて一点注意するなら、LEDの座標です。前進一杯で”L”又は”R”の値は+100になりますがLEDの座標は手前側が”4″となりますので、マップした数値をそのまま使うと操作とLEDの表示が逆さまになってしまいますので”4″から引く形になっています。これも「アナログ入力を使う」の中で説明しています。ジョイスティック側のプログラムは以上です。
(2)自動車側
自動車側のプログラムには以下の様な動作が要求されます。
- 無線で受信した”L”、”R”それぞれの速度に応じて左右の連続回転サーボモーターの回転方向と速度を調節する。
- マイクロビット上のLEDに受信した速度情報をジョイスティック側と同様な方法で表示する。(但し、表示方向に注意)
- (お約束で)プログラムが起動するとハートマークが500mSだけ点灯する。(起動確認)
基本的にやる事は上記ぐらいです。これを基に作り上げたプログラムを以下に示します。大した分量では無いですね。
左の写真が実験に使う自動車ですが、前後を写真の様に決めました。(三輪車のイメージです。)この向きで使うと、マイクロビットのLED表示は左側がX=4、右側がX=0になります。また、Y方向も速度+100でY=4、速度-100でY=0になりますので注意が必要です。また、回転サーボモーターの制御ですが、車体にサーボモーターを取り付ける際に片側はひっくり返して取り付けますので回転方向も逆転させる必要があります。(両方同じ方向に回すと、その場でぐるぐる回ってしまいます。)プログラムはこの辺の事を考慮して作ってあります。
無事に動きましたでしょうか?メーカーさんのサイトにも参考プログラムが出ていますが、こちらはジョイスティックを使った物ではなく、マイクロビット本体のA/Bボタンを使って操縦したものになっていますので操作が限定されています。(前進/後進/右/左のみで速度制御は出来ません)アナログジョイスティックならではの速度制御を試していただきたいと思います。
さて、今回でマイクロビットの実験は終了です。マイクロビットの回ではプログラムに使う部品の紹介に加え、どの様に部品を繋ぎ合わせたら希望する動作をさせる事が出来るのかも紹介してきました。一つ一つの部品は大した機能を持っていなくても、それらを組み合わせて行けば色々な事が出来るようになります。また、重要なのは思い通りの動作をさせるにはどの部品とどの部品をどういう風に組み合わせれば良いかに気付く事です。複雑な動作を単純な動作の組み合わせに置き換えて行きましょう。最初は中々気付くのが難しいかも知れませんが色々な機能を作って行くうちに似たような例が出てきますので段々楽になってきます。色々作って遊んで自分の中の引き出しを増やして行きましょう。
無線モジュール.comでは無線モジュールを利用した様々な提案・開発を行っております。こちらのページには無線化の際のヒントを載せています。
開発実績はこちらに掲載してあります。是非ご覧になってください。