昨今では、文科省のGIGAスクール構想により、小学生から一人1台PCの導入が進められています。PCと言えば昔はWindows一色でしたが、価格やセキュリティなどを理由に、iPadやChromebook等、従来のWindows以外のプラットフォームを搭載した端末が学校で利用される機会が増えていると聞きます。
特にChromebookはWindowsPCと比べてかなり安いようで、学校のみならず家庭の子供向けPCとして浸透しているようです。そんな時流にVstoneも乗るべく、Windows以外の様々な環境で使えるプログラミング教材を作ってみることにしました。
開発とは言っても、今回はパッケージ製品として世に出すのではなく、一般流通している汎用部品で構成し、ソフトウェアも含めてオープンソース的に無償提供することにしました。
今回の教材では、今どきのナウい教材を目指すため、具体的に以下の目標を立てました。
- scratch風のブロックプログラミング形式
- 専用のアプリを使わず、ブラウザベースで気軽に利用できる
- Windows以外の幅広いプラットフォームに対応(特にChromebook)
これらは、最近発売された教材で良く見られる仕様ですね。ただ、調べたところでは全てを備えている教材は中々無く、あったとしてもかなり高額商品のようです。一部商品では、マルチプラットフォームを謳っているものの、linuxのシェルを直接操作させたり、裏で別のソフトを実行させるといった若干煩わしいものもあるようです。今回はそういった煩わしさも排除し、1ブラウザまたは1アプリで使える教材を目指します。
本記事では、技術的な詳細説明はさておき、まずは誰でも簡単にハードウェアを準備できてアプリを利用できる手順について解説します。技術的な詳細は、今後補足記事として力の続く限り説明していく予定です(あまり期待はしないで下さい)。
マイコンの選定
何はともあれ、まずはハードウェアの準備です。そもそも、メインとなるマイコンを決めないと始まりません。自作ハードウェアのマイコンと言えば、今真っ先に思いつくものはArduinoです。しかし、ブラウザから通信処理が可能なArduinoは存在するのでしょうか?丁度、近頃「webUSB」と呼ばれるChromeブラウザでUSB端末と通信するための機能が出始めており、Arduinoでもこれを使えないか調査したところ、webUSB用のライブラリが公開されているのを見つけました。
https://qiita.com/n0bisuke/items/b5a90ead155097dce484
すべてのArduinoマイコンで使えるわけではなく、いわゆるATmega32U4を搭載していてUSB-HID化できるArduino向けのライブラリのようです。代表格はArduino Leonardですね。
これでもいいですが、もっと入手性や値段でベストな物は無いか…と探したところ、より小型で安価な「Pro Micro 5V/16MHz」と言うものを見つけました。Arduino Leonardとほぼ互換があり、更に小型で1000円ほど安いと、非常に良さそうな商品です。
早速Pro Microを取り寄せ、前述のArduino用webUSBライブラリの解説ページにあるプログラムを書き込んでChromebookで動かしたところ、すんなりと通信成功できました。とても素敵ですね。ただし、webUSBの技術はプラットフォームによって非常に制約の差が激しく、Chromebook/Mac/Linux/Androidでは緩い制約ですんなり動く反面、Windows/iOSでは制約が厳しく、気軽に動かせないようです(iOSに至ってはそもそもUSB全般が絶望的)。この辺は力業で何とかできそうなので何とかしていきます。
ちなみにwebUSB以外の通信手段としては、「WiFiやBLE(bluetooth low energy)等の通信機能を使った方法」及び「光信号や音声信号などを使ったアナログ的な方法」が考えられます。前者は搭載コストや通信設定などの難易度・通信の安定性等で若干の懸念があり、後者も双方向通信が困難などの理由により、今回は不採用となりました。
また、USBを採用する利点として、USBバスパワーによる電源供給が可能なところがあります。電池ボックス等が必要無く動かせるので、ハードウェアの準備が楽になります。
と言うわけで、使用するマイコンはPro Micro 5V/16MHzに決まりました。
入出力の選定
次に、センサやLED等の入出力デバイスについて検討していきます。これを決めるためには、そもそものロボットの形・役割から考える必要がありそうですね。
世の中のロボット教材は、多くが1.ロボットカータイプ、2.音やLEDを制御するタイプのどちらかに当てはまると思います。Vstone製教材で言えば、前者は「ビュートレーサー/ローバー」後者は「計測制御プログラマ」が当てはまりますね。
ロボットカータイプだと、回路以外に車部分のメカニカルな設計まで行う必要があり、開発の規模や難易度が上がってしまいます。今回は後者の、音やLEDを制御するタイプの教材で行きましょう。
もっとも、汎用的な拡張が容易なArduinoで設計するので、色々頑張ればロボットカータイプの制作も不可能ではないでしょう(モータドライバ基板や外部電源が別途必要になります)。
音やLEDを制御するタイプの教材と言うことで、LEDとブザーは必須ですね。LEDも一つだけだとつまらないので、明るさの指定が可能なものを二つ使うことにします。ブザーも音階を指定してメロディーを奏でられるようにします。
更に、市販されているこのタイプの教材には、実生活で役立つ要素を売りにしている教材が多いようです(時計とか)。今回の教材もそれにあやかって、何か実生活に役立ちそうな機能を入れて見ましょう。何かぴったりくるセンサは無いかな…と探してみたところ、I2C通信デバイスで温度・湿度・気圧を計測できるセンサを見つけたので、これを搭載してみようと思います。
余談ですが、最初は今話題の「心拍」「血中酸素濃度」を測れるセンサを見つけたので、「これだ!」と思って入手してみたものの、残念ながらPro Microではどうもうまく動きませんでした(M5Stackでは問題無く動作。I2Cなら何でも動かせるという認識が甘かった?)。もしPro Microでうまく動かす方法が公開されたら、ぜひチャレンジしてみてください。
あとは、プログラム実行+αの用途で、ボタンを1個搭載したいと思います。まとめると以下のインターフェースを搭載します。
- LED(明るさ設定可能) ×2
- ブザー(音階指定可能) ×1
- ボタン(プログラム開始用) ×1
- 温度・湿度・気圧センサ ×1
これで教材の仕様が固まりました。次は必要な部品を洗い出してみましょう。
部品類の準備
考えた仕様を満たすために、具体的に必要となる部品類をリストアップします。部品の購入先ですが、マイコンやセンサなどの主要な部品は既に紹介しているのでそちらをご参照ください。多くの部品はswitch scienceのオンラインショップでまとめて入手可能かと思います。もちろん、センサ・マイコン含めてswitch science以外でも流通していると思うので、安いショップを探して購入するのもありです。
- Pro Micro 5V/16MHz ×1
- BME280搭載 温湿度・気圧センサモジュール ×1
- 圧電ブザー ×1
- ボタン ×1
- LED ×2
- 10kΩカーボン抵抗 ×1
- 510Ωカーボン抵抗 ×2
- ブレッドボード ×1
- ジャンパワイヤー 適量(20~30本程度)
- ピンヘッダ(20×1列) 適量(2~3個)
カーボン抵抗は、LED及びボタンのプルアップ抵抗として使用します。今回、社内ですぐに確保できた部品を多数流用しており、圧電ブザーやボタンは基板実装用の物を半ば無理やり組み込んでいますが、小型の物であればおそらく入手しやすい部品で代用可能です。
ブレッドボードまで含めて全て新規購入しても、合計5,000円程度(送料別)で購入できると思います。
ちなみに、マイコンにはPro Micro 5V/16MHzの代わりにArduino Leonardを使用しても問題ありませんが、出力ポートのピン配置が若干異なるようなので、この次に説明する回路図のポートは適時仕様を調べて置き換えてください。
回路図と結線
ハードウェアの仕様が固まったので、次に回路図を考えてその通りに配線をつないでみたいと思います。見づらいところも多々ありますが、以下が今回のブレッドボード上に配置した場合の配線です。
Pro Microのピン配置などのハードウェア仕様は、switch scienceの販売ページなどで資料へのリンクがあります。ただ英語表記で技術的に詳細な(難しい)内容になっているので、概要を調べる場合は別途web検索しても良いかと思います。下記webページなどがピン配置情報の概要としてまとまっています。
https://blogger.for-next.info/2020/09/arduino-pro-micro.html
多くの部品はPro Microのポートにほぼそのまま接続するだけでOKですが、LEDには間に抵抗が入り、またボタンも押していない時の入力を安定させるためにプルアップ抵抗をつなげます。LEDには極性(+/-の向き)があるので注意してください。
Pro MicroとBME280には、ピンヘッダをはんだ付けする必要があります。はんだ付けしたらブレッドボードに直挿しします。上記の図では、配線をつなげるポートのみ、基板上のシルク印刷と同じ文字を表記したので参考にしてください。
BME280はGND以外の配線は、VcoreにVcc、SCKにSCL、SDIにSDAを接続します。またI2Cバスアドレスを0x76に設定するため、SDOにGNDを接続します。
配線をつなぎ終えた物がこちらになります。
ちなみに、今回はとりあえずセンサをBME280だけにしていますが、Pro Microにはいわゆるアナログ入力ポートも備わっており、今回はPro MicroのA0~A3をアナログ入力ポートとして使えるようにしています。
市販のアナログセンサ(5V対応品)を買ってきて、Vcc・GNDをつなぎ、信号出力をA0~A3のどれかにつないで使うことが可能です。なお、センサの種類によって、間に抵抗などが別途必要な場合もあるので注意してください。
動かす
さあ、ハードの準備ができたのでいよいよ動かしてみましょう!本教材の各種ソフトウェアはgithubなどでソースを公開したり、サーバ上で動くものは弊社サーバにアップロードしています。これらを用いて、教材の動かし方をザっと駆け足で解説していきます。
本体にファームを書き込む
まずは本体にファームを書き込みます。ファームは、Arduinoの開発環境上でソースをビルドして書き込むため、対応したPCが必要になります。対応PCは、Windows/Mac/Linuxは無償で利用でき導入も簡単なようですが、Chromebookは開発環境の導入が若干複雑で、また利用に費用が掛かる場合があるようです。
https://chromebook.nomad-life.net/1916777/【メモ】chromebookにarduinoをインストール
もしChromebookユーザであっても、環境が揃うならここだけはChromebook以外で作業する方が良さそうです(もっとも、もしかしたら今後ChromebookでもArduinoの開発が容易になるかもしれません)。
本記事では、WindowsPCでの手順を説明します。
Arduino IDEは下記のURLより入手可能です。公式のページは英語ですが、これがわかりにくい場合は、web検索で「Arduino IDE」と入力すると、日本語でのインストール方法の解説ページがたくさん見つかりますね。
https://www.arduino.cc/en/software
ファームウェアのソースはgithub上で配布しているので、下記URLよりソースをコピーするかプロジェクトをクローンします。
https://github.com/vstoneofficial/webusb_programland/
gitの使い方が良くわからなければ、とりあえずソースをzipでダウンロードするのが簡単です。
ソースをダウンロードしたら、その中の「webusb_leonard.ino」をArduino IDEで開いてください。
ボードの種類とシリアルポートの設定
次に、ボードの種類とシリアルポートを設定します。ボードの種類はArduino IDEのメニューから「ツール」→「ボード」の項目を開き、リストアップされた中から「Arduino Leonard」を選択します。
次にシリアルポート番号を設定します。教材本体をPCに接続して正しく認識されると、「ツール」→「シリアルポート」で「COM??(Arduino Leonard)」というポートが出て来るので、それを選択します。
ライブラリのインストール
必要なライブラリをインストールします。今回必要なのはwebUSBとMIDI USBです。MIDI USBは以下の記事で導入方法を紹介しているのでご参照ください。基本的には、メニューから「ツール」→「ライブラリを管理」を開いて、「検索をフィルタ」に「MIDIUSB」と入力して見つかるライブラリをインストールするだけです。
webUSBは、以下のURLからプロジェクトをダウンロードorクローンして、librariesフォルダ内にあるWebUSBフォルダを、PC内のArduino/librariesフォルダに丸ごとコピーします。
https://github.com/kimio-kosaka/webUSB-arduino
ビルドと書き込み
ビルドする前に、まずプログラミングアプリの動作環境がiOSか否かによってソースを書き換えます。ソース冒頭の2行目は、動作環境がiOSが否かを選択するものです。
//下記をコメントアウトするとiOS以外、コメントアウトを外すとiOS専用ファームに切り替え(要再ビルド) //#define IOS #ifdef IOS
iOSの場合はこの行のコメントアウトを外して「#define IOS」にします。iOS以外の場合は、コメントアウトして「//#define IOS」にします。ソースを書き換えたら、ビルド・書き込みをしてください。
書き込めたら教材本体側の準備は完了です。
実行アプリorURLを開いて通信を開始する
次に、プログラミングするPC・タブレット側の準備をします。こちらも、何のPC・タブレットを使うかによって若干手順や必要な機材が異なりますので、個別に説明します。なお、いずれの環境でもインターネット環境が必要となりますので、必ずオンライン状態で実行してください。
Windows(10以降)の場合
いきなり冒頭の「ブラウザでもできる」を否定する形になりますが、WindowsではwebUSBによる通信処理が困難なため、専用アプリで動かします。また、そのアプリ内でブラウザの機能を使うため、関連するランタイムのインストールが必要となります。まずは、下記URLにアクセスし、「エバーグリーン ブートストラップ」の「ダウンロード」をクリックしてください。(もしかしたら今後のOSのアップデートで、このライブラリが標準で組み込まれてインストール不要になるかもしれません)。
https://developer.microsoft.com/ja-jp/microsoft-edge/webview2/
インストーラをダウンロードしたら実行して必要なライブラリをインストールしてください。
続いて下記URLよりアプリをダウンロードしてください。ダウンロードしたらzipファイルを展開して、arduinowebusb_wpf.exeを実行してください。
https://www.vstone.co.jp/webusb/programland/download/programland_webusb_win_release2.zip
実行したら、PCと教材本体を接続して、画面上の「接続」をクリックしてください。
接続後、下図のようにセンサ・気温・湿度に数値が表示されたら接続成功です。続いて画面操作概要にお進みください。
2021.11.10追記
一部のPCでは、COMポートの名称が「Arduino Leonard」ではないために通信ができない問題が発生するため、修正版を公開しました(programland_webusb_win_release2)。
この修正版をダウンロードした上で、arduinowebusb_wpf.exeと同じフォルダにあるsettings.iniをテキストエディタで開いて、「Arduino Leonard」の文字列を、PCが認識しているCOMポートの名称に書き換えると通信できます。
この問題はArduino Leonardが正常にPCに認識されていない場合に起こるのか、筆者の環境ではPCのデバイス概要ではArduino Leonardに「!」マークがついていますが、Arduino IDEやアプリからは問題なく通信ができています。筆者のPCでは、下図のように「USB シリアル デバイス」という名称で認識されており、setting.iniをこれに書き換えると通信できました(USB・シリアル・デバイスの各単語の間に半角スペースが入ります)。
なんとなく、Arduino Leonardを正常に認識させることで解決できそうな気もしますが、Arduino Leonardのドライバ回りの配布データがすぐに見つからず、わかりませんでした(そもそもちゃんとCOMポートとして使えているのが余計気になりますが…)
iOS(iPhone/iPad)の場合
iOSもWindows同様、ブラウザ上のwebUSBでの通信が困難なため、以下で公開しているアプリをインストールしてください。
https://itunes.apple.com/jp/app/id1582972741?mt=8
次に、教材と接続します。接続には別途Lightning USB カメラ アダプタケーブルが必要です。ネットショップ/iPhone売り場等で1000円程度から販売しているようです。
なお、iOS版の注意として、必ずアプリを起動する前に本体と接続してください。接続したら、インストールしたアプリを起動し、表示された画面内の「接続」をタップしてください。
接続後、下図のようにセンサ・気温・湿度に数値が表示されたら接続成功です。続いて画面操作概要にお進みください。
教材接続前にアプリを先に起動してしまった場合は、接続してもセンサ値が「undefined」と表示され、正しく接続できていません。この場合、教材は接続したまま、一度アプリを完全に終了させてからもう一度アプリを実行してください。
上記以外の環境(Chromebook、Android、Mac、Linux)
Chromebook、Android、mac、linuxをお使いの場合は、ChromeブラウザでアプリのURLを開くだけで使えるようになります。Chrome以外のブラウザでは動作保証していないため、必ず最新のChromeブラウザを使用してください。アプリのURLは下記になります。
https://www.vstone.co.jp/webusb/programland/
URLを開いたら、教材本体を接続して画面上の「接続」をクリックしてください。
クリックすると下図のようなウィンドウが表示されます。「Arduino Leonard」を選択して「接続」をクリックしてください。
接続後、下図のようにセンサ・気温・湿度に数値が表示されたら接続成功です。続いて画面操作概要にお進みください。
なお、Androidタブレット等、いわゆるPCじゃない端末を使っている場合は、USB-OTGケーブルを使って接続しないと認識しない可能性があります。USB-OTGケーブルはPCショップや家電量販店の他、100均などでも売っているので各自調達してください。
画面操作概要
画面はプログラムランドと同様、上に保存や実行のためのインターフェースが、その下にブロックを選択して配置していくエリアがそれぞれ存在します。
操作用ボタン・インターフェース
画面の一番上に並んだボタンはそれぞれ下記の機能を持ちます。
- 新規 / 保存 / 読み込み…ファイルの読み書きやプログラムの新規作成
- 取り消す / やり直し…UNDO及びREDO
- 接続 / 切断…通信の開始・終了
- 実行…現在作成中のプログラムを書き込んで実行
- 書き込み…現在作成中のプログラムを書き込み
- メモリマップ…メモリマップウィンドウを表示/非表示
ボタンの下にある項目は、それぞれ下記の機能を持ちます。
- センサ値…通信中に本体から読み取ったセンサ値を表示
- プログラム転送率…プログラム書き込み時の進捗を表示
- ツールボックスの選択…ブロックの種類を初級者(簡易版)・上級者(詳細版)から選択
- 通信速度…本体との通信速度を指定。通信が安定しない場合は数値を増やして通信速度を遅くしてください
- 関連情報…ファームや関連アプリ等必要な情報へのリンク
ブロックの種類
プログラミングの方法は、プログラムランドとほぼ共通しています。ブロックの配置エリアの真上にあるツールボックスより追加するブロックを選択し、「はじめ」のブロックから命令を実行する順番通りにブロックを接続します。プログラムを作成したら、本体と通信を開始して「実行」や「書き込み」をクリックして転送します(いずれも本体に記録されたプログラムが上書きされます)。前者の場合、プログラムの実行に合わせて、画面内の現在実行されているブロックが縁取り状態で表示されます。
ツールボックスの選択で、デフォルト設定の「初心者」で使えるブロックの概要は下記の通りです。
- ライト…LEDのON/OFFを選択。時間のブロックと組み合わせると、指定の時間だけ光らせることが可能
- ブザー…ブザーから音を鳴らす。オクターブ・音階・長さ・鳴り終えるまで待つか、をそれぞれ設定する。長さは1=全音符、2=2分音符の換算で、.5がつく数字は付点音符を表す
- つづける…現在の状態を維持したまま、指定の時間だけ待つ
- くり返し…囲ったブロックを指定の条件で繰り返す
- はい/いいえ…指定の条件で命令を分岐する
- おわり…プログラムを終了する
ツールボックスの選択の「上級者」で使えるブロックの概要は下記の通りです。
- ライト…LEDの明るさを指定(0~100%)。時間のブロックと組み合わせると、指定の時間だけ光らせることが可能
- ブザー…初心者向けと同一。ブザーから音を鳴らす
- つづける…初心者向けと同一。現在の状態を維持したまま、指定の時間だけ待つ
- 変数演算…メモリマップの任意の値を使って結果を任意のアドレスに代入する。ブロックの種類は、メモリマップと定数・メモリマップ同士のそれぞれを演算するものに分かれている
- 繰り返し…囲ったブロックを指定の条件で繰り返す。初心者向けの物に加え、メモリマップを使った条件指定が可能なブロックも存在。また、breakは途中でループを抜ける機能
- はい/いいえ…指定の条件で命令を分岐する。初心者向けの物と異なり、メモリマップをベースにした複雑な条件指定が可能
- おわり…初心者向けと同一。プログラムを終了する
メモリマップ
メモリマップのボタンをクリックすると、別ウィンドウでメモリマップが表示されます。通信中なら現在の値をリアルタイムで表示します。なお、ツールボックスと表示が被ってしまいますが仕様です(直したいけど直せませんでした。すみません…)。
メモリマップウィンドウは位置やサイズを変更でき、また、ウィンドウ表示中にもう一度メモリマップのボタンをクリックすると閉じることができます。
メモリマップの各項目について簡単に説明します。これらは、上級者向けのツールボックスに含まれる変数演算や条件分岐で利用できます。
- ランダム…0~255の数値がランダムで切り替わる
- 時間…プログラム開始から1秒ずつ加算される
- 気温…センサから得られた現在の気温(℃)
- 湿度…センサから得られた現在の湿度(%)
- ブザー音程…ブザーの音程。0で停止、1~36の範囲でひくいド~たかいシの音程になる
- ブザー時間…ブザーを鳴らす時間。この数値×16msecだけブザーが鳴る
- センサ1~4…A0~A3のセンサ入力
- LED1・LED2…LEDの明るさ。0~255の範囲で大きいほど明るくなる
- スイッチ…ボタン入力。0でOFF、1でON
- 変数1~8…プログラムで任意に利用可能な変数
今回は極力単純化するための割り切りで、メモリマップの数値は0~255の整数に限定し、256以上の数や負の数・小数点は扱えません。おかげで温度・湿度は小数点以下が切り捨てられ、気圧は900~1000位の数値になるため使用していないという、結構残念な(割り切った?)仕様となっています。ただこの辺の問題は、公開しているソースを元に自分で改良できる余地があります。
さあ、大体の動かし方は理解できたでしょうか?この教材を使ったプログラム例としては、こんな感じで室内の温度アラームみたいな実用プログラムが思いつきますね。暑い季節を考えて、室温が28℃代を超えると熱中症防止のためブザーとLEDで警告、更に30℃代を超えるとより激しく警告する、というものです。
ちょっとプログラムを改良すれば湿度も含めたアラーム(湿度が高すぎたら警告)とか、逆に冬場で温度が23℃を超えたら暖房かけすぎのアラートを鳴らすとかの応用が思いつきます。
タイマー機能を使えば、180秒(3分)を測って音と光で知らせるラーメンタイマーなんかも簡単に作れますね(タイマーの正確性については「そこそこ」程度とお考え下さい)。
ちなみに、もし5分以上のカップ麺を作ろうとしたら、メモリマップの仕様上、タイマーは最大で255秒なので、4分ちょっとしか計測できませんが、どうすればよいでしょうか?ヒントは「タイマーが0に戻った(直前より小さくなった)ときに、変数を使ってカウントする」です。
次回予告
とりあえずハードウェアを作って動かせるようになりましたが、自作ハードウェアなので色々カスタマイズしてみたいところもあると思います。次回以降、下記のような項目について、解説していきたいと思います(ソフトウェア関係の解説が多くなります)。
- アナログ入力の接続例
- モータの接続と制御
- ファームやプログラミングソフトの概要解説
- iOSのUSB通信方法(MIDIがカギ)
- 自分でカスタマイズしたアプリを使う方法
それでは、次回をお楽しみに。