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

ギリギリまでお手軽にMicroPythonでIoTやるための手引書

この記事はPythonその2 Advent Calendar 2019の2日目です。1日目は@ssh-22さんのre.subを使った高度な文字列置換でした。


Arduino, Raspberry Pi の誕生によって急速にエコシステムが整ってきているIoT界隈ですが、Raspberry Pi は Python で実装していけるもののちょっとした電子制御には Arduino の方が圧倒的に手軽に利用できます。
とはいえ Arduino 言語(C/C++もどき)ではなく、使い慣れた Python で書きたいという方もいらっしゃるのではないでしょうか。本記事では組み込み用 Python である MicroPython を利用した開発を金銭的な意味でも手軽に始める手引を書いていきたいと思います。

用意するもの

  • Arduino ……ではなく ESP32開発ボード
  • サンハヤト社 ニューブレッドボード SAD-101

作業環境はmacOS + Python3です。

ESP32開発ボード

最近のArduino界隈ではArduinoと同じ開発環境が使えて、Wifi/Bluetoothが使えるESP32が主流になっています(正確にはArduinoではないけど大体同じように使える)。
定番のArduion UNOよりも概ね高機能なのに安いESP32-DevKitCおよび互換品がよく使われています。

急ぐなら1,480円の秋月電子 ESP32-DevKitCとか、2,200円のスイッチサイエンスESPr Developer 32なりを調達しましょう。

ただ個人的にはaliexpressなどの海外通販をおすすめします。今回は436円のこちらを調達しました。お値段1/3です。ただし届くまで3週間位かかりました。
1,500円程度で買えるなら国内で購入してもいいのですが、電子工作は部品を壊したり、なにか作るのに使ったら使い回すのが面倒だったりするので、急がなければ1/3の値段で3つ買っておく方がおすすめです。
海外通販でクレジットカード決済をしたくない方にはpaypalが使えるbanggoodなどのほかサイトも有るのですが、国内購入と価格差が少ないので国内で買ってしまったほうがいいかもしれません。それでもRaspberry Piに比べれば半額以下です。

(追記)と思ったらAmazonで安く売ってますね。2個でも2,000円以下なのでもうこのへんでいいんじゃないかな。

サンハヤト社 ニューブレッドボード SAD-101

ESP32-DevKitCはピン列の間の幅が少し広く、安く売っている両サイド5穴ずつのブレッドボードだと差し込み穴がたりません。
ニューブレッドボードシリーズであれば両サイド6穴ずつなので使いやすいです。今回は一番シンプルな SAD-101 を用意しました。
ちょっと高級なブレッドボードなのでAmazonで518円です。

MicroPythonのインストール

あとは日本語訳されているドキュメントに従ってESP32にMicroPythonをセットアップしていきましょう。

通常ESP32-DevKitC購入時にはArduino CoreというArduino互換ファームウェアが書き込み済みです。
このままではArduino言語でしか実装できないのでMicroPythonのファームウェアを書き込み直します。

ファームウェアのダウンロード

Firmware for ESP32 boards

ESP32用のMicroPythonでは「Wifiが使えるがBluetoothが使えないファーム」「Bluetoothは使えるがWifiが使えないファーム」のどちらかを選択しなければなりません。
今回は「Wifiが使えるファーム」の安定ビルドを選んでみます。

image.png

ドライバのインストール

ESP32-DevKitCにUSB接続するためにSilicon Labsのドライバをインストールします。

CP210x USB - UART ブリッジ VCP ドライバ

今回はmacOS用ドライバをインストールしました。ESP32をUSBで接続すると、おそらく/dev/cu.SLAB_USBtoUARTにESP32が認識されるはずです。

書き込み済みファームウェアの初期化

$ pip install esptool
$ esptool.py --port /dev/cu.SLAB_USBtoUART erase_flash

実行するとこんな結果が出ると思います。

$ esptool.py --port /dev/cu.SLAB_USBtoUART erase_flash
esptool.py v2.8
Serial port /dev/cu.SLAB_USBtoUART
Connecting........_
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: XX:XX:XX:XX:XX:XX
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 8.4s
Hard resetting via RTS pin...

ファームウェアの書き込み

$ esptool.py --chip esp32 --port /dev/cu.SLAB_USBtoUART write_flash -z 0x1000 esp32-idf3-20190529-v1.11.bin

実行するとこんな結果が出ると思います。

$ esptool.py --chip esp32 --port /dev/cu.SLAB_USBtoUART write_flash -z 0x1000 esp32-idf3-20190529-v1.11.bin
esptool.py v2.8
Serial port /dev/cu.SLAB_USBtoUART
Connecting........____
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: XX:XX:XX:XX:XX:XX
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 1146864 bytes to 717504...
Wrote 1146864 bytes (717504 compressed) at 0x00001000 in 63.5 seconds (effective 144.4 kbit/s)...
Hash of data verified.

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

これで MicroPython のセットアップができました。
早速Pythonで動かしていってみようと思います。

Pythonの実行

MicroPython REPLの利用

まずはREPLプロンプトにアクセスしてみます。

$ screen /dev/tty.SLAB_USBtoUART 115200

おもむろにhelp() [enter]と入力して以下のように出力されれば成功です。

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')
>>>

print()も返ってきます。

>>> print("hello")
hello

screenコマンドはctrl + a + kで終了確認のプロンプトが出るのでyで終了します。

ソースコードの転送

REPLでコードを書いていくのは辛いのでソースコードファイルを転送できるようにします。
まずはツールのインストール。

$ pip install adafruit-ampy

転送済みのファイルを確認します。

$ ampy -p /dev/tty.SLAB_USBtoUART ls
/boot.py

boot.pyだけが転送されている事がわかります。

内容も確認してみます。

$ $ ampy -p /dev/tty.SLAB_USBtoUART get /boot.py
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
#import webrepl
#webrepl.start()

全行コメントアウトされている事と、boot.pyに書かれた内容はボードがリセットされたときの最初の1度だけ実行されることがわかります。
boot.py実行後に(存在すれば)メイン処理としてmain.pyが実行されます。以下のようなコードをmain.pyとして転送してLチカしてみます。

import machine
import time

pin13 = machine.Pin(13, machine.Pin.OUT)

while True:
  pin13.on()
  time.sleep_ms(500)
  pin13.off()
  time.sleep_ms(500)

転送は以下のコマンドで行います。

$ ampy -p /dev/tty.SLAB_USBtoUART put main.py

これで500ms間隔でD13ピンに接続されたLEDが点灯すれば成功です。

まとめ

MicroPythonを知った当初はファームウェアの書き換えが必要など、敷居が高いように思えましたが実際にやってみると慣れないツールを使う局面はあるもののそれほど難しいこともなくPythonコードの転送と実行まで実現できました。今回の手順は1度やってしまえばあとはソースコードを転送するだけなのでPythonに慣れた方はESP32をMicroPythonで使うというのもかなりアリな選択肢ではないでしょうか。
今回は行っていませんが、ESP32の通信機能を利用してWifi APへの接続も以下のような感じで簡単に出来るようなので夢が広がります。

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

そしてなにか面白いものを作ったらぜひIoTLTで発表すると良いと思います。

ちなみに冒頭でも書きましたが届くまで待つことが出来るなら436円でこれだけ遊べるのです。控えめに言って最高じゃないですか?


明日は@TsuMakotoさんのAmazon PersonalizeをPython SDKで入門です。

moomooya
React+Flaskでなにか考えてたけど、FirebaseならTypeScriptだけでいいや。 パブリックなアウトプットを減らしてコード書く年にする。
http://www.slideshare.net/isamusuzuki54
rakus
「IT技術で中小企業を強くします!」というミッションを掲げ、中小企業の業務効率化に貢献する複数のクラウドサービスを提供しているIT企業です。「楽楽精算」「メールディーラー」など、国内トップシェアを誇る複数のサービスを開発し、累計導入社数は5万社を超えています。次の時代の"楽"を創るための、まだ見ぬサービスや機能を生み出す取り組みは、今日も続いています。
https://www.rakus.co.jp/
Why not register and get more from Qiita?
  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