esp_wifi_repeaterを使ってみる

mDNS機能


ESP8266ではmDNS.queryService() を使って、同じサービスエンドポイントをもつノードがネットワーク内にいるかどうかを調べることができます。
そこで、esp_wifi_repeaterでも、mDNSの機能が使えるかどうか確認してみました。
esp_wifi_repeaterとは別に、新しく2台のESP8266を用意し、以下のスケッチを2台に書き込みます。
このスケッチでは、「_esp8266_wifi_udp」という名前のサービスエンドポイントを登録し、
同じサービスエンドポイントを持つノード(ステーション)があるかどうかを調べます。

サービスエンドポイントの登録は以下の関数を使います。
addService("service-id", "protocol", port)
サービスエンドポイントは[_service-id_protocol]として公開されます。

時々サンプルに以下の様なコードを見かけます。
addService("_html", "_tcp", 80)
サービスエンドポイントには自動的にアンダースコアーが付くので、この場合[__html__tcp]となります。
/*
  ESP8266 mDNS-SD responder and query sample

  This is an example of announcing and finding services.

  Instructions:
  - Update WiFi SSID and password as necessary.
  - Flash the sketch to two ESP8266 boards
  - The last one powered on should now find the other.
*/

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

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

char myDomainName[16] = {0};
char remoteDomainName[16] = {0};

IPAddress localIp;
IPAddress remoteIp;
unsigned int remotePort;

unsigned long lastQueryService = 0;

WiFiUDP Udp;
unsigned int localPort = 4210;  // local port to listen on

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

  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" connected");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("subnetMask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(WiFi.gatewayIP());
  localIp = WiFi.localIP();
 
  Udp.begin(localPort);
  //Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
  Serial.print("Now listening at IP :");
  Serial.print(localIp);
  Serial.print(" UDP port :");
  Serial.println(localPort);

  sprintf(myDomainName, "ESP_%06X", ESP.getChipId());
  Serial.print("myDomainName: ");
  Serial.println(myDomainName);
  // Set up mDNS responder:
  // - first argument is the domain name, in this example
  //   the fully-qualified domain name is "esp8266.local"
  // - second argument is the IP address to advertise
  //   we send our IP address on the WiFi network
  if (!MDNS.begin(myDomainName)) {
    Serial.println("Error setting up MDNS responder!");
    while(1) {}
  }
 
  Serial.println("mDNS responder started");
  // Announce esp tcp service on port 8080
  MDNS.addService("esp8266_wifi", "udp", localPort);

}

void loop() {
  MDNS.update();
  unsigned long now = millis();
  if (now - lastQueryService > 5000) { // 5秒経過
    lastQueryService = now;
    // Send out query for esp tcp services
    Serial.println("Sending mDNS query");
    int n = MDNS.queryService("esp8266_wifi", "udp");
    Serial.println("mDNS query done");
    if (n == 0) {
      Serial.println("no services found");
    } else {
      Serial.print(n);
      Serial.println(" service(s) found");
      for (int i = 0; i < n; ++i) {
        // Print details for each service found
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(MDNS.hostname(i));
        Serial.print(" (");
        Serial.print(MDNS.IP(i));
        Serial.print(":");
        Serial.print(MDNS.port(i));
        Serial.println(")");
 
        MDNS.hostname(i).toCharArray(remoteDomainName, sizeof(remoteDomainName));
        if (strcmp(remoteDomainName, myDomainName) != 0) {
          remoteIp = MDNS.IP(i);
          remotePort = MDNS.port(i);
          Serial.print("localIp=");
          Serial.print(localIp);
          Serial.print(" localPort=");
          Serial.print(localPort);
          Serial.print(" remoteIp=");
          Serial.print(remoteIp);
          Serial.print(" remotePort=");
          Serial.println(remotePort);
        }
      }
    }
    Serial.println();
  }
}

Arduino-IDEでは2つのシリアルコンソールを同時に開くことができないので、
スケッチを2台に書き込んだら、TeraTermを2つ開いてそれぞれのESP8266にシリアル接続します。
ESP8266-1(192.168.4.3)からはESP8266-2(192.168.4.4)が、
逆にESP8266-2(192.168.4.4)からはESP8266-1(192.168.4.3)が同じネットワーク内に見つかります。

サービスエンドポイントだけで相手のIPアドレスを知ることができます。






こ ちらで公開しているESP8266-UART-to-UART-Wifi-Bridgeを使うと、ESP8266だけで以下の様に
UARTしか持たないマイコン間をWiFiで通信することができます。


このような用途で使う場合、インターネットには接続しないので、外向けのルーターは不要です。
マイコン間の通信のために、インターネットに接続しない、ローカルなWiFiネットーワーク(マイコンネットワーク)を構築したかったのですが、
esp_wifi_repeaterはまさに最適なファームです。

続く...