Arduino勉強会/0O-WiFiモジュールその2
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[Arduino勉強会]]
#contents
2015/10/31からのアクセス回数 &counter;
** Arduinoのスケッチを作る [#f5ee0316]
[[Arduino勉強会/0N-WiFiモジュールその1]]
でESP-WROOM-02を使ってWebサーバにアクセスできるところまで...
今回は、プログラムを書いてESP-WROOM-02を操作してみましょ...
*** 定数の定義 [#h916c7bc]
ATコマンドやSSID、パスワードは#define分で定義しておきます。
#pre{{
#define ST_SSID "<<SSIDを指定>>"
#define ST_PASSWD "<<パスワードを指定>>"
#define SERVER_ADDR "49.212.164.205"
#define SERVER_PORT 80
#define CRLF "\r\n"
#define CRLF2 "\r\n\r\n"
#define STATION_MODE 1
}}
*** コマンドを関数にまとめる [#ae35fc6b]
以下のATコマンドを関数に整理します。
- AT+CWMODE
- AT+CWJAP
- AT+CIPSTART
- AT+CIPSEND
ATコマンドは終わりにCR+LFを追加するためにatCommand関数も...
#pre{{
int atCommand(char *cmd) {
Serial.print(cmd);
Serial.print(CRLF);
return 1;
}
int atCwMode(int mode) {
sprintf(buf, "AT+CWMODE=%d", mode);
return atCommand(buf);
}
int atCwJap(char *ssid, char *passwd) {
sprintf(buf, "AT+CWJAP=\"%s\",\"%s\"", ssid, passwd);
return atCommand(buf);
}
int atCipStart(char *server_addr, int server_port) {
sprintf(buf, "AT+CIPSTART=\"TCP\",\"%s\",%d", server_ad...
return atCommand(buf);
}
int atCipSend(char *uri) {
sprintf(buf, "GET %s HTTP/1.0%s%s", uri, CRLF, CRLF2);
int len = strlen(buf);
Serial.print("AT+CIPSEND=");
Serial.print(len);
Serial.print(CRLF);
delay(1000);
Serial.print(buf);
}
}}
*** 初期化 [#obe6d74b]
ESP-WROOM-02の操作の内、以下の処理は1回だけすればよいので...
にまとめます。
- モード設定:
- ルータに接続:
#pre{{
atCwMode(STATION_MODE);
delay(1000);
atCwJap(ST_SSID, ST_PASSWD);
}}
*** ボタンアクションの追加 [#l7346133]
タクトスイッチのボタンを押したときに、Sageサーバにアクセ...
スケッチを修正します。
#pre{{
if (digitalRead(sw_pin) == LOW) {
pc.println("SW pressed");
delay(500);
atCipStart(SERVER_ADDR, SERVER_PORT);
delay(1000);
atCipSend("/hello.html");
}
}}
** テスト [#g7abef6c]
準備ができたので、スケッチを動かしてみます。
コマンドの実行状況がシリアルモニタに表示されるので、プロ...
#pre{{
ESP8266IF3tTest
AT+CWMODE=1
OK
AT+CWJAP="<<SSIDを指定>>","<<パスワードを指定>>"
WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP
OK
SW pressed
AT+CIPSTART="TCP","49.212.164.205",80
CONNECT
OK
AT+CIPSEGET /hello.html HTTP/1.0
Recv 30 bytes
SEND OK
+IPD,303:HTTP/1.1 200 OK
Date: Tue, 27 Oct 2015 12:29:51 GMT
Server: Apache
Last-Modified: Sat, 24 Oct 2015 23:49:16 GMT
ETag: "c005e-34-522e260431c88"
Accept-Ranges: bytes
Content-Length: 52
Connection: close
Content-Type: text/html; charset=UTF-8
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
CLOSED
}}
** atCommandの変更 [#cc6262c9]
これまでatCommand関数が正しく処理できたかを確認していませ...
ATコマンドでは正しく処理できたときにOK、失敗の時にERRORを...
そこで、最後に返された文字がKかRで正常修了と異常終了の判...
atCommandを以下の様に変更して、再度スケッチを実行してみま...
処理によって、OKがでるまでの時間が異なるため、atCommandに...
待ち時間を入れることにします。
レスポンスの出力に少し文字の取りこぼしがありますが、何と...
を受信できるようになりました。
現段階のスケッチは、以下の通りです。
#pre{{
#include <SoftwareSerial.h>
#define ST_SSID "<<SSIDを指定>>"
#define ST_PASSWD "<<パスワードを指定>>"
#define SERVER_ADDR "49.212.164.205"
#define SERVER_PORT 80
#define CRLF "\r\n"
#define CRLF2 "\r\n\r\n"
#define STATION_MODE 1
#define WAIT_ONECE 2000
#define OK 'K'
#define ERR 'R'
#define FAIL 'L'
char buf[128];
int interval_waits[] = {50, 80, 160, 200, 300, 600, 1200,...
int retry_count = sizeof(interval_waits)/sizeof(int);
int sw_pin = 10;
int sTx_pin = 12;
int sRx_pin = 11;
int c;
SoftwareSerial pc(sRx_pin, sTx_pin);
int last_char = -1;
int waitForResponse() {
last_char = -1;
int err_count = 0;
// 返されたデータをすべて読み込む
for (int i = 0; i < retry_count; i++) {
while (Serial.available()) {
while((c = Serial.read()) != -1) {
if (c != '\r' && c != '\n')
last_char = c;
// デバッグ用
pc.write(c);
}
}
// OK, ERROR, > , FAIL, CLOSED
if (last_char == OK || last_char == ERR || last_char ...
// pc.println("wait");
delay(interval_waits[err_count++]);
}
}
int atCommand(char *cmd, int wait_time) {
int c;
Serial.print(cmd);
Serial.print(CRLF);
delay(wait_time);
// 応答を待つ
waitForResponse();
// 最後に返された文字がKまたはRでなかったら、WAIT_ONECE...
if (last_char != OK && last_char != ERR && last_char !=...
delay(WAIT_ONECE);
pc.println("Do wait onece");
if (Serial.available()) {
while((c = Serial.read()) != -1) {
if (c != '\r' || c != '\n')
last_char = c;
// デバッグ用
pc.write(c);
}
}
}
if (last_char == OK)
return 1;
else if (last_char == ERR)
return 0;
else
return -1;
}
int atCwMode(int mode) {
sprintf(buf, "AT+CWMODE=%d", mode);
return atCommand(buf, 0);
}
int atCwJap(char *ssid, char *passwd) {
sprintf(buf, "AT+CWJAP=\"%s\",\"%s\"", ssid, passwd);
return atCommand(buf, 2000);
}
int atCipStart(char *server_addr, int server_port) {
sprintf(buf, "AT+CIPSTART=\"TCP\",\"%s\",%d", server_ad...
return atCommand(buf, 500);
}
int atCipSend(char *uri) {
sprintf(buf, "GET %s HTTP/1.0%s%s", uri, CRLF, CRLF2);
int len = strlen(buf);
char tmp[32];
sprintf(tmp, "AT+CIPSEND=%d%s", len, CRLF);
// uriを送る
atCommand(tmp, 1000);
Serial.print(buf);
// 応答を待つ
waitForResponse();
}
void setup() {
pc.begin(9600);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leon...
}
pinMode(sw_pin, INPUT);
pc.println("ESP8266IF3tTest");
delay(1000);
atCwMode(STATION_MODE);
atCwJap(ST_SSID, ST_PASSWD);
}
void loop() {
if (pc.available()) {
while((c = pc.read()) != -1)
Serial.write(c);
}
if (Serial.available()) {
pc.println("Got Response");
while((c = Serial.read()) != -1)
pc.write(c);
}
if (digitalRead(sw_pin) == LOW) {
pc.println("SW pressed");
delay(500);
atCipStart(SERVER_ADDR, SERVER_PORT);
atCipSend("/hello.html");
}
}
}}
** クラスにまとめる [#h168da8c]
取りあえず、HTTPサーバにGET要求を送るだけのクラスEspClien...
作成しました。
#pre{{
class EspClient {
public:
EspClient(int rx_pin, int tx_pin);
void begin(int baud);
int atCommand(char *cmd, int wait_time);
int atCwMode(int mode);
int atCwJap(char *ssid, char *passwd);
int atCipStart(char *server_addr, int server_port);
int atCipSend(char *uri);
int atRest();
void atClose();
void println(char *s);
protected:
int waitForResponse();
static const int interval_waits[8];
static const int retry_count;
private:
char buf[256];
int last_char;
SoftwareSerial pc;
};
}}
*** クラスのテスト [#k8757d47]
先ほどのスケッチをEspClientを使った形に修正します。
#pre{{
#include "EspClient.h"
#include <SoftwareSerial.h>
#define ST_SSID "<<SSIDを指定>>"
#define ST_PASSWD "<<パスワードを指定>>"
#define SERVER_ADDR "49.212.164.205"
#define SERVER_PORT 80
int sw_pin = 10;
int sTx_pin = 12;
int sRx_pin = 11;
EspClient esp(sRx_pin, sTx_pin);
void setup() {
pinMode(sw_pin, INPUT);
esp.begin(9600);
esp.println("ESP8266IF3tTest");
esp.atCwMode(STATION_MODE);
esp.atCwJap(ST_SSID, ST_PASSWD);
}
void loop() {
if (digitalRead(sw_pin) == LOW) {
esp.println("SW pressed");
// チャタリング防止
delay(500);
esp.atCipStart(SERVER_ADDR, SERVER_PORT);
esp.atCipSend("/hello.html");
}
}
}}
*** スケッチのダウンロード [#pc104016]
ESPClientTestのスケッチを以下からダウンロードできます。
- ESPClientTestスケッチ &ref(ESPClientTest.zip);
** コメント [#f880ac71]
#vote(おもしろかった[0],そうでもない[0],わかりずらい[0])
皆様のご意見、ご希望をお待ちしております。勉強会で分から...
スパム防止に画像の文字列も入力してください。
#comment_kcaptcha
終了行:
[[Arduino勉強会]]
#contents
2015/10/31からのアクセス回数 &counter;
** Arduinoのスケッチを作る [#f5ee0316]
[[Arduino勉強会/0N-WiFiモジュールその1]]
でESP-WROOM-02を使ってWebサーバにアクセスできるところまで...
今回は、プログラムを書いてESP-WROOM-02を操作してみましょ...
*** 定数の定義 [#h916c7bc]
ATコマンドやSSID、パスワードは#define分で定義しておきます。
#pre{{
#define ST_SSID "<<SSIDを指定>>"
#define ST_PASSWD "<<パスワードを指定>>"
#define SERVER_ADDR "49.212.164.205"
#define SERVER_PORT 80
#define CRLF "\r\n"
#define CRLF2 "\r\n\r\n"
#define STATION_MODE 1
}}
*** コマンドを関数にまとめる [#ae35fc6b]
以下のATコマンドを関数に整理します。
- AT+CWMODE
- AT+CWJAP
- AT+CIPSTART
- AT+CIPSEND
ATコマンドは終わりにCR+LFを追加するためにatCommand関数も...
#pre{{
int atCommand(char *cmd) {
Serial.print(cmd);
Serial.print(CRLF);
return 1;
}
int atCwMode(int mode) {
sprintf(buf, "AT+CWMODE=%d", mode);
return atCommand(buf);
}
int atCwJap(char *ssid, char *passwd) {
sprintf(buf, "AT+CWJAP=\"%s\",\"%s\"", ssid, passwd);
return atCommand(buf);
}
int atCipStart(char *server_addr, int server_port) {
sprintf(buf, "AT+CIPSTART=\"TCP\",\"%s\",%d", server_ad...
return atCommand(buf);
}
int atCipSend(char *uri) {
sprintf(buf, "GET %s HTTP/1.0%s%s", uri, CRLF, CRLF2);
int len = strlen(buf);
Serial.print("AT+CIPSEND=");
Serial.print(len);
Serial.print(CRLF);
delay(1000);
Serial.print(buf);
}
}}
*** 初期化 [#obe6d74b]
ESP-WROOM-02の操作の内、以下の処理は1回だけすればよいので...
にまとめます。
- モード設定:
- ルータに接続:
#pre{{
atCwMode(STATION_MODE);
delay(1000);
atCwJap(ST_SSID, ST_PASSWD);
}}
*** ボタンアクションの追加 [#l7346133]
タクトスイッチのボタンを押したときに、Sageサーバにアクセ...
スケッチを修正します。
#pre{{
if (digitalRead(sw_pin) == LOW) {
pc.println("SW pressed");
delay(500);
atCipStart(SERVER_ADDR, SERVER_PORT);
delay(1000);
atCipSend("/hello.html");
}
}}
** テスト [#g7abef6c]
準備ができたので、スケッチを動かしてみます。
コマンドの実行状況がシリアルモニタに表示されるので、プロ...
#pre{{
ESP8266IF3tTest
AT+CWMODE=1
OK
AT+CWJAP="<<SSIDを指定>>","<<パスワードを指定>>"
WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP
OK
SW pressed
AT+CIPSTART="TCP","49.212.164.205",80
CONNECT
OK
AT+CIPSEGET /hello.html HTTP/1.0
Recv 30 bytes
SEND OK
+IPD,303:HTTP/1.1 200 OK
Date: Tue, 27 Oct 2015 12:29:51 GMT
Server: Apache
Last-Modified: Sat, 24 Oct 2015 23:49:16 GMT
ETag: "c005e-34-522e260431c88"
Accept-Ranges: bytes
Content-Length: 52
Connection: close
Content-Type: text/html; charset=UTF-8
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
CLOSED
}}
** atCommandの変更 [#cc6262c9]
これまでatCommand関数が正しく処理できたかを確認していませ...
ATコマンドでは正しく処理できたときにOK、失敗の時にERRORを...
そこで、最後に返された文字がKかRで正常修了と異常終了の判...
atCommandを以下の様に変更して、再度スケッチを実行してみま...
処理によって、OKがでるまでの時間が異なるため、atCommandに...
待ち時間を入れることにします。
レスポンスの出力に少し文字の取りこぼしがありますが、何と...
を受信できるようになりました。
現段階のスケッチは、以下の通りです。
#pre{{
#include <SoftwareSerial.h>
#define ST_SSID "<<SSIDを指定>>"
#define ST_PASSWD "<<パスワードを指定>>"
#define SERVER_ADDR "49.212.164.205"
#define SERVER_PORT 80
#define CRLF "\r\n"
#define CRLF2 "\r\n\r\n"
#define STATION_MODE 1
#define WAIT_ONECE 2000
#define OK 'K'
#define ERR 'R'
#define FAIL 'L'
char buf[128];
int interval_waits[] = {50, 80, 160, 200, 300, 600, 1200,...
int retry_count = sizeof(interval_waits)/sizeof(int);
int sw_pin = 10;
int sTx_pin = 12;
int sRx_pin = 11;
int c;
SoftwareSerial pc(sRx_pin, sTx_pin);
int last_char = -1;
int waitForResponse() {
last_char = -1;
int err_count = 0;
// 返されたデータをすべて読み込む
for (int i = 0; i < retry_count; i++) {
while (Serial.available()) {
while((c = Serial.read()) != -1) {
if (c != '\r' && c != '\n')
last_char = c;
// デバッグ用
pc.write(c);
}
}
// OK, ERROR, > , FAIL, CLOSED
if (last_char == OK || last_char == ERR || last_char ...
// pc.println("wait");
delay(interval_waits[err_count++]);
}
}
int atCommand(char *cmd, int wait_time) {
int c;
Serial.print(cmd);
Serial.print(CRLF);
delay(wait_time);
// 応答を待つ
waitForResponse();
// 最後に返された文字がKまたはRでなかったら、WAIT_ONECE...
if (last_char != OK && last_char != ERR && last_char !=...
delay(WAIT_ONECE);
pc.println("Do wait onece");
if (Serial.available()) {
while((c = Serial.read()) != -1) {
if (c != '\r' || c != '\n')
last_char = c;
// デバッグ用
pc.write(c);
}
}
}
if (last_char == OK)
return 1;
else if (last_char == ERR)
return 0;
else
return -1;
}
int atCwMode(int mode) {
sprintf(buf, "AT+CWMODE=%d", mode);
return atCommand(buf, 0);
}
int atCwJap(char *ssid, char *passwd) {
sprintf(buf, "AT+CWJAP=\"%s\",\"%s\"", ssid, passwd);
return atCommand(buf, 2000);
}
int atCipStart(char *server_addr, int server_port) {
sprintf(buf, "AT+CIPSTART=\"TCP\",\"%s\",%d", server_ad...
return atCommand(buf, 500);
}
int atCipSend(char *uri) {
sprintf(buf, "GET %s HTTP/1.0%s%s", uri, CRLF, CRLF2);
int len = strlen(buf);
char tmp[32];
sprintf(tmp, "AT+CIPSEND=%d%s", len, CRLF);
// uriを送る
atCommand(tmp, 1000);
Serial.print(buf);
// 応答を待つ
waitForResponse();
}
void setup() {
pc.begin(9600);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leon...
}
pinMode(sw_pin, INPUT);
pc.println("ESP8266IF3tTest");
delay(1000);
atCwMode(STATION_MODE);
atCwJap(ST_SSID, ST_PASSWD);
}
void loop() {
if (pc.available()) {
while((c = pc.read()) != -1)
Serial.write(c);
}
if (Serial.available()) {
pc.println("Got Response");
while((c = Serial.read()) != -1)
pc.write(c);
}
if (digitalRead(sw_pin) == LOW) {
pc.println("SW pressed");
delay(500);
atCipStart(SERVER_ADDR, SERVER_PORT);
atCipSend("/hello.html");
}
}
}}
** クラスにまとめる [#h168da8c]
取りあえず、HTTPサーバにGET要求を送るだけのクラスEspClien...
作成しました。
#pre{{
class EspClient {
public:
EspClient(int rx_pin, int tx_pin);
void begin(int baud);
int atCommand(char *cmd, int wait_time);
int atCwMode(int mode);
int atCwJap(char *ssid, char *passwd);
int atCipStart(char *server_addr, int server_port);
int atCipSend(char *uri);
int atRest();
void atClose();
void println(char *s);
protected:
int waitForResponse();
static const int interval_waits[8];
static const int retry_count;
private:
char buf[256];
int last_char;
SoftwareSerial pc;
};
}}
*** クラスのテスト [#k8757d47]
先ほどのスケッチをEspClientを使った形に修正します。
#pre{{
#include "EspClient.h"
#include <SoftwareSerial.h>
#define ST_SSID "<<SSIDを指定>>"
#define ST_PASSWD "<<パスワードを指定>>"
#define SERVER_ADDR "49.212.164.205"
#define SERVER_PORT 80
int sw_pin = 10;
int sTx_pin = 12;
int sRx_pin = 11;
EspClient esp(sRx_pin, sTx_pin);
void setup() {
pinMode(sw_pin, INPUT);
esp.begin(9600);
esp.println("ESP8266IF3tTest");
esp.atCwMode(STATION_MODE);
esp.atCwJap(ST_SSID, ST_PASSWD);
}
void loop() {
if (digitalRead(sw_pin) == LOW) {
esp.println("SW pressed");
// チャタリング防止
delay(500);
esp.atCipStart(SERVER_ADDR, SERVER_PORT);
esp.atCipSend("/hello.html");
}
}
}}
*** スケッチのダウンロード [#pc104016]
ESPClientTestのスケッチを以下からダウンロードできます。
- ESPClientTestスケッチ &ref(ESPClientTest.zip);
** コメント [#f880ac71]
#vote(おもしろかった[0],そうでもない[0],わかりずらい[0])
皆様のご意見、ご希望をお待ちしております。勉強会で分から...
スパム防止に画像の文字列も入力してください。
#comment_kcaptcha
ページ名:
SmartDoc