こんばんは。
今回は前回の記事からちょっと発展させて、技適認証済み ESP- WROOM -02 ( ESP8266 ) と Arduino で Safari や Chrome などの スマホ ブラウザ に Hello World を表示させてみました 。ATコマンド で UART シリアル通信 です。かなり力技です。
スマートフォン側については、ブラウザ( Google Chrome ) 以外はアプリを一切使用しておりません。(ATコマンドで制御してます)
以下のプログラムは無保証とさせて頂きます。
ESPr Developer などの ESP-WROOM-02開発ボードを使った方が遙かに簡単でおススメです。
ESPr Developer ( ESP-WROOM-02 開発ボード )の使い方をザッと紹介
以下、古い記事です。
(2018/11/25)
配線は感じになります。
ネットでかなり情報を探したのですが、殆どがHTTP通信ソフトを使っているものばかりで、ブラウザだけで通信する情報がありませんでした。
ですから、未熟ながらかなり力技で表示させてみました。
まだ、WROOMから送信されてくるデータが文字化けするなどの対策ができていませんが、それ以外は問題ないようなので、とりあえず報告します。→(文字化け対策方法が分かりました!! こちらをご覧ください)
(このESP-WROOM-02はamazonさんで購入した、マイクロテクニカさん販売店のものです)
(※2015年当初とはタイプが異なっています)
似たような製品として以下のサイトをご参照ください。
https://akizukidenshi.com/catalog/g/g113646/
また、この記事を書いた当初のESP-WROOM-02(ESP8266)のプログラムメモリ(フラッシュ)は4MBでしたが、仕様変更されて2MBになってしまいました。プログラミングできる量が半減してしまいましたのでご注意ください。
(ロジックレベル変換モジュールは秋月さんで購入したものです。)
前回の記事では、電源を立ち上げてもロジックレベルコンバーターが起動してなかったり、WROOM02のリセットができていなかったり、コマンドを手動で送信しなければなりませんでしたが、今回は、
Arduinoでハードウェアリセット、ロジックレベル変換モジュール起動を制御してみました。
配線はこのようにします。
この回路図は古いままで、良く分からず作成した当時のものです。
電源を立ち上げる時の注意は前回の記事と同様ですが、もう一つ注意があります。
順番は
- ルーターなどのアクセスポイントを立ち上げて、5分以上たつのを待つ。
- その後、Arduino にまず7~12V 出力1AくらいのACアダプターを先につなげて、10秒以上待つ。
なぜなら、ハードウェアリセットがかかっている最中にArduinoのシリアルモニターを立ち上げたくないため。 - 最後にArduino にUSBケーブルとPCをつなぎ、IDEを立ち上げて、シリアルモニターを立ち上げる。
面倒ですね・・・。
WROOM-02の電流が立ち上げ時に170mA以上消費するためにこういう立ち上げ順序が必要なんです。
シリアルモニターなどを使わなく、プログラムが完成すればアダプターだけでいいんですけどね。
まだ実験中なので、仕方ないです。
因みに、再起動するときに、電源を入れ直してもWROOMが起動しなかった場合は次の方法を試してみてください。
私も何回か起動しなくなり、何度電源入れ直しても立ち上がらないということがありました。
このロジックレベル変換モジュールなどと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で動作確認済み)
以下のプログラムは無保証とさせて頂きます。
ESPr Developer などの ESP-WROOM-02開発ボードを使った方が遙かに簡単でおススメです。
ESPr Developer ( ESP-WROOM-02 開発ボード )の使い方をザッと紹介
(2018/11/25)
【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)
#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");
}
これの動作はこんな感じです。
- セットアップで、ESP-WROOM-02 をハードウェアリセットし、ロジックレベル変換モジュールのOEピンをLOWにして起動させます。
- 改行コード\nを受信したらその文字列1行の中から WIFI という文字を検知します。そしたらWIFIのTCP通信セットアップをします。 ここで、文字化けすることがあり、WIFI の文字がWHFI になったり WIGI になったりして検知しないことがあります。
その場合はArduino をリセットし直します。
- シリアルモニターではこうなります。
改行\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 という符号拡張したようなデータが返って来るので、それはカンマ表示するようにしました。この辺の処理はうまくできていません。良い方法があったら教えてください。
(→対策がありました!!。 こちらのページをご覧ください。)
(→そして、この記事以降、文字化け完全解消しました!! →こちらのページをご覧ください。)
- AT+CWMODE=1 ステーションモードにセット
- 3秒間コード受信
- AT+CWJAP=”SSID”,”PASSWORD” ルーターのアクセスポイントのSSIDとパスワードをセット
- 10秒間コード受信
- AT+CIFSR ルーターが割り当てたIPアドレスとWROOM-02のMACアドレスを確認
- 3秒間コード受信
- AT+CIPMUX=1 マルチプルコネクション有効
- 3秒間コード受信
- AT+CIPSERVER=1,1001 サーバーモード有効、ポートを1001に指定
- 10秒間コード受信
- “Arduino WROOM Server OK!” と表示されたら、ブラウザからのGET送信してもOKです。
ここで、OKと表示されていなく、ERRORが表示されているところは、コネクションが確立されておりません。もう一度プログラムやパスワード、SSIDを確認してみてください。
ここまで問題なければ、ブラウザのURLアドレス入力欄に
http://xx.xx.xx.xx:1001
とxxのところにルータから割り当てられたWROOM-02のIPアドレスを入力し、コロンとポート番号(プログラムで指定したもの)を入力します。
こんな感じです。 今は http:// は無くてもいけますね。
すると、ブラウザからの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番号です。
シリアルモニターでは以下のような感じになります。
ブラウザの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表示も簡単です。 https://www.mgo-tec.com/blog-entry-ss-wroom-howto01.html その他、以下の記事では Wi-Fi 双方向通信したり、画像を転送したりもできてしまいました。 https://www.mgo-tec.com/blog-entry-jr-train-message-board-01.html https://www.mgo-tec.com/blog-entry-easywebsocket-beta13.html https://www.mgo-tec.com/blog-entry-wroom-esp8266-bme280-ssd1351-sd.html https://www.mgo-tec.com/blog-entry-neopixel-paper-illumination01.html
Amazon.co.jp 当ブログのおすすめ












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