ESP8266 core for Arduino の 2.0 から OTA がサポートされたよな、ということで試してみたら簡単にできた。大本に入ったので、ライブラリも別に用意する必要も無い。
ESP-WROOM-02 は便利なんだけど、ファームウェアの書き込みがいささか面倒なので OTA でできると大変便利。
例によって cho45 先生が先にやってるので、やってることをなぞるだけ。
サンプルコードを実行して WiFi 接続がうまくいくと IP Address が表示される。
Ready
IP address: 192.168.24.159
PlatformIO 使ってるなら platform.ini の項目に ota 用の env を追加する。upload_port の項目を追加するだけで良い。
[env:esp-ota]
platform = espressif
framework = arduino
board = esp12e
targets = upload
upload_port = 192.168.24.159
[env:esp]
platform = espressif
framework = arduino
board = esp12e
targets = upload
upload_speed = 921600
$ platformio run -e esp-ota
...
17:49:50 [INFO]: Starting on 0.0.0.0:27101
17:49:50 [INFO]: Upload size: 225984
...
17:49:51 [INFO]: Waiting for device...
Uploading: [============================================================] 100% Done...
17:50:02 [INFO]: Waiting for result...
17:50:02 [INFO]: Result: OK
みたいな感じで割とサクッと終わる。なおesp8266側をシリアルコンソールに表示しておくと、そちらにも進捗表示がprintされる。
mDNS での名前解決
IP をいちいち打ち込むのが面倒、と言う場合は mDNS での名前解決を行うこともできる。標準だと esp8266-[ChipID]
の名前が使われるが、明示的に以下のように指定もできる。
ArduinoOTA.setHostname("myesp8266");
OSX から dns-sd コマンドで調べてみる。
$ dns-sd -B _arduino._tcp
Browsing for _arduino._tcp
DATE: ---Mon 08 Feb 2016---
17:55:24.666 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
17:55:24.667 Add 2 5 local. _arduino._tcp. esp8266-a2ebe8
IPを調べる。
$ dns-sd -G v4 esp8266-a2ebe8.local
DATE: ---Mon 08 Feb 2016---
17:56:13.100 ...STARTING...
Timestamp A/R Flags if Hostname Address TTL
17:56:13.101 Add 2 5 esp8266-a2ebe8.local. 192.168.24.159 120
実際はホスト名さえ解ってればOK。
upload_port = esp8266-a2ebe8.local
みたいに指定する。なおシリアルコンソール上で自動でセットされたホスト名を知りたい場合は
char hostname[15];
sprintf(hostname, "esp8266-%06x", ESP.getChipId());
Serial.print("Hostname: ");
Serial.println(hostname);
と現状する必要がある。ArduinoOTAClass の _hostname 変数は private だし、getHostname() インターフェイス持ってないまじか〜。
追記・pull req 送ったので、 ArduinoCore 2.3.0 で ArduinoOTA::getHostname() インターフェイスが導入されました。
認証
平文でやりとりしてるのでセキュアでないが、一応認証もサンプルコードにあるとおりつけられる。ArduinoOTA.setPassword()
で指定し、アップロードのフラグで --auth=xxx
を付ければOK。
PlatformIO では .ini で
upload_flags = --auth=xxx
で指定してやればおk。
特に今のところハマりどころも無く、サクッと OTA 書き込みできた。シリアルUSB経由でのファームウェア書き込みより転送速度も速いし、セキュリティのことを考慮しなくて良い環境では良さそう。