2015年11月8日 星期日

Step By Step系列---開始玩ESP8266-12 with Arduino IDE(第2篇-幫你的ESP8266加入mDNS服務)

我是用自己DIY的開發板做實驗的



程式範例如下, 如何執行在上一篇有說, 忘記的人可以點這裡去看看
/*
  ESP8266 mDNS範例
  這個HTTP server範例可以讓你用mDNS的方式來找到ESP8266, 本範例你可以輸入http://moon.local來取代用IP連線
 */

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>

const char* ssid = "your SSID";
const char* password = "your SSID PASSWORD";

// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);

void setup(void)
{
  Serial.begin(115200);

  WiFi.begin(ssid, password); //開始連接到你指定的wifi
  Serial.println("");

  while (WiFi.status() != WL_CONNECTED) {   //等待連線
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //印出連線後被分配到的IP Address


  //不加MDNS.begin, 就完全無法使用mDNS服務
  if (!MDNS.begin("moon")) {    //mDNS的主機名稱就是MDNS.begin()內的名稱
    Serial.println("Error setting up MDNS responder!");
    while(1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");  //顯示已啟動mDNS service

  server.begin();  //開始TCP(HTTP) Server服務
  Serial.println("TCP server started");

  MDNS.addService("http", "tcp", 80);  //有執這行指令可以讓手機透過某些機制找到esp8266.local, 不加就找不到, 但pc的瀏覽器還是可以找得到esp8266.local
}

void loop(void)
{
  WiFiClient client = server.available();  //假如有任何連線到server, 就啟動一個client連線
  if (!client) { //沒有連線就跳回loop開頭
    return;
  }
  Serial.println("");
  Serial.println("New client");  //有偵測到任何連線到server的, 就顯示新的client連線

  //假如client已經和server連線, 並且client並沒有丟任何資料到server時, 就一直執行delay(1), 這個delay(1)是防止長時間delay時, 如果條件更改, 會無法即時反應
  while(client.connected() && !client.available()){
    delay(1);
  }

  //讀取從client發來的http request
  String req = client.readStringUntil('\r'); //ESP8266讀取從我的電腦發送的GET / HTTP/1.1(http request)
  Serial.println(req);

  int addr_start = req.indexOf(' '); //找出' '(空格)在req中的位置
  Serial.print("addr_start = ");
  Serial.println(addr_start);
  int addr_end = req.indexOf(' ', addr_start + 1); //找出第二個空格在req中的位置
  Serial.print("addr_end = ");
  Serial.println(addr_end);
  if (addr_start == -1 || addr_end == -1) {     //如果都找不到, 會得到-1
    Serial.print("Invalid request: ");
    Serial.println(req);
    return;
  }
  req = req.substring(addr_start + 1, addr_end); //讀取從addr_start+1(4)到addr_end(5), 如果原字串內容為"GET / HTTP/1.1", 則會讀取到"/"這個字串
  Serial.print("Request: ");
  Serial.println(req);
  client.flush();

  String s;
  if (req == "/") //假如request為root path(根網頁)
  {
    IPAddress ip = WiFi.localIP();
    String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
    //這個字串是server回應給client的http狀態碼"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n" , 200是指client請求成功, 網頁資料將隨這個回應傳回到client
    //http狀態碼請看https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81
    //<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
    //s += ipStr;
    //s += "</html>\r\n\r\n";
    //從<!DOCTYPE HTML>後面這串就是網頁的原始碼內容
    s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
    s += ipStr;
    s += "</html>\r\n\r\n";
    Serial.println("Sending 200");
  }
  else
  {
    s = "HTTP/1.1 404 Not Found\r\n\r\n"; //404代碼是指找不到網頁資料
    Serial.println("Sending 404");
  }
  client.print(s);

  Serial.println("Done with client");
}

這種服務的好處是不管你的IP如何變, 你的mDNS名稱都不會變, 這好像是APPLE發明的, 果然很厲害

29 則留言:

  1. 版主你這幾篇esp8266的文章太有價值了,造福我們這些剛入門的新手
    謝謝你

    回覆刪除
  2. 不客氣, 我也算是剛入門的新手, 只是ESP8266這塊板子太神奇了, 所以想和大家分享, 才寫了一系列的文章, 也能幫自己做個記錄, 你的blog文章也很棒, 我也加了追踪, 目前有個想法需要android程式, 去讀QR code, 當做wifi的log in data, 正好你的文章裡有介紹, 如果卡關了, 可以問你嗎?

    回覆刪除
  3. 作者已經移除這則留言。

    回覆刪除
  4. 如果是android sqlite資料庫有接觸過...互相討論OK

    回覆刪除
    回覆
    1. 請問一下, 如果只是要簡單的andoird控制app, 需要去學那艱深的android sdk程式, 還是可以學像phonegap這種hybird即可呢? 可否給點意見?

      刪除
  5. 網上Arduino IDE+ ESP8266的資料不多,Code帶說明的更少,太有用了。謝謝!

    回覆刪除
  6. 那ESP8266有辦法用mDNS去找到其他裝置嗎?
    現在遇到的困難是android可以找的到ESP8266的板子並連線
    但是ESP8266板子如何用mDNS去找區網中的其他裝置呢

    回覆刪除
    回覆
    1. 依照我的理解, mDNS只是你裝置的綽號, 假設你的名字叫王小明, 你沒有跟你的同學講你的綽號叫小強, 是沒有人知道的, 同樣道理, 要叫mDNS來找device, 那就要被尋找的device也同樣用mDNS到區網去註冊, 註冊成功後, 理論上都應該找得到

      刪除
    2. 我的意思是android有在mDNS上註冊了,我用電腦搜尋區網中的mDNS裝置,都有把ESP8266及android註冊的名稱都列出來,也可以取得ip,但我不知道怎麼在Arduino的程式碼中去搜尋,網路上的資料都是開啟mDNS伺服器,沒看到連線的Orz

      刪除
    3. 你也許可以參考esp8266 arduino ide裡的wifiClient的example程式碼, 它有提到去連另一個device的程式碼, 也許就是你要的

      刪除
  7. 版主你好:
    請問一下如果我用的是Android的手機,要如何像在PC上那樣連接上這個ESP8266裝置呢?

    回覆刪除
    回覆
    1. 直接輸入ESP8266的位址如192.168.1.6 , 但是要android手機和ESP8266在同一個網域中, 不同網域那又是另外的事了, 希望能幫到你

      刪除
  8. 版主你好:
    請問一下如果我用的是Android的手機,要如何像在PC上那樣連接上這個ESP8266裝置呢?

    回覆刪除
    回覆
    1. android手機好像不太能用這個功能, 只能以ip連接

      刪除
  9. 自己DIY的開發板,請問有接線圖嗎 ?

    回覆刪除
    回覆
    1. 如果你只要玩esp8266, 建議你買現成的, 網址如下 http://goods.ruten.com.tw/item/show?21524765074193
      我也用這個, 只是多接了OLED和Micro SD card

      刪除
  10. 請問老師,單純使用8266,只能使用GPIO來控制設備的ON或OFF,如果要連接類比輸入信号,是否有辦法解決,謝謝指導

    回覆刪除
    回覆
    1. esp8266-12e有一根是adc功能, 所以可以讀取類比信號, 把它當arduino ide來用

      刪除
  11. 版主你好,請問一下,我燒錄了該程式,可以用http://IP進入,但是無法用http://moon.local,手機跟電腦都一樣,不知有沒有其他要注意的地方呢?

    回覆刪除
    回覆
    1. 你可否抓一下uart的訊息, 比較好看出是那有問題?

      刪除
    2. 謝謝版主,問題已解決,查了一些資訊,發現要安裝itunes,電腦就連的上了,不過Android的手機依然無法,感謝

      刪除
    3. 恭喜你解決問題了, android手機我試也是不行, 但又有人說可以, 期待好心人出現囉~

      刪除
  12. 作者已經移除這則留言。

    回覆刪除
  13. 您好~~ 想請問版主 esp8266能否透過arduino像是ov7670影像模組上傳照片到雲端或是網站嗎?

    回覆刪除
    回覆
    1. 沒有玩過, 傳輸影像用arduino or ESP8266傳輸速度和畫質還有解析度, 應該都很差, 有關影像的部份可能要用別的solution

      刪除
  14. 寫的很好,不過我用Android手機試也不行,有辦法找出Android的解法方式嗎? 感恩!

    回覆刪除
    回覆
    1. 到FB社群去問看看吧~~~民間有很多高手

      刪除

歡迎大家來討論交流一下~~~