這次我不使用手機來設定 ssid 與密碼, 改用筆電, 因為這次我要讓 ESP8266 連線到手機的無線基地台, 而 Android 手機不讓我們同時打開 wifi 與熱點分享, 據華為客服解釋, 這是因為同時打開這兩個功能會加劇手機耗電, 所以打開 wifi 時, 熱點分享就會被自動關閉, 反之亦然. 所以既然我要讓 ESP8266 透過手機熱點分享連上互聯網, 那我就沒辦法同時打開其 wifi 連線到 ESP8266 的 SoftAP (192.168.4.1) 去做連線設定, 所以就改用筆電連線 ESP8266 的 SoftAP 來設定.
前文參考 :
# AllAboutEE 的 ESP8266 伺服器測試 (二)
程式修改如下 :
#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(10,11); //(RX,TX)
const int MAX_PAGE_NAME_LEN=48;
char buffer[MAX_PAGE_NAME_LEN + 1];
void setup() {
Serial.begin(9600);
esp8266.begin(9600);
sendData("AT+RST\r\n",2000,DEBUG); // reset module
sendData("AT+CWMODE=2\r\n",1000,DEBUG); // configure as access point
sendData("AT+CIFSR\r\n",1000,DEBUG); // get ip address
sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
}
void loop() {
if (esp8266.available()) { // check if the esp is sending a message
if (esp8266.find("+IPD,")) {
delay(1000);
//esp8266 link response : +IPD,0,498:GET / HTTP/1.1
//retrieve connection ID from response (0~4, after "+IPD,")
int connectionId=esp8266.read()-48; //from ASCII to number
//subtract 48 because read() returns ASCII decimal value
//and in ASCII, "0" (the first decimal number) starts at 48
if (esp8266.find("GET /")) { //retrieve page router from remaining response
memset(buffer, 0, sizeof(buffer)); //clear buffer (all set to 0)
if (esp8266.readBytesUntil('/', buffer, sizeof(buffer))) {
if (strcmp(buffer, "update") == 0) { //update wifi
//"?ssid=aaa&pwd=bbb HTTP/1.1"
esp8266.find("?ssid="); //skip ssid token
memset(buffer, 0, sizeof(buffer)); //clear buffer (all set to 0)
esp8266.readBytesUntil('&', buffer, sizeof(buffer)); //retrieve ssid
String ssid=buffer;
esp8266.find("pwd="); //skip pwd token
memset(buffer, 0, sizeof(buffer)); //clear buffer (all set to 0)
esp8266.readBytesUntil(' ', buffer, sizeof(buffer)); //retrieve pwd
String pwd=buffer;
//set joint AP
sendData("AT+CWMODE=3\r\n",2000,DEBUG);
sendData("AT+CWJAP=\"" + ssid + "\",\"" + pwd + "\"\r\n",6000,DEBUG);
sendData("AT+CIFSR\r\n",1000,DEBUG);
//show result
String webpage="<html>Wifi setup OK!</html>";
String cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
String closeCommand = "AT+CIPCLOSE=";
closeCommand+=connectionId; // append connection id
closeCommand+="\r\n";
sendData(closeCommand,3000,DEBUG);
}
else { //show setup page
String webpage="<html><form method=get action='/update/'>SSID <input name=ssid type=text><br>";
String cipSend = "AT+CIPSEND=";
cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
webpage="PWD <input name=pwd type=text> ";
cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
webpage="<input type=submit value=Connect></form></html>";
cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
String closeCommand = "AT+CIPCLOSE=";
closeCommand+=connectionId; // append connection id
closeCommand+="\r\n";
sendData(closeCommand,3000,DEBUG);
}
}
}
}
}
}
String sendData(String command, const int timeout, boolean debug) {
String response="";
esp8266.print(command); // send the read character to the esp8266
long int time=millis();
while ((time+timeout) > millis()) {
while(esp8266.available()) {
// The esp has data so display its output to the serial window
char c=esp8266.read(); // read the next character.
response += c;
}
}
if (debug) {Serial.print(response);}
return response;
}
將我的手機 4G 上網與可攜式 Wifi 基地台分享打開 (SSID 為 H30-L02-webbot), 然後用筆電的 wifi 連線 ESP8266 模式 2 下建立的 SoftAP, 打開筆電瀏覽器連線 192.168.4.1, 顯示 wifi 設定頁面, 輸入 SSID 與密碼後, 按 Connect 順利完成設定.
序列埠監控視窗輸出訊息如下 :
AT+RST
OK
bB�鑭b禔S��"軬B�侒��餾�
[System Ready, Vendor:www.ai-thinker.com]
AT+CWMODE=2
no change
AT+CIFSR
192.168.4.1
OK
AT+CIPMUX=1
OK
AT+CIPSERVER=1,80
OK
1.1
Host: 192.168.4.1
User-Agent: Mozilla/5.AT+CIPSEND=0,77
> <html><form method=get action='/update/'>SSID <input name=ssid
SEND OK
AT+CIPSEND=0,31
> PWD <input name=pwd type=text>
SEND OK
AT+CIPSEND=0,47
> <input type=submit value=Connect></form></html>
SEND OK
AT+CIPCLOSE=0
OK
Unlink
HTTP/1.1
HAT+CWMODE=3
OK
AT+CWJAP="H30-L02-webbot","1234567890"
OK
AT+CIFSR
192.168.4.1
192.168.43.40
OK
AT+CIPSEND=0,27
> <html>Wifi setup OK!</html>
SEND OK
AT+CIPCLOSE=0
OK
Unlink
其實應該是執行 AT+CWJAP 前改成模式 1 較合理, 但此處為了用 AT+CIFSR 確認是否有順利連上無線基地台才用模式 3, 可見確實從無線 AP 的 DHCP 獲得 192.168.43.40 這個 IP. 這時若改用此 IP 連線, 也會連線到 ESP8266 伺服器, 像 192.168.4.1 一樣顯示設定網頁 :
同時檢查手機的網路連線, 發現經過上面的連線設定後, ESP8266 確實連線到手機分享的無線基地台, 其 IP 為 192.168.43.40 :
所以我可能需要修正一下我對 Webduino 操作模式的猜測, 在其主機板上有一個單切雙擲開關, 當要設定 wifi 連線時, 關關要切到設定側, 這時 ESP8266 應該是在模式 2, 用手機連線到 192.168.4.1 做完 wifi 設定成功後拔掉電源, 把關關切到工作側, 再送電就會連線到指定的 AP 了, 這時 ESP8266 應該在模式 1.
2016-06-02 補充 :
注意, 以上只是一個測試專案的中間過程記錄, 不是最終結果.
今天把程式做最後修改測試, 我推翻上面的猜測, 仍維持最早的假定, 即在做 wifi 設定時 ESP8266 是在模式 3, 而在工作模式是設在模式 1. 參見此系列測試的完結篇 :
# AllAboutEE 的 ESP8266 伺服器測試 (四) : 完結篇
沒有留言 :
張貼留言