n_shinichi’s blog

日々の備忘録、 趣味のあれこれなど紹介 (すみません、メニュー、リンク、カテゴリー分けがうまくできてません、★記事一覧★で見てください...) NHK魔改造の夜ではDンソーのベテランアドバイザーってことで出ました♪

MENU

ハーフインチサイズのロボを製作・・・  OTA対応でのおぼえ その2

ESP-01D、これまでのマイコンモジュールよりかなり小さく

ピンヘッダーとかの引き出しもなく、

構成的にはマイコンと水晶、アンテナ前段回路と

パスコン少々、書き込みとかで必要なポートの抵抗くらいがついたもの。

フツーついてそうな最低限の動作確認のLEDすらついてない。

 

こちらは先回紹介したOTAで書き込む時の様子

 

TwitterにArduinoIDEで無線で動画上げてるように無線書き込みは

Uploading・・・の表示から始まったのだとすれば有線より遥かに速い。

 その辺はネットによく見かける情報通り。

有線の時とはメッセージが違ってて

モリーの使用内訳いろいろ出てるけどよくわかってない。

Code in flash...

OTAとESPNOW使うコードで300kB弱程度 27%しか使ってない。

ユーザーの処理分はほとんど入れてない。Lチカだけ。

まだまだたっぷり余りある。

以前、M5StickCでOTAとBLE使おうとすると4MBでは足りないって

ArduinoIDEに怒られてできんかった。

 使い方がうまくできてなかったかもしれないけど。。。

 ただ、ネットにはできないって情報もあったので詳しくみてない。

 

それに比べればESPNOWはすごく小さい。

 消費電力も実際は送信のほんの一瞬、電流は大きいけど平均の消費電流では

 使い方でも多少変わるけどリモコン程度10Hzくらいで通信ならほぼ増分なし。

 ちゃんと測ってないけど赤外線通信とそう変わらない感じ。

 

ちょっと気になるのは RAM消費 60kBほど使ってる 91%

 ただ意図的にユーザー分で使うのは当分1kBもいらんので

 よほど困らないとは思うけど

 

ESPNOWで使うコードの型はこんだけ

 エラー処理とかは全くなし、ほぼ最小設定。

#include <ESP8266WiFi.h>    //  M5ではWiFi.h
#include <espnow.h>            //  M5 では esp_now.h

uint8_t slaveAddress = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

unsigned char recvData[100];
static int8_t sendData[100];

 

void setup()
{
     setupESPNOW();

}

 

void loop()

{

    joy_x = recvData[1];  //ジョイスティックデータを受信とか

    sendData[1] =  Batt;   //バッテリー電圧を送信とか

    esp_now_send(slaveAddress, (uint8_t*)sendData, 100);

}

 

void setupESPNOW(){
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    esp_now_init();
    esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
    esp_now_register_recv_cb(onRecv);
}

void onRecv(uint8_t* mac_addr, uint8_t* on_RecvData, uint8_t len) {
    for (int i=0; i<len; i++) recvData[i] = on_RecvData[i];
}

 

******************************************************

でもってOTAは・・・

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#define STASSID "*****"
#define STAPSK "*******"

const char* ssid = STASSID;
const char* password = STAPSK;

 

void setup() {
     OTA_setup();

}

 

void loop(){

 

}

 

 

void OTA_setup(){

   WiFi.mode(WIFI_STA);

   WiFi.begin(ssid, password);
   while (WiFi.waitForConnectResult() != WL_CONNECTED) {
     delay(5000);
     ESP.restart();
   }

  ArduinoOTA.onStart(() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else {  // U_FS
      type = "filesystem";
    }

  });

  ArduinoOTA.begin();

}

******************************************************************

どちらも 

 WiFi.mode(WIFI_STA);には入る。

で、ESPNOWでは WiFi接続は終了しておく。

 イメージは通信ハード機能は活かしてWiFiプロトコルは停止...のような。

 WiFi.disconnect();

OTAはWiFiの接続を始める。

 WiFi.begin(ssid, password);

 

 

OTAモードに入れるようになったら、シリアルポートに

ネットワークポートが表示されます。

この場合アドレスは192.158.0.8

最後の1桁は電源入れ直したりすると時間が

空くと違う番号になる場合よくある。

 

いろいろ試しても見たけど結局、、、

OTAは書き換えると再起動までのシーケンスがあるので

ソフト的にはなんか処理して関数で戻ってくるような格好は

ならずそこで一旦終了、電源切る。といっしょなので

単純にESPNOW通信やってて・・・、

OTAに入る時は WiFi.begin(ssid, password); を起動すれば

OTAモードになる。それだけのことだった。

当然OTAモードに入ると、ESPNOWは繋がらない。

もう外部からは何もできない。

 

なので基本、何かESPNOW通信でOTAモードに入る

関数用意しておけばESPNOWとOTAは共存できる。

 

注意しないといけないのはOTAモードに入るところの処理なんかを

いじったりした時にちゃんとOTAモードに移行できなかった場合が

起きるかもってこと。勘違いのバグがあったりとかで。

もしそうなるとシリアル書き込みのとこを使ったりロボに組み込んで

触れなくなると書き込みができなくなる。

 

なので、ソフトが落ち着くまでは

ウォッチドッグ的に割込みである一定の時間が経ったら強制的に

OTAモードに移行するようにするのがいい気がする。

今は面倒なのでLoop()で適当にカウンタ回して5分ほどしたら強制的に

OTAモードに移行するようにしてる。

これでひとまずちょっとしたポカでOTAに行かなくなった時も

ちゃんとOTAモードで時間が経てば待機になる。

 

★ちょいと不思議なこと。

 一応、不安定ではあるけど、OTAモードに入った後も

 OTAの書き込みを実際に始めなければしばらくして

 ESPNOWの通信はたまにできることが多い。

  それって WiFiがOFFしてるってこと?

 ESP.restart(); ・・・リセットとは違う?

 ネットを調べると動作にバグがある?ようなのがいっぱい出てくる。

 条件をちゃんと調べてないけど。

 

 この状態になるとOTAで書き込みが一発で行かなくなることが多い。

 最初これでハマった。何が起きてるかわからず間違いがあるかと思った。

 何度もOTA書き込みを実行してると、ESPNOWが不通になったタイミング、

 それってWiFiがONしてる状態のはず?・・・な時に、

 ArduinoIDEでOTA書き込み実行すれば書き込める。。。って傾向があるみたい。

 

 ま、とにかくこの方法でOTAはひとまず使えるようになった。

小さなマイコンモジュールでこれは効果絶大。

使えるポート増えるし♪

コネクタとか付けなくていいし。

埋もれたとこに組み込めるし...