1. AT Server

本實作將Arduino 透過 UART 與 ESP8266 連線建立伺服器(ESP8266當網路卡)

顯示 A0 ~ A5腳位數值

連線位址  http://tomorrows.local/       (域名:tomorrows 可換)

優點:透過Arduino可使用更多函式庫

缺點:體積無法太小,配線較複雜

請先至  ESP8266 相關  更新 ESP8266 韌體  否則連線很不穩定

再來 設定 ESP8266 BAUD 為 57600 (若序列埠出現亂碼再往下調慢為38400)

設定AT指令為:

AT+UART_DEF=57600,8,1,0,0

未加入mDNS 的版本(穩定)

#include <SoftwareSerial.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);   // 若LCD 無法啟用,請將0X3F 改為0X27

SoftwareSerial ESP(3, 2);  // 接收腳, 傳送腳(Arduino)

#define SSID " "    //這裡填入你家AP的SSID

#define PASSWORD " "   //這裡填入你家AP的密碼

String response = "";

String cmd1 = "";

String cmd = "";

void sendATcmd(String cmd, unsigned int time){

    response = "";  // 接收ESP回應值的變數  

    ESP.print(cmd); // 送出AT命令到ESP模組

    unsigned long timeout = time + millis();

    

    while (ESP.available() || millis() < timeout) {

      while(ESP.available()) {

        char c = ESP.read(); // 接收ESP傳入的字元

        response += c;

      }

    }

    Serial.print(response);  // 顯示ESP的回應

}

void gotIP(){

  sendATcmd("AT+CIFSR\r\n",1000);

  lcd.setCursor(0,0);

  for(int i=24 ; i<40 ; i++){

  lcd.print(response[i]);

  delay(20);

  }

}

void setup() {

  Serial.begin(9600);

  pinMode(13,OUTPUT);

  ESP.begin(57600);

  lcd.init();                     

  lcd.backlight(); 

  lcd.clear();

  cmd="AT+CWJAP=\"";

  cmd+=SSID;

  cmd+="\",\"";

  cmd+=PASSWORD;

  cmd+="\"";

  cmd+="\r\n"; 

  sendATcmd("AT+RST\r\n", 2000); // 重置ESP模組,等待2秒

  sendATcmd("AT+CWMODE=1\r\n",1000); // 設成AP模式,等待1秒

  sendATcmd(cmd,10000); // 取得連線(視AP連線效能作調整,預設7000毫秒)

  sendATcmd("AT+CIFSR\r\n",1000); // 取得IP位址,等待1秒

  sendATcmd("AT+CIPMUX=1\r\n",1000); // 允許多重連線,等待1秒

  sendATcmd("AT+CIPSERVER=1,80\r\n",1000); // 在80埠啟動伺服器,等待1秒

  gotIP();

   digitalWrite(13,1);

}

void loop() { 

  if (ESP.available()) {

    if (ESP.find("+IPD,")) {  // 若接收到"+IPD,",代表有用戶連線了…

        float x0 = analogRead(A0);  // 讀取A0類比值

        float x1 = analogRead(A1);  // 讀取A0類比值

        float x2 = analogRead(A2);  // 讀取A0類比值

        float x3 = analogRead(A3);  // 讀取A0類比值

        float x4 = analogRead(A4);  // 讀取A0類比值

        float x5 = analogRead(A5);  // 讀取A0類比值

        delay(100);

 

        byte connID = ESP.read()-48;  // 讀取連線編號(1~5)並轉成數字[建議這裡先說明最多 5 個連線]

        

        // 建立HTML內容

String HTML= "HTTP/1.1 200 OK\r\n";

        HTML+="Content-Type: text/html\r\n\r\n" ;

        HTML+= "<!doctype html>\r\n<html>\r\n<head><meta charset=\"utf-8\">";

   //     HTML+= "<link rel=\"shortcut icon\"href=\"http://www1.csjh.ntpc.edu.tw/s2/images/mark.gif\">";

   //     HTML+="<meta http-equiv=\"refresh\"content=\"15\">";

        HTML+="<title>ESP8266</title></head>";

        HTML+="<body><h1>Arduino</h1><p>A0:";

        HTML+= x0;  // 顯示A0類比腳位值

        HTML+="</p><p>A1:";

        HTML+= x1;  // 顯示A1類比腳位值

        HTML+="</p><p>A2:";

        HTML+= x2;  // 顯示A2類比腳位值

        HTML+="</p><p>A3:";

        HTML+= x3;  // 顯示A3類比腳位值

        HTML+="</p><p>A4:";

        HTML+= x4;  // 顯示A4類比腳位值

        HTML+="</p><p>A5:";

        HTML+= x5;  // 顯示A5類比腳位值

        HTML+="</p></body></html>";

    

        // 建立AT+CIPSEND命令字串

        String cipSend = "AT+CIPSEND=";

        cipSend += connID;    // 附加連線編號

        cipSend += ",";

        cipSend +=HTML.length();  // 取得HTML內容的長度

        cipSend +="\r\n";

     

        sendATcmd(cipSend,1000);  // 送出HTML內容

        sendATcmd(HTML, 1000);

     

        // 建立AT+CIPCLOSE命令字串

        String cipClose = "AT+CIPCLOSE=";

        cipClose+=connID;   // 附加連線編號

        cipClose+="\r\n"; 

        sendATcmd(cipClose,1000);  // 送出「中斷連線」命令

    }

  } 

}

已加入mDNS 的版本(mDNS 經常失效)

#include <SoftwareSerial.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);   // 若LCD 無法啟用,請將0X3F 改為0X27

SoftwareSerial ESP(3, 2);  // 接收腳, 傳送腳(Arduino)

#define SSID " "    //這裡填入你家AP的SSID

#define mDNS "tomorrows"    //要連線的位址  ex.   http://tomorrows.local/ 

#define PASSWORD " "   //這裡填入你家AP的密碼

String response = "";

String cmd1 = "";

String cmd = "";

int j = 0 ;

void sendATcmd(String cmd, unsigned int time){

    response = "";  // 接收ESP回應值的變數  

    ESP.print(cmd); // 送出AT命令到ESP模組

    unsigned long timeout = time + millis();

    

    while (ESP.available() || millis() < timeout) {

      while(ESP.available()) {

        char c = ESP.read(); // 接收ESP傳入的字元

        response += c;

      }

    }

    Serial.print(response);  // 顯示ESP的回應

}

void gotIP(){

  sendATcmd("AT+CIFSR\r\n",1000);

  lcd.setCursor(0,0);

  for(int i=24 ; i<40 ; i++){

  lcd.print(response[i]);

  delay(20);

  }

}

void reboot(){

    digitalWrite(13,0);

  sendATcmd("AT+RST\r\n", 2000); // 重置ESP模組,等待2秒

  sendATcmd(cmd,10000); // 取得連線(視AP連線效能作調整,預設7000毫秒)

  sendATcmd("AT+CIFSR\r\n",1000); // 取得IP位址,等待1秒

  sendATcmd("AT+CIPMUX=1\r\n",1000); // 允許多重連線,等待1秒

  sendATcmd("AT+CIPSERVER=1,80\r\n",1000); // 在80埠啟動伺服器,等待1秒

  sendATcmd(cmd1,1000); // 開啟mDNS

  digitalWrite(13,1);

}

void setup() {

  Serial.begin(9600);

  pinMode(13,OUTPUT);

  ESP.begin(57600);

  lcd.init();                     

  lcd.backlight(); 

  lcd.clear();

  cmd="AT+CWJAP=\"";

  cmd+=SSID;

  cmd+="\",\"";

  cmd+=PASSWORD;

  cmd+="\"";

  cmd+="\r\n"; 

  cmd1="AT+MDNS=1,\"";

  cmd1+=mDNS;

  cmd1+="\",\"iot\",80";

  cmd1+="\r\n";

 

  sendATcmd("AT+RST\r\n", 2000); // 重置ESP模組,等待2秒

  sendATcmd("AT+CWMODE=1\r\n",1000); // 設成AP模式,等待1秒

  sendATcmd(cmd,10000); // 取得連線(視AP連線效能作調整,預設7000毫秒)

  sendATcmd("AT+CIFSR\r\n",1000); // 取得IP位址,等待1秒

  sendATcmd("AT+CIPMUX=1\r\n",1000); // 允許多重連線,等待1秒

  sendATcmd("AT+CIPSERVER=1,80\r\n",1000); // 在80埠啟動伺服器,等待1秒

  sendATcmd(cmd1,1000); // 開啟mDNS

  gotIP();

   digitalWrite(13,1);

}

void loop() { 

  if (ESP.available()) {

    if (ESP.find("+IPD,")) {  // 若接收到"+IPD,",代表有用戶連線了…

        float x0 = analogRead(A0);  // 讀取A0類比值

        float x1 = analogRead(A1);  // 讀取A0類比值

        float x2 = analogRead(A2);  // 讀取A0類比值

        float x3 = analogRead(A3);  // 讀取A0類比值

        float x4 = analogRead(A4);  // 讀取A0類比值

        float x5 = analogRead(A5);  // 讀取A0類比值

        delay(100);

 

        byte connID = ESP.read()-48;  // 讀取連線編號(1~5)並轉成數字[建議這裡先說明最多 5 個連線]

        

        // 建立HTML內容

String HTML= "HTTP/1.1 200 OK\r\n";

        HTML+="Content-Type: text/html\r\n\r\n" ;

        HTML+= "<!doctype html>\r\n<html>\r\n<head><meta charset=\"utf-8\">";

   //     HTML+= "<link rel=\"shortcut icon\"href=\"http://www1.csjh.ntpc.edu.tw/s2/images/mark.gif\">";

   //     HTML+="<meta http-equiv=\"refresh\"content=\"15\">";

        HTML+="<title>ESP8266</title></head>";

        HTML+="<body><h1>Arduino</h1><p>A0:";

        HTML+= x0;  // 顯示A0類比腳位值

        HTML+="</p><p>A1:";

        HTML+= x1;  // 顯示A1類比腳位值

        HTML+="</p><p>A2:";

        HTML+= x2;  // 顯示A2類比腳位值

        HTML+="</p><p>A3:";

        HTML+= x3;  // 顯示A3類比腳位值

        HTML+="</p><p>A4:";

        HTML+= x4;  // 顯示A4類比腳位值

        HTML+="</p><p>A5:";

        HTML+= x5;  // 顯示A5類比腳位值

        HTML+="</p></body></html>";

    

        // 建立AT+CIPSEND命令字串

        String cipSend = "AT+CIPSEND=";

        cipSend += connID;    // 附加連線編號

        cipSend += ",";

        cipSend +=HTML.length();  // 取得HTML內容的長度

        cipSend +="\r\n";

     

        sendATcmd(cipSend,1000);  // 送出HTML內容

        sendATcmd(HTML, 1000);

     

        // 建立AT+CIPCLOSE命令字串

        String cipClose = "AT+CIPCLOSE=";

        cipClose+=connID;   // 附加連線編號

        cipClose+="\r\n"; 

        sendATcmd(cipClose,1000);  // 送出「中斷連線」命令

    }

  }

  if(millis()/1000%120==0){       //每300秒重啟一次ESP8266

      reboot();

  }

      lcd.setCursor(0,1);

      lcd.print(120-millis()/1000%120);

      lcd.print("   ");

  

}