ESP-WROOM-02単体でWi-Fi通信とNeoPixel両方動かしたい(3)

ESP-WROOM-02単体でWi-Fi通信とNeoPixel両方動かしたい(3)

の続きです。

結論から言うと、

できました。

できなかった原因は身も蓋もない話で、配線を間違えていました。

抵抗とか、TOUTにつなぐと取れる値がなんなのかとか、きちんと理解していなかったということです。

(;´Д`)

大騒ぎして結局それかい!って感じですが、遠回りして得られたこともなくもないので、前回と前々回で躓いていた点についてひとつずつ見ていきたいと思います。

ESP-WROOM-02開発ボードの力はすごかった

電力が~絶対電力が~とか言っていましたが、なんのことはない、配線がダメダメだっただけなので、ある意味この開発ボードの底力を証明することができました。

Wi-Fiモジュールとしての、そのものの電力消費がけっこうすごいということは以前リンクした記事でもいろいろと検証されていましたが、

こちらのふたつの記事でモジュールそのものの消費電力と、開発ボードで出せる電力が書かれています。

5V→3.3V 電源レギュレーター XC6222B (最大出力電流700mA)

電源容量も全く問題ない余裕の容量です。やっぱりWROOMには500mA以上欲しいと思いますので、かなり厳選してパーツを選んでいる感じがしますね。

とのこと。

んっ?

そういえばこの記事ずっと「ESP-WROOM-02単体で」とか言ってるけど、単体って言っていいのかな…

・・・

まいっか!

ArduinoとつながずにArduino化して使う的な意味だと思ってください。

それにしてもスイッチサイエンスさんのこの開発ボード、こんなに小さいのにすごいポテンシャルですね。

Wi-Fi通信自体も難なく行うことができ、かつ、5VピンからNeoPixelを光らせつつ3V3ピンからCDSセンサー経由してTOUTに値を送り込める。
こんなことがUSB一本でできる!
しかも、ArduinoIDEからの書き込みも、USB一本でできる!!

USB一本でだいたいなんでもできる!!

スイッチサイエンスさんの回し者じゃありませんがそう思われてもいいです。
自発的に回っていく所存。

じゃあ、レインボーで固まるとか言ってたのはなんだったの?

NeoPixelサンプルアニメのループ挙動について

前回の記事でブラウザからボタンを押してアニメーションを切り替えるということをしていて、9番あたりにくると固まっちゃうんだよね~なんて言っていましたが、固まっていませんでした。

なんのことはない、NeoPixelのアニメーションが1周するまで、次の動きにいかない(onsendによる処理を待つ)というだけのことでした。

正確に言うと、アニメーション中であってもボタンをガシガシクリックしまくっておくと、そのonsendの情報は蓄積されているようで、アニメーションが1周したあとにたまっていた分がまとめてシリアルモニタにダダダッと流れてきていたようです。
1~8番に設定していたアニメーションも、定期的に一時停止したような状態になったあとまた再生を繰り返す、という挙動だったので、これがloop()の切れ目だったということですね。
(´ヘ`;)ウーム…

ところで、1周ごとに切れ目がある、ということは連続で再生し続けて一向に次の動きに移らない9番は…

void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) {

//以下略

( ゚д゚)

  for(j=0; j&lt;256*5; j++) {

( ゚д゚ )

5回も繰り返しとんのかーい!!

じわじわまわるレインボーが5回ぐるぐるし終わるまでonsendに反応しないだけであった。

1周ごとに一時停止するのはどこでなにが起きているの?

本来の目的とはあまり関係ないので解決しなくてもいいことなんですが、loopごとにアニメーションが一時停止するのがいただけないと思いましたのでわからないなりにちょっとだけ調べてみました。
loop内の記述はこれだけ。

void loop() {
  milkcocoa.loop();
  switch(animation){
    case 1:colorWipe(strip.Color(20, 0, 0), 50);break;
    case 2:colorWipe(strip.Color(0, 20, 0), 50);break;
    case 3:colorWipe(strip.Color(0, 0, 20), 50);break;
    case 4:theaterChase(strip.Color(20, 20, 20), 50);break;
    case 5:theaterChase(strip.Color(20, 0, 0), 50);break;
    case 6:theaterChase(strip.Color(0, 20, 0), 50);break;
    case 7:theaterChase(strip.Color(0, 0, 20), 50);break;
    case 8:rainbow(20);break;
    case 9:rainbowCycle(20);break;
    case 10:theaterChaseRainbow(50);break;
  };
}

となるとやっぱり、milkcocoa.loop()の中身が知りたいですね~
最初の環境設定のときはzipからまるごとincludeさせてしまいましたが、ちょっとGitHubのソースをのぞいてみたいと思います。

たぶんMilkcocoa.cppあたりがメインだよね。

void Milkcocoa::loop() {

( ゚д゚)ハッ! 112行目なんかこれっぽい!

void Milkcocoa::loop() {
  connect();
  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt->readSubscription(1000))) {
    for (uint8_t i=0; i<MILKCOCOA_SUBSCRIBERS; i++) {
      if(milkcocoaSubscribers[i] == 0) continue;
      if (subscription == (milkcocoaSubscribers[i]->mqtt_sub) ) {
        DataElement de = DataElement((char *)milkcocoaSubscribers[i]->mqtt_sub->lastread);
        milkcocoaSubscribers[i]->cb( de );
      }
    }
  }
}

最初のconnect()っていうのは同じファイルのもっと前のほうにいました。

void Milkcocoa::connect() {
  int ret;

  if (mqtt->connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  while ((ret = mqtt->connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt->connectErrorString(ret));
       Serial.println(ret);
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt->disconnect();
       delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT Connected!");
}

最初に接続が確立されていればなにもせずreturn、接続してなかったら接続を試みる、起動時に必ず行われている処理ですね。
ということはさっきのMilkcocoa::loop()では、まず最初に接続を行って、接続ができていたら…

while ((subscription = mqtt-&gt;readSubscription(1000))) {

・・・( ゚д゚)

なにかをめっちゃ繰り返していますね。

しかも、(1000)って。

このへん、めちゃくちゃ怪しいですね。

「readSubscription()」がなんなのか、ぐぐってみました。
英語のページばっかりでした。
ときどき日本語のページがひっかかりますが、直接的な説明が見つからなかったので英語のページもあわせていろいろ読んでみると、subscriptionっていうのはPub/Sub通信のSubだっていうことがわかりました(はいそうです、私の知識はもうそのへんからしてないのです)。

もうこれ以上深く見ていくのはしんどいのでやめてしまいましたがきっとこのへんでonsendを見てるんだろうな、と思ってます。

(1000)なんて何かの実行時間的なものとしか思えないので、とりあえず自分のローカルに展開されているファイルを(100)にして保存してみました。

※ローカルファイルは「\Documents\Arduino\libraries\Milkcocoa_Arduino_SDK-master」って感じの場所に展開されていました。

そしてこの状態でArduinoIDEから再度書き込みすると、一時停止の感覚が短くなったような気が。そこで思い切って(0)にしてみると、スムーズにアニメーションを繰り返すようになりました!

でも、なんのために(1000)にしてあるのかもわからずやっているので、今はたまたまちゃんと動いていますがほかに影響があるかもしれません。
実際には同じアニメーションを流し続ける予定もないし、冒頭のYoutube動画で動かしているやつはSDKには変更を加えていません。

そしてさらなる疑問も

あとなんとなく感じたことなんですが、sendとかpushとかなにもせずただ光らせているだけにして、照度もシリアルモニタに出さないで放っておくと、Wi-Fi再接続を繰り返すことが多いような気がするんです。
検証も何もしていませんが。
Milkcocoaと送受信する用がない時でも、とれた照度はSerial.println()しとくと割と安定しています。

裏側のこと、よく見えないまま使っているのって不安もありますが、こうやって簡単にモノが作れていくのは楽しいですね。
また何か進展あったら記事書きます。