WROOM 単体に Arduino スケッチで Wi-Fi ストリーミング

記事公開日:2015年8月23日
最終修正日:2017年5月24日

スポンサーリンク

最近は ESP-WROOM-02 ( ESP8266 )をさらに使い易くした ESPr Developer を使っています。
USB-シリアル変換、余裕のある容量の電源レギュレーター、ロジックレベル変換をパッケージにした ESP-WROOM-02 開発ボードです。
ATコマンドやWi-Fi通信が安定して実現できるので、超お勧めです。
こちらの記事も合わせてご覧ください。
ESPr Developer ( ESP-WROOM-02 開発ボード )の使い方をザッと紹介

今回は、ハードウェアのArduinoを一切使わず、ESP-WROOM-02(ESP8266)単体にArduinoスケッチを書き込み、Wi-Fi通信させてみました。
WROOMではNTPサーバーから時刻を取得し、iOSのSafariやAndroidのGoogle ChromeなどのスマートフォンブラウザにServer-Sent Eventsを使ってリアルタイムストリーミング表示させてみました。
見た目は地味ですが、やっている中身はスゴイです。
WroomForArduino_SSE_NTP01
今までは、ArduinoとWROOM(ESP8266)とシリアルUART通信で、ATコマンドで制御していましたが、ネットでも多くの情報があるとおりに、私もWROOM(ESP8266)に直接Arduinoスケッチをフラッシュに書き込んでみました。
つまり、ハードウェアのArduinoは不要なんです。
こんなちっちゃいものにArduinoとWi-fiモジュールが入っているので、メモリは容量無いだろうと思ってました。
が、しかし!!・・・・
実はArduino MEGA以上のSRAMを装備していたのです。
なんと
フラッシュメモリ  1MB (内19%はブートローダやWiFiで既に使用済み)
SRAM 81KB (内54%は使用済み)
もあるんです。
使用済みのところは、何も動作しない空スケッチをコンパイルした場合のメモリーで既に使用されているのです。
それでも、Arduino MEGAを遙かに超えるメモリーです。
私は何か間違えているんでしょうか・・・???
と思うくらいメモリーがスゴイんです。
SRAMなんかはMEGAが8KBですよ。
WROOMはその10倍です!
ウソでしょ・・・
54%使用済みとしても37kBもあるんです・・・。  ウソでしょ・・・。
何かの間違いかもと思いつつ、多量の文字列を扱うスケッチをコンパイルしてみたら、SRAMが54%から61%に増えただけでした。
こりゃぁ~、本物みたいです。
ということで、ArduinoUNOで苦労したメモリを顧みず、ガンガン文字列を貪欲にスケッチに書き込んでみました。
ATコマンドを一切使わず、NTPサーバーから時刻を取得し、WROOMからスマホブラウザにServer-Sent Eventsで時刻をストリーミング送信して表示させた動画はこんな感じです。

ブラウザからのコネクションもライブラリを使うサクッといきました。
メモリーが多量にあるので、ライブラリをガンガン使えます。
こりゃぁ、みなさんスゴイですよ!!
ただ、残念なのが、ADコンバーターが1ピンしかなく、しかも1Vまでしか使えないことです。
でも、ADコンバーターを外付けすればいいだけの話。
ま、何にしてもESP-WROOM-02(ESP8266)のポテンシャルには参りました・・・。
では、この使用方法を順番に解説していきましょう。
※Windowsの場合について説明します。

1.最新版 Arduino IDE をダウンロード

リンクは→こちら
ここはArduino.ccのホームページです。
必ず1.6.5 の方をダウンロードしてください
後でインストールする Arduino core for ESP8266 WiFi chip は他のバージョンではまず正常に動作しませんのでご注意ください。

1.6.12でも動作しました。

最近ちょこっと耳にしたのですが、Arduinoを立ち上げた数人の本家の方たちと、ハードウェア設計班とで分裂したらしいですね。
ですから、EthernetShiels2は IDE1.6.5では動作せず、Arduino.orgページのバージョンでないと動作しないなどの問題があるようです。
私は現在 ver1.7.6 と ver1.6.5 の両方を使い分けるので、Windows Installerはダウンロードしませんでした。
ZIPファイルをダウンロードして使い分けてます。
WROOM(ESP8266)は2015/8/22現在ではver 1.6.5 で動作するようなのでそれをダウンロードして、ZIPならばご自分の好きなフォルダに解凍してください。

2.Timeライブラリをダウンロードしてインストール

Arduino playgroundにあるTimeライブラリのホームページを開きます。
リンクは→こちら
次に下図のような表示のところをクリックします。
ws_Yahoo_message05
次にGitHubのところをクリック
ws_Yahoo_message06
次のようなところをクリックしてZIPファイルをダウンロードしてください。
Shinonome03
ZIPを解凍するとTime-masterフォルダがありますので、更にその中のTime-masterフォルダをIDEのlibrariesフォルダにフォルダごとコピーしてください。

WroomForArduino_SSE_NTP03
もし、IDEをWindows Installerでインストールした場合はC:\ドライブのProgram FilesフォルダにArduinoフォルダがあります。
この辺はインターネットに沢山の情報がありますので、分からない場合は検索してみてください。

3.Arduino IDEのボードマネージャーにESP8266をインストール

まず、以下のGitHubのESP8266ボードデータがあるホームページを開きます。
リンク→こちら
そのページの下図のところのテキストをコピーします。

WroomForArduino_SSE_NTP04

そしたら、Arduino IDE ver 1.6.5を起動して、下図の環境設定を選択。

WroomForArduino_SSE_NTP05

下図の部分に先ほどコピーしたテキストのリンクをペースト(貼り付け)ます。そしてOKをクリックします。
WroomForArduino_SSE_NTP06-1
次に下図のようにボードマネージャーを選択して開きます。
WroomForArduino_SSE_NTP07

次に下図のようにESP8266ボードをインストールします。
WroomForArduino_SSE_NTP08
するとこんな感じでインストール開始します。(ネットには接続しておいてください)
WroomForArduino_SSE_NTP09
終ったら、他のボードも念のため最新版にインストールしておいた方がいいと思います。

4.準備するもの

No品名個数参考購入先
1ESP-WROOM-021Amazon,マイクロテクニカ販売のものなど。
秋月さんや楽天でも売ってます。
2超小型USBシリアル変換モジュール
(3.3V対応)
1秋月電子通商
3三端子レギュレーター
TA48M033F
(秋月さんで購入すると電界コンデンサーとセラミックコンデンサー込でした)
1秋月電子通商
4電解コンデンサー
47uF 35V
1
5積層セラミックコンデンサー
0.1uF
2
6ブレッドボード1
7ジャンパーワイヤー等
8パソコン、USBケーブル,等
9最新のiOSやAndroidスマホ
および、SafariかGoogleChrome
10WROOMがマイクロテクニカ販売のものならば、
2mmピンヘッダ
2mmジャンパーピン
2.54mmピンヘッダ
1式
11リセット用超小型タクトスイッチ
2mmピンヘッダに合うもの
1

5.WROOM(ESP8266)のハンダ付け

まず、ESP-WROOM-02(ESP8266)を接続します。
私はamazonさんのマイクロテクニカさん販売のものを使いました。

これを購入すると取扱説明書がダウンロードできますので、その通りに接続します。
私の場合は説明書通りに2mmピンヘッダもハンダ付けしました。
※2mmピンヘッダおよび2mmジャンパーピン、超小型タクトスイッチ等は別途購入が必要です
下図のような感じです。
フラッシュダウンロードモード(書き込みモード)でジャンパーピンをセットします。

Pin No.Level
GPIO 15LOW
GPIO   2HIGH
GPIO   0LOW
ENHIGH

WroomForArduino_SSE_NTP10

6.各部品の接続

ブレッドボードに下図のように接続します。 シンプルですねぇ~!!
WroomForArduino_SSE_NTP11WroomForArduino_SSE_NTP12

全てできたら、USBケーブルをパソコンと接続する前にWROOMの電源ピンを外して、3.3Vが来ているか確認してからWROOMと接続した方が安全です。
全てOKならばUSBとパソコンを接続します。
ここで、疑問に思った方は鋭いです。
WROOM(ESP8266)は以前の記事で電源容量がキモとお伝えしました。
しかし、今回の接続では、USBシリアル変換モジュールの最大電流が 100mA なんです。
これでも、問題なく動作しました。
ん??  そうすると、そんなに電流無くてもいけるのかな???
この検証はいつか解決してみたいと思います。

7.Arduino IDEの設定

次にArduino IDE1.6.5を起動して、下図のようにツールメニューを設定します。
まずはボードはGeneric ESP8266 Moduleを選択。
WroomForArduino_SSE_NTP13
COMポートはご自分の環境に合わせて設定してください。私の場合はCOM3でした。
WroomForArduino_SSE_NTP14
その他は以下のように全て設定していきます。フラッシュメモリーはとりあえず最大を選んでみました。
WS_lib15
Reset Method を “nodemcu” にするとスイッチサイエンスさんの開発ボードを使うときはいちいちリセットボタンを押さずにバンバン書き込めるので便利です。
毎回リセットスイッチを押して再起動したい場合は”ck”にします。この図では”nodemcu”にしてますが、マイクロテクニカさんの場合は”ck”で良いと思います。
いろいろ変えて試してみてください。

次に書き込み装置を設定します。
とりあえず下図のように選択しました。
WroomForArduino_SSE_NTP16

8.スケッチを入力

スケッチを以下を参考に入力していきます。


ArduinoIDE1.6.12でも動作確認できました。
このバージョンを使う場合、以前のバージョンをアンインストールした後、こちらの記事を参照していただき、Arduino15フォルダを削除してから再インストールしてください。
また、SSE STOP ボタンを押した後のWDTエラーを解消しました。
そして、再接続できるようにしました。

Ikeuchi Toruさんの記事を参考に改変しました。
Ikeuchiさん、ありがとうございました。m(_ _)m
(2016/10/13時点)
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <TimeLib.h>//timeライブラリver1.4の場合
 
const char* ssid = "xxxx";
const char* password = "xxxx";
 
boolean SSE_on = false;//Server-Sent Events設定が済んだかどうかのフラグ
 
WiFiServer server(80);

WiFiClient client;
 
//-------NTPサーバー定義----------------
unsigned int localPort = 2390;      // local port to listen for UDP packets
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.nist.gov";
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
WiFiUDP udp;
 
long LastTime = 0;
 
//*****************セットアップ**********************
void setup() {
  Serial.begin(115200);//このシリアル通信はモニター用
  delay(10);
 
  // Connect to WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
   
  WiFi.begin(ssid, password);
   
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
   
  // Start the server
  server.begin();
  Serial.println("Server started");
 
  // Print the IP address
  Serial.println(WiFi.localIP());
 
  //NTPサーバーでタイムを取得
  udp.begin(localPort);
  WiFi.hostByName(ntpServerName, timeServerIP); 
  setSyncProvider(getNtpTime);
  delay(3000);
}
 
//メインループ***********************************************
void loop() {
  HTTP_Responce();
  yield();//これは重要!!これがないと動作しない。
}
 
//**********************Server-Sent Events レスポンス関数**************
void HTTP_Responce()
{
  client = server.available();//クライアント生成は各関数内でしか実行できないので注意
  while(client.status()!=CLOSED){
    String req = client.readStringUntil('\r');
    if (req.indexOf("GET / HTTP") != -1){//ブラウザからリクエストを受信したらこの文字列を検知する
      Serial.print(req);
      //ブラウザからのリクエストでAccept-Language文字列の行まで読み込む
      while(req.indexOf("Accept-Language") == -1){
        req = client.readStringUntil('\r');
        Serial.print(req);
        yield();
      }
      String str;
      //-------ここからHTTPレスポンスのHTMLとJavaScriptコード
      str = "HTTP/1.1 200 OK\r\n";
      str += "Content-Type:text/html\r\n";
      str += "Connection:close\r\n\r\n";//1行空行が必要
      str += "<!DOCTYPE html><html><head>\r\n";
      str += "<meta name=\"viewport\" content=\"initial-scale=1.5\">\r\n";
      str += "<script type=\"text/javascript\">\r\n";
      str += "var source=new EventSource(\"";
      str += String(WiFi.localIP());//ルーターのローカルIPアドレスを自動取得
      str += "\");\r\n";
      str += "var obj1=document.getElementById(\"SSE_stop\");\r\n";
      str += "source.addEventListener('msg_1',function(event){\r\n";
      str += "var ms1 = document.getElementById('msgs1');\r\n";
      str += "ms1.innerHTML = event.data;});\r\n";
      str += "source.addEventListener('msg_2',function(event){\r\n";
      str += "var ms2 = document.getElementById('msgs2');\r\n";
      str += "ms2.innerHTML = event.data;});\r\n";
      str += "source.addEventListener('msg_3',function(event){\r\n";
      str += "var ms3 = document.getElementById('msgs3');\r\n";
      str += "ms3.innerHTML = event.data;});\r\n";
      str += "function fnc1(){source.close();}\r\n";//STOPボタンを押したら切断する関数
      str += "</script></head><body><form><FONT size=\"1\">\r\n";
      str += "NTP Server Sync</FONT><br>\r\n";
      str += "<FONT size=\"3\"><b>ESP-WROOM-02(ESP8266)<br>Arduino Watch</b><br>\r\n";
      str += "<FONT size=\"6\" color=\"#7777FF\"><b>\r\n";
      str += "<div id=\"msgs1\">Event wait 1</div>\r\n";
      str += "<div id=\"msgs2\">Event wait 2</div>\r\n";
      str += "</b></FONT>\r\n";
      str += "Get Sync NTP server Time";
      str += "<div id=\"msgs3\">Event wait 3</div><br>\r\n";
      str += "<input type=\"button\" id=\"SSE_stop\" value=\"SSE STOP\" onclick=\"fnc1()\">\r\n";
      str += "</form></body></html>\r\n";
      delay(1000);//1秒待ってレスポンスをブラウザに送信
      client.print(str);
      delay(1);//これが重要!これが無いと切断できないかもしれない。
      str = "";
      SSE_on = true;//Server-Sent Event 設定終了フラグ
      client.stop();
      Serial.println("\nGET HTTP client stop--------------------");
      req ="";
      SSE_Responce();
    }else if(req != ""){
      delay(1);
      client.stop();
      delay(1);
      client.flush();
    }
    req ="";
    yield();
  }
}
//**************Server-Sent Events データ送信関数****************************
void SSE_Responce()
{//HTTPレスポンス1度目を送信したら、すぐにブラウザから2回目のGETリクエストが来る
  while(SSE_on == true){//無限ループ
    client = server.available();
    while(client.status()!=CLOSED){
      String req = client.readStringUntil('\r');
      if(req.indexOf("GET") != -1){//2回目のGETを検知したらServer-Sent Eventsレスポンス送信
        Serial.println("GET in--------------------");
        Serial.print(req);
        while(req.indexOf("Accept-Language") == -1){
          req = client.readStringUntil('\r');
          Serial.print(req);
        }
        if(SSE_on == true){
          Serial.println("\nsse responce send--------------------");
          String sse_resp;
          //ストリーム配信をブラウザが認識するためのレスポンス
          sse_resp = "HTTP/1.1 200 OK\r\n";
          sse_resp += "Content-Type:text/event-stream\r\n";//SSE使用時に必ずサーバー側からブラウザへこれを返す
          sse_resp += "Cache-Control:no-cache\r\n";
          sse_resp += "\r\n";//必ずこの空行が必要
           
          client.print(sse_resp);
          delay(3000);//ここの秒数はもう少し少なくても問題ない
          Serial.println(sse_resp);
 
          String sse_data;
         
          Serial.println("sse data send--------------------");
          String str_h;
          String str_m;
          String str_s;
          String sync_h="?";
          String sync_m="?";
          String sync_s="?";
          LastTime = millis();   
          while(client.status()!=CLOSED){//Event Sourceデータの無限ループストリーム送信
            if(hour()<10){//一桁の数値を二桁にする
              str_h = "0" + String(hour()) ;
            }else{
              str_h = String(hour());
            }
            if(minute()<10){
              str_m = "0" + String(minute()) ;
            }else{
              str_m = String(minute());
            }
            if(second()<10){
              str_s = "0" + String(second()) ;
            }else{
              str_s = String(second());
            }
            //30秒毎にNTPサーバーから時刻をゲットしてArduinoタイムを修正
            if(millis()-LastTime > 30000){
              WiFi.hostByName(ntpServerName, timeServerIP); 
              setSyncProvider(getNtpTime);
              LastTime = millis();
              sync_h = str_h;
              sync_m = str_m;
              sync_s = str_s;
            }
            sse_data = "event:msg_1\n";//ブラウザへ送るeventを発生させて改行コードをつける
            sse_data += "data:";
            sse_data += String(year())+"/"+String(month())+"/"+String(day());//data:の後に送りたいデータをつける
            sse_data += "\n\n";//イベントを発生させるためには必ず改行コード2回連続をつける
            sse_data += "event:msg_2\n";
            sse_data += "data:";
            sse_data += str_h+":"+str_m+":"+str_s;
            sse_data += "\n\n";
            sse_data += "event:msg_3\n";
            sse_data += "data:";
            sse_data += sync_h + ":" + sync_m + ":" + sync_s;//NTPサーバから取得した時刻を表示
            sse_data += "\n\n";
            client.print(sse_data);
            sse_data = "";
            yield();
          }
          delay(1);
          client.stop();
          delay(1);
          client.flush();
          Serial.println("Client.Stop-----------------");
          Serial.println();
          SSE_on = false;
          break;
        }
      }
      req = "";
      yield();
    }
    yield();
  }
}
//************NTPサーバータイム取得関数*****************************
const int timeZone = 9;     // 日本時間
//const int timeZone = 1;     // Central European Time
//const int timeZone = -5;  // Eastern Standard Time (USA)
//const int timeZone = -4;  // Eastern Daylight Time (USA)
//const int timeZone = -8;  // Pacific Standard Time (USA)
//const int timeZone = -7;  // Pacific Daylight Time (USA)
 
time_t getNtpTime()
{
  while (udp.parsePacket() > 0) ; // discard any previously received packets
  sendNTPpacket(timeServerIP);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    delay(1);//これを入れないと更新できない場合がある。
    int size = udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  return 0; // return 0 if unable to get the time
}
//******************NTPリクエストパケット送信****************************
unsigned long sendNTPpacket(IPAddress& address)
{
//  Serial.println("sending NTP packet...");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
 
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  udp.beginPacket(address, 123); //NTP requests are to port 123
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();
}

このプログラムをコンパイルする前に、プログラムの最初の方にあるご自分のルーターで設定したSSIDやパスワードの部分を書き換えるのを忘れずに。
const char* ssid = “xxxx”;←ここのxxxxの部分をご自分のルーターのSSIDに書き換える
const char* password = “xxxx”;←ここのxxxx部分をご自分のルーターのパスワードに書き換える
このプログラムの詳細な説明は後日アップする予定ですが、過去の記事を参考にしていただければある程度は理解できるかと思います。
NPTサーバー通信はサンプルコードを改良しました。

9.スケッチをコンパイルおよびWROOMに書き込み

ではいよいよスケッチをコンパイルしてWROOMのフラッシュに書き込みします。
Arduino IDEの書き込みボタンを押して、コンパイル&書き込みを行います。
以下のように赤いテキストでピリオドが連続して出ればOKです。
WroomForArduino_SSE_NTP17
ただ、もし、うまくいかない場合は、USBを抜き、WROOMの電源を一旦切り、もう一度USBをパソコンと接続して立ち上げなおしてください。
USBを接続しなおした場合に1回目はコンパイルがうまくできません。直ぐもう一度書き込みボタンを押してください。そうすれば書き込みが始まると思います。

10.実行させる

ではいよいよ実行させていきます。
まず、WROOM(ESP8266)のジャンパーピンを下図のようにセットして、フラッシュブートモード(読み込み専用)にします。
WroomForArduino_SSE_NTP18
そして、USBケーブルを抜き、WROOM(ESP8266)の電源を一旦落とします。
次に、ご自分のルーター(アクセスポイント)をあらかじめ立ち上げておき、ルーターの設定やファイアウォール、DHCP、アクセス制限などを確認し、WROOMがコネクトできるようにしておきます。
次に再度USBケーブルを接続してWROOMの電源を立ち上げ、直ぐにArduino IDEのシリアルモニターを起動しておきます。
シリアルモニターの右下の通信速度設定は115200bpsにします。
そして、起動後に再度WROOMのリセットボタンを押します。
すると、下図のように表示されます。
WroomForArduino_SSE_NTP19
次にスマホのWi-Fiを起動し、Wi-FiのSSID、パスワードを設定し、最新ブラウザ(Android4.2.2以上 最新版Google Chrome、または iOS8.4以上 Safari)を起動し、下図のようにURL入力欄にご自分のルーターで割り当てられたローカルIPアドレスを入力します。
WroomForArduino_SSE_NTP20
すると、以下のようにシリアルモニターにブラウザからのGETリクエストが表示され、WROOMからEvent-Streamレスポンスを返し、再度ブラウザからStreamのGETリクエストがあり、WROOMからServer-Sent Eventsのデータを無限連続ストリーミング送信する様子が表示されます。
WroomForArduino_SSE_NTP21
動画はこのページの最初の方のYouTube動画をご覧ください。
このまま放っておくと、永遠にストリーミング送受信しますので、ブラウザの「SSE STOP」ボタンを押すとストリーミング停止します。
そうすると、シリアルモニターには以下のように表示されます。
停止後、数分すると再度自動的にルーターとコネクションし始めます。
この動作はなぜそうなるのかわかりません。
これはどうやら例外エラーのようです。いつかこれは解消したいと思います。
ちなみに、WROOM(ESP8266)がフラッシュダウンロードモード(書き込みモード)になっていると、再コネクションしませんので注意してください。

WDT例外エラーはなくなりました。
プログラムを改変しました。
Ikeuchi Toruさんの記事を参考に改変しました。
Ikeuchiさん、ありがとうございました。m(_ _)m

さて、皆さま、これでちゃんと動作しましたでしょうか?
ここで、
ちょっとしたトラブルシューティングをお知らせします。

●再コンパイルおよび書き込みができない場合
一度、プログラムを実行してストリーミング通信をしてしまった場合、Arduino IDEで再コンパイルおよび書き込みしようとしても、書き込みを完了できません。
その場合次の手順をやってみてください。

  • 一旦USBケーブルを抜いてWROOM(ESP8266)の電源を落とす。
  • GPIO 0番 をLOWに接続し、FLASHダウンロードモード(書き込みモード)にする。(忘れがち!!)
  • USBケーブルとパソコンを接続する。
  • 一呼吸置いて、Arduino IDEのコンパイル&書き込みボタンを押します。しかし、一回目はエラーになる。
  • もう一度コンパイル&書き込みボタンを押す。(エラーになったら、再度試してみる)

●実行しても、シリアルモニターに何も表示されない
次の手順を試してみてください。

  • 書き込みが完了したら、一旦USBを抜いてWROOM(ESP8266)の電源を落としてください。
  • その後、GPIO 0番 をHIGHに接続して、FLASHブートモード(読み込み専用モード)にする(忘れがち!!)
  • USBとパソコンを接続し、Arduino IDEのシリアルモニターを再起動する。
  • WROOMの電源を入れてからシリアルモニターを起動する時間が十分短ければ起動状況が表示されますが、シリアルモニターの起動が遅ければ既にWi-Fiセットアップ完了してしまっているので、シリアルモニターには表示されません。
    その場合は、WROOMのリセットボタン(無ければRSTピンとGNDをリード線でショートする)を押してリセットすると起動状態がモニターされます。

以上です。 みなさまもしっかり動作しましたでしょうか・・・?。
もし、これでうまく動かないなどありましたら、コメントやお問い合わせフォームでお問い合わせください。
ここまでお読み頂きありがとうございます。
では、また・・・

mgo-tec電子工作 関連コンテンツ ( 広告含む )

スポンサーリンク

最近は ESP-WROOM-02 ( ESP8266 )をさらに使い易くした ESPr Developer を使っています。
USB-シリアル変換、余裕のある容量の電源レギュレーター、ロジックレベル変換をパッケージにした ESP-WROOM-02 開発ボードです。
Wi-Fi通信が安定して実現できるので、超お勧めです。
こちらの記事も合わせてご覧ください。
ESPr Developer ( ESP-WROOM-02 開発ボード )の使い方をザッと紹介
その他、以下の記事では Wi-Fi 双方向通信したり、画像を転送したりもできてしまいました。
鉄道 JR風 有機EL 電光掲示板を作ってみた。(スマホで編集できて、Yahoo! ニュースも表示できる)
EasyWebSocket BETA 1.3 をアップしました。
NTP時刻・温度・湿度・気圧データのSDカードロガー制作。日本語フォントもSDカードから読み込む ( ESP-WROOM-02 使用 )
NeoPixel と紙で フルカラー LED イルミネーション オブジェを作ってみた

Amazon.co.jp 当ブログのおすすめ







投稿者:

mgo-tec

Arduino , ESP32 ( ESP-WROOM-32 ) , ESP8266 ( ESP-WROOM-02 )等を使って、主にスマホと連携した電子工作やプログラミング記事を書いてます。ライブラリも作ったりしてます。趣味、独学でやってますので、動作保証はしません。 電子回路やプログラミングの専門家ではありません。 畑違いの仕事をしてます。 でも、少しだけ電気の知識が必要な仕事なので、電気工事士や工事担任者等の資格は持ってます。

「WROOM 単体に Arduino スケッチで Wi-Fi ストリーミング」への12件のフィードバック

  1. 参考にさせていただいています。
    一点、モジュールの個体差でしょうか
    我が家の環境では、
    while (millis() – beginWait < 1500) {
    の後に、delay(1);を挿入しないと
    NTPから取得したデータの更新が
    正常に機能せず、time関数の初期値で
    表示されていました。

  2. soarusさん
    貴重なコメントありがとうございました。
    当方の環境ではdelay(1);を入れなくても、iOS、Androidともに問題なかったので、他の方の環境で動くのかが疑問でした。
    動かなくて悩んでいる方にはとても助かる意見だと思います。
    早速、スケッチを追加修正させていただきました。
    当方の環境でもdelay(1);を追加しても問題なく動作しました。
    また何かありましたら、意見をお寄せください。

  3. とても興味深い記事だったので参考にさせていただいております。
    当記事の通りにセッティングを行い、プログラムをそのまま(SSID,PASSWARDは変えました)検証いたしましたところ、182行目の「setSyncProvider(getNtpTime); 」が引っ掛かってしまい、書き込むことができませんでした。
    どのようにしたら改善することができるのでしょうか。
    よろしくお願いします。

    -環境-
    windows7
    Arduino 1.6.7
    ↓エラーコード
    —————————————————————–
    C:\Users\aki\Documents\Arduino\ESP-WROOM-02\ESP-WROOM-02.ino: In function ‘void setup()’:
    ESP-WROOM-02:61: error: ‘getNtpTime’ was not declared in this scope
    setSyncProvider(getNtpTime);
    ^
    ESP-WROOM-02:61: error: ‘setSyncProvider’ was not declared in this scope
    setSyncProvider(getNtpTime);
    ^
    C:\Users\aki\Documents\Arduino\ESP-WROOM-02\ESP-WROOM-02.ino: In function ‘void loop()’:
    ESP-WROOM-02:67: error: ‘HTTP_Responce’ was not declared in this scope
    HTTP_Responce();
    ^
    C:\Users\aki\Documents\Arduino\ESP-WROOM-02\ESP-WROOM-02.ino: In function ‘void HTTP_Responce()’:
    ESP-WROOM-02:126: error: ‘SSE_Responce’ was not declared in this scope
    SSE_Responce();
    ^
    C:\Users\aki\Documents\Arduino\ESP-WROOM-02\ESP-WROOM-02.ino: In function ‘void SSE_Responce()’:
    ESP-WROOM-02:169: error: ‘hour’ was not declared in this scope
    if(hour()<10){
    ^
    ESP-WROOM-02:174: error: 'minute' was not declared in this scope
    if(minute()<10){
    ^
    ESP-WROOM-02:179: error: 'second' was not declared in this scope
    if(second()<10){
    ^
    ESP-WROOM-02:187: error: 'getNtpTime' was not declared in this scope
    setSyncProvider(getNtpTime);
    ^
    ESP-WROOM-02:187: error: 'setSyncProvider' was not declared in this scope
    setSyncProvider(getNtpTime);
    ^
    ESP-WROOM-02:195: error: 'year' was not declared in this scope
    sse_data += String(year())+"/"+String(month())+"/"+String(day());
    ^
    ESP-WROOM-02:195: error: 'month' was not declared in this scope
    sse_data += String(year())+"/"+String(month())+"/"+String(day());
    ^
    ESP-WROOM-02:195: error: 'day' was not declared in this scope
    sse_data += String(year())+"/"+String(month())+"/"+String(day());
    ^
    C:\Users\aki\Documents\Arduino\ESP-WROOM-02\ESP-WROOM-02.ino: In function 'time_t getNtpTime()':
    ESP-WROOM-02:229: error: 'sendNTPpacket' was not declared in this scope
    sendNTPpacket(timeServerIP);
    ^
    ESP-WROOM-02:242: error: 'SECS_PER_HOUR' was not declared in this scope
    return secsSince1900 – 2208988800UL + timeZone * SECS_PER_HOUR;
    ^
    exit status 1
    'getNtpTime' was not declared in this scope
    ——————————————————————————–

    1. A.koniさん

      コメントありがとうございます。
      おそらく、Arduino IDE が1.6.7であることが原因だと思います。
      Arduino core for ESP8266 WiFi chip は推奨Arduino IDE は1.6.5 です。
      1.6.7ではまず正常に動作しないようです。

      当方のブログでも、最新版IDEのページへリンクを貼っていましたので、修正しました。
      私も1.6.7の動作確認は最近までやっておらず、申し訳ございませんでした。
      その他のページでも1.6.5をインストールするように修正しています。
      Arduino core for ESP8266 WiFi chipも1.6.5限定でなく、他のバージョンでも動作するようにしてほしいですね。
      ご指摘ありがとうございました。

      1. 当方、1.6.9にて同じコンパイルエラーになっていました。
        #include を
        #include に変更するとコンパイル、動作ともにできました。
        最近Arduinoを始めたど素人ですが参考までに。

        1. kumaさん

          コメントありがとうございます。
          Sever-Sent Events はしばらく使ってなかったもので、不具合が分かりませんでした。
          Arduino Timeライブラリも知らぬ間に結構変更されていて、ライブライ使用方法も変わっていることに気がづきませんでした。
          kumaさんのコメント欄では<>の中の文字が消えてしまってますが、現在のTimeライブラリでは
          #include <Time.h> → #include <TimeLib.h>
          と変更しなければならないということでした。
          kumaさん、こういうことでよろしいでしょうか?
          当方でもArduno1.6.9でこのように変更したら動作しました。
          大変失礼いたしました。
          記事を修正したいと思います。

  4. 有用な記事ありがとうございます。
    ビギナー過ぎて良く分からず、基本的なことかと思いますが質問させてください!

    2.Timeライブラリをダウンロードしてインストール
    のところで”Time”をクリックしてダウンロードとありますが、クリックすると右記のページが開きます。”http://www.pjrc.com/teensy/td_libs_Time.html”
    このページにある” Teensyduino Installer”をクリックして、”http://www.pjrc.com/teensy/td_download.html”を開き、
    以下の環境の中から使っている環境のインストーラをダウンロードしてArduinoフォルダの中の”libraries”フォルダにコピーすれば良いという認識で合っていますでしょうか

    Macintosh OS-X Installer
    Linux Installer (32 bit)
    Linux Installer (64 bit)
    Windows XP / 7 / 8 / 10 Installer

    宜しくお願いいたします。

    1. かわさん

      記事をご覧頂きありがとうございます。
      ライブラリのページが知らぬ間に変わっている事が多く、私も困っております。

      今、多忙で記事訂正が出来ないのですが、Windowsであればこちらの記事のTimeライブラリインストールの節を参照してみて下さい
      (MACは持ち合わせておりませんので分かりません)
      https://www.mgo-tec.com/blog-entry-1616shinonome-ws-oled-news.html

      1. mgo-tecさん
        お忙しいところ迅速な返答ありがとうございます!
        リンク先確認いたします

        1. かわさん

          先のコメントのkumaさんの件で気付いたのですが、Timeライブラリの仕様が変更されておりました。
          #include <Time.h> → #include <TimeLib.h>
          と変更しないと動きません。
          記事も修正しました。
          これで試してみてください。

  5. Arduino IDE 1.6.7 にて setSyncProvider(getNtpTime); でコンパイルエラーが出る件。
    void setup()の前に、以下を記述するとコンパイルが可能です。

    void HTTP_Responce();
    void SSE_Responce();
    time_t getNtpTime();
    unsigned long sendNTPpacket(IPAddress& address);

    私の方では Arduino IDE 1.6.7 でコンパイルできましたが、間違いかもしれませんので、他の方で試されてお返事を頂けると幸いです。

    1. macsbugさん

      コメント投稿ありがとうございます。
      私は1.6.7はいろいろと問題があったので、今は使ってません。
      先のコメント投稿でもあったように、現在は1.6.9で快適に動作しております。
      setSyncProviderの件もTimeライブラリが知らぬ間にバージョンアップしていたりしてエラーになっていたようです。
      最新版をダウンロードした場合には
      #include<Time.h> → #include<TimeLib.h>に変更したら動作します。

      ただし、注意していただきたいのは、古いIDEをアンインストールする場合、Arduino15フォルダを削除せねばなりません。
      その方法はこちらの記事を参照にしてください。
      https://www.mgo-tec.com/esp8266-board-install01-html

コメントを残す

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

*画像の文字を入力してください。(スパム防止の為)