ESP8266 で NodeMCU ファームウェアと MicroPython を試してみる

(更新

Evaluating NodeMCU firmware and also MicroPython. Key points are, we can run esptool.py with ‘flash_id’ command to obtain Flash size information, and also, it may help to boot ESP8266 correctly by once disconnecting UART wires from ESP8288 after re-frashing.  ‘erase_flash’ command for esptool.py may also help.

前回 ESP8266 を評価してから時間が経ってしまいましたが、ある試作に使ってみたくて、以前購入した ESP-WROOM-02 を引っ張り出してきました。ESP8266 単体で試作したいので、ESP8266 に対して AT コマンドを発行するコンパニオンデバイス(Arduino とか)を「併用しない」構成にしたいと考えています。

現在知られているものとしては、次のような方法がありそうです。

  • Espressif が配布している SDK でバリバリとプログラミングする。(これはちょっとハードルが高そうです)
  • ESP8266 core for Arduino で、Arduino 風のプログラミングをする。(現実的な解だと思います)
  • NodeMCU ファームウェアを利用する。(Lua と呼ばれるスクリプト言語で ESP8266 をコーディングできるという試みです。興味深いです)
  • MicroPython を利用する。(NodeMCU に似てますが、私が経験のある Python 言語でコーディングできるということで、かなり惹かれます)

ということで、今回はこのうち NodeMCU ファームウェアと MicroPython を評価してみることにしました。日本でも、既に多くの先達が試みて役に立つブログなどがたくさんありますが、私も試してみたところ結構はまってしまったので、私なりの作業録をまとめてみました。ポイントは、ESP8266 に外付けされた SPI フラッシュメモリのサイズを調べることと、外部 UART コネクタの扱い、の 2点です。

開発用ブレッドボードに組む

まず最初に、ハードウェアのセットアップをしなくてはいけません。スイッチサイエンス社で以前に購入した「ESP-WROOM-02ピッチ変換済みモジュール《シンプル版》」というものをパーツ箱から見つけてきました。ピンヘッダが半田付けされていないので、適当に IC クリップで繋ごうかと思ったのですが、実は ESP8266 は外部ピンを抵抗でプルアップしたりしないと正しく動作しないので、この方法は諦めました。

というわけで、これまたパーツ箱から見つけてきたヘッダピンを半田付けします。

そしてこれを、手持ちのブレッドボードに搭載して、評価環境の完成です。抵抗器は手持ちの 22kΩを使いましたが、1k〜100kΩ等の適当なもので問題ないと思います。(データシートによると、ESP8266 の I_IL は最大 50nA、出力ドライブ能力は 12mA ということです。)

今にもショートしそうなマンハッタンスタイル(?)ですが、とりあえず動きました。

各ピンの配線は、こちらを参考にしてください。リンクが無くなってしまったときのために備忘録として書くと、

  • GND: GND
  • IO0: 3.3Vに抵抗でプルアップ
  • EN: 3.3Vに抵抗でプルアップ
  • RST: 3.3Vに抵抗でプルアップ
  • TXD: 3.3V UART ケーブルの RXD 端子に
  • RXD: 3.3V UART ケーブルの TXD 端子に
  • 3V3: 3.3V

です。

まずは起動してみる

ファームウェアを書き換える前に、まずは起動してみましょう。シリアル端末ソフトを 115200bps に設定して接続します。電源端子に 3.3V(電流が必要です。500mA くらいは安定して取れる電源を使いましょう)を繋ぎ、化け化けの文字のあとに、次のような表示が出れば OK です。

 ets Jan  8 2013,rst cause:4, boot mode:(3,0)

wdt reset
load 0x40100000, len 1320, room 16 
tail 8
chksum 0xb8
load 0x3ffe8000, len 776, room 0 
tail 8
chksum 0xd9
load 0x3ffe8308, len 412, room 0 
tail 12
chksum 0xb9
csum 0xb9

2nd boot version : 1.3(b3)
  SPI Speed      : 40MHz
  SPI Mode       : QIO
  SPI Flash Size : 8Mbit
jump to run user1

r??-?
ready

表示される値等は若干異なるかも知れません。(なお、ここで SPI Flash Size: 8Mbit と表示されても、実際に搭載されている Flash メモリサイズは異なることがあるようです。)

最初に NodeMCU ファームウェア(Lua)をインストールしてみる

NodeMCU ファームウェアのサイトに行くと詳しく説明がありますが、いくつかポイントをまとめておきます。

ファームウェアはウェブ上でビルドできる

こちらのサイトで、オンラインビルドができます。私は ADC(A/Dコンバータ)を使いたかったので、Select modules to include というメニューで ADC を追加しました。後はデフォルトです。

ファームウェアは esptool.py というツールで書き込める

こちらのサイトからダウンロードできる esptool.py というソフトでフラッシュに書き込めます。私は pip でインストールしました。

最初の問題は、ESP8266 のハードウェア設定です。通常のモードではなく、ハードウェアを UART Download mode というモードに切り替える必要があります。具体的には、デバイスを

  • IO0: GNDに抵抗でプルダウン
  • IO2: 3.3Vに抵抗でプルアップ

のように設定します。

次に esptool.py で設定するパラメタです。私の場合は Mac OS X で

$ esptool.py -p /dev/tty.usbserial-なんとかかんとか write_flash --flash_size 32m 0 nodemcu-master-なんとかかんとか-float.bin

($ はプロンプト)のようにしましたが、–flash_size と –flash_mode というオプションがくせ者です。(私はここではまりました。)

結論から言うと、これは esptoo.py に flash_id というコマンドを与えることがで確認できます。あるいは、Espressif  社から純正のフラッシュツールをダウンロードして利用する方法もあります。

$ esptool.py -p /dev/tty.usbserial-なんとかかんとか flash_id

というように実行すると、

esptool.py v1.1
Connecting...
Manufacturer: a1
Device: 4016

のような診断結果を得られます。(なお、コマンドの実行時にエラーが出る場合は、一度 ESP8266 の電源を落とし、コマンドを実行した後すぐに電源を再投入すると、うまく行くようです。)

ここで重要なのは、末尾の 4016 という数字です。下 4桁が 16 であればフラッシュサイズは 32Mbit ですが、異なる場合は、それぞれ

  • 09: 256Kbit
  • 10:  512Kbit
  • 11: 1Mbit
  • 12: 2Mbit
  • 13: 4Mbit
  • 14: 8Mbit
  • 15: 16Mbit
  • 16: 32Mbit

となります。(詳しい説明としては、こちらのサイトが非常に参考になりました。)

また、4016 のような数字の上 2桁が 40 の場合は、–flash_mode は qio、30 の場合は dio とするようです。これも、上述のサイトに説明があります。なお、デフォルトは qio ですが、もし上 2桁が 30 だった場合は、–flash_mode dio というオプションを付けてみてください。

もし、Espressif 社の Windows 用 GUI ツールを使う場合は、起動して COM PORT を設定のうえ Download Panel 1 の START ボタンを押すと、DETECTED INFO という窓に次のような結果が得られます。

スクリーンショット 2016-09-13 18.38.19

この結果を利用して esptool.py を使うこともできますし、素直にこの GUI ツールでフラッシュを書き込むこともできます。

再起動時が問題

さて、無事にフラッシュメモリにファームウェアを書き込めたか気になりますが、ここでハマることがあるようです。私もいきなり現象にぶつかり、ファームウェアの書換をほとんど諦めかけました。

新しいファームウェアを試すには、ESP8266 のピン設定を元に戻して電源を再投入する必要がありますが、この際に、一度 UART ケーブルも外して差し直したほうが良いようです。私もうまく再現できていませんが、正しく起動できなかった場合は、

  1. 電源ケーブルを外し、
  2. UART ケーブルも外し、
  3. ESP8266 のピン設定を戻し、
  4. 再度ケーブルを繋いで電源を投入する

という手順を取ってみてください。

そして NodeMCU のフラッシュを無事に書き込み、UART を 115200bps で接続すると、次のような出力が得られるはずです。

NodeMCU custom build by frightanic.com
        branch: master
        commit: 8e48483c825dea9c12b37a4db3d034fccbcba0bf
        SSL: false
        modules: adc,file,gpio,net,node,tmr,uart,wifi
 build  built on: 2016-09-12 07:59
 powered by Lua 5.1.4 on SDK 1.5.4.1(39cb9a32)
lua: cannot open init.lua
> 

あとは、NodeMCU のウェブサイトを参考にして遊んでみてください。

同様にして MicroPython も試す

同様の方法で、MicroPython も動かせます。

MicroPython のファームウェアは、ここでダウンロードできます。スクロールして下のほうを見ると、ESP8266 用のファームウェアがあります。(NodeMCU と違い、バイナリファイルが置かれています。)

また、フラッシュメモリに書き込む手順はここにありますが、基本的には NodeMCU と同じ方法で問題ないようです。書き込んだあと、再起動すると次のようなメッセージが表示されます。

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.
>>>

なお、起動時に次のようなメッセージが出た場合は、esptool.py で write_flash をする前に、erase_flash コマンドを実行すると良いようです。

FAT filesystem appears to be corrupted. If you had important data there, you
may want to make a flash snapshot to try to recover it. Otherwise, perform
factory reprogramming of MicroPython firmware (completely erase flash, followed
by firmware programming).

とりあえず、今日はここまでです。今後は、以下を検討する予定です。

  • deep-sleep(低消費電流化)
  • ボタン電池動作
  • ADC(A/D コンバータ)