chakokuのブログ(rev4)

日々のごった煮ブログです

M5 Stick-C Plusを買った。MicroPythonを入れて使いたいが結構面倒な印象->場当たり的だがESP32のGeneric版ファームで動いた(駄文)

ESP32のDevKit等でMicroPythonを動かしてきたけど、電源供給が必要なため単独では動かせなかった。M5 Stack/M5 StickならLCDも付いているし、LiPoバッテリー内蔵なので、使いたいときにサクッと動かせて便利だ。ということでこぶりでかわいいM5 Stick-C Plusを買ってみた。

買った理由は、大量に積読になっている平凡社の太陽とか芸術新潮をヨメが捨てろと叫んでいて、スキャンしてから捨てたいと思った。PFU製の大判のスキャナはめちゃ高い*1ので、スマフォのカメラでページの写真とったらええやんとなった。スマフォで写真とるにしても、シャッターボタンをどうするか?となり、100均ではスマフォ用シャッターボタン売られてるらしい。が、マイコン小僧(苦笑)としてはシャッタボタンを自作したいと思い、BLEでシャッターボタンを作れると知りまして、だったら、ESP32+MicroPythonで作ったらええやんとなって、使いたいときに使えるEPS32といえばバッテリー内蔵のM5だとなって、M5 Stickを買ったのでした。

まだMicroPythonをインストールしていないが、、M5 StcikにMicroPythonを焼くのは多少面倒な感じであった。そもそも、M5 Stack/M5 StickCってMicroPythonで全面サポートしているのだろうか。全面サポートとは、、、M5についてるLCDとかセンサ類のドライバは自分で探して入れる感じなんだろうか。。M5 パッケージとかないのかも。
M5のサイトでもメインでサポートしているのはArduinoのようなのだが。。なぜMicroPythonは手厚くサポートされないのだろうか。。MicroPythonのサイトでは、M5 Stack ATOMがサポート対象になっている。M5 Stack ATOMは、M5シリーズの一番コンパクトなやつで、ATOMに搭載されているESP32はPicoで、Flashサイズも4MBなので、、ハード仕様はM5 Stickと同等だ。LCDや加速度センサ等のドライバ類は無視して、MicroPythonの標準ライブラリの範囲ではそのまま動くのではないかと推測、、M5 Stack ATM用ファームを焼いてみる。

ESP32側をダウンロードモードにしないといけないのかもしれませんが、、適当にesptoolで焼いてみる。
flash_idは取得できた

$ esptool.py --port  /dev/ttyS16   flash_id
esptool.py v2.8
Serial port /dev/ttyS16
Connecting....
Detecting chip type... ESP32
Chip is ESP32-PICO-D4 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 94:b9:7e:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...

MicroPythonのサイトの手順に倣って焼いてみる

esptool.py --chip esp32 --port /dev/ttys16 erase_flash
esptool.py --chip esp32 --port /dev/ttys16  write_flash -z 0x1000 esp32-20190125-v1.10.bin

と思ったが、、肝心のファームが無いようだ

No firmware is available for this board.

ソースを取ってきてビルドしてねということか??
他の人の事例を見てもUIFlowが関係していて、UIFlowは使いたくないから、UIFlowとまったく関係なしに素でMicroPythonを入れたいのだが。。だとしたら、、M5Stickにくっついている周辺デバイスは無視して、、ESP32PICOだけが存在するボードと思ってファームを焼けばいいのか。(そうすると、液晶パネルとかのデバイスは自力でドライバを入れないといけなくなる。めんどうくさい)

GitHubには、esp32の下にPICO用のソースが置かれていて、これをビルドしてくれということなのかもしれない。
micropython/ports/esp32/boards/LOLIN_S2_PICO/
ARMのビルド環境はあるけど、ESP32用はないので、そこから作らないといけない。。はぁ。。

今日の結論
M5 Stick-Cはコンパクトでかわいいが、標準の開発環境はUIFlowとかArduinoのようで、MicroPythonはメインではサポートされていない。いろんな人が自力でインストールしている。また、コアがESP32-PICO-D4なので、genericなESP32用のファームだと多分動かないと思われる(Flashの配置方法が違うので(自分の理解))(だめもとで焼いてみてもいいけど)

手元にあった古いMicroPythonの普通のESP32用ファームを試しに焼いてみた
まずflashを消去

$ esptool.py --chip esp32 --port /dev/ttyS16 erase_flash
esptool.py v2.8
Serial port /dev/ttyS16
Connecting.....
Chip is ESP32-PICO-D4 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 94:b9:7e:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 5.2s
Hard resetting via RTS pin...

ファームを焼く

$ esptool.py --chip esp32 --port /dev/ttyS16  write_flash -z 0x1000 esp32-idf3-20191220-v1.12.bin
esptool.py v2.8
Serial port /dev/ttyS16
Connecting....
Chip is ESP32-PICO-D4 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 94:b9:7e:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 1247280 bytes to 787794...
Wrote 1247280 bytes (787794 compressed) at 0x00001000 in 70.8 seconds (effective 140.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

焼くには焼けた。。ブートして動くのかどうか。。(REPL用のシリアルとか違ってるかもしれないし。。)
ブートすると以下のようなダウンロードモードで立ち上がってきた

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x0 (DOWNLOAD_BOOT(UART0/UART1/SDIO_FEI_FEO_V2))
waiting for download

ブートできないからだろうか。それとも、ブートスイッチが働いている??
最新版ファームを落としてもう一度焼きなおしてみる

$ esptool.py --chip esp32 --port /dev/ttyS16  write_flash -z 0x1000 esp32-20210902-v1.17.bin
esptool.py v2.8
Serial port /dev/ttyS16
Connecting......
Chip is ESP32-PICO-D4 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 94:b9:7e:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 1527504 bytes to 987584...
Wrote 1527504 bytes (987584 compressed) at 0x00001000 in 88.8 seconds (effective 137.7 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

シリアルコンソールで確認
適当に改行を打つとプロントが返る。。汎用のESP32ファームで動いた。Flashの接続方法とか違ってるはずなんだけど。。番地が同じだから動いてしまうのだろうか。。よくわからない。

>>>
MPY: soft reboot
MicroPython v1.17 on 2021-09-02; ESP32 module with ESP32
Type "help()" for more information.
>>> help()
Welcome to MicroPython on the ESP32!

For generic online docs please visit http://docs.micropython.org/

For access to the hardware use the 'machine' module:

import machine
pin12 = machine.Pin(12, machine.Pin.OUT)
pin12.value(1)
pin13 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP)
print(pin13.value())
i2c = machine.I2C(scl=machine.Pin(21), sda=machine.Pin(22))
i2c.scan()
i2c.writeto(addr, b'1234')
i2c.readfrom(addr, 4)

Basic WiFi configuration:

import network
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
sta_if.scan()                             # Scan for available access points
sta_if.connect("<AP_name>", "<password>") # Connect to an AP
sta_if.isconnected()                      # Check for successful connection

Control commands:
  CTRL-A        -- on a blank line, enter raw REPL mode
  CTRL-B        -- on a blank line, enter normal REPL mode
  CTRL-C        -- interrupt a running program
  CTRL-D        -- on a blank line, do a soft reset of the board
  CTRL-E        -- on a blank line, enter paste mode

For further help on a specific object, type help(obj)
For a list of available modules, type help('modules')
>>> help('modules')
__main__          gc                ubinascii         urandom
_boot             inisetup          ubluetooth        ure
_onewire          machine           ucollections      urequests
_thread           math              ucryptolib        uselect
_uasyncio         micropython       uctypes           usocket
_webrepl          neopixel          uerrno            ussl
apa106            network           uhashlib          ustruct
btree             ntptime           uheapq            usys
builtins          onewire           uio               utime
cmath             uarray            ujson             utimeq
dht               uasyncio/__init__ umqtt/robust      uwebsocket
ds18x20           uasyncio/core     umqtt/simple      uzlib
esp               uasyncio/event    uos               webrepl
esp32             uasyncio/funcs    upip              webrepl_setup
flashbdev         uasyncio/lock     upip_utarfile     websocket_helper
framebuf          uasyncio/stream   upysh
Plus any modules on the filesystem

仕事だったら、なんとなく動きましただとクビだけど、、趣味だから結果オーライでいいだろう。ちゃんとファイルシステムも使えるので非常に楽。ただし、、LCDドライバとかは自力でいれないといけないだろう。UIFlowに頼らずにやっていくので、ある程度の不便はしょうがないだろう。

>>> from upysh import *

upysh is intended to be imported using:
from upysh import *

To see this help text again, type "man".

upysh commands:
pwd, cd("new_dir"), ls, ls(...), head(...), cat(...)
newfile(...), mv("old", "new"), rm(...), mkdir(...), rmdir(...),
clear

>>> ls()
     139 boot.py
>>> cat('boot.py')
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
#import webrepl
#webrepl.start()

電池内蔵でポケットに入れて持ち歩けるパッケージでMicroPythonが動くといろいろ楽しめる気がする(こんな動かし方でいいのかどうか分からないけど)。

素で入れるとLEDも点灯しないので、電源がOnかOffか分からない。自動でPowerOffにはならないだろうから、電源Onの場合はLEDを点灯させる必要あり。何も工夫しない場合は以下で点灯する。が、、これでは明るすぎてすぐにバッテリーが減るだろう。PWMで暗くするか、tickタイマで瞬間光る程度にすべきかと。

from machine import Pin
led = Pin(10, Pin.OUT)
led.off()                                #  LEDのアノード側が3.3Vに接続され、カソード側がGPIOに接続されていると思われる

もう少し改良して、電源Onの時にPWMでLEDが暗く点灯するように仕込みました(Flash上のファイル、boot.pyにPWMによるLED点灯コードを追加)
file:boot.py

import machine
pwm_led = machine.PWM(machine.Pin(10),freq=100)
pwm_led.duty(1000)   # 0-1023

M5 Stick-Cの電源が入るとLEDが薄暗く光るので、電源切り忘れが起きにくくなることを期待。下記は薄暗く点灯しているところ

■ご参考
https://docs.m5stack.com/en/core/m5stickc_plus
https://micropython.org/download/M5STACK_ATOM/
https://github.com/micropython/micropython/tree/master/ports/esp32/boards/LOLIN_S2_PICO

*1:例:ScanSnap SV600等、6万する。これで300ページスキャンしたとして、1ページあたり200円、1ページ200円ってどんだけ高い情報やねんとなってやめました。