目次

MicroPython

since 2016-10-04

概要

関連記事

リンク

CPython との違い

urequests

urllib.urequest

>>> import upip
>>> upip.install("urllib.urequest")
>>> from urllib import urequest
>>> response = urequest.urlopen("http://example.jp/index.html")
>>> print(response.read())
>>> response.close()

uaiohttpclient

>>> import upip
>>> upip.install("micropython-uaiohttpclient")

picoweb

>>> import upip
>>> upip.install("pycopy-ulogging")
Installing to: /lib/
Installing pycopy-ulogging 0.3 from https://files.pythonhosted.org/packages/56/85/47a6790260c85f0dad460124d1f9a6dbdaa0b0ac33b0ac89194f6f106276/pycopy-ulogging-0.3.tar.gz
>>> upip.install("picoweb")
Installing to: /lib/
Installing picoweb 1.8.2 from https://files.pythonhosted.org/packages/c2/22/a1eb0cf52b72e818fe47acadaf8ade200d7c0c7c6fc5acc7b47f53f2a338/picoweb-1.8.2.tar.gz
Installing pycopy-uasyncio 3.7 from https://files.pythonhosted.org/packages/e5/58/80b8b403c52ea88d44844570dbe487d7a4b3045ae0ecad0c9f4dbac0d104/pycopy-uasyncio-3.7.tar.gz
Installing pycopy-pkg_resources 0.2.1 from https://files.pythonhosted.org/packages/05/4a/5481a3225d43195361695645d78f4439527278088c0822fadaaf2e93378c/pycopy-pkg_resources-0.2.1.tar.gz
Installing pycopy-uasyncio.core 2.3.2 from https://files.pythonhosted.org/packages/ca/b2/c5bba0bde7022b6d927a6144c026d7bf310d3f8a20e031571fbf1a08a433/pycopy-uasyncio.core-2.3.2.tar.gz

aioble

いろいろ

uasyncio

ツール

rshell

mpremote

MicroPython 1.12 + ESP32 (2019)

since 2019-12-25

https://github.com/micropython/micropython/releases/tag/v1.12

https://micropython.org/download#esp32

http://docs.micropython.org/en/latest/esp32/tutorial/intro.html

機材

Windows 10 + WSL Ubuntu

$ pwd
/home/nishimotz/esp/v1.12

$ ls -l
total 1920
-rwxrwxrwx 1 nishimotz nishimotz 1408544 Dec 25 10:33 esp32-idf4-20191225-v1.12-5-g42e45bd69.bin

$ sudo /usr/local/bin/python3.8 -m pip install esptool

$ esptool.py
esptool.py v2.8

途中略

$ esptool.py --port /dev/ttyS8 erase_flash

Erasing flash (this may take a while)...
Chip erase completed successfully in 4.3s
Hard resetting via RTS pin...

$ esptool.py --chip esp32 --port /dev/ttyS8 write_flash -z 0x1000 esp32-idf4-20191225-v1.12-5-g42e45bd69.bin

Wrote 1408544 bytes (894648 compressed) at 0x00001000 in 78.7 seconds (effective 143.1 kbit/s)...
Hash of data verified.

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

TeraTerm

MicroPython v1.12-5-g42e45bd69 on 2019-12-25; ESP32 module with ESP32
Type "help()" for more information.
>>>

ESP32 BLE

http://docs.micropython.org/en/latest/library/ubluetooth.html

iPod touch の LightBlue アプリで見守りつつ下記を実行する。

>>> from ubluetooth import BLE
>>> ble = BLE()
>>> ble.active(True)
I (59560) BTDM_INIT: BT controller compile version [a482cda]
I (66078) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (66178) phy: phy_version: 4102, 2fa7a43, Jul 15 2019, 13:06:06, 0, 0
GAP procedure initiated: stop advertising.
True
>>> ble.gap_advertise(100, adv_data='Python')
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0

LightBlue に ESP32 というペリフェラルが見える(ことがある)。

だが Advertisement data が No になっている。

examples を動かす

素直にソースコードから examples を探そう。

https://github.com/micropython/micropython/tree/v1.12/examples/bluetooth

これらをローカルにダウンロードする。

ファイルをデバイスにコピーして実行するので WSL から ampy を使う。

TeraTerm で COM7 でつながったので ttyS7 を指定する。

$ sudo /usr/local/bin/python3.8 -m pip install adafruit-ampy
$ export AMPY_PORT=/dev/ttyS7

main.py を作る

$ cat main.py

from ble_temperature import demo
demo()

TeraTerm が disconnect の状態で、WSL から下記を実行

$ ampy put ble_advertising.py
$ ampy put ble_temperature.py
$ ampy put main.py

コンソールを見ながらやりたいので TeraTerm から connect して、デバイスの RESET を押す。

ここでは Android アプリの BLE Scanner (Bluepixel) を使ってみる。

mpy-temp という名前のデバイスが見つかった。

connect すると

の PRIMARY SERVICE が見つかる。

ENVIRONMENTAL SENSING を選択すると

という READ / NOTIFY できる項目がある。

NOTIFY を有効にすると10秒ごとに値が更新される。

Alert サービス

ble_temperature を流用して Alert サービスが作れることを確認した。

# ble_alert.py
 
import bluetooth
import struct
import time
from ble_advertising import advertising_payload
from micropython import const
import machine
 
_IRQ_CENTRAL_CONNECT    = const(1 << 0)
_IRQ_CENTRAL_DISCONNECT = const(1 << 1)
_IRQ_GATTS_WRITE        = const(1 << 2)
 
_ALERT_UUID = bluetooth.UUID(0x1802)
_ALERT_CHAR = (bluetooth.UUID(0x2a06), bluetooth.FLAG_WRITE,)
_ALERT_SERVICE = (_ALERT_UUID, (_ALERT_CHAR,),)
_ADV_APPEARANCE = const(768)
 
class BLEAlert:
    def __init__(self, ble, name='mpy-alert', update_alert=None):
        self._update_alert = update_alert
        self._ble = ble
        self._ble.active(True)
        self._ble.irq(handler=self._irq)
        ((self._handle,),) = self._ble.gatts_register_services((_ALERT_SERVICE,))
        self._connections = set()
        self._payload = advertising_payload(name=name, services=[_ALERT_UUID], appearance=_ADV_APPEARANCE)
        self._advertise()
 
    def _irq(self, event, data):
        if event == _IRQ_CENTRAL_CONNECT:
            conn_handle, _, _, = data
            self._connections.add(conn_handle)
        elif event == _IRQ_CENTRAL_DISCONNECT:
            conn_handle, _, _, = data
            self._connections.remove(conn_handle)
            self._advertise()
        elif event == _IRQ_GATTS_WRITE:
            conn_handle, attr_handle = data
            data = self._ble.gatts_read(self._handle)
            value = struct.unpack('<b', data)[0]
            if self._update_alert:
                self._update_alert(value)
 
    def _advertise(self, interval_us=500000):
        self._ble.gap_advertise(interval_us, adv_data=self._payload)
 
 
def demo():
    pin2 = machine.Pin(2, machine.Pin.OUT)
    pin2.value(0)
 
    def update_alert(value):
        pin2.value(1 if value else 0)
 
    ble = bluetooth.BLE()
    alert = BLEAlert(ble, update_alert=update_alert)
 
    while True:
        time.sleep_ms(1000)
 
 
if __name__ == '__main__':
    demo()

これで BLE Scanner から mpy-alert が見つかり、接続でき、1か2を書き込むと IO2 の LED が点灯する。

_ADV_APPEARANCE は ble_temperature と同じ値を使っているが、ちゃんと調べるべき。

インターフェース 2018年1月号 / 2018年9月号 (2017)

2017年11月25日発売 CQ出版 Interface(インターフェース) 2018年1月号寄稿しました

「第4部 マイコンPython無線センシング実験室」

<html> <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=qf_sp_asin_til&t=r4wh-22&m=amazon&o=9&p=8&l=as1&IS1=1&detail=1&asins=B0776K46DV&linkId=4eb4e1754833c75c1e83398814d4cc1e&bc1=FFFFFF&lt1=_blank&fc1=333333&lc1=0066C0&bg1=FFFFFF&f=ifr">

  </iframe>

</html>

2018年9月号にも執筆しました。

電子工作のためのPython (2017)

2016年11月12日(土曜) PyCon mini Hiroshima 2016 で MicroPython の話をしました

ESP8266 port

更新記録:2016-10-17 v1.8.5 で動作確認

https://www.kickstarter.com/projects/214379695/micropython-on-the-esp8266-beautifully-easy-iot

Adafruit の解説とビデオ

esp8266-20161017-v1.8.5.bin をダウンロード。

入手したもの:スイッチサイエンス ESPr One(Arduino Uno同一形状 ESP-WROOM-02開発ボード)

IDE からスケッチの書き込みはいちおう確認

MicroPython on the ESP8266

http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/intro.html#deploying-the-firmware

これを入れたときに技適がどうなるかはよくわからないので、自己責任でお願いします。

いつもの MacPorts 環境にまず esptool を入れる

https://github.com/themadinventor/esptool/

esptool は Python 3.x 未対応らしい。

$ sudo python2 -m pip install esptool

$ which esptool.py
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/esptool.py

ESPr One を USB で Mac に接続。

シリアルポート確認は ls /dev/cu* で可能。

$ esptool.py -p /dev/cu.usbserial-DN01J32J flash_id
esptool.py v1.1
Connecting...
Manufacturer: a1
Device: 4016

$ esptool.py -p /dev/cu.usbserial-DN01J32J chip_id
esptool.py v1.1
Connecting...
Chip ID: 0x00082ed6

$ esptool.py -p /dev/cu.usbserial-DN01J32J read_mac
esptool.py v1.1
Connecting...
MAC: 5c:cf:7f:08:2e:d6

繋がっているようだ。

$ esptool.py -p /dev/cu.usbserial-DN01J32J --baud 460800 write_flash --flash_size=8m 0 esp8266-20161017-v1.8.5.bin

esptool.py v1.1
Connecting...
Running Cesanta flasher stub...
Flash params set to 0x0020
Writing 565248 @ 0x0... 565248 (100 %)
Wrote 565248 bytes at 0x0 in 14.7 seconds (307.6 kbit/s)...
Leaving...

終わった。

Arduino IDE のシリアルモニタで

>>> a = 'hello'
>>> a[-1]
'o'
>>> 

動いた!!

チュートリアルによるとすでに WiFi が有効になっているらしい:

WebREPL daemon started on ws://192.168.4.1:8266
Started webrepl in setup mode
could not open file 'main.py' for reading

MicroPython v1.8.4-10-gbc28ac8 on 2016-09-09; ESP module with ESP8266
Type "help()" for more information.

>>> help()
Welcome to MicroPython!

For online docs please visit http://docs.micropython.org/en/latest/esp8266/ .
For diagnostic information to include in bug reports execute 'import port_diag'.

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
# Change name/password of ESP8266's AP:
ap_if = network.WLAN(network.AP_IF)
ap_if.config(essid="<AP_NAME>", authmode=network.AUTH_WPA_WPA2_PSK, password="<password>")

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)

>>> import esp
>>> esp.check_fw()
size: 562812
md5: d7157c7b8c04bc252192de49358543fb
True


>>> import port_diag
FlashROM:
Flash ID: 1640a1 (Vendor: a1 Device: 4016)
Flash bootloader data:
Byte @2: 00
Byte @3: 40 (Flash size: 4MB Flash freq: 40MHZ)
Firmware checksum:
size: 562812
md5: d7157c7b8c04bc252192de49358543fb
True

Networking:
STA ifconfig: ('0.0.0.0', '0.0.0.0', '0.0.0.0', '208.67.222.222')
AP ifconfig: ('192.168.4.1', '255.255.255.0', '192.168.4.1', '208.67.222.222')
Free WiFi driver buffers of type:
0: 8
1: 0
2: 8
3: 4
4: 7
lwIP PCBs:
Active PCB states:
Listen PCB states:
Local port 8266, foreign port 20480 snd_nxt 258 rcv_nxt 1073707032 State: LISTEN
TIME-WAIT PCB states:

screen & picocom

Auduino IDE シリアルモニタを使わなくても以下でアクセスできる:

$ screen /dev/cu.usbserial-DN01J32J 115200

screen を終了するには control+A K という話

$ sudo port install picocom

$ which picocom
/opt/local/bin/picocom

$ picocom --baud 115200 /dev/cu.usbserial-DN01J32J

picocom を終了するには Ctrl+A Ctrl+X

https://linux.die.net/man/8/picocom

Raspbian で作業する

Raspberry Pi 3 の USB ポートに ESPr One をつなぐ。

$ sudo apt-get install picocom
$ sudo python2 -m pip install esptool
$ esptool.py -p /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m 0 esp8266-20161030-v1.8.5-82-ge429daa.bin
$ picocom --baud 115200 /dev/ttyUSB0

LED1 の点滅

>>> import machine
>>> pin14 = machine.Pin(14, machine.Pin.OUT)
>>> pin14.value(1) # 点灯
>>> pin14.value(0) # 消灯

https://www.switch-science.com/catalog/2620/ に「LED1 本ボードではデジタル14番ピン」と書いてある。

PWM でだんだん明るくなる:

>>> pwm14 = machine.PWM(pin14)
>>> pwm14.freq(500)
>>> import time
>>> for i in range(1024):
...     time.sleep(0.01)
...     pwm14.duty(i)

スイッチで割り込み

「モード切替ボタン(MODE):ボタンを押している間はGPIO0がLOW」と書かれているのでやってみる:

>>> def callback(p):
...     print('pin change', p)
...     
>>> pin0 = machine.Pin(0, machine.Pin.IN)
>>> pin0.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback)
<IRQ>

MODE ボタンを押すと:

>>> pin change Pin(0)

RTCなど

CPU クロック

>>> machine.freq()
80000000

リアルタイムクロック(あるのか。。)

>>> rtc = machine.RTC()
>>> rtc.datetime()
(2000, 1, 1, 5, 0, 38, 16, 87)
>>> rtc.datetime()
(2000, 1, 1, 5, 0, 38, 35, 869)
>>> rtc.datetime()
(2000, 1, 1, 5, 0, 38, 47, 423)

ファイルシステム

チュートリアルと順番が逆になったけどファイルシステム:

>>> import os
>>> os.listdir()
['boot.py']

WebREPL

シリアル接続のターミナルで WebREPL を初期化すると、以後の作業は WebREPL だけで可能になる。

作業環境の WiFi ルーターにクライアントとして繋がるようにしておく。 そしてデフォルトの AP モードの接続を止めてやる。

>>> import network                                                                                                             
>>> sta_if = network.WLAN(network.STA_IF)                                                                                      
>>> sta_if.active()                                                                                                            
True                                                                                                                           
>>> sta_if.ifconfig()                                                                                                          
('192.168.1.27', '255.255.255.0', '192.168.1.1', '192.168.1.1')                                                                

>>> ap_if = network.WLAN(network.AP_IF)                                                                                        
>>> ap_if.active(False)                                                                                                             
>>> ap_if.active()                                                                                                             
False                                                                                                                          

ここでは 192.168.1.27 でルーターに繋がったこととする。

それから、ここに書いてあるとおりにやる。

https://learn.adafruit.com/micropython-basics-esp8266-webrepl/access-webrepl

https://github.com/micropython/webrepl/archive/master.zip

MicroPython v1.8.5-10-g0e69e6b on 2016-10-17; ESP module with ESP8266
Type "help()" for more information.
>>> import webrepl
>>> webrepl.start()
WebREPL daemon started on ws://192.168.4.1:8266
WebREPL daemon started on ws://192.168.1.27:8266
Started webrepl in normal mode
>>> 

webrepl.html を Firefox で開く。

ページ内のアドレス欄に

ws://192.168.1.27:8266/

と書いて [connect] ボタンを押すと接続できて、下記のようになる:

Welcome to MicroPython!                                                                                                                            
Welcome to MicroPython WebREPL!                                                                                                                    
                                                                                                                                                   
This is the first time you connect to WebREPL, so please set a password                                                                            
to use for the following WebREPL sessions. Once you enter the password                                                                             
twice, your board will reboot with WebREPL running in active mode. On                                                                              
some boards, you may need to press reset button or reconnect power.                                                                                
                                                                                                                                                   
New password: ******                                                                                                                               
Confirm password: ******                                                                                                                           
Password successfully set, restarting...                                                                                                           
Disconnected         

ここで設定するパスワードは以後の作業でずっと必要になる。

パスワードを2回入力すると接続が切れる。

シリアルのターミナルが下記のようになる:

WebREPL daemon started on ws://0.0.0.0:8266
Started webrepl in normal mode
could not open file 'main.py' for reading

MicroPython v1.8.4-10-gbc28ac8 on 2016-09-09; ESP module with ESP8266
Type "help()" for more information.
>>> 

もういちど WebREPL で [connect] を押すと:

シリアルターミナル

WebREPL connection from: ('192.168.1.4', 53893)

WebREPL 側

Welcome to MicroPython!                                                                                                                            
Password:   
WebREPL connected                                                                                                                                  
>>>          

ここで USB ケーブルを Mac から抜いて、ただの電源アダプタにつないでやる。

するとさきほど設定した情報で WiFi ルーターに再接続されるので、Mac から WebREPL に再接続できる。

darwin (Mac) port

Mac のネイティブ実行ファイルとしてビルドする:

$ git clone https://github.com/micropython/micropython.git
$ cd micropython/
$ git submodule update --init
$ cd unix
$ make axtls
$ make
$ ./micropython
MicroPython v1.8.4-120-g99d62c4 on 2016-10-04; darwin version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
[4, 2, 1, 9, 7, 6, 14, 12, 11, 19, 17, 16, 24, 22, 21, 29, 27, 26, 34, 32, 31, 39, 37, 36, 44, 42, 41, 49, 47, 46]
>>> 

UNIX port

since 2016-12-07

updated on 2018-05-12

Windows Subsystem for Linux (Ubuntu) で検証。

https://github.com/micropython/micropython/issues/1991

http://forum.micropython.org/viewtopic.php?t=517

$ sudo apt-get install pkg-config libffi-dev
$ cd ports/unix
$ make axtls
$ make

LINK micropython
   text    data     bss     dec     hex filename
      2       0       0       2       2 build/build/frozen.o
   5006    3735       0    8741    2225 build/build/frozen_mpy.o
 391947    5920    2456  400323   61bc3 micropython

$ ./micropython
MicroPython v1.9.3-637-gaeaace0 on 2018-05-12; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>>

$ sudo make install
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
install -d /usr/local/bin
install micropython /usr/local/bin/micropython

$ which micropython
/usr/local/bin/micropython

$ micropython -m upip -h
upip - Simple PyPI package manager for MicroPython
Usage: micropython -m upip install [-p <path>] <package>... | -r <requirements.txt>
import upip; upip.install(package_or_list, [<path>])

If <path> is not given, packages will be installed into sys.path[1]
(can be set from MICROPYPATH environment variable, if current system
supports that).
Current value of sys.path[1]: /home/nishimotz/.micropython/lib

Note: only MicroPython packages (usually, named micropython-*) are supported
for installation, upip does not support arbitrary code in setup.py.

upip

since 2018-05-12

http://docs.micropython.org/en/latest/unix/reference/packages.html

$ micropython -m upip install micropython-pystone_lowmem
Installing to: /home/nishimotz/.micropython/lib/
Warning: pypi.org SSL certificate is not validated
Installing micropython-pystone_lowmem 3.4.2-4 from https://files.pythonhosted.org/packages/2b/e9/cd38fe0fe0024193e6b8132b8c370c28ccd4bd8fae92dd5ae3b54d08768f/micropython-pystone_lowmem-3.4.2-4.tar.gz

$ micropython
MicroPython v1.9.3-637-gaeaace0 on 2018-05-12; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> import pystone_lowmem
>>> pystone_lowmem.main()
Pystone(1.2) time for 500 passes = 6ms
This machine benchmarks at 83333 pystones/second
>>>
$ pwd
path-to/micropython/ports/unix

$ ls modules/
upip.py  upip_utarfile.py

$ micropython -m upip install -p modules micropython-pystone_lowmem
Installing to: modules/

$ ls modules/
pystone_lowmem.py  upip.py  upip_utarfile.py

$ make clean
$ make axtls
$ make
$ sudo make install
$ rm ~/.micropython/lib/*

$ micropython
MicroPython v1.9.3-637-gaeaace0 on 2018-05-12; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> import pystone_lowmem
>>> pystone_lowmem.main()
Pystone(1.2) time for 500 passes = 6ms
This machine benchmarks at 83333 pystones/second
>>>

MicroPython ESP32 (2017)

since 2017-03-25

入手した dev board (1月末に購入したまま放置していた)

秋月の dev board には後述する Blue LED がないらしい。

https://github.com/micropython/micropython-esp32/tree/esp32/esp32

うまく行く方法を知りたい人は Ubuntu でやり直すところまで読み飛ばしてください。

Windows 10 から

結末としては、FLASH のオプションを変えてビルドしなそうとしたら、ものすごく遅くなって、終わりそうにないので諦めた。

ESP-IDF setup (Windows)

step2 だけでいいと書いてある。

MSYS2 は Git for Windows に入っているものだと make がないので。。

"C:\Program Files\Git\usr\bin\bash"

ではなく、上記ページから落とした

esp32_win32_msys2_environment_and_toolchain-20170111.zip

の msys32\msys2_shell.cmd を実行したターミナルで、以下の作業を行う。

$ pwd
/c/work/esp32

$ git clone --recursive https://github.com/espressif/esp-idf.git
Cloning into 'esp-idf'...
remote: Counting objects: 20248, done.
remote: Total 20248 (delta 0), reused 0 (delta 0), pack-reused 20247
Receiving objects: 100% (20248/20248), 15.32 MiB | 1.11 MiB/s, done.
Resolving deltas: 100% (13538/13538), done.
Checking out files: 100% (1955/1955), done.
Submodule 'components/aws_iot/aws-iot-device-sdk-embedded-C' (https://github.com/espressif/aws-iot-device-sdk-embedded-C.git) registered for path 'components/aws_iot/aws-iot-device-sdk-embedded-C'
Submodule 'components/bt/lib' (https://github.com/espressif/esp32-bt-lib.git) registered for path 'components/bt/lib'
Submodule 'components/coap/libcoap' (https://github.com/obgm/libcoap.git) registered for path 'components/coap/libcoap'
Submodule 'components/esp32/lib' (https://github.com/espressif/esp32-wifi-lib.git) registered for path 'components/esp32/lib'
Submodule 'components/esptool_py/esptool' (https://github.com/espressif/esptool.git) registered for path 'components/esptool_py/esptool'
Submodule 'components/micro-ecc/micro-ecc' (https://github.com/kmackay/micro-ecc.git) registered for path 'components/micro-ecc/micro-ecc'
Cloning into 'C:/work/esp32/esp-idf/components/aws_iot/aws-iot-device-sdk-embedded-C'...
Cloning into 'C:/work/esp32/esp-idf/components/bt/lib'...
Cloning into 'C:/work/esp32/esp-idf/components/coap/libcoap'...
Cloning into 'C:/work/esp32/esp-idf/components/esp32/lib'...
Cloning into 'C:/work/esp32/esp-idf/components/esptool_py/esptool'...
Cloning into 'C:/work/esp32/esp-idf/components/micro-ecc/micro-ecc'...
Submodule path 'components/aws_iot/aws-iot-device-sdk-embedded-C': checked out '7132505b00d2dd57f48478e75efa636021919aae'
Submodule path 'components/bt/lib': checked out '9a4bb1d5287572664f170f9df4dbfd71babdfc68'
Submodule path 'components/coap/libcoap': checked out '6468887a12666f88b8704d797fc176cd4f40ee4c'
Submodule path 'components/esp32/lib': checked out 'c88869b1aca5a062d1ebc5e0199fd8720cb08710'
Submodule path 'components/esptool_py/esptool': checked out '907273664ada32fc33f3fbfeba99550512c67e4d'
Submodule path 'components/micro-ecc/micro-ecc': checked out '14222e062d77f45321676e813d9525f32a88e8fa'

ここをみて

https://github.com/micropython/micropython-esp32/blob/esp32/esp32/Makefile

ESPIDF_SUPHASH := c06cc31d85cc700e1dbddbe527d4282c4bc5845a

であることを知る。

$ cd /c/work/esp32/esp-idf

$ git checkout c06cc31d85cc700e1dbddbe527d4282c4bc5845a
warning: unable to rmdir components/aws_iot/aws-iot-device-sdk-embedded-C: Directory not empty
M       components/esp32/lib
M       components/esptool_py/esptool
Note: checking out 'c06cc31d85cc700e1dbddbe527d4282c4bc5845a'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at c06cc31... Merge branch 'bugfix/partition_and_mmap_issues' into 'master'

上の階層に戻って本体を clone する

$ cd ..

$ git clone --recursive https://github.com/micropython/micropython-esp32.git
Cloning into 'micropython-esp32'...
remote: Counting objects: 51026, done.

make する

$ export ESPIDF=/c/work/esp32/esp-idf

$ cd micropython-esp32

Git for Windows の MSYS には make がなくてこうなる

$ make -C mpy-cross
bash: make: command not found

ちゃんと toolchain を使うと、

$ pwd
/c/work/esp32/micropython-esp32

$ make -C mpy-cross
make: Entering directory '/c/work/esp32/micropython-esp32/mpy-cross'
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
mkdir -p build/genhdr
Generating build/genhdr/mpversion.h
GEN build/genhdr/qstr.i.last
GEN build/genhdr/qstr.split
GEN build/genhdr/qstrdefs.collected.h
QSTR updated
GEN build/genhdr/qstrdefs.generated.h
mkdir -p build/py/
mkdir -p build/py/../extmod/
mkdir -p build/py/../lib/embed/
mkdir -p build/py/../lib/utils/
CC ../py/mpstate.c
CC ../py/nlrx86.S
CC ../py/nlrx64.S
CC ../py/nlrthumb.c
CC ../py/nlrxtensa.S
CC ../py/nlrsetjmp.c

...

CC ../py/../lib/utils/printf.c
CC main.c
CC gccollect.c
LINK mpy-cross
   text    data     bss     dec     hex filename
 176137    2624     724  179485   2bd1d mpy-cross
make: Leaving directory '/c/work/esp32/micropython-esp32/mpy-cross'

おわった。

すでに export ESPIDF=/c/work/esp32/esp-idf しているという前提で続き。

$ cd esp32
$ make
...

MPY modules/apa106.py
MPY modules/dht.py
Traceback (most recent call last):
  File "modules/dht.py", line 1
SyntaxError: invalid syntax
make: *** [../py/mkrules.mk:118: build/frozen_mpy/dht.mpy] Error 1

止まってしまった。

$ cat modules/dht.py
../../esp8266/scripts/dht.py

$ ls -la modules/dht.py
-rw-r--r-- 1 nishimotz nishimotz 28 Mar 25 12:15 modules/dht.py

あーこれシンボリックリンクか。。。

https://github.com/micropython/micropython-esp32/tree/esp32/esp32/modules

git config core.symlinks true しとけばよかったらしい。

clone しなおすのが面倒なのでコピーする。

$ cd modules
$ cp ../../esp8266/scripts/dht.py .
$ cp ../../esp8266/modules/ds18x20.py .
$ cp ../../esp8266/modules/onewire.py .

最後は?

$ cat urequests.py
../../../micropython-lib/urequests/urequests.py

micropython-lib いるのか

https://github.com/micropython/micropython-lib

$ cd ../../../
$ git clone https://github.com/micropython/micropython-lib.git
$ cd micropython-esp32/esp32/modules
$ cp ../../../micropython-lib/urequests/urequests.py .

つづき

$ cd ..
$ make

...

CC /c/work/esp32/esp-idf/components/wpa_supplicant/port/os_xtensa.c
LINK build/application.elf
   text    data     bss     dec     hex filename
 650793  164104  121328  936225   e4921 build/application.elf
Create build/application.bin
esptool.py v2.0-beta2
Create build/firmware.bin
bootloader      9408
partitions      3072
application   937776
total        1003312

おわった

USB-MicroUSB ケーブルで ESP32 ボードをPCにつなぐ。

# Makefile
PORT ?= COM4
BAUD ?= 115200
$ make erase
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
Erasing flash
esptool.py v2.0-beta2
Connecting........___
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 2.2s
Hard resetting...

$ make deploy
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
Writing build/firmware.bin to the board
esptool.py v2.0-beta2
Connecting........___
Uploading stub...
Running stub...
Stub running...
Attaching SPI flash...
Configuring flash size...
Compressed 1003312 bytes to 546234...
Wrote 1003312 bytes (546234 compressed) at 0x00000000 in 48.2 seconds (effective 166.7 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting...

TeraTerm で COM4 につないでリセットしたが、MicroPython 起動せず。

ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0x00
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:QIO, clock div:2
load:0x3fff0008,len:8
load:0xffffffff,len:-1

esptool.py で頑張ってみる

うまくいかないので esptool.py の動作確認からやり直す。

$ $ESPIDF/components/esptool_py/esptool/esptool.py -h
usage: esptool [-h] [--chip {auto,esp8266,esp32}] [--port PORT] [--baud BAUD]
               [--before {default_reset,no_reset}]
               [--after {hard_reset,soft_reset,no_reset}] [--no-stub]
               {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,version}
               ...

esptool.py v2.0-beta2 - ESP8266 ROM Bootloader Utility

positional arguments:
  {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,version}
                        Run esptool {command} -h for additional help
    load_ram            Download an image to RAM and execute
    dump_mem            Dump arbitrary memory to disk
    read_mem            Read arbitrary memory location
    write_mem           Read-modify-write to arbitrary memory location
    write_flash         Write a binary blob to flash
    run                 Run application code in flash
    image_info          Dump headers from an application image
    make_image          Create an application image from binary files
    elf2image           Create an application image from ELF file
    read_mac            Read MAC address from OTP ROM
    chip_id             Read Chip ID from OTP ROM
    flash_id            Read SPI flash manufacturer and device ID
    read_flash_status   Read SPI flash status register
    write_flash_status  Write SPI flash status register
    read_flash          Read SPI flash content
    verify_flash        Verify a binary blob against flash
    erase_flash         Perform Chip Erase on SPI flash
    erase_region        Erase a region of the flash
    version             Print esptool version

optional arguments:
  -h, --help            show this help message and exit
  --chip {auto,esp8266,esp32}, -c {auto,esp8266,esp32}
                        Target chip type
  --port PORT, -p PORT  Serial port device
  --baud BAUD, -b BAUD  Serial port baud rate used when flashing/reading
  --before {default_reset,no_reset}
                        What to do before connecting to the chip
  --after {hard_reset,soft_reset,no_reset}, -a {hard_reset,soft_reset,no_reset}
                        What to do after esptool.py is finished
  --no-stub             Disable launching the flasher stub, only talk to ROM
                        bootloader. Some features will not be available.


$ $ESPIDF/components/esptool_py/esptool/esptool.py -p COM4 -b 115200 flash_id
esptool.py v2.0-beta2
Connecting........_
Detecting chip type... ESP32
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016
Hard resetting...
$ $ESPIDF/components/esptool_py/esptool/esptool.py -p COM4 -b 115200 write_flash 0 build/application.bin
esptool.py v2.0-beta2
Connecting........__
Detecting chip type... ESP32
Uploading stub...
Running stub...
Stub running...
Attaching SPI flash...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 937776 bytes to 540199...
Wrote 937776 bytes (540199 compressed) at 0x00000000 in 47.6 seconds (effective 157.6 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting...

やっぱり起動せず

>ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
Falling back to built-in command interpreter.
OK
>

エラーメッセージで探した

https://github.com/micropython/micropython-esp32/issues/49

You might need to use FLASH_MODE = dio and FLASH_SIZE = 2MB config settings in your GNUmakefile.

とのことだ。。修正して make からやりなおしかな。。

Ubuntu 16.10 amd64 でやり直した

$ sudo apt-get install git wget make libncurses-dev flex bison gperf python python-serial
$ mkdir esp32-setup
$ cd esp32-setup
$ wget --no-check-certificate https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz
$ cd ..
$ mkdir esp
$ cd esp
$ tar -xzf ../esp32-setup/xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz 
$ cd ..
$ export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin
$ git clone --recursive https://github.com/espressif/esp-idf.git
$ cd esp-idf/
$ git checkout c06cc31d85cc700e1dbddbe527d4282c4bc5845a
$ cd ..
$ git clone --recursive https://github.com/micropython/micropython-esp32.git
$ git clone https://github.com/micropython/micropython-lib.git
$ export ESPIDF=$HOME/esp/esp-idf
$ cd micropython-esp32/
$ make -C mpy-cross
$ cd esp32

Makefile を編集。

FLASH_MODE = dio
FLASH_SIZE = 2MB
$ make

最後の make erase / make deploy は root で実行する。

$ su
# export ESPIDF=/home/(USERNAME)/esp/esp-idf
# make erase
# make deploy

FLASH_MODE をちゃんと設定すればすんなり動いた。

https://github.com/Nicholas3388/LuaNode

Download the DOIT dev-board schematic here と書かれているところから回路図を参照。GPIO2 が青いLEDであることを把握。

I (1298) heap_alloc_caps: Initializing. RAM available for dynamic allocation:
I (1299) heap_alloc_caps: At 3FFD02B0 len 0000FD50 (63 KiB): DRAM
I (1308) heap_alloc_caps: At 3FFE8000 len 00018000 (96 KiB): D/IRAM
I (1330) heap_alloc_caps: At 40099F20 len 000060E0 (24 KiB): IRAM
I (1351) cpu_start: Pro cpu up.
I (1362) cpu_start: Single core mode
I (1375) cpu_start: Pro cpu start user code
I (1436) cpu_start: Starting scheduler on PRO CPU.
could not open file 'boot.py' for reading
could not open file 'main.py' for reading
MicroPython v1.8.6-645-gf3913bf-dirty on 2017-03-26; ESP32 module with ESP32
Type "help()" for more information.
>>> import machine
>>> pin2 = machine.Pin(2,machine.Pin.OUT)
>>> pin2.value(1)
>>> pin2.value(0)

成功。

WSL で作業する

2018-04-20

Windows COM4 に書き込みをする場合

$ export PORT=/dev/ttyS4
$ export BAUD=115200
$ sudo chmod 777 $PORT
$ cd ~/esp/micropython/ports/esp32
$ make erase
$ make deploy

ampy

since 2018-04-20

インターフェース1月号では upysh を紹介したが m5stack のファームには upysh が入っていないようだ。

かわりに ampy を使うと便利かも知れない。

https://github.com/adafruit/ampy

https://ambidata.io/blog/2018/03/15/ampy/

前述の WSL 環境

$ which python3
/usr/bin/python3
$ sudo python3 -m pip install adafruit-ampy
$ which ampy
/usr/local/bin/ampy
$ export AMPY_BAUD=115200
$ export AMPY_PORT=/dev/ttyS6
$ sudo chmod 777 $AMPY_PORT
$ ampy ls
boot.py

baud は設定した方が安定するようだ。

スイッチを読む

BOOT スイッチ

>>> import machine
>>> pin0 = machine.Pin(0,machine.Pin.IN)
>>> pin0.value()
1
>>> pin0.value()
0

EN スイッチを押すとリブートする(逆じゃないのか)

TouchPad

http://nick.zoic.org/etc/esp32-capacitive-sensors/

https://github.com/micropython/micropython-esp32/pull/23

D12 にリード線をつなぐ

import machine
import time
t = machine.TouchPad(machine.Pin(12))
while True:
    time.sleep(0.1)
    print(t.read())

触ると数字が減る

1390
1388
1382
196
195
191
195
191
196
191
195
191

Raspberry Pi 3

since 2017-12-12

https://www.raspberrypi.org/forums/viewtopic.php?t=191744