ESP8266 ( ESP-WROOM-02 ) SPI 通信高速化、その2 ( 複数デバイス、Mode、Watchdog Timer 問題 )

記事公開日:2016年10月12日
最終修正日:2017年1月2日

スポンサーリンク

こんばんは。

前回の記事では、Arduino core for ESP8266ライブラリのdigitalWrite() は速度が遅く、レジスタにダイレクトアクセスした方が3倍速くなり、さらにSPIライブラリ中のSCLK信号生成にdigitalWrite()関数を使っている場合では、GPIO レジスタ Direct Access にすれば高速化できるというお話でした。

Adafruit の OLED ( 有機EL ) SSD1351 ライブラリは、そのままではESP8266 ( ESP-WROOM-02 ) では使えなくて、shiitakeo さんによる digitalWrite() 仕様に改変すれば動くようになりました。 (こちらの記事参照
そして、そのdigitalWrite() をGPIO レジスタDirect Access に変えれば高速化できます。

実は、ツイッターで@arms22 さんから Arduino core for ESP8266 のSPIライブラリでSPI.setFrequency を使えば速度が上げられるということを教えていただきました。
Adafruitライブラリ中のSPIライブラリは使えないと思っていたのですが、よくよく調べてみると使えるということが分かったんです。

それで、ESPRESSIF社の以下のサイト
ESPRESSIF Support Documents
にある esp8266-technical_reference_en.pdf というファイルをよく読んでみると、レジスタDirect Access でSPI設定もできるじゃぁないですか・・・!

そこで、Arduino core for ESP8266 標準の SPI ライブラリを更に解読してみました。
すると、ちゃんとライブラリ中でSPIのレジスタDirect Access を使っているじゃぁないですか!!!

また、前回の記事で、メインloop() よりもForループやwhileループの方が速いということ述べましたが、実は、メインloop() ではウォッチドッグタイマが動作していて、それで休止時間が生じているということが分かりました。
つまり、ESP8266 ではWi-Fi機能などやその他の機能の監視をループ中に行う余地が無ければ、正常に動作しないようです。
WiFi.begin を動作させて、loop()内でwhile(1)ループを作ってしまうと、シリアルモニタにWDTエラーになって、永遠とリセットを繰り返します。
WDT とはつまり、ウォッチ・ドッグ・タイマ というわけですね。
いや~、お恥ずかしながら、これは知りませんでした・・・。

要するに、私がESP8266 やSPIについていろいろと無知だっただけなんですけど、今回は新たな発見があり、とても勉強になりました。
@arms22さんに感謝です。

前回説明したレジスタ Direct Access は CS や DC 信号に使えますので、それと合わせてSPIライブラリを高速化して使えば、SPI については最大速度で使用することができます。
それについてはいろいろと注意点がありました。

では、具体的にスケッチやプログラミングでどのように使っていったら良いのかを説明していきたいと思います。

1.SPIデバイスの最大周波数の確認

まず、使うSPIデバイスの最大周波数を確認します。
データシートに大体記載されています。
例えば、OLED SSD1351 の場合はデータシートのタイミングチャートにこんな感じで記載されています。

SPI_SPEED_UP2_01

Clock Cycle Time 最少 = 50 ns

とあります。
つまり、SCLK パルス1波長50ns ということは周波数でいうと20MHz になります。
これを調べた上で、ESP8266 ( ESP-WROOM-02 ) のSPI 周波数を決めます。

因みに、Amazonで販売している、このTFT液晶ディスプレイ

ドライバにILI9340 を使用しているようですが、データシートに66ns とありました。
つまり、約15MHz となります。

2.SPI ライブラリの使い方

では、まず、以下の簡単なスケッチをArduino IDE に入力してみます。
ESP8266 ボード設定は下図の様にCPU Frequency = 160MHz にしておきます。
SPI_SPEED_UP2_02

#include <SPI.h>

void setup() {  
  delay(1000);
  Serial.begin(115200);
  Serial.println();

  SPI.begin();
  SPI.setFrequency(20000000);
  SPI.setDataMode(SPI_MODE2); //※これは実は Mode 3
  
  Serial.println("wait-------------------");
  delay(5000);
}

void loop() {
  for(int i=0; i<8; i++){
    SPI.write(B10010010);
  }
}

【解説】
シリアルモニタに” wait—————-” と表示されたら5秒以内にロジアナを起動させて測定するプログラムです。

9行目の
SPI.setFrequency(20000000);
というところで、SPI信号を20MHz で出力させます。
前回の記事で、GPIO レジスタ Direct Access では最高6MHz ですので、それのさらに3倍以上の速度です。
先にも述べたように、OLED SSD1351 側の受け入れクロック周波数は20MHz までですので、これに合わせます。

10行目で、SPI のモードを設定します。
しかし、いささか問題がありました。後で述べます。

GPIO MOSIピンに8bit データを出力させるには、18行目のように
SPI.write(B10010010);
という感じでOKです。
MOSIピンを指定する必要はありません。
SPIライブラリを使うと自動的にESP8266 のGPIO #13 に割り当てられます。

では、これをコンパイル書き込み実行させます。

ロジックアナライザ ZEROPLUS LAP-C を使って測定していきます。
ロジアナがあると無いのとでは雲泥の差でエラー原因特定やデバッグに有利です。
私はこれを買ってホントに正解だったと思っています。
Amazon.co.jp

では、まず、ザッとロジック波形はこんな感じになりました。
SPI_SPEED_UP2_04

前回の記事で述べましたが、メインloop()の繰り返しより、forループの繰り返しの方が速いですね。
forループの初回の後は長めの休止区間、2回目以降は短めの休止区間があります。
これについては解明しましたので、後で述べます。

パルスをズームして見てみるとこうなります。

SPI_SPEED_UP2_03

そうなんです。
スケッチ上でSPI_MODE2 と指定しているのに、パルスがMODE 3 になってます。
SPIインターフェースのMODEの違いは以下の様なはずです。

【 Mode 0 】
SPI_mode_0

【 Mode 1】
SPI_mode_1

【 Mode 2】
SPI_mode_2

【 Mode 3】
SPI_mode_3

SPI.write(B10010010); で送っているMOSI信号のビットを見てみても、明らかにMode 3 ですよね。
これは私の考え方が間違っているのか、Arduino core for ESP8266 ライブラリが間違えているのか・・・?

いずれにしても、OLED SSD1351 のデータシートでもMode 3 で記述してあり、それでしか動かないので、ライブラリが誤っていると思われます。

ということで、皆さん、気を付けてください。
ESP8266 のSPI ライブラリでは、
SPI.setDataMode(SPI_MODE2); は Mode 3 です!!

3.無限ループのウォッチ・ドッグ・タイマ ( Watchdog Timer ) 問題

さて、メインloop() の繰り返しが遅いならば、動作速度を上げる為に、whileループでやってしまうとどうなるのでしょうか?
試しに以下のスケッチをコンパイル実行させてみてください。

#include <SPI.h>

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();

  SPI.begin();
  SPI.setFrequency(20000000);
  SPI.setDataMode(SPI_MODE2); //※これは実は Mode 3
  Serial.println("wait-------------------");
  delay(5000);
}

void loop() {
  while(1){
    for(int i=0; i<8; i++){
      SPI.write(B10010010);
    }
//    yield(); //WDTを動作させるために必要
  }
}

すると、シリアルモニタではこんなエラーになります。
SPI_SPEED_UP2_05

そうそう、よく見るエラー

Soft WDT reset

ですね。
これは、つまり、ウォッチ・ドッグ・タイマ( Watchdog Timer 略して WDT ) が実行されないことによるエラーだそうです。
強制リセットが繰り返されてしまいます。

お恥ずかしながら、今までマイコンの記事を書いてきましたが、この事はつい最近知ったばかりです。
当方は独学で記事を書いてますので、何卒ご容赦ください。
m(_ _)m
今までこういうエラーが出たり、フリーズしていたりしたら、これが原因の可能性があります。

マイコンというものはウォッチドッグタイマを装備していて、ループ内のある一定区間を休止させて、裏側で監視機能を動作させるタイマがあるとのことです。
ESP8266 ( ESP-WROOM-02 )ではWi-Fiの電波発信、受信などの動作を裏で動作させているのだろうと考えられます。
ですから、先で述べたメインのloop() 繰り返し中の休止区間ではこのウォッチドッグタイマ(WDT) が動作しているわけです。
これを無視してwhileループを組んでしまうと Soft WDT reset エラーが出てしまうわけです。

これを回避しつつ、loop()よりも速度アップさせるには、20行目のコメントアウトを解除してください。
つまり、whileループの中に

yield();

という関数を置いて下さい。
これは、ループ内で他の裏のタスクを実行させる関数です。
delay(1) でも同じような動作をするらしいです。

それでコンパイル実行させると、見事にエラーが出なくなりましたね。

ついでにロジアナ LAP-C で速度を見てみると、こうなりました。

SPI_SPEED_UP2_06

休止区間が1.32us と大幅に短くなりました。
メインloop() よりも格段に高速化できたことになります。
delay(1) の場合は1ms も休止させてしまいますが、yield() は格段に速いです。恐るべし。

ただ、これでも2.5ms経過すると95.9us休止する区間が出現します。
これもウォッチドッグタイマの類ではないでしょうか。

ということで、この件は意外とネットでも情報がありました。
ループ内の休止区間もこれでほとんど解明できたのではないかと思います。

教訓: loop() 以外で無限ループを組む場合にはyield()を置くべし!!

私がこれに気が付いて、記事を書いている最中、同じことを述べている Ikeuchi Toru さんという方の以下の記事を見つけました。

Server-Sent Event(SSE)を利用して、スマホのブラウザにセンサデータを表示
(この記事は消去されたようです)

これは、私が以前書いた記事のスケッチのエラーを解消されています。
素晴らしいですね。 感謝いたします。
ありがとうございました。m(_ _)m

実は、この yield() は、Wi-Fi でHTTP GET してテキストデータを受信する時のwhileループではあまり効果を発揮しないような気がします。
他の原因として、ESP8266 ( ESP-WROOM-02 ) の過大電流による電圧低下も考えられますが、瞬時降下した場合はリセットするので、その原因は考えられないような気がします。

例えば以下の記事、

Twitter 検索結果のツイートを有機EL ( OLED )に表示させてみた

ではツイートを定期取得していますが、これを動作させながら他のパソコンでネットサーフィンしていると、しばらく経つとHTTP受信中にフリーズしてしまうことが多々ありました。
ループを抜けられるようにタイムアウト設定も組んでみたのですが、なかなかwhileループやforループを抜けてくれませんでした。
そこで、この前知ったyield() を試してみたのですが、それでも抜けてくれませんでした。
予想できるのが、他のIPアドレスでネットサーフィンしているとESP8266に送られるパケットが遅れてウォッチドッグタイマが上手く機能しないのではないかと思いました。

それで、今、実験中なのですが、yield()と合わせて、delayMicroseconds(); を所々追加して試しております。
delay(1)では遅すぎるので、ウォッチドッグタイマを確実に動作させつつ、動作速度を保つためにいろいろと試行錯誤中です。
この結果は後日報告したいと思います。

その他に何かご意見がありましたら、是非情報を頂けると有り難いです。

4.SPIライブラリとSDライブラリとGPIO レジスタ Direct Access を共用する使い方

今回の実験で使うのは
●ESPr Developer ( ESP-WROOM-02 ( ESP8266 ))
Amazon.co.jp

●SparkFun マイクロSDカードスロット・ピッチ変換基板
Amazon.co.jp

micro SDHC カード class10

ロジックアナライザー ZEROPLUS  LAP-C

ロジアナ測定だけですので、他のSPIデバイスはここでは使いません。

接続はこんな感じです。
ZeroPlus21
Arduino core for ESP8266 の SPIライブラリを使う場合は、

SCLK  GPIO #14
MOSI  GPIO #13
MISO  GPIO #12

のように、自動的にGPIOピンが割り当てられます。
SDカードライブラリでは、SDカードのCS ( Chip Select )ピンは

SD CS  GPIO #15

に割り当てられます。

ですから、そのピン以外をレジスタ Direct Access に使うことになりますが、16番ピンはDirect Access を割り当てることができません。
16番ピンはDeep Sleep 解除などの割込み入力に使われる端子です。
よって、Direct Access で自由に使える端子は

GPIO #0
GPIO #2
GPIO #4
GPIO #5

となります。
これをSDカード以外のCSピン、DC ( Data Command ) ピン、リセットピンに割り当てます。

では、Arduino core for ESP8266のSDカードライブラリとSPIライブラリ、そしてGPIO レジスタDirect Access を共用した使用例として、次のサンプルスケッチをご覧ください。

#include <SPI.h>
#include <SD.h>

#define PIN_OUT *(volatile uint32_t *)0x60000300
#define PIN_OUT_SET *(volatile uint32_t *)0x60000304
#define PIN_OUT_SET_CLEAR *(volatile uint32_t *)0x60000308
#define PIN_ENABLE *(volatile uint32_t *)0x6000030C
#define PIN_ENABLE_SET *(volatile uint32_t *)0x60000310
#define PIN_ENABLE_CLEAR *(volatile uint32_t *)0x60000314
#define PIN_IN *(volatile uint32_t *)0x60000318
#define PIN_00  *(volatile uint32_t *)0x60000328
#define PIN_02  *(volatile uint32_t *)0x60000330
#define PIN_04  *(volatile uint32_t *)0x60000338
#define PIN_05  *(volatile uint32_t *)0x6000033C
#define PIN_12  *(volatile uint32_t *)0x60000358
#define PIN_13  *(volatile uint32_t *)0x6000035C
#define PIN_14  *(volatile uint32_t *)0x60000360
#define PIN_15  *(volatile uint32_t *)0x60000364

File f;

char c;
int i;

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();

  PIN_OUT = (1<<5 | 1<<4 | 1); // GPIO #0,#4,#5 を出力に設定
  PIN_ENABLE = (1<<5 | 1<<4 | 1); // GPIO #0,#4,#5 の出力を有効
  PIN_00 = 0; // 0=high SD CS
  PIN_05 = 0; // DC
  PIN_04 = 0; // Reset

  if (!SD.begin(15,20000000)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }

  f = SD.open("test.txt", FILE_READ);
  
  SPI.begin();
  SPI.setFrequency(20000000);
  SPI.setDataMode(SPI_MODE2);
  
  Serial.println("wait-------------------");
  delay(5000);
}

void loop() {
  c = f.read();
  f.seek(0);

  SPI.setFrequency(20000000);
  SPI.setDataMode(SPI_MODE2); //※これは MODE 3 なので注意

  SpiCommandWrite(B10110010);
  SpiDataWrite(B10001001);

  SPI.setFrequency(20000000);
  SPI.setDataMode(SPI_MODE0);

  SpiCommandWrite(B10110010);
  SpiDataWrite(B10001001);

  yield();
}

void SpiCommandWrite(byte b){
  PIN_05 = 1; // 1=LOW
  PIN_00 = 1; // 1=LOW
  SPI.write(b);
  PIN_00 = 0; // 0=HIGH 
}

void SpiDataWrite(byte b){
  PIN_05 = 0; // 0=HIGH
  PIN_00 = 1; // 1=LOW
  SPI.write(b);
  PIN_00 = 0; // 0=HIGH
}

【解説】

●4-18行:
GPIO レジスタアドレスの定義です。
好きな名前に設定できます。
アドレスはESPRESSIF社の以下のサイト
ESPRESSIF Support Documents
の esp8266-technical_reference_en.pdf というファイルに表記されている通りです。
今回使わないものもありますが、今後の為に載せておきます。

●20行:
SDカードのファイルハンドルを定義

●30-34行:
今回は別のSPIデバイスを使いませんが、測定の為の例として
CS       GPIO #0
RSET  GPIO #4
DC      GPIO #5
とすると、これをレジスタDirect Access で割り当てる場合、前回の記事で述べたように、ビットをそのピン番号までシフトさせる方式を使って出力を有効にします。

PIN_OUT = (1<<5 | 1<<4 |1);
PIN_ENABLE = (1<<5 | 1<<4 |1);

#0 番ピンは 1<<0 です。
シフトしないのと同じですので、こういう表記になります。
これで、レジスタDirect Access でGPIOピンの出力が有効になります。

そして、PIN_00 = 0; とすればHIGHレベルになります。
間違えないようにしてほしいのは、0がHIGH、 1がLOWです。

●36-49行:
これは、お馴染みのSDカードとSPIの標準的な使い方ですので、説明を省きます。
SDカードとSPI通信のクロック周波数は同じ20MHz にしておきます。

●53-54行:
53行目でSDカードのテキストを1文字(1バイト)読み込みます。
54行目で読み取り位置を最初の文字に戻します。

●56-57行:
SPIライブラリを起動し、SPIモードを3にします。
先にも述べたように、ライブラリの誤りで、SPI_MODE2 がモード3です。
SDカードのモードはゼロなので、ここで変えるわけです。

●59行目:
SPIデバイスではデータを送る前にコマンドを送ります。
それは71-76行で関数化しています。
これは、OLED SSD1351 の場合の例ですが、
DCピンをLOW にして、CSピンをLOWにしてコマンドを出力します。

●60行目:
SPIデバイスに実データを送ります。
78-83行で関数化してます。
これも、OLED SSD1351 の場合の例ですが、
DCピンをHIGHにして、CSをLOWにすればデータ出力できます。

【測定開始】

では、予めmicro SDHC カードにtext.txt ファイルを作っておき、”testing 1, 2, 3, ” と入力して保存しておきます。

シリアルモニタに “wait———–” と出たら5秒以内にロジアナ LAP-C を起動して測定するとこんな感じになりました。

SPI_SPEED_UP2_12

メインloop() 開始直後、初回の micro SDHC カードの文字を読み込むまでは450us も時間がかかっています。
その後、テキストを読み込むわけですが、拡大した図はこんな感じになります。

SPI_SPEED_UP2_08

SCLK 信号はちゃんと SPI mode 0 になってますね。
ただ、疑問なのが、c = f.read(); で1文字読み込むと思いきや、全文字読み込んでしまっています。これは何故でしょうか??? さっぱり分かりません。

その先の信号を拡大してみてみると、こうなります。

SPI_SPEED_UP2_09

loop() を繰り返したら再びSDカードを読み込むと思いきや、一切読み込んでません。
はて???
これは、最初にテキストを読み込んだら、SRAMに記憶しているんでしょうか?
謎です。
どなたか解る方がいらっしゃったら教えていただきたいです。

さて、SDカードの読み書きをする場合のSPI信号はmode 0 でした。
OLED SSD1351 は mode 3 なので、SDカードを読み込んだ後、モードを変えなければなりません。
それが、56-57行目の
SPI.setFrequency(20000000);
SPI.setDataMode(SPI_MODE2);
というわけです。

スケッチ中にこれを入れるのと入れないのとでは時間的に違いがあるのかどうかをロジアナで調べてみるとこんな感じでした。


SPI_SPEED_UP2_10

入れない場合の休止時間が9.3us
入れた場合の休止時間が9.41us

ということで、それほど大きく遅れないということでヨシとします。

実際に入れた場合で、モード切替部分の波形を拡大してみるとこんな感じです。

SPI_SPEED_UP2_11

ちゃんとモードが変えられてますね。
これが変えることができれば、複数のSPIデバイスをコントロールできるということになります。
しっかり、CSやDCピンも動作しているのでバッチリです。

以上です。

5.まとめ

今回はSPIインターフェースについて、更なる発見と多くを学びました。

SDカードも含めた複数のSPIデバイスを使うには、SCLK信号のモード切替ができるかどうかがキモでした。
それと、whileなどの無限ループを組む場合はウォッチドッグタイマを意識して、休止時間を設けることが重要だということを学びました。

そして、それを踏まえたうえで、ライブラリのクロック周波数を最大限まで上げて、GPIO レジスタDirect Access を使えば、かなり速度アップできることを学びました。

ライブラリをよくよく解読してみると、やっぱり、Arduino core for ESP8266 ライブラリでは SPI のレジスタ直叩きを使用しておりましたね。
これには感服いたしました。さすがです。

と、いうことで、これでSPIデバイスは怖くなくなりました。
次回からいろいろと応用していこうと思います。

ではまた・・・。

スポンサーリンク

Amazon.co.jp広告





投稿者:

mgo-tec

Arduino, ESP8266, ESP-WROOM-02 等を使って、主にスマホと連携した電子工作やプログラミング記事を書いてます。ライブラリも作ったりしてます。趣味、独学でやってます。

「ESP8266 ( ESP-WROOM-02 ) SPI 通信高速化、その2 ( 複数デバイス、Mode、Watchdog Timer 問題 )」への4件のフィードバック

  1. mgo-tecさん、こんにちわ。
    ロジックアナライザーやマニュアルの確認等々、詳細な追求をご苦労様でした。
    このような具体的な波形を含んだ丁寧な記事は大変助かっています。
    私も ESP8266 + 2.2″ 240×320 SPI TFT ILI9341 の高速抽画での WDT Error で悩まされています。
    結論:現在(2016.10.13現在)、Adafruit_ILI9341_ライブラリーのサンプルプログラム_graphicstestにてWDT Errorは発生していません。
    理由:サンプルプログラムに yield(); が 16カ所追加されています。
    ライブラリー:以下を使用。
    https://github.com/adafruit/Adafruit_ILI9341
    https://github.com/adafruit/Adafruit-GFX-Library
    2016年4月頃のgraphicstest サンプルには、yield(); が無く WDTが発生していました。
    その時の私の結論は ESP.wdtDisable(); を3カ所記載して動き済ましています。

    TFTの価格:以下は紹介されているアマゾン(1599円)より約半額で2個買えます。
    ebaでの最安値は、733円($7.07)です。業者は sensesmart。
    240×320 3.3V 2.4″ SPI TFT LCD Touch Panel Serial Port Module with PBC ILI9341
    http://www.ebay.com/itm/2-4-240×320-SPI-TFT-LCD-Touch-Panel-Serial-Port-Module-with-PBC-ILI9341-3-3V/172226401724?_trksid=p2047675.c100005.m1851&_trkparms=aid%3D222007%26algo%3DSIC.MBE%26ao%3D1%26asc%3D39242%26meid%3D73e174f5697a42ce9fbbd4c16b9ff194%26pid%3D100005%26rk%3D4%26rkt%3D6%26sd%3D162005196054

    販売数が1番の業者は modulefans で 736円です。
    http://www.ebay.com/itm/240×320-3-3V-2-4-SPI-TFT-LCD-Touch-Panel-Serial-Port-Module-with-PBC-ILI9341-/171983887298?hash=item280b09dbc2:g:4LkAAOSwI-BWMzzZ
    736円

    2.4″ 240×320 TFT の少し前の記事ですが参考になれば、、。
    Try ESP8266 Adafruit_ILI9341 again
    https://macsbug.wordpress.com/2016/04/20/try-esp8266-adafruit_ili9341-again-2/

    Using the TFT LCD display in the ESP8266
    https://macsbug.wordpress.com/2016/04/16/using-the-tft-display-in-the-esp8266/

    How to use the UTFT Library the TFT LCD in ESP8266
    https://macsbug.wordpress.com/2016/04/18/how-to-use-the-utft-library-the-tft-lcd-in-esp8266/

    How to touch operation of the TFT LCD in ESP8266
    https://macsbug.wordpress.com/2016/04/25/how-to-touch-operation-of-the-tft-lcd-in-esp8266-2/

    Bodmer氏はArduinoでTFTのグラフィックス描画性能にトライされ表にあるようにスピードアップされたとの事。
    ただし、これはArduinoでESP8266では動作しませんが参考になります。(答えでなくて申し訳ない)
    Arduino TFT display and font library
    http://www.instructables.com/id/Arduino-TFT-display-and-font-library/?ALLSTEPS
    Step 10: TFT_ILI9341 library now on Github

    1. macsbugさん

      とても有益な情報ありがとうございます。
      そして、記事をお読みいただき感謝いたします。
      yield()はかなり有効ですよね・・・。

      私も今、高速応答TFTまたはOLEDを探しております。
      なかなか安くてSPIの高速通信(例えば、SPI 40MHz以上)対応のものが無いんですよね。
      このリンクを参考に探してみます。

      いろいろとありがとうございました。

  2. nishioka.sstです。以前コメントさせて頂いたことがあります。
    いろいろな製作記事があってとても楽しみにしております。
    記事中のSoft WDT reset、yield(); ・・について参考になりました。
    私も仕事に関係するのですが、最近似たような?ことがありました。
    http://nskikaku.sakura.ne.jp/NS2016/ns2016.html
    (2016,10/5)の記事は関連していると思います。
    原因はまだ良くわからないのですがyield();で上手く動いていますね。
    でもdelay(1);ではダメだったです。

    1. nishioka.sstさん

      ご無沙汰しております。
      いつも当ブログに訪れていただいているようで、感謝いたします。

      記事拝見させていただきました。なるほど・・・!!
      かなり高度なことをやっておられますね。
      しかも、yield()は私が気付く前に既に試されていたんですね。
      スバらしいです!!
      当方の記事と全く同じ症状ですね。
      これは安定動作にはとても有効な方法だと思います。
      これからこういう情報がドンドン出てきて、ますますESP8266が安定して来そうですね。
      また何かありましたらドンドン情報くださいませ。
      m(_ _)m

コメントを残す

メールアドレスが公開されることはありません。


*