2021/02/21

M5CORE2とタッチパネル

M5Stack Fireで動くアプリをM5CORE2に移植しようとしている。
GPIOのボタンがないので、タッチパネルを有効にしてソフトウェアボタンを代わりにしようとしている。

それはよかったのだが、移植先でソフトウェアボタンの応答性がよろしくない。
ログも出せない状態なのでLEDの点灯だけで様子を見ているのだが、タッチパネルのFT6336UにI2C readしているところがなかなか戻ってこないようで、それも5秒くらい間が空いている。

 

I2Cのアクセスにmutexとかかけてないからよくないのでは、と思っていたのだが、FT6336UのINTピンはOUTPUTで、readできるようになったときにアサートするようになっているらしい。read準備できていないときにI2C readするとどうなるのかはわからなかった。スタートコンディションにならないとかで今回の妙に時間が空く現象が起きたんじゃなかろうか。

ただ、I2C readを定期的に行うようにしたのはINTでtaskを起こしてI2C readする、というのがうまくいっていなさそうだったから変更しただけなのだ。
なんだろうね。

 

M5CORE2でI2C接続しているものは、これら。

image

私が今回使いたいのは、AXP192とFT6336U。
AXP192にGPIOがあるので指示はI2Cで出すし、タッチパネルのFT6336UからはI2Cで結果を読み取るし。
それが別々のtaskで好き勝手やってたら、そりゃうまく動かんわな。

I2Cのドライバレベルでは排他は持ってないだろうから、簡易的にmutexの変数をグローバルにして衝突だけは回避させるか。
失敗したらランダム時間待ってからリトライ、というのでも暫定対応としては悪くないかも。


というわけで、今日の作業はおしまいだ。
何も解決していないのだが、M5CORE2のソケットを外してみたので写真を載せておこう。
裏蓋は六角レンチが無いと開けられないが、ソケットだけなら丈夫な細い鉄串か何かで取り外せる。爪楊枝くらいだとちょっと強度が足りない気がするがね。

image

2021/02/20

M5CORE2にはGPIOのボタンが無い

M5CORE2は全面がタッチパネルになっていて、ハードウェアのボタンは電源とリセットしかない。
LCDよりもタッチパネルの方が広くなっていて、LCDが無い部分に丸が描いてある。ここをボタンと見なせばいいんじゃないの、ということだろう。

image

for AWSにもソフトウェアボタンの実装がある。
初期化のところを見ると、左上の座標と幅x高さを与えれば、そこがボタン扱いになるようだ。つまり画面の下にある3つに固定されているわけではないということだ。

 

サンプルではボタンの読込をこんな感じで行っている。
for文の中でポーリングしているのだが、本体の方ではtaskが立ち上がっているようで、ポーリングのタイミングでタッチパネルの状態を見に行くのではなく、その時点で最後にtaskで更新されたデータを読むだけである。

状態が変わったタイミングでコールバックもらいたいと思ったが、コールバック関数をよくわからんtaskに登録してコンテキストがどうなってるか悩むことになるくらいなら、コールバックするためのtaskを別に立ち上げた方がよいだろうな。

2021/02/14

M5CORE2のシステムLED

M5CORE2の電源LEDを点灯させたい。

電源LEDと書いたが、正確にはSYS_LEDという名前だ。

image

なので、電源がONになると自動的に点灯する、というわけではない。
そしてこれ以外にLEDは無いので、LCDもLEDも制御していない状態だと外見から電源が入っているかどうかわからないのだ。

だからLEDを点灯させたいのだ。


困ったことに、SYS_LEDはESP32のGPIOではなくAXP192、つまり電源制御用のチップ側につながっている。
GPIO1だ。

image

LEDのところからすると、SYS_LEDが0Vになれば電流が流れて点灯するはずだ。

 

for AWSのコードでは、起動時に1Enableにするときに0を設定している。
どちらもAxp192_SetGPIO1Mode()という関数を使っている。
AXP192_GPIO1_CTL_REGが0x92なので、そこがGPIOのHI/LO設定なのだろう。

一応確認しておく。
AXP192データシートは・・・中国語版PDFしか見当たらなかった。

image

くっ・・・。
下位3bitが有効で、デフォルト値は111。なんとなく文字の雰囲気からハイインピーダンスだろうか。
起動時に001、ONにするときに000。

功能设置 → 機能設定

000 NMOS 漏极开路输出 → NMOSオープンドレイン出力
001 通用输入功能 → ユニバーサル入力機能

値の書込では無くモードの設定なのか。
ユニバーサル入出力が、いわゆるGPIOモードなのだと思う。
でも、LEDのONでオープンドレインにする・・・? いや、関数名からするとLEDを有効にする、なのだが同時に点灯もしているのだ。

あ、001は「入力」で、000は「出力」だった。
入力の時って、だいたいハイインピーダンスよね。

 

Hi/Loの制御はこっちだと思う。

image

デフォルトの出力値が0なので、GPIO1の設定を出力にしただけでLEDが点灯する、というわけだ。
念のためHiにしたら点灯しなかったので、間違ってないだろう。

いやあ、久々にポート制御するので不安だったよ。

 

(追記)

システムLEDのON/OFFをする場合、0x94レジスタのHi/Loでは結局ダメだった。
Hiにしたら等電位になって点灯しないと思うのだが、そうならない。
0x92レジスタでINPUT(OFF)/OUTPUT(ON)にするしかなく、まあfor AWSの実装そのままになった。
すっきりせんなぁ。

2021/02/13

M5CORE2とFireはけっこう違う

何を今さら、と言われそうだが・・。

M5Stack Fireで作られたプログラムをM5CORE2で動かそうと考えていた。
それならFireを購入すればいいやん、と言われそうだが、新しい方を使いたかったのだよ(もちろん値段が安かったからという理由もあるのは言うまでもない)。

LCDは幸い同じデバイスで、FLASHサイズも同じ。PSRAMは大きくなる方だから問題ない。
明らかに違うのはボタンが物理的に存在しないということくらいだ。

 

などとのんきに構えていたのだが、ピンアサインが結構違うのだな……

番号が違うだけだったら変更すれば済むのだが、M5CORE2では一部が電源チップにあるGPIOを使っているのだ。接続がI2Cなので、ESP32から制御するときはI2Cでお話ししないといけない。LCDに何も出てこないと思ったら、そういうことなのだ。

ボタンも、GPIOで直接見に行くようになっていたのだが、そっちはそもそもの方式を変更せねばならない。
for AWSの方にVirtual Buttonというコンポーネントがあったので持ち込めばなんとかなるかもしれんが、ともかく何とかしないといかんのだ。

 

まあいい。
最近組み込みしてないので、気分転換と思おう。

M5CORE2の付属モジュール

前回、AWS版のGitHubにあるサンプルからコードを削りすぎて音が出なくなった。
ノーマルなM5CORE2にもあったハードウェアだから1つはいらないんじゃないの?ということで削ったのだがそうではないらしい。

そもそも、私が思っているハードウェア差分は正しいのだろうか?

 

image

商品ページの2枚目の画像があったのだが、M5CORE2の本体と付属モジュールという分け方をした場合、MPU6886の6軸加速度センサとSPM1423のマイクセンサは付属モジュールに当たるのだ。

for AWSはこの付属モジュールを取り除いて、こっちを挿す。

image

なるほどね。

なのでハードウェアの差分としては、セキュアエレメントのATECC608AとRGB LEDのSK6812、あとは電源周りとなる。

すっきりだ。


そこである程度元に戻して再起動しなくしたのがこちら。

https://github.com/hirokuma/Core2-for-AWS-IoT-EduKit/tree/d9000f4a1fdf23fe01f1d48d1cb98f60c9cbbf11/Hardware-Features-Demo

どうも再起動している原因はスピーカーのようなのだ。
分かりづらいので、masterとの差分で見るとこちらだ。

https://github.com/m5stack/Core2-for-AWS-IoT-EduKit/compare/m5stack:3c5aa62...hirokuma:d9000f4#diff-fea5e934abd550c3049b8f91b1f307c8200a0610f1f3e06acb60a2273058855bR59

あれ、マイクじゃ無くてスピーカー?
いや、microphoneTaskを止めれば起動した。

https://github.com/m5stack/Core2-for-AWS-IoT-EduKit/compare/m5stack:3c5aa62...hirokuma:8561420#diff-fea5e934abd550c3049b8f91b1f307c8200a0610f1f3e06acb60a2273058855bR192

microphoneTaskはなにかというと、mic_fft_test.cにあった。グラフィックっぽいデータもあるようだが、一番下に出力するのだろうか?

image

2021/02/11

M5CORE2で動かす

M5CORE2にfor AWS用のサンプルを改造して動かそうとしているがうまく動かない。
落ち着こう。

 

まず、対象としているハードウェアはこれだ。

M5Stack Core2 ESP32 IoT Development Kit for AWS IoT EduKit | m5stack-store
https://m5stack.com/products/m5stack-core2-esp32-iot-development-kit-for-aws-iot-edukit

M5CORE2にM5GO Bottom2 for AWSというものがひっついているのだと思っている。

  • MPU6886: 6軸加速度センサ
  • SPM1423: デジタルマイクロフォン
  • SK6812: RGB LEDsの制御
  • ATECC608 Trust&GO: セキュアエレメント

MPU6886とSPM1423はM5CORE2側よね?

M5GO Battery Bottom2 (for Core2 only) | m5stack-store
https://m5stack.com/products/m5go-battery-bottom2-for-core2-only

ああ、個別に付いているのか。

そして削りまくって・・・

https://github.com/hirokuma/Core2-for-AWS-IoT-EduKit/commit/a163841af30128488517b5bf9943ed3451eece5b

image

消しすぎな気もするし、鳴っていた音も出なくなったからあきらかに削りすぎなのだろうが、再起動を繰り返すよりましだ。

デバイスが重なっているやつはなんなのか、ちょっとわからんですな。

M5CORE2にうまく接続できない

idf.py flashで焼こうとするのだが、タイムアウトして接続できない。

A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
CMake Error at run_cmd.cmake:14 (message):
  esptool.py failed
Call Stack (most recent call first):
  run_esptool.cmake:21 (include)

なぜだ。

$ idf.py -p /dev/ttyUSB0 flash
Executing action: flash

...

[100%] Built target app
esptool.py --chip esp32 -p /dev/ttyUSB0 -b 460800 --before=default_reset --after=no_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 16MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x10000 M5Core2ForAWSDemo.bin
esptool.py v3.0
Serial port /dev/ttyUSB0

いやいや、460800ってbpsだと思うけど、menuconfigの設定と違うでしょう!
それに、beforeでresetしそうなのにしないし、afterでresetしないようなのにするし。

これはどうもデフォルト値らしい。そしてmenuconfigのbps設定はidf.py monitor用だった。
慌てたらいかんね。

しかしコマンドだと苦労するのに、M5Burnerだとあっさり焼けるのが哀しい。


よくわからんが、接続待ちになったときにM5CORE2のリセットボタンを2回押すとよさそうな気がする。
確実にとはいかないのだが、だいたいいけてる。
もしかしたら1回でもいいのかもしれん。

M5Burnerだとそんなことないから、idf.py flashだけか?
そんな記事も見かけないので、VirtualBox経由でやっているせいというのもあるのかも。

まあ動けばよかろうなのだ。

 

2021/02/23追記

いままでLubuntu18.04だったのだが、なんとなくLubuntu20.04にアップグレードしてみた。
ターミナルも、QTerminalにしてみた。
それが何の関係があるかというと、ターミナルのカーソルがブリンクしないようになったのだ。

接続待ちの時は、こんな感じでキャラクターがプログレスバーのように進んでいると思う。

Connecting........_____....._____....._

で、私が最近身につけてきたのは、「_」が出力される直前までリセットボタンを押したままにして、出力される前に離す、という技だ。
これがけっこうな確率で接続に成功する。。。していた。
「出力される前に」なので、「.」が出力されて「_」が出力される前に指を離さないといけないため、私はカーソルのブリンクでタイミングを計っていたのだ。

 


なお、CORE2 for AWSのサンプルはまだリセットを繰り返している。

 

image

"Bat"の行が出力されているから、この行までは動いているはずだ。
そしてここはイベントループっぽいから、別のところでリセットしているのか。
タッチパネルを触ると値が変わるから、ループは止まっていないようだし。

セキュアエレメントも外したし、LEDも外したけど、まだダメだ。
他に何があるんだーー

M5CORE2を元に戻したい

さて、前回はM5CORE2に適当なプログラムを焼いて、再起動を繰り返す状態になった。
元に戻したいです……

さっき気付いたのだが、Core2の名称は"M5CORE2"なのかな。

まあ、買ったときのケースにはM5STACKと書いてあったし、発売元のシールにもM5Stack CORE2と書いてあるから、略称なのかもしれん。


まず、M5StackのダウンロードページからM5Burnerというアプリをダウンロードする。
私はWindows環境なのでWindows版をダウンロードした。

https://m5stack.com/pages/download

zipファイルの中にexeファイルがあったので起動する。

起動するとネットに接続して、焼けそうなファームウェアの一覧が出てくる。
もしファイアウォールの設定をしたりして起動時に接続できないと一覧が出てこないので注意だ。

一覧のどこかにCre2FactoryTestというやつがあるので、それをダウンロードして焼けば良い。
もしM5Stackを

image

画像ではBurnボタンだが、最初はDownloadなのだ。ダウンロードしてBurnすると元に戻った。

もう怖くない!

M5Stack Core2

 

image

M5Stack Core2 IoT開発キット - スイッチサイエンス
https://www.switch-science.com/catalog/6530/

 

M5Stack Core2を購入した。

このM5Stackだが、シリーズがたくさんある。
今回も最初はM5Stack Fireというものを買うつもりだったのだが、どこかの記事で、今はCore2だ、というようなのを見かけた気がするのでこちらを選んだのだ。PSRAMが載っていれば良かったので、Core2でもよいのだ。

 

届いたCore2の電源を入れて出てきたのが写真の画面だ。
音センサが付いているようで、FFTしてるのかどうかは知らんが音を拾ってグラフがリアルタイムで動いていた。ESP32ってそのくらいの性能はあるんだねぇ。
立方体が描かれていたので、何軸か分からないけど加速度センサも載っているのだろう。

そして何より、この価格でタッチパネル式のカラー液晶画面が付いているということに驚きを隠せない。


さて、ハードウェアはともかく、ソフト屋さんとして気になるのは開発環境だ。

M5Stack Docs - The reference docs for M5Stack products.
https://docs.m5stack.com/#/en/core/core2

ここには、UIFlow, MicroPython, Arduinoとなっている。

  • UIFlow: ブラウザベースのブロック形ビジュアルプログラミング開発環境
  • MicryPython: 組み込み向けPython
  • Arduino: あのArduino

うーん、ESP8266のようにC言語でやれんのだろうか。Arduinoがあるから、そこから直接APIをたたけるようになってるのかな?

M5Stack Core2 SDK でメガドライブエミュレーターをビルドする | hiromasa.another :o)
https://another.maple4ever.net/archives/2881/

できることはできるようだ。

 

今回やろうとしているのはGitHubで公開されていたもので、どうもM5Stack FIREを想定しているようだった。esp-idfなんて文字も出てくるから、たぶんいけるだろう。まあ、センサの類は使えないかもしれないが、M5Stackは有名どころだしサポートしてくれていることを期待しよう。

 

Get Started - ESP32 - — ESP-IDF Programming Guide v4.2 documentation
https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/get-started/index.html

私はWindows使いなのだが、ここではVirtualBox上に作っているLubuntu環境を使う。
Windowsでの開発環境も用意されているのだけど、やっぱり手になじむ方が安心なのだ。

gitでv4.2を取ってくる。。。835MBもある。過去はいらないから--depth 1にすると・・・変わらん。
どうもsubmoduleで取ってきているようで、そっちには--depthが反映されないようなのだ。

--single-branchを追加すると・・・741MB。
--shallow-submodulesも追加して・・・446MB。

git clone -b v4.2 --depth 1 --single-branch --recursive --shallow-submodules https://github.com/espressif/esp-idf.git

ありがとう、この記事を書いた人!

[Git] とにかく速く特定のブランチをgit cloneしたい場合のTips - Qiita
https://qiita.com/koara-local/items/8b90162637593456433b

で、次はinstall.shを実行するのだが、pipでエラーになった。というかインストールされていなかった。。
どうも私の環境はpython 2.7がインストールされているようなので、"sudo apt install python-pip"でよかろう。

その後はかなり進んだのだが、またエラーになった。
"ERROR: Could not find a version that satisfies the requirement bidict>=0.21.0"とか言われるんだけど、

https://github.com/espressif/esp-idf/issues/6262

requirements.txtに追加すれば良いそうだが、python2がデフォルトである理由もないので、そっちを変更しよう。

$ sudo update-alternatives --config python
There is only one alternative in link group python (providing /usr/bin/python): /usr/bin/python3
Nothing to configure.
update-alternatives: warning: forcing reinstallation of alternative /usr/bin/python3 because link group python is broken

? 壊れているのか??
再設定がいるようだが、 /usr/bin/python3があって、そいつはpython3.6のシンボリックリンクらしい。

$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 1
$ sudo update-alternatives --config python
There are 2 choices for the alternative python (providing /usr/bin/python).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /usr/bin/python3     10        auto mode
  1            /usr/bin/python3     10        manual mode
  2            /usr/bin/python3.6   1         manual mode

急に増えやがった。。。
消そう。

$ sudo update-alternatives --remove python /usr/bin/python3.6
$ sudo update-alternatives --config python
There is only one alternative in link group python (providing /usr/bin/python): /usr/bin/python3
Nothing to configure.

$ python -V
Python 3.6.9

古いが、まあいいや。
python3にすると、終わった。

". ./export.sh"と出てくるので、環境変数の読込はexport.shを使うのだろう。
いつも思うが、なんでsourceコマンドと.が同じなんだろうね。

あとはチュートリアル通り、hello_worldをコピーして、idf.pyでesp32に設定してmenuconfigする。
make menuconfigでも画面は出たのだが、きっと何か前処理をしてから行ったりしているのだろう。

image

何を設定すればよいのかわからん・・・・。

Serial flasher config: Flash sizeを16MBにする
Component config -> ESP32-specific
  CPU frequencyを240MHzにする
  Support for external, SPI-connected RAMを有効にする
    SPI RAM configは何を選べばよいの?

Linuxのカーネルだと、targetファイルみたいなのを指定するとそのターゲットデフォルトの設定にできていたように思うのだが、そういうしくみは無いのだろうか? M5StackのGitHubを見てもArduinoライブラリが並んでいるだけのようだ。

こちらの方はCore2用のテンプレートを用意されている。
GitHubにTemplateなんて分類があるのか・・・。

M5Stack Core2 SDK でメガドライブエミュレーターをビルドする | hiromasa.another :o)
https://another.maple4ever.net/archives/2881/

これを使うかどうかは別として、Core2向けの環境を作るということについての情報が役立つ。そして読んでいくほどに、これを自分でやるのはつらいというのがわかってくる。
しかし、今回使いたいesp-idfのバージョンが指定されてて、4.2なのだ。
うーむ……


あ、これはCore2 for AWS用みたいだけど、idf.pyを使ってる。

https://github.com/m5stack/Core2-for-AWS-IoT-EduKit

こちらの紹介を読んだが、Core2にセキュアエレメントが載ったセットのようだ(あと黄色い)から、なんとかなるんじゃないだろうか。

git clone --depth 1 https://github.com/m5stack/Core2-for-AWS-IoT-EduKit.git
cd Core2-for-AWS-IoT-EduKit/Hardware-Features-Demo
idf.py menuconfig
idf.py build

esp-idf v4.2でビルドできた。
さて、焼くか。

Windowsのデバイスマネージャでは、こう見えている。
今回はVirtualBoxから焼くので、VirtualBoxのデバイス設定で指定する。

image

dmesgで見ると/dev/ttyUSB0となっていた。

idf.py -p /dev/ttyUSB0 flash

はい、Permission deniedで失敗! いつも通りですな。
sudoするとexport.shで設定したものが見えないから、アクセス権を追加した。

[小ネタ]Ubuntu でttyUSB0(USBシリアル変換)が権限関連で使えない場合の対処方法 - Qiita
https://qiita.com/chromabox/items/b3ceaab6efa6edde2bda

さて、これでPermission deniedは解消したのだが、接続に失敗する。
タイムアウトしているのだが、それが終わるとCore2本体も再起動しているから、まったく分かっていないわけでもなさそうだ。
connecting中にCore2のリセットボタンを押してみたら進んだのだが、うちのノートPCはUSBの接続が甘いので、ちょうど接続がよくなっただけかもしれん。

 

ともかく、焼けた!
そして、なんか画面に出てきた!
そしてそして、再起動を繰り返すようになった……

まあ、セキュアエレメントのチップが載っていないから、そのアクセスに失敗したからだろう。

なんとなくいけそうな気がするので、このままがんばってみよう。

2021/02/07

私はHTTPをよく知らない

「自分、組み込み屋ですので」でネットワークのことから逃げられる時代はもう終わった・・・。
いや、ずいぶん前に終わっていたのだが、認める勇気がなかったのだろう。

ネットワークは、socketを開いてlistenさせ、相手側はconnectすればあとはプロトコルで勝手にやればよい、くらいの知識で十分だったのだが、もうちょっと上の方も知らないと話に追いつけないのだ。

MQTTは実装したことがあるので調べ直せば思い出しそうだが、やはりHTTPをスルーはできまい。
というわけで、今回はHTTPについてさらっとまとめよう。


HTTPといえば、やはりブラウザだろう。
昔はMosaicというブラウザがあってね、SunのSS10で見せてもらったことが記憶に残っているよ。

HyperText Transfer Protocolの略で、HTTP。

https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol
https://tools.ietf.org/html/rfc2616
https://developer.mozilla.org/ja/docs/Web/HTTP/Overview

3番目に載せたMozillaの説明がわかりやすそうだ。

  • クライアント・サーバプロトコル
  • クライアントのメッセージ:リクエスト
  • サーバのメッセージ:レスポンス
  • 直接クライアントとサーバが接続することもあるし、間にプロシキが挟まることもある。
  • プロトコルとしてはリクエスト間に関係性は無い(ステートレス)。ただCookieによってセッションという概念を持ち込むことはできる。

 

クライアントとサーバのフローはそれぞれメッセージを投げるだけなので、あとはメッセージの仕様を確認すればなんとなくHTTPがわかったと思ってよいのでは無かろうか。

HTTPメッセージ
https://developer.mozilla.org/ja/docs/Web/HTTP/Overview#http_messages

 

リンク先の画像ではちょっと分かりづらいかもしれんが、1行目はこう。

Method + (space) + Path + (space) + Version of the protocol

Pathは、たとえばcurlコマンドで "curl http://127.0.0.1/time" とアクセスしたとすると、

GET /time HTTP/1.1

となった。


むかし組み込みのHTTPサーバをデバッグしたこともあるし、デバッグ用にHTTPサーバをPocoライブラリ使って作業したことがあるのだが、暗号の処理と同じ感じ匂いがしている。
危ないので自分で実装するものじゃ無いよね、というやつだ。

ただ、自分で実装しない=自分で知っておく必要はない、ではないのだ。まあ万人が知っておく必要があるというものでもないとは思うが、知っていると楽しいと思うのだよ。