Help us understand the problem. What is going on with this article?

[M5StickC+UIFlow] Tips ※随時更新

検証環境

本体:
 M5StackC
ファームウェアバージョン:
 UIFlow-v1.3.2

USBモードに変更したい

こちらのページを参考にしてください。

USBポートに刺しても認識しない

Windows Update へのアクセスを制限されている環境(WSUS サーバ以外アクセス禁止等)で、公式サイトからダウンロードできる「CP210X Driver」では、M5StickC を刺しても COM ポートを認識してくれません。
FTDI VCP Driver」をインストールしてください。

USBモードでのポート名を知りたい。

Windows PC の場合は ComX、WSL環境では /dev/ttySX (X≒ComXの番号と同一)です。
※その他の環境は試してないので分かりません。

NTPサーバと時刻同期するには

UIFlow-v1.3.2 Firmware には時刻は設定できますが、NTPサーバと同期(ntp_sync)するモジュールが入っていません。
こちらのページで公開されている ntptime.py を使わせていただくと同期できるようになります。

ちなみにファイルをデバイスへコピーするには ampy を使いましょう。

コーディング例
import ntptime

offset = 9 * 3600
ntptime.host = 'ntp.nict.jp'
ntptime.settime(offset)

now = utime.localtime() #現在時刻の取得
print(now) #(YYYY, MM, DD, HH, MM, SS, MS)

VSCode から M5StickC にアクセスしたい

拡張機能 vscode-m5stack-mpy をインストールしましょう。
使い方についてはこちらのページの「Quick Start」に書かれています。

ampy で M5StickC にアクセスできない

いざ ampy で M5StickC にアクセスしようとしても、次のエラーメッセージが表示されてアクセスできません。

ampy.pyboard.PyboardError: could not enter raw repl

ampy はデバイス側でREPL(対話モード)が使える状態になってないと利用できません。

そのような場合は、一旦 ターミナル(TeraTerm(Windows)や screen(Linux等))からデバイスにシリアル接続します。(baudrate=115200 )
接続後エンターキーを押しても無反応なはずですので、そこで何度か Ctrl + C を押せば、見慣れた Python インタプリタのプロンプト(>>>)が表示されます。

最後にその状態からターミナルをデバイスから切断すれば、ampy でアクセスできるようになります。
※ screen の場合、デタッチのみではセッションが残ってしまいますので、確実にセッションも切断しましょう(session kill PID

ちなみにデバイスの電源をOFF/ONしてしまうと、再度 ampy でアクセスできなくなります。
その場合はもう一度ターミナル接続してREPLが利用できる状態にする必要がありますので注意してください。

起動時にアプリを自動実行させたい

独自の main.py を作成、デバイスへ転送し、電源を再投入するけど自動実行されない。
大抵の方はそんな状態に陥ると思います。(私もそうなりました)

ネット上の情報では対応方法を見つけることができず、大抵は「boot.py が実行された後、main.py が実行される」とだけしか書かれていません。

当方で調査、検証した結果、独自アプリを自動起動させる手段は、以下の2通りがあるようです。

(手段1)/flash/config.json を変更する

まずは独自アプリを main.py というファイル名で作成、デバイスにアップロード(/flash/main.py)します。

そして /flash/config.json を次のように変更します。
/flash/config.json 内のキー start の値を flow から app に変更するだけです)

config.json(変更前)
{"server": "Flow.m5stack.com", "start": "flow", "mode": "usb", "wifi": {"ssid": "", "password": ""}}
config.json(変更後)
{"server": "Flow.m5stack.com", "start": "app", "mode": "usb", "wifi": {"ssid": "", "password": ""}}

変更後に電源を再投入すれば、UIFlow のロゴマークが表示された後に main.py が自動実行されます。

(手段2)/flash/apps 下にアプリを配置する

独自アプリを作成し、デバイスの /flash/apps 下にアップロードします。
※今回は /flash/apps/hoge.py というアプリを配置しました。LCD中央に「HOGE」と表示するだけのアプリです。
※各ボタンの配置がわからない時はこちらの画像を参照してください。

一度電源をOFFし、ボタンAを押しながらパワーボタンを押して電源を投入します。
下図のように Program が表示されます。

ボタンBを押して下図のように APP.List を表示します。

ボタンAを押してアプリのリストを表示します。
更にボタンBを押して自動実行したいアプリ(今回は hoge)を選択します。

アプリ選択後、ボタンAを押すと選択したアプリが実行されます。

以上の操作で、電源再投入後も選択したアプリが自動実行します。

AWS IoT Core と連携したい

無理です、諦めてください。

・・・というのは半分冗談で半分本気です。

実は執筆時点の UIFlow-v1.3.2 と M5StickC の組み合わせで SSL(TLS)接続を行うと、メモリ絡みのエラーが頻発します。(mbedtls_ssl_handshake error や、Stack Overflow でファームウェアがクラッシュ)

だからTSL接続が必須なIoTクラウドサービス(AWS IoT Core や Google Cloud IoT Core 等)に対しては、直接連携することが出来ません
(将来のバージョンアップで出来るようになるかもしれませんが)

そこで直接連携出来ないのであれば、ブローカー的なものを間に挟めば良いのです。そう、MQTTブローカーです。
MQTTブローカーのオープンソース実装である「Mosquitto」をVMインスタンスやコンテナ上で稼働し、更にブリッジ機能を利用することで、AWS IoT Core に接続し、メッセージ交換ができるようになります。

[連携イメージ]
Mosquitto.png

環境構築

MQTTブローカーを使った AWS IoT へのブリッジ環境の構築方法は、クラメソさんのこのページが参考になると思います。

(実際の本番環境では MQTT ブローカー自身が SPOF にならないよう、K8s 上に実装する等の工夫が必要でしょう。)

更にもう一工夫

クラメソさんの記事では、bridge.conf 内のブリッジするトピックを、以下のように固定していました。
awsiot_to_localgatewaylocalgateway_to_awsiotboth_directions

/etc/mosquitto/conf.d/bridge.conf(一部抜粋)
# Specifying which topics are bridged
topic awsiot_to_localgateway in 1
topic localgateway_to_awsiot out 1
topic both_directions both 1

ブリッジするトピックの指定ですが、実はワイルドカード(#)を利用することでき、例えば publish されたトピック全てをブリッジする場合は次のように記述することができます。

/etc/mosquitto/conf.d/bridge.conf(一部抜粋)
# Specifying which topics are bridged
topic # both 1

AWS IoT の 「$aws/things/~」 へ Publish する場合

AWS IoT の場合、デバイスから Publish するトピックに $aws/things/~ を指定する場合もあります。(Shadow 等)
Mosquitto では Publish されたトピックに $ 記号が含まれていると、正常に転送されない不具合(仕様?)があるようです。

そんな場合は次のように設定することで、 MQTT ブローカーから AWS IoT へ Publish するトピック全てに $aws/ を先頭に付与することが出来ます。

/etc/mosquitto/conf.d/bridge.conf(一部抜粋)
# Specifying which topics are bridged
topic # out 1 "" $aws/
topic # in 1

デバイスからは $aws/ を除いたトピック(things/~)へ Publish することで、目的のトピックへ転送されます。

そもそも bridge.conf の内容が反映されない

/etc/mosquitto/conf.d 下に bridge.conf を置いただけでは、設定が反映されない場合があるようです。(手元にある CentOS7 がそうでした)

その場合は /etc/mosquitto/mosquitto.conf に、次の include_dir 行を追加してください。

include_dir /etc/mosquitto/conf.d

Timer で OSError 261 が発生する

マルチスレッドの実行でよく使う Timer ですが、その際スクリプトは次のように書くと思います。

from machine import Timer

def int_handler_timer_0(t):
    print('Timer0')

def int_handler_timer_1(t):
    print('Timer1')

t0 = Timer(0)
t0.init(period=10000, mode=Timer.PERIODIC, callback=int_handler_timer_0)
t1 = Timer(1)
t1.init(period=5000, mode=Timer.PERIODIC, callback=int_handler_timer_1)

一見問題ないように見えるスクリプトですが、いざ実行すると OSError: 261 が発生し、Timer(1) 側がスタックしてしまいます。

検証したところ、M5StickC には Timer が2個しかなく、更にその2個は -10 を指定しなければスタックしてしまうようです。

なので上記スクリプトを実行するには、次のようにそれぞれ Timer(-1)Timer(0) とする必要があります。

from machine import Timer

def int_handler_timer_0(t):
    print('Timer0')

def int_handler_timer_1(t):
    print('Timer1')

t0 = Timer(-1)
t0.init(period=10000, mode=Timer.PERIODIC, callback=int_handler_timer_0)
t1 = Timer(0)
t1.init(period=5000, mode=Timer.PERIODIC, callback=int_handler_timer_1)

また Timer は 2個しかありませんので、次のように 3つ目の Timer を追加すると OSError: 261 が発生し、Timer(1) がスタックします。

from machine import Timer

def int_handler_timer_0(t):
    print('Timer0')

def int_handler_timer_1(t):
    print('Timer1')

def int_handler_timer_2(t):
    print('Timer2')

t0 = Timer(-1)
t0.init(period=10000, mode=Timer.PERIODIC, callback=int_handler_timer_0)
t1 = Timer(0)
t1.init(period=5000, mode=Timer.PERIODIC, callback=int_handler_timer_1)
t2 = Timer(1)
t2.init(period=1000, mode=Timer.PERIODIC, callback=int_handler_timer_2)
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away