ESP8266のSTAモードでUDP通信

昨日はAPモードでのUDP通信を実験した。
しかし、APモードだとネットに接続できなくなるのが不便である。そこでSTAモードも試してみる。ただしSTAモードの場合、IPアドレスWiFiルータからDHCPで割り振られることが一般的なので、IPアドレスではアクセスしにくい。そこでmDNSを利用する。mDNSはローカルネット内でDNS情報をマルチキャストする仕組みで、ホスト名.local でアクセスできる。

#include <ESP8266WiFi.h> // WiFi
#include <ESP8266mDNS.h> // mDNS
#include <WiFiUDP.h>     // UDP

// SSIDとパスワード (環境に合わせる)
const char *ssid = "hoge";
const char *password = "piyo";

// ホスト名
char hostName[16];
  
// UDPオブジェクト
static WiFiUDP udp;

// mDNSオブジェクト
MDNSResponder mdns;

// ポート番号
#define LOCAL_PORT  0xC000  // 自分のポート番号
#define REMOTE_PORT 0xC001  // 相手のポート番号

// IPアドレス
IPAddress localIP;  // 自分のIPアドレス
IPAddress remoteIP; // 相手のIPアドレス

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

  // ホスト名(固有名になるように)
  sprintf(hostName, "esp8266-%06x", ESP.getChipId());
  Serial.print("HostName: ");  Serial.println(hostName);

  // STAの設定
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
}

void loop() {
  static bool isConnected = false;
  char packetBuffer[256];
  
  // APへの接続待ち
  if (WiFi.status() != WL_CONNECTED) {
    if(isConnected){
      isConnected = false;
      // UDPの停止
      udp.stop();
    }
    delay(500);
    Serial.print(".");
    return;
  }
  if(!isConnected){
    isConnected = true;
    
    // IPアドレスの取得
    localIP = WiFi.localIP();
    Serial.println();
    Serial.print("Connected to "); Serial.println(ssid);
    Serial.print("STA IP address: "); Serial.println(localIP);
    
    // UDPの開始
    udp.begin(LOCAL_PORT);
    if ( mdns.begin ( hostName, localIP ) ) {
      Serial.println ( "MDNS responder started" );
    }else{
      Serial.println("Error setting up MDNS responder!");
    }
  }
  mdns.update();
  
  // パケット受信があればデータ取得
  int packetSize = udp.parsePacket();
  if (packetSize) {
    int len = udp.read(packetBuffer, packetSize);
    if (len > 0) packetBuffer[len] = '\0';
    
    // 相手のIPアドレス取得
    remoteIP = udp.remoteIP();
    
    Serial.print(remoteIP);
    Serial.print(" / ");
    Serial.println(packetBuffer);
    
    // パケット送信
    udp.beginPacket(remoteIP, REMOTE_PORT);
    udp.write(packetBuffer);
    udp.endPacket();
  }
}