WROOM と Arduino で ブラウザ に Hello World を表示させてみました

記事公開日:2015年7月26日
最終修正日:2018年3月7日

こんばんは。
今回は前回の記事からちょっと発展させて、技適認証済み ESP- WROOM -02 ( ESP8266 ) と Arduino で Safari や Chrome などの スマホ ブラウザ に Hello World を表示させてみました 。ATコマンド で UART シリアル通信 です。かなり力技です。
スマートフォン側については、ブラウザ( Google Chrome ) 以外はアプリを一切使用しておりません。(ATコマンドで制御してます)

配線は感じになります。
Wroom_Hello_01

スポンサーリンク


ネットでかなり情報を探したのですが、殆どがHTTP通信ソフトを使っているものばかりで、ブラウザだけで通信する情報がありませんでした。
ですから、未熟ながらかなり力技で表示させてみました。
まだ、WROOMから送信されてくるデータが文字化けするなどの対策ができていませんが、それ以外は問題ないようなので、とりあえず報告します。→(文字化け対策方法が分かりました!! こちらをご覧ください)

(このESP-WROOM-02はamazonさんで購入した、マイクロテクニカさん販売店のものです)

(ロジックレベル変換モジュールは秋月さんで購入したものです。)

前回の記事では、電源を立ち上げてもロジックレベルコンバーターが起動してなかったり、WROOM02のリセットができていなかったり、コマンドを手動で送信しなければなりませんでしたが、今回は、
Arduinoでハードウェアリセット、ロジックレベル変換モジュール起動を制御してみました。
配線はこのようにします。
Wroom_Hello_Pic_01

電源を立ち上げる時の注意は前回の記事と同様ですが、もう一つ注意があります。
順番は

  1. ルーターなどのアクセスポイントを立ち上げて、5分以上たつのを待つ。
  2. その後、Arduino にまず7~12V 出力1AくらいのACアダプターを先につなげて、10秒以上待つ。
    なぜなら、ハードウェアリセットがかかっている最中にArduinoのシリアルモニターを立ち上げたくないため。
  3. 最後にArduino にUSBケーブルとPCをつなぎ、IDEを立ち上げて、シリアルモニターを立ち上げる。

面倒ですね・・・。
WROOM-02の電流が立ち上げ時に170mA以上消費するためにこういう立ち上げ順序が必要なんです。
シリアルモニターなどを使わなく、プログラムが完成すればアダプターだけでいいんですけどね。
まだ実験中なので、仕方ないです。
因みに、再起動するときに、電源を入れ直してもWROOMが起動しなかった場合は次の方法を試してみてください。
Wroom_Hello_Pic_06

私も何回か起動しなくなり、何度電源入れ直しても立ち上がらないということがありました。
このロジックレベル変換モジュールなどとArduinoと結線していると、電源を抜いても浮遊電圧があるようで、ロジックレベルが上がっているのかも知れません。(←実はArduino側に問題がありました。Arduino側のUSBを挿したままと外した時とでは起動状態が変わるようです)
試しに、WROOMのRST側の電圧を測りながらアダプターやUSBを抜き差ししてみたところ、Arduino側のUSBを抜くとロジック電圧が下がっていきました。特に、USBはパソコン側を抜いてもダメで、Arduino側を抜くことです。下がった状態で電源を入れることが良いのかもしれません。
あまり詳しく解析できてませんが、これで試してみてください。ダメなら、全て抜いて、1日置いておくと動くかも・・・
オレンジ色の線が新たに配線したところと、5V電源側に電解コンデンサーを追加してみました。
UART(シリアル)通信でESP-WROOM-02から帰って来る信号が文字化けするので、ロジックレベル変換にノイズが出てるのかなと思って、安定させるためにコンデンサーを追加してみました。
あとは、ロジックICは未使用ピンを全部プルアップ、ダウンした方が良いはずなのですが、双方向コンバーターの場合は、必ずしもそうしなくても良いらしいのです。
マニュアルにも書いてないっぽいのですが、試しに未使用ピンだけ全部ショートさせてたり、プルアップダウンしたりしましたが、あまり効果はありませんでした。
本当はロジック系のオシロスコープで波形を解析したいところです。
あと、ESP-WROOM-02のジャンパーピンはプルアップ、プルダウン抵抗が無いので、それが問題かと思って、10kΩのプルアップ、ダウン抵抗をつけてみましたが、それも効果なしでした。
ロジックレベル変換モジュールを別のメーカーに替えてみようかとも考えていますが、今回は文字化け状態でもブラウザ側へは問題なく通信できているので、次回の課題とします。
Arduino IDE側のとりあえずのソースコードはこんな感じです。
(コードを少々変更しました。(2015/7/28 19:20))
(Arduino IDE 1.7.6で動作確認済み)

#include <SoftwareSerial.h>

SoftwareSerial ESP8266_Serial(2,3); // RX, TX

String str_buf;

long LastTime = 0;

void setup()
{
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  ESP8266_Serial.begin(115200);

  //Logic Level Converter OUTPUT ON: ロジックレベル変換モジュール出力ON
  pinMode(7, OUTPUT);
  digitalWrite(7,LOW);
  //WROOM-02 Reset: WROOM02をリセット
  pinMode(6, OUTPUT);
  digitalWrite(6,HIGH);
  delay(5000);
  digitalWrite(6,LOW);
  delay(10);
  digitalWrite(6,HIGH);
}

void loop()
{
  if(ESP8266_Serial.available()){
    char c = ESP8266_Serial.read();
    Serial.write(c);
    str_buf += c;
    if(c=='\n'){
      Serial.println("<CR>------------------------");
      if(str_buf.indexOf("WIFI")>=0){
        Serial.println("Wi-Fi Connecting ***********************");
        LastTime = millis();
        while( millis() - LastTime < 5000L ){ // 5sec Data Receive
          if( ESP8266_Serial.available()) Serial.write( ESP8266_Serial.read());
        }
        Serial.println();
        //---------------------------------
        ESP8266_Serial.print("AT+CWMODE=1");
        ESP8266_Serial.print("\r\n");
        Serial.println("AT+CWMODE=1");
        Data_Read_Display(3000);  //ここの秒数は各自の環境に合わせて変えてください。
        //----------------------------------
        ESP8266_Serial.print("AT+CWJAP=\"SSID\",\"PASSWord\"");  //ご自分のルーターAPのSSIDとパスワードを入力
        ESP8266_Serial.print("\r\n");
        Serial.println("AT+CWJAP=");
        Data_Read_Display(10000);  //ここの秒数は各自の環境に合わせて変えてください。
        //-----------------------------
        ESP8266_Serial.print("AT+CIFSR");
        ESP8266_Serial.print("\r\n");
        Serial.print("AT+CIFSR=  ");
        Data_Read_Display(3000);  //ここの秒数は各自の環境に合わせて変えてください。
        //-----------------------------
        ESP8266_Serial.print("AT+CIPMUX=1");
        ESP8266_Serial.print("\r\n");
        Serial.print("AT+CIPMUX=1  ");
        Data_Read_Display(3000);  //ここの秒数は各自の環境に合わせて変えてください。
         //----------------------------
        ESP8266_Serial.print("AT+CIPSERVER=1,1001");
        ESP8266_Serial.print("\r\n");
        Serial.print("AT+CIPSERVER=1,1001  ");
        Data_Read_Display(10000);
        Serial.println("Arduino WROOM Server OK!");
        str_buf = String('\0');
      }
      str_buf = String('\0');
    }

    //ブラウザからのGET要求が来たらHTMLコードを送信する
    if(str_buf.indexOf("GET")>=0){
      Data_Read_Display(5000);  //ここの秒数は各自の環境に合わせて変えてください。
      HTTP_response("Hello! World!!");
      
      str_buf = String('\0');
    }
  }
  
  if (Serial.available())
    ESP8266_Serial.write(Serial.read());
}

//WROOM02からのメッセージを設定した時間だけ受信する関数***********************************
void Data_Read_Display(int w_time)
{
  char c;
  LastTime = millis();
  while( millis() - LastTime < w_time ){ //受信を実行する時間をw_timeで決める
    if( ESP8266_Serial.available()) {
      c = ESP8266_Serial.read();
      if(c > 0x80 || c < 0 || c=='\0' || c=='\t' || c=='\v'){
        Serial.print(',');
      }else{
        Serial.write(c);
      }
    }
  }
  Serial.println();
}

//HTTPリクエストとHTMLをブラウザに送信する関数*******************
void HTTP_response(String message)
{
  String html_str;
  
  html_str = "HTTP/1.1 200 OK\r\n";
  html_str += "Content-Type: text/html\r\n";
  html_str += "Connection: close\r\n";
  html_str += "\r\n";
  html_str += "<html>\r\n";
  html_str += "<head>\r\n";
  html_str += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.3, maximum-scale=2.0\">\r\n";
  html_str += "</head>\r\n";
  html_str += "<body>\r\n";
  html_str += message;
  html_str += "<br>\r\n";
  html_str += "</body>\r\n";
  html_str += "</html>\r\n";
   
  ESP8266_Serial.print("AT+CIPSEND=");
  ESP8266_Serial.print(0); //--------Client ID クライアントに付与されるID
  ESP8266_Serial.print(',');
  ESP8266_Serial.print(html_str.length());
  ESP8266_Serial.print("\r\n");

  LastTime = millis();
  while( millis() - LastTime < 5000L ){ // 5sec Data Receive
    if( ESP8266_Serial.available()) Serial.write( ESP8266_Serial.read());
  }
  Serial.println(); 
  char html_c[html_str.length()+1];
  html_str.toCharArray(html_c,html_str.length()+1);
  ESP8266_Serial.write(html_c);
  Serial.println(html_str);
  delay(3000);
  ESP8266_Serial.print("AT+CIPCLOSE=");
  ESP8266_Serial.print(0);
  ESP8266_Serial.print("\r\n");
}

これの動作はこんな感じです。

  1. セットアップで、ESP-WROOM-02 をハードウェアリセットし、ロジックレベル変換モジュールのOEピンをLOWにして起動させます。
  2. 改行コード\nを受信したらその文字列1行の中から WIFI という文字を検知します。そしたらWIFIのTCP通信セットアップをします。 ここで、文字化けすることがあり、WIFI の文字がWHFI になったり WIGI になったりして検知しないことがあります。
    その場合はArduino をリセットし直します。
  • シリアルモニターではこうなります。
    Wroom_Hello_Pic_02改行\nを検知したら<CR>—–と表示させるようにしました。
    最初の行の文字化けは76.8kbpsの転送レートの文字なので必ず文字化けするので、問題ありません。
    WIFIを検知したら
    Wi-Fi Connecting********
    と表示させて次の構文に行きます。
    ここでは、返ってきた CONNECTED  という文字も化けてますね・・・
    ・ATコマンドを以下のようにArduino からシリアル送信します。
    ATコマンドは\n\rを後に送信しなければいけませんが、なぜか、
    ESP8266_Serial.print(“\n\r”);

    ESP8266_Serial.write(“\n\r”);
    は受け付けてくれません。
    なので、いろいろ試行錯誤して、
    ESP8266_Serial.println();
    ESP8266_Serial.print(‘\r’);

    としたら、ようやく受け付けてくれました。

    実は ESP8266_Serial.print(“\r\n”); でいけました!!
    \r と \n の順番を間違えてました。 すみません m_ _ m
    ATコマンドの後に<CR><LF>を連続で送るということです。(2015/7/27 15:00)

    また、ATコマンドを送信した後、OK などのコードを受信しないと次のコード送信してもエラーになってしまいます。
    返って来る文字が文字化けしている場合もあるので、とりあえず、送信コードは確実にエラーなく受信しているようなので、こちらのネット環境に合わせて、受信期間秒数をいい具合に変えてひたすら受信させて、文字化けコードは無視し、次のコード送信してます。
    かなり、素人的な力技ですみません。
    返って来る文字列をシリアルモニタに表示させると 0xFF という符号拡張したようなデータが返って来るので、それはカンマ表示するようにしました。この辺の処理はうまくできていません。良い方法があったら教えてください。
    (→対策がありました!!。 こちらのページをご覧ください。)
    (→そして、この記事以降、文字化け完全解消しました!! →こちらのページをご覧ください。)
  1. AT+CWMODE=1  ステーションモードにセット
  2. 3秒間コード受信
  3. AT+CWJAP=”SSID”,”PASSWORD”   ルーターのアクセスポイントのSSIDとパスワードをセット
  4. 10秒間コード受信
  5. AT+CIFSR       ルーターが割り当てたIPアドレスとWROOM-02のMACアドレスを確認
  6. 3秒間コード受信
  7. AT+CIPMUX=1      マルチプルコネクション有効
  8. 3秒間コード受信
  9. AT+CIPSERVER=1,1001    サーバーモード有効、ポートを1001に指定
  10. 10秒間コード受信
  11. “Arduino WROOM Server OK!” と表示されたら、ブラウザからのGET送信してもOKです。

Wroom_Hello_Pic_03

ここで、OKと表示されていなく、ERRORが表示されているところは、コネクションが確立されておりません。もう一度プログラムやパスワード、SSIDを確認してみてください。
ここまで問題なければ、ブラウザのURLアドレス入力欄に
http://xx.xx.xx.xx:1001
とxxのところにルータから割り当てられたWROOM-02のIPアドレスを入力し、コロンとポート番号(プログラムで指定したもの)を入力します。
こんな感じです。 今は http:// は無くてもいけますね。
Wroom_Hello_Pic_05

すると、ブラウザからのGETリクエストが Arduino のシリアルモニターで確認できます。
でも、全部は表示されず、途中で止まってしまうので、プログラムで5秒だけ受信させた後、
次のようなコマンドを送信します。
AT+CIPSEND=0,バイト数
0という数字はクライアントとコネクションできてから割り当てられるID番号だそうです。
初めてコネクションするのであれば、だいたい0です。
わからなければ、とりあえずブラウザからリクエストしてみれば、
0,CONNECT
などとWROOMからデータが返ってきます。その番号がIDです。
あと、送るバイト数を送らなければいけないのが厄介で、全てのHTML文字列を一まとめにしてバイト数をカウントしてます。
ですから、Stringクラスが収納可能なバイト数しか送ることができません。
これは次回の課題ですね。
次に返って来るデータを5秒受け取ってから、HTTPレスポンスとHTMLを送信します。
送信終わったら、数秒後ArduinoからATコマンドで切断メッセージを送ります。
AT+CIPCLOSE=0
0がID番号です。
シリアルモニターでは以下のような感じになります。
Wroom_Hello_Pic_04

ブラウザのGoogle Chrome では切断した後、もう一度
GET /favicon.ico HTTP/1.1
と、もう一度投げかけてくるので、それは無視してよいです。
そうすると、一番上の写真のように、ブラウザに
Hello! World!!
と表示されると思います。
ちなみに、これでUNOのメモリは
プログラムストレージ 26%
グローバル変数 42%
でした。
以上、たったこれだけ表示させるだけでもえらい労力を費やしました。
なかなかWiFiは手強いです。
早くだれかいいライブラリを作ってくれないかなぁ・・・。
また何か進展ありましたらご報告します。

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

スポンサーリンク

mgo-tec電子工作 関連コンテンツ ( 広告含む )
Amazon.co.jp 当ブログのおすすめ

投稿者:

mgo-tec

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

「WROOM と Arduino で ブラウザ に Hello World を表示させてみました」への2件のフィードバック

  1. > 初めての動く記事をありがとうございます。大変助かります。
    いえいえ、見切り発車的な記事で、まだまだ未完成だらけです。 
    誤り等まだまだあるかもしれませんので、何かありましたらコメントよろしくお願いします。

コメントを残す

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

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください