オートラップ計測ロボットを作る ー IoT編
前回制作したオートラップ計測ロボットをthe Internetへ接続して、計測結果をクラウドへアップロードします。
WiFiモジュールはスイッチサイエンス社が販売しているEsper Developerが定番です。
単にWiFiへ接続する簡単なプログラムなら、Arduinoも必要ありません。しかし、このロボットはR/Cカーの通過を判断したり、LEDチカチカしたり、ビープ音鳴らす必要があるので、そういう部分はArduinoで行い、計測完了後、このWiFiモジュールを使ってデータをアップロードします。
最初、単純にPCにつないで、シリアル経由でATコマンドで色々試しているうちに、ATコマンドを受け付けなくなりました。そういうときはFirmwareを更新(新しいものでなくてもいい)してやれば戻るという話があったので、実際何度がそうしました。
閑話休題。
しかし、ロボットがWiFiにつながるだけでは、クラウドへデータをアップロードできません。サーバサイドに受信するプログラムが必要です。今回はFirebaseを使ってプログラムを作成しました。人気のあるMBaaS(Mobile Backend as Service)です。
データを蓄積するデータベースにはCloud Firestoreを、データを受信しデータベースに保存するプログラムはCloud Functionsを利用します。今回ぐらいの用途なら無料版で十分利用できます。
Firebaseの準備は他の方にまかせて、簡単にFunctionsの説明だけします。
Cloud Functionsは色々な言語で開発できますが、今回はJavascriptを選択しました。以下はリクエストから計測結果を取得し保存、以前のコースレコードと比較し更新します(なんかnote不具合なのかコード挿入すると以降書けなくなるね)。
exports.uploadResults = functions.https.onRequest((request, response) => {
if (request.query.results) {
const record = createNewRecord(request.query.results);
if (record) {
db.collection('results').doc(record.recordedAt).set(record)
.then(() => {
db.collection('results').doc('CourseRecord').get()
.then(best => {
const latest = updateBestTime(best.exists ? best.data() : {}, record);
db.collection('results').doc('CourseRecord').set(latest)
.then(() => {
response.send(record);
});
});
});
} else {
response.send("no record.");
}
} else {
response.send("no results.");
}
});
GitHubに置いてあるので、興味ある方はどうぞ。
計測ロボット側のプログラムも機能追加して、計測完了後WiFiへつないで、Functionを呼び出せるようにしました。
こちらもGitHubで公開しています。
ちょっと電源容量が心配だったんですが、なんとか追加電源なしで動作しています。できるだけ同時にLEDやビープ音を利用しないように工夫しています。
たとえば、計測完了時に2秒ほどビープ音を鳴らしていますが、そのとき通信すると、ビープ音が細切れになって、明らかに電力不足でした。ビープ音が鳴り終わるまで待ってから送信するようにしています。
WiFiモジュールは外付けしかしてません。いずれ気が向けばシールドに載せてあげたいと思いますが、なんだかこれはこれで子連れみたいでいい感じです。
これでクラウドへどんどん計測データが溜まっていきます。その場で計測値を見えるようになるだけでも良かったんだけど、「あれ、今まで一番速かったときのタイムは?なんだっけ?」となると、チャレンジ心が消えてしまいます。
計測ロボットがIoT化(Internet of Things)できたので、あとはこれにVUI(Voice User Interface)を付加したいと思います。
Google Home Miniのアクションを作成して、「コースレコード教えて」とか「直近のタイムは?」とかに回答させたいと思います。
最終回は「VUI編」です。