M5StackのリセットをUSB経由で行う方法

f:id:apt-k-ueno:20200107184121p:plain Aptpod Advent Calendar 2019 21日目担当のハードウェアグループの織江です。
この記事では電子工作を趣味とする界隈でも人気のM5stackの小技を紹介したいと思います。

M5Stackとは

M5Stackは中国深セン発の液晶付き汎用開発プラットフォームです。 世界的に有名なArduinoと互換性が高く人気を博しています。
一般的に電子部品の開発ボードは基板剥きだしで、製品としてのケース が付いていなかったりするため製品化には大きなハードルがあります。
この製品は液晶画面ボタン、スピーカー、WiFi、BT、バッテリー等の汎用 に使える機能が(評価機としては)しっかりとしたケースに入っていて エンジニア以外の方が触っても自然に使えるようになっているのが 特徴だと言えると思います。

日本ではスイッチサイエンスから購入することが可能です。

M5Stack Basic - スイッチサイエンス

弊社では液晶等の表示装置の無い組み込みPCをよく使うのですが、簡易的な表示器が欲しい際にこうした製品を利用します。

M5Stackのリセット回路の問題点

大変便利なM5Stackなのですが、不安定な動作をするときがたまにあります。
弊社で直面した大きな課題の一つは
電源投入時に正しくリセットされないことがある
というものです。(画面が真っ暗なまま何も起きない)

弊社のユースケースは下記の通りで、自動車のエンジンがかかるのに連動して起動できる 車載PC(Linux)のUSBポートの電源に連動してM5Stackの電源を入れたいという条件でした。
車載PCの状態を定期的にM5Stackに送信して液晶画面に表示する機能を実装しています。
M5Stack内臓のLipoバッテリーは自動車の中で使うことを想定しているため、 取り除いた状態で使用しています。

f:id:aptpod_tech-writer:20191217123032j:plain
使用例

調査の結果M5Stack内のESP32というメインのマイコンのリセット信号が電源電圧が立ち上がる前にぐねぐねと立ち上がっており、正しくリセットできていないため後段の周辺回路も 正しく動作していないということが分かりました。
f:id:aptpod_tech-writer:20191217174207j:plain ただ、電源・充電管理とUSBシリアル変換IC(CP2104)だけは正しく 動作していることが分かりました。

f:id:aptpod_tech-writer:20191217154722j:plain
M5Stack簡易ブロック図
リセットの配線を公式の回路図で確認すると下記の赤い丸の部分になります。
f:id:aptpod_tech-writer:20191217125356j:plain
M5Stack回路図抜粋

この回路図でENと書かれたリセット信号はDTR・RTS信号を経由して、さらにUSBシリアル変換IC(CP2104)経由でリセットできることが分かります。

Pythonを使ったM5Stackのリセット方法

では実際にこのUSBシリアル変換IC経由のリセットを試してみたいと思います。

まず適当なLinuxマシンを用意します。
今回はVirtualbox上のUbuntu16.04LTSを用いました。
続いてドライバのインストールを行います。詳しくは説明しませんが こちらのサイトが参考になります。
usbserial とcp210xのドライバをインストールします。
drivers - Ubuntu 16.04.1 usbserial missing - Ask Ubuntu

特に何も設定しなければM5Stackが/dev/ttyUSB0として認識されるようになるかと思います。
後はシリアル通信を開始する際にDTRとRTSピンを下記のように操作するとリセットをかけることが出来ます。
ピンを操作した後rtsctsをFalseにしないとその後の通信ができなくなるのでその点が注意点です。

import serial
import time
ser = serial.Serial('/dev/ttyUSB0',115200)  
ser.setDTR(False)
time.sleep(0.1)
ser.setRTS(False)
ser.rtscts = False
time.sleep(1) # wait esp32 wakeup  

#your code here

ser.close()

f:id:aptpod_tech-writer:20191219095621j:plain
起動画面
f:id:aptpod_tech-writer:20191217183520g:plain
リセット失敗した状態(画面真っ暗)からのリセット

あとがき

通常リセット回路はどのような電源が繋がれても確実にリセットされるようになっていると嬉しいのですが、必ずしもそうなっているとは限らないです。
M5Stackの場合はたまたまUSBシリアル変換ICだけは 正しくリセットされるようでしたのでそこを起点にメインのマイコンを復帰させることができました。

参考URL

M5Stack Basic - スイッチサイエンス
pySerial API — pySerial 3.4 documentation
Arduino UNOでpyserialを使ったら再起動してしまった - Qiita