LoginSignup
2
1

More than 3 years have passed since last update.

MDNSを使って、動作中のESP8266機の一覧を表示する

Last updated at Posted at 2019-06-28

半年前にESP8266の小物を増やそうとして、WiFiルータ接続数の限界を迎えました。
その対策は最大256台接続のWiFiルータを導入して問題解決したのですが、
最近新たな問題が発生しました。
ESP8266小物がどんだけ動いているのか把握できねぇ(笑)
小物を何種類かを作り散らかして動作確認中なのですが、ソイツ等が動作中かダウン
してるかの確認をするのが大変になってきました。

そんな訳で今回は、MDNSを使って動作中の機器リストを作ることにしました。
もっともそれだけならArduino ESP8266ExampleにあるMDNS_Web_Serverで済むの
ですが、WebServerを少しマトモにしてiPad/iPhoneでも確認できる様にしました。

ESP8266環境で必要なリソース

 特に無し

機能

 iPad/iPhoneのsafariからESP8266.local/アクセスすることで
 mdnsのサービス http,tcp にエントリしている機器一覧が確認できる。

 エントリには 機器のIP.local/ でリンクを貼ってあります。

使い方

メインソースはこんな風にします。

esp8266.ino

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

const char* ssid = "guest";
const char* password = "guest";

ESP8266WebServer server(80);
// HTMLヘッダ
const char *ESPHTMLHeader ="<html lang=\"ja\">\n<head>\n\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\">\n\
<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n</head>\n";
//=====================================================================================
#define IPTABLES 256                  // 保持する端末数
String MDNShostname[IPTABLES];
IPAddress MDNSIPAddress[IPTABLES];
unsigned long MDNSmillis[IPTABLES];
#define MDNSDeleteMillis (5 * 60 * 1000)      // 端末が無くなったと判断するまでの時間
#define SEEKDELAY (60*1000)
unsigned long OldMillis;
//=====================================================================================
void MDNSseek( String name1, String name2 ){
  int n = MDNS.queryService(name1, name2); // Send out query for esp tcp services
  bool updateList = false;
  if (n != 0) {
    for (int iFound = 0; iFound < n; ++iFound) {
      bool boolFound = false;
      int unuseNumber = -1;
      for( int i=0 ; i<IPTABLES ; i++ ){
        if( MDNShostname[i]=="" ){ unuseNumber = i;  continue; }
        if( MDNS.hostname(iFound)==MDNShostname[i] ){
          boolFound = true;
          MDNSmillis[i] = millis();
        }
        if( millis() < MDNSmillis[i] ){
          MDNSmillis[i] = millis();
        }else{
          unsigned long Lastmillis = millis() - MDNSmillis[i];
          if( Lastmillis >  MDNSDeleteMillis ){
            Serial.print( MDNShostname[i] );  Serial.print( ":" );  Serial.println( Lastmillis );
            MDNShostname[i] = "";
            updateList = true;
          }
        }
      }
      if( boolFound == false && unuseNumber!=-1 ){
        MDNShostname[unuseNumber]  = MDNS.hostname(iFound);
        MDNSIPAddress[unuseNumber] = MDNS.IP(iFound);
        MDNSmillis[unuseNumber]    = millis();
        updateList = true;
      }
    }
  }else{
    for( int i=0 ; i<IPTABLES ; i++ ){
      if( MDNShostname[i]=="" ) continue;
      unsigned long Lastmillis = millis() - MDNSmillis[i];
      if( Lastmillis >  MDNSDeleteMillis ){
        Serial.print( MDNShostname[i] );  Serial.print( ":" );  Serial.println( Lastmillis );
        MDNShostname[i] = "";
        updateList = true;
      }
    }
  }
  if( updateList == true ){
    int iCount = 1;
    Serial.print("List update!! [");
    Serial.print( name1 );  Serial.print( ":" );  Serial.print( name2 );  Serial.println( "]" );
    for( int i=0 ; i<IPTABLES ; i++ ){
      if( MDNShostname[i]=="" ) continue;
      Serial.print(iCount); Serial.print(" : ");  Serial.print( MDNShostname[i] );
      Serial.print(" (");   Serial.print(MDNSIPAddress[i]); Serial.println(")");
      iCount++;
    }
    if( iCount==1 )          Serial.println( "none" );
  }
}
//=====================================================================================
void indexHtml() {
  Serial.println( "execute : index.html" );
  int count = 0;
  String output = ESPHTMLHeader;
  output += "MDNS PC list</br>\n";
  for( int i=0 ; i<IPTABLES ; i++ ) {
        if( MDNShostname[i]=="" ) continue;
        output += "<a href=\"http://";
        output += String(MDNSIPAddress[i][0]);  output += ".";
        output += String(MDNSIPAddress[i][1]);  output += ".";
        output += String(MDNSIPAddress[i][2]);  output += ".";
        output += String(MDNSIPAddress[i][3]);  output += "/\">";
        output += (count+1);
        output += ". ";
        output += MDNShostname[i];
        output += ".local/</a></br>\n";
        count ++;
  }
  output += "\n</form>\n</html>\n";
  server.send(200, "text/html", output);
}
//=====================================================================================
void setup(void)
{  
  Serial.begin(115200);

  // Connect to WiFi network
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");  

  // Wait for connection
  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());

  if (!MDNS.begin("esp8266")) {
    Serial.println("Error setting up MDNS responder!");
    while(1) { 
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");

  // Start TCP (HTTP) server
  server.begin();
  Serial.println("TCP server started");

  // Add service to MDNS-SD
  MDNS.addService("http", "tcp", 80);

  //
  server.on("/index.html", indexHtml  );
  server.on("/",           indexHtml  );
  OldMillis = millis();
}
//=====================================================================================
void loop(void)
{
  server.handleClient( );
  MDNS.update();
  // 起動直後は頻繁に行うが、通常時は少し時間を空けて確認する様に変更予定
  if( (OldMillis+SEEKDELAY)>millis() )
    if( millis()>SEEKDELAY )
      if( OldMillis<millis() )  return;
  OldMillis = millis();
  MDNSseek( "http", "tcp" );
  Serial.print("*");
}

機器サンプルはArduinoIDEにあるMDNSサンプルのMDNS_web_server.inoになります。
実際は以下のコードぐらいで済みます。

unit.ino
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>

void setup(void)
{  
  // wifi接続部
   ~~ 省略 ~~
  // MDNS宣言部
  MDNS.begin("~~機器名~~");
  // MDNS-SDサービス
  MDNS.addService("http", "tcp", 80);
}

void loop(void)
{
  MDNS.update();
}
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1