chakokuのブログ(rev4)

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

ESP8266にluaインタプリタを導入してみる

GitHub*1から落としたZIP版パッケージを展開、esp-open-sdkへのパスを通してmakeした。(なお、正しくは、、追加パスは先頭に書くべき)
コンパイル環境は、VMWare上に構築したUbuntu内で実行


$ export PATH=$PATH:/opt/Espressif/esp-open-sdk/xtensa-lx106-elf/bin/
$ make


ビルドした結果

../tools/esptool.py elf2image .output/eagle/debug/image/eagle.app.v6.out -o ../bin/
make[1]: Leaving directory `/home/foo/uc/nodemcu-firmware-master/app'

$ ls bin/
0x00000.bin 0x10000.bin

バイナリが生成された。ファイル名は配置する番地を表していると思われる。

Makefileにはフラッシュへの書き込みステートメントもあるので使ってみる。
なお、書き込みは、USB-Serial変換器を使ってPCのUSBとESP8266(ESP-WROOM-02)を接続。Linuxからは、/dev/ttyUSB0で接続できる。フラッシュへの書き込みに先立ち、ESP8266はピンを正しく結線してダウンロードモードに移行させる。


$ sudo make flash
make -C ./app flash
make[1]: Entering directory `/home/foo/uc/nodemcu-firmware-master/app'
../tools/esptool.py --port /dev/ttyUSB0 write_flash 0x00000 ../bin/0x00000.bin 0x10000 ../bin/0x10000.bin
Connecting...
Erasing flash...
Writing at 0x00008000... (100 %)
Erasing flash...
Writing at 0x00081400... (100 %)

Leaving...
make[1]: Leaving directory `/home/foo/uc/nodemcu-firmware-master/app'

ピンの結線を戻して電源Off/Onでbootモードで再起動させる。下記はESP8266からシリアルで送信されるLuaインタープリタの起動メッセージ(9600baud)


NodeMCU 1.4.0 build 20151006 powered by Lua 5.1.4 on SDK 1.4.0
lua: cannot open init.lua

> print(node.info())
1 4 0 15624854 1458337 4096 0 40000000
以上の手順でLuaインタープリタが内蔵され、電源投入で起動されるのを確認した。Lua言語ってよく分からなったのですが、少し調べるとPythonと同等にしっかりした素性の言語と分かりまして、本も買ってきっちり勉強してみたいと思った次第でございます。ちなみに、、目指すゴールは、SPIで接続した温度、気圧センサーの計測データをMQTTプロトコルでBlueMixかどこかのPaaS?にPublishすること。NodeMCU(Lua+組み込み用ライブラリ群)では、SPIライブラリやMQTTライブラリがすでに提供されているようなので、適切にAPIを呼び出せばそれほど苦労することなく、データをPublishすると思えるのだが。。

lua言語がよくわからないまま少し使い始めた。さっそく、i2cのライブラリを使ってみたがエラーになる。


> i2c.setup()
stdin:1: attempt to index global 'i2c' (a nil value)
stack traceback:
stdin:1: in main chunk
> print(i2c)
nil
GPIOのライブラリは正しく組み込まれているようだ。

> gpio.mode(1,gpio.INT)
> print(gpio)
romtable: 0x4027ad08
>
なぜi2cがだめなのか?? 拡張ライブラリとしての組み込みがおかしいのか、それともi2cの名前ではなのか??不明。

グローバルな名前空間はテーブル:_Gに格納されているということで、調べてみたら、ハングした。


> for x,y in pairs(_G) do ; print(x,y) ; end
c_ヌマRSFjSハテj迮

NodeMCU 1.4.0 build 20151006 powered by Lua 5.1.4 on SDK 1.4.0
Hello
>


> l = file.list();
> print(l)
table: 0x3fff11c0
> for k,v in pairs(l) do ; print(k,v); end
c_ヌマRSFjSテヤ

NodeMCU 1.4.0 build 20151006 powered by Lua 5.1.4 on SDK 1.4.0
lua: cannot open init.lua
> print(node.bootreason())
4
>

bootreason:4 は、WatchDog timeoutだそうで、やっぱり暴走しているようだ。

どうもおかしい。NodeMCUのマニュアルでは特別な手順が必要とも書かれておらず普通に使えるはずなんだけど。。コンパイルでしくじってるのかもということで、出来合いのバイナリを再度入れてみる予定。それでもやっぱりi2cが使えなかったら、luaをやめて、プリミティブなCでスクラッチから書くことにする。

最後の手として、、、ビルドしてくれるサイトがあるので、ここでバイナリを作ってみた。
http://nodemcu-build.com/index.php
コンパクトなバイナリにするため、file, gpio, i2c, node, tmr, uart, wifiに絞ってビルド。ビルドが終わるとメールで通知されるので、メールのURLにアクセスしてダウロードする。しかし、、これはどうやってフラッシュに焼けばいいのやら。
と少し困っていたら、Wikiにフラッシュへの書き込み方法が書かれていて、バイナリを0番地から配置すればいいようだ。
http://nodemcu.readthedocs.org/en/dev/en/flash/#esptool


ubuntu:~/uc/nodemcu-firmware-master/bin$ sudo ../tools/esptool.py --port /
dev/ttyUSB0 write_flash 0x00000 nodemcu-master-7-modules-2016-03-24-06-25-54-integer.bin
[sudo] password for foo:
Connecting...
Erasing flash...
Writing at 0x0005fc00... (100 %)

Leaving...


NodeMCU custom build by frightanic.com
branch: master
commit: c8037568571edb5c568c2f8231e4f8ce0683b883
SSL: false
modules: file,gpio,i2c,node,tmr,uart,wifi
build built on: 2016-03-24 06:25
powered by Lua 5.1.4 on SDK 1.4.0
lua: cannot open init.lua
Webサイトでビルドしたらめちゃくちゃ安定している!!! これはなんとしたことか。。

> i2c.setup()
stdin:1: bad argument #1 to 'setup' (number expected, got no value)
stack traceback:
[C]: in function 'setup'
stdin:1: in main chunk
> for k,v in pairs(_G)
>> do
>> print(k,v)
>> end
module function: 3fff12b8
newproxy function: 3fff15c8
pairs function: 3fff14f0
__index lightfunction: 40259600
package table: 3fff0e68
_G table: 3fff07b0
require function: 3fff1308
ipairs function: 3fff1358
>
これならluaが使えそうだ!! すばらしい。 しかし、、なんでGitHubから落としたソース一式だとまともに動かないのか??最新版ソースはデグレしているから?

最新を取ってくるのではなくて、latest releaseから取ってるべきなのかも。あぁ分かっていない。。↓↓↓
https://github.com/nodemcu/nodemcu-firmware/releases/tag/0.9.6-dev_20150704
ソース一式は以下
https://github.com/nodemcu/nodemcu-firmware/archive/0.9.6-dev_20150704.tar.gz

というわけで、、最新リリース版ソースから再度コンパイルしてみる


wget https://github.com/nodemcu/nodemcu-firmware/archive/0.9.6-dev_20150704.tar.gz
cd xxx //適当なディレクトリに移る
tar xvfz ../Downloads/0.9.6-dev_20150704.tar.gz
cd nodemcu-firmware-0.9.6-dev_20150704/
vi app/include/user_modules.h // 使わないモジュールはコメントアウト
export PATH=/opt/Espressif/esp-open-sdk/xtensa-lx106-elf/bin:$PATH //コンパイラへのパスを通す
make // makeする
sudo make flash // ツールを使って書き込む
ブートモードに配線を変えて電源Off/On

NodeMCU 0.9.6 build 20150704 powered by Lua 5.1.4
lua: cannot open init.lua
> i2c.setup()
stdin:1: bad argument #1 to 'setup' (number expected, got no value)
> for k,v in pairs(_G)
>> do
>> print(k,v)
>> end
module function: 0x3fff3448
require function: 0x3fff3498
pairs function: 0x3fff2d28
newproxy function: 0x3fff2de8
package table: 0x3fff2f58
_G table: 0x3fff2688
__index lightfunction: 0x4025f7e0
ipairs function: 0x3fff2c38
>

Latest Release版だと安定して動作する。問題なし!

■メモ書き
情報はgithubの以下より
https://github.com/nodemcu/nodemcu-firmware/blob/master/README.md

ビルド手順
https://github.com/nodemcu/nodemcu-firmware/blob/master/README.md#build-instructions


git clone --recursive https://github.com/pfalcon/esp-open-sdk.git /opt/esp-open-sdk
cd /opt/esp-open-sdk
make STANDALONE=y
PATH=/opt/esp-open-sdk/xtensa-lx106-elf/bin:$PATH
cd /opt/nodemcu-firmware
make

flashメモリ上のファイルシステムスクリプトを書き出す手順は以下


file.open("hello.lua","w+")
file.writeline(print("hello nodemcu"))
file.writeline(print(node.heap()))
file.close()
上記を実行すると、flashメモリにファイル名:hello.luaが生成され、ファイルの内容が、 print("hello nodemcu") node.heap()となる。

LUA言語解説(Programming in Lua)
http://www.lua.org/pil/contents.html

eLuaのドキュメント
http://www.eluaproject.net/doc/v0.9/en_index.html

SPIで周辺デバイスを制御する方法(NodeMCUのmanual)
https://nodemcu.readthedocs.org/en/dev/en/modules/spi/

SPIを動かす時のPIN配置(多分)
https://github.com/MetalPhreak/ESP8266_SPI_Driver#hspi-hardware-pins

SPIモジュールのソース(ラッパと言うべきか)
https://github.com/nodemcu/nodemcu-firmware/blob/dev/app/modules/spi.c