測試 1 :
#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(7,8); //(RX,TX)
const String ssid="EDIMAX-tony";
const String pwd="1234567890";
const int MAX_PAGE_NAME_LEN=8; //buffer size
char buffer[MAX_PAGE_NAME_LEN + 1]; //store page_name
void setup() {
Serial.begin(9600);
esp8266.begin(9600);
sendData(F("AT+RST\r\n"),2000,DEBUG); // reset ESP8266
sendData(F("AT+CWMODE=1\r\n"),1000,DEBUG); //configure as station
sendData(F("AT+CIPMUX=1\r\n"),1000,DEBUG); //enable multiple connections
sendData(F("AT+CIPSERVER=1,80\r\n"),2000,DEBUG); //turn on server 80 port
while (!connectWifi(ssid, pwd)) {
Serial.println(F("Connecting WiFi ... failed"));
delay(2000);
}
sendData(F("AT+GMR\r\n"),1000,DEBUG);
delay(3000); //wait for wifi connection to get local ip
sendData(F("AT+CIFSR\r\n"),1000,DEBUG); //get ip address
}
void loop() {
if (esp8266.available()) { // check if esp8266 is sending message
if (esp8266.find("+IPD,")) {
delay(1000); //waiting for response: 0,234:GET /?pinD2=1
int connectionId=esp8266.read()-48; //turn ASCII to number
bool on=false;
if (esp8266.find("GET /?pin")) { //retrieve page name (router)
char type=(char)esp8266.read(); //read char after ?pin
int pin=esp8266.parseInt(); //get first int number from serial
int val=esp8266.parseInt(); //get first int number from serial
if (val==1) {on=true;}
if (type=='D') { //update output status
Serial.print(F("Digital pin "));
Serial.print(pin);
Serial.print(F(" is changed to "));
Serial.println(val);
pinMode(pin, OUTPUT); //set pin as ouput
digitalWrite(pin, val);
}
}
String webpage=F("<html><body>");
webpage += F("<h3>Click update button to turn D2 pin ON or OFF</h3>");
webpage += F("<form action='/' method='GET'>");
webpage += F("<input type='radio' name='pinD2' value='1'");
if (digitalRead(2)) {webpage += F(" checked>");}
else {webpage += F(">");}
webpage += F("ON");
webpage += F("<input type='radio' name='pinD2' value='0'");
if (digitalRead(2)) {webpage += F(">");}
else {webpage += F(" checked>");}
webpage += F("OFF");
webpage += F(" State : ");
if (digitalRead(2) == HIGH) {webpage += F(" ON");}
else if (digitalRead(2) == LOW) {webpage += F(" OFF");}
webpage += F(" <input type='submit' value='Update'>");
webpage += F("</form>");
webpage += F("</body></html>");
String cipSend=F("AT+CIPSEND=");
cipSend += connectionId;
cipSend += ",";
cipSend += webpage.length();
cipSend += F("\r\n");
sendData(cipSend,1000,DEBUG);
sendData(webpage,1000,DEBUG);
delay(1);
sendData("AT+CIPCLOSE=" + (String)connectionId + "\r\n",1000,DEBUG);
}
}
}
boolean connectWifi(String ssid, String pwd) {
String res=sendData("AT+CWJAP=\"" + ssid + F("\",\"") + pwd + F("\"\r\n"),8000,DEBUG);
res.replace("\r\n",""); //remove all line terminator
if (res.indexOf("OK") != -1) {return true;}
else {return false;}
}
String sendData(String command, const int timeout, boolean debug) {
String res=F("");
esp8266.print(command);
long int time=millis();
while ((time + timeout) > millis()) {
while(esp8266.available()) {res.concat((char)esp8266.read());}
}
if (debug) {Serial.print(res);}
return res;
}
這裡利用圓鈕元素 Radio 來選擇所要的狀態, 並透過讀取 D2 腳的目前狀態, 將 checked 這個屬性放到 ON 或 OFF 兩個圓鈕其中一個, 其實這就不需要 State 這個文字標示了. 但因為 Radio 可以選來選去, 在還沒按下 Update 之前就會搞不清楚現在到底是哪個狀態, 所以我還是保留 State 標示. 注意, 這兩個圓鈕必須取相同名稱, name 屬性值必須相同才會有二選一的效果, 這裡必須取名為 pinD2, 因為 Radio 的名稱就是要傳遞的參數名稱.
瀏覽器連線結果如下 :
而經過排版的網頁原始碼如下 :
上面程式裡我把 timeout 計時器都設為 1 秒, 反應速度變快了, 但運作仍正常.
如果把 D2 改成 D13, 就可以利用 Nano 板子上的 LED 來看到開啟與關閉的效果了, 程式如下 :
測試 2 :
#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(7,8); //(RX,TX)
const String ssid="EDIMAX-tony";
const String pwd="6628005572056";
const int MAX_PAGE_NAME_LEN=8; //buffer size
char buffer[MAX_PAGE_NAME_LEN + 1]; //store page_name
void setup() {
Serial.begin(9600);
esp8266.begin(9600);
sendData(F("AT+RST\r\n"),2000,DEBUG); // reset ESP8266
sendData(F("AT+CWMODE=1\r\n"),1000,DEBUG); //configure as station
sendData(F("AT+CIPMUX=1\r\n"),1000,DEBUG); //enable multiple connections
sendData(F("AT+CIPSERVER=1,80\r\n"),2000,DEBUG); //turn on server 80 port
while (!connectWifi(ssid, pwd)) {
Serial.println(F("Connecting WiFi ... failed"));
delay(2000);
}
sendData(F("AT+GMR\r\n"),1000,DEBUG);
delay(3000); //wait for wifi connection to get local ip
sendData(F("AT+CIFSR\r\n"),1000,DEBUG); //get ip address
}
void loop() {
if (esp8266.available()) { // check if esp8266 is sending message
if (esp8266.find("+IPD,")) {
delay(1000); //waiting for response: 0,234:GET /?pinD2=1
int connectionId=esp8266.read()-48; //turn ASCII to number
bool on=false;
if (esp8266.find("GET /?pin")) { //retrieve page name (router)
char type=(char)esp8266.read(); //read char after ?pin
int pin=esp8266.parseInt(); //get first int number from serial
int val=esp8266.parseInt(); //get first int number from serial
if (val==1) {on=true;}
if (type=='D') { //update output status
Serial.print(F("Digital pin "));
Serial.print(pin);
Serial.print(F(" is changed to "));
Serial.println(val);
pinMode(pin, OUTPUT); //set pin as ouput
digitalWrite(pin, val);
}
}
String webpage=F("<html><body>");
webpage += F("<h3>Click update button to turn D13 pin ON or OFF</h3>");
webpage += F("<form action='/' method='GET'>");
webpage += F("<input type='radio' name='pinD13' value='1'");
if (digitalRead(13)) {webpage += F(" checked>");}
else {webpage += F(">");}
webpage += F("ON");
webpage += F("<input type='radio' name='pinD13' value='0'");
if (digitalRead(13)) {webpage += F(">");}
else {webpage += F(" checked>");}
webpage += F("OFF");
webpage += F(" State : ");
if (digitalRead(13) == HIGH) {webpage += F(" ON");}
else if (digitalRead(13) == LOW) {webpage += F(" OFF");}
webpage += F(" <input type='submit' value='Update'>");
webpage += F("</form>");
webpage += F("</body></html>");
String cipSend=F("AT+CIPSEND=");
cipSend += connectionId;
cipSend += ",";
cipSend += webpage.length();
cipSend += F("\r\n");
sendData(cipSend,1000,DEBUG);
sendData(webpage,1000,DEBUG);
delay(1);
sendData("AT+CIPCLOSE=" + (String)connectionId + "\r\n",1000,DEBUG);
}
}
}
boolean connectWifi(String ssid, String pwd) {
String res=sendData("AT+CWJAP=\"" + ssid + F("\",\"") + pwd + F("\"\r\n"),8000,DEBUG);
res.replace("\r\n",""); //remove all line terminator
if (res.indexOf("OK") != -1) {return true;}
else {return false;}
}
String sendData(String command, const int timeout, boolean debug) {
String res=F("");
esp8266.print(command);
long int time=millis();
while ((time + timeout) > millis()) {
while(esp8266.available()) {res.concat((char)esp8266.read());}
}
if (debug) {Serial.print(res);}
return res;
}
修改的部分只有黃色高亮度部分, 實際測試結果如下 :
上面兩個小 LED 是 RX, TX, 第三個是 PWR 電源燈, 第四個小 LED 便是 NANO 連接 D13 腳的內建 LED, 利用區網連線 ESP8266 的伺服器, 就可以透過 Arduino 輸出的網頁來控制 LED 的明滅. 也可以用手機連線同一無線基地台來進行遠端控制, 當然這個遠端只是無線基地台信號涵蓋內的範圍, 還不是 Global.
參考 :
# Monitor your home remotely using the Arduino WiFi Shield
# LED’s Control Through ESP8266 + Arduino Web Page
# Control a Lamp Remotely Using the ESP8266 WiFi Chip
# How to Control Your ESP8266 From Anywhere in the World
# ESP8266 Thing Development Board Hookup Guide
# An easy way to control your Arduino from Internet
沒有留言:
張貼留言