きっかけ
2019/10/12現在、台風19号が近づいてきています。私のTwitterのTLでは気圧計を自作されて気圧が下がるのを監視されている方が多くいらっしゃいました。この流れに乗りたいと思い、急遽作ってみました。
台風接近に伴い、気圧測定の電子工作が盛んなようなので😄 #M5Stack pic.twitter.com/fEGk3mumnG
— robo8080 (@robo8080) 2019年10月11日
オムロンの絶対圧センサをM5StickVにつないで気圧測定祭に参戦 https://t.co/ZISfw6vzad pic.twitter.com/gOqNIbfZnq
— ミクミンP/Kazuhiro Sasao (@ksasao) 2019年10月11日
makerの義務だと聞いたもので#bme280 #隙あらば便乗 pic.twitter.com/nBfsvLwwCt
— けい (@KeiMameshiba) 2019年10月11日
使ったのはm5StickCです。ご存じない方のためにざっくりご説明するとm5StickCは画面、赤外LED、スピーカ、6軸センサ等々が載ったwifiにも繋がる人気のマイコンです。Arduino IDEでC言語ベースでは結構情報がある*1と思うのですが、最近UiFLOWというブラウザ上でブロックプログラミングやmicro pythonを使える環境を導入してみたところだったので、今回はそちらでトライしてみました。
※2019/10/13追記※
micro pythonを最初から使う場合でしたら、norifumi(norifumi (@norifumi5001) | Twitter
)さんの以下の記事が大変分かりやすいです。台風が去った後にこの記事を発見しました。普段から勢いで書いてしまいがちなのですが、あらかじめ調べるのも大切ですね...。
※2019/10/15追記※
Kenta IDA(https://twitter.com/ciniml)さんがUiFLOWで直接Ambientのライブラリを再現されていらっしゃいました。
ブロックプログラミングでもここまでできるとは使う前は想像もしていませんでした。なかなか奥が深いです。
私も面倒だったのでUIFlowで適当に作ってAmbientの公開チャネルに投げました。まあ、適当に作るにはUIFlow楽でいいですね。 https://t.co/b7n2bkATTg pic.twitter.com/3yWDLxghKV
— Kenta IDA (@ciniml) 2019年10月11日
※追記ここまで※
目次
説明
UiFLOW*2はIDでm5StickCやm5Stackというマイコンを紐づけてWifi経由でブラウザ上からプログラムを転送できる優れものの開発環境です。ブロックプログラミングやmicro pythonで書くことができます。今回はm5StickCのEnv Hat*3を使うため、Hatに対応しているBeta版の1.4.0を使いました。
ブロックプログラミング
温度、湿度、気温の表示
最初にブロックプログラミングで値を取得して画面に表示させてみました。プログラムと動作の様子はこんな感じです。
プログラムはこんな感じです
— パスコンパス (@pscmps) 2019年10月10日
それにしても動画の34℃は暑すぎる様な…?
メカに近すぎて熱を拾っているのか初期不良か、それとも本当に暑いのか pic.twitter.com/j78I4XHFpQ
上記の様に用意されたブロックを繋ぐだけで簡単に欲しいデータを表示することができます。すごいです。また、画面の方は以下の様に指定をします。Labelをドラッグ&ドロップして配置しています。簡単なことを実行するのであればプログラムが全く分からない方でも直感的に使える素晴らしい環境だと思います。
時間の表示
m5StickCには腕時計の様に付けられるバンドが付属しています。時間も一緒に表示したいなと思い、情報を探していたら以下の五味さんのツイートを拝見しました。最初にntpサーバから時刻を取得し、その後内部のリアルタイムクロックで時を刻みます。
#M5Stack のUIFlowのブロックで、NTP(https://t.co/7oEq1pX1fY)を使ってRTC設定するメモ pic.twitter.com/XnRlji3Qrh
— 五味 (@GomiHgy) 2019年9月29日
ブロックを再現し、時刻も表示できました。ありがとうございました。ここまでできると次にはログをどこかに残したくなってきます。
m5StickCはせっかくwifiでネットにつながる機能もあるのでサーバにデータを上げること等できるのではないでしょうか。
先日の技術書典で友人に買ってきてもらった以下の本にMQTTというやり方があることが書いてあり、それでやってみようと思ったのですが、Beta版ではMQTTブロックがまだサポートされていませんでした。別の方法を探します。また、以下の本はUiFLOWの導入法等も丁寧に書いてあり参考になりました。
micro pythonでAmbientと接続
Ambientというサービスを使ってみることにしました。以下の公式のサイトを参考にしました。ブロックプログラミングではなく、micro pythonで書いています。参考にした記事ではUiFLOWではなくローカルから開発していたので少し書き方は変えています。 ambidata.io
クリックするとプログラムを表示します
# https://github.com/AmbientDataInc/ambient-python-lib/blob/master/ambient.py
# ここから下まで上記の内容をコピペしています。
class Ambient:
def __init__(self, channelId, writeKey, *args):
try:
import urequests
self.requests = urequests
self.micro = True
except ImportError:
import requests
self.requests = requests
self.micro = False
self.url = 'http://ambidata.io/api/v2/channels/' + str(channelId) + '/dataarray'
self.channelId = channelId
self.writeKey = writeKey
if len(args) >= 2:
self.userKey = args[1]
if len(args) >= 1:
self.readKey = args[0]
def send(self, data):
if isinstance(data, list):
__d = data
else:
__d = [data]
headers = {'Content-Type' : 'application/json'} if self.micro else {}
r = self.requests.post(self.url, json = {'writeKey': self.writeKey, 'data': __d}, headers = headers)
return r
def read(self, **args):
url = 'http://ambidata.io/api/v2/channels/' + str(self.channelId) + '/data'
__o = []
if hasattr(self, 'readKey'):
__o.append('readKey=' + self.readKey)
if 'date' in args:
__o.append('date=' + args['date'])
else:
if 'start' in args and 'end' in args:
__o.append('start=' + args['start'])
__o.append('end=' + args['end'])
else:
if 'n' in args:
__o.append('n=' + str(args['n']))
if 'skip' in args:
__o.append('skip=' + str(args['skip']))
if len(__o) > 0:
url = url + '?' + '&'.join(__o)
self.r = self.requests.get(url)
return list(reversed(self.r.json()))
def getprop(self):
url = 'http://ambidata.io/api/v2/channels/' + str(self.channelId)
if hasattr(self, 'readKey'):
url = url + '?' + 'readKey=' + self.readKey
self.r = self.requests.get(url)
self.prop = self.r.json()
return self.prop
# この上までがコピペです
from m5stack import *
from m5ui import *
from uiflow import *
import urequests
import hat
setScreenColor(0x111111)
hat_env0 = hat.get(hat.ENV)
# こちらを追記しました。
am = Ambient(※ここにAmbientの自分のチャンネルIDを貼り付けます, '※こちらには自分のライトキーを貼り付けます')
# ラベルの設定等です。(ブロックプログラミングで自動生成されます)
label0 = M5TextBox(3, 4, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
label1 = M5TextBox(3, 57, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
label2 = M5TextBox(38, 76, "hPa", lcd.FONT_Default,0xFFFFFF, rotate=0)
label3 = M5TextBox(4, 91, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
label4 = M5TextBox(40, 109, "%", lcd.FONT_Default,0xFFFFFF, rotate=0)
label5 = M5TextBox(4, 125, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
label6 = M5TextBox(43, 141, "oC", lcd.FONT_Default,0xFFFFFF, rotate=0)
datetime = None
time = None
def first_index(my_list, elem):
try: index = my_list.index(elem) + 1
except: index = 0
return index
# タイマーを設定して表示しています。(追記箇所以外はブロックプログラミングで自動生成されます)
@timerSch.event('timer1')
def ttimer1():
global datetime, time
label0.setText(str(rtc.now()))
label1.setText(str(hat_env0.pressure))
label3.setText(str(hat_env0.temperature))
label5.setText(str(hat_env0.humidity))
#追記しました。Ambientにデータを送っています。gitのmain.pyからの引っ張ってきました。
r = am.send({'d1': hat_env0.pressure, 'd2': hat_env0.temperature, 'd3': hat_env0.humidity})
# 以下の処理はなくても動いていますが、あった方が良いのかもしれません
# r.close()
pass
# この辺りは五味さんの時間取得の処理部分です(自動生成)
label0.setText('')
try:
req = urequests.request(method='GET', url='http://ntp-a1.nict.go.jp/cgi-bin/time')
label0.setText(str(('ok:' + str((req.status_code)))))
datetime = (req.text).split(' ')
time = datetime[3].split(':')
rtc.setTime(int(datetime[4]), first_index(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], datetime[1]), int(datetime[2]), int(time[0]), int(time[1]), int(time[2]))
label0.setText(str(rtc.now()))
except:
label0.setText(str(('err:' + str((req.status_code)))))
timerSch.run('timer1', 100, 0x00)
UiFLOWで複数のmicro pythonファイルもアップロードできるのでしょうか。よく分からなかったためAmbient.pyをimportするのではなくベタ書きで使ってしまいました。今回はそこまで長くなかったので問題ないですが、時間のある時に今後のために色々いじって調べてみたいです。
下のツイートがデータを送ってPCの画面にAmbientのグラフを表示している様子です。左上が気圧、右が湿度、下が温度です。
結局 #Ambient を使って成功しました
— パスコンパス (@pscmps) 2019年10月11日
一応 #UiFLOW 上のmicro pythonベタ書きで動かせたので後でブログでコードを公開しようかなと思います
Gitもいい加減使える様にならなきゃとは思っているんですが… pic.twitter.com/vqUtVQ34gb
以下の図は2:35現在のグラフの様子ですが、だんだんと気圧が下がってきているのが観察できます。ノイズがちょっと気になりますね。また、温度は放熱を拾っている様であまり当てになりません。
まとめ
UiFLOWでもm5StickCとAmbientを使うと割と手軽にIoTチックなことができました。m5Stack系のデバイスは公式側の開発スピードが速く、どんどん情報が古くなってしまうのがデメリットでもあり魅力であると思います*4。流行り物好きな方にはおすすめです。
上述した様に、ブロックプログラミングで完結する様な内容であれば初心者でも比較的手が出しやすいです*5。
台風にはお気を付けください。読んでくださりありがとうございました。
その他の記事
普段はM5StickVとサーボを繋いだ2軸首振りマシンの記事を多く書いています。もしご興味ありましたら読んでいただけたら幸いです。
*1:たなかまさゆきさんのブログです。Arduino言語で書かれています。
M5StickCにENV HAT(気温、湿度、気圧)をサーバーにアップする その1(基礎編) – Lang-ship
*2:UIFLOWはこちらのページです。M5Flow
使い方はこちら等参考になるかと思います。M5Stack UI Flowを使ってみよう
*3:温度、湿度、気圧が取れます M5StickC ENV Hat(DHT12/BMP280/BMM150搭載) - スイッチサイエンス
*4:ntpサーバにアクセスするブロックがバージョンで互換性が切れるということ等あった様です。