ESP8266のAPモードでUDP通信

ESP8266のWiFi機能はAPモード(親機)とSTAモード(子機)、およびAP+STAモードがある。
まずは、APモードでPCとUDP通信してみた。

ESP8266側のスケッチ

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

// SSIDとパスワード
const char *ssid = "esp8266";
const char *password = "12345678"; // 8文字以上

// UDPオブジェクト
static WiFiUDP udp;

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

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

void setup() {
  Serial.begin(115200);
  delay(100);
  
  // APの設定
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, password);
  localIP = WiFi.softAPIP();
  Serial.println();
  Serial.print("AP IP address: ");Serial.println(localIP);
  
  // UDPの開始
  udp.begin(LOCAL_PORT);
}

void loop() {
  char packetBuffer[256];
  
  // パケット受信があればデータ取得
  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();
  }
}

PC側のC#アプリ (抜粋)

public partial class Form1 : Form
{
    const int REMOTE_PORT = 0xC000;  // 自分のポート番号
    const int LOCAL_PORT  = 0xC001;  // 相手のポート番号

    // ソケットオブジェクト
    private System.Net.Sockets.UdpClient udp;
    private bool isConnected = false;

    public Form1()
    {
        InitializeComponent();
        timer.Interval = 100;
    }

    // 接続/切断
    private void buttonConnect_Click(object sender, EventArgs e)
    {
        // 接続
        if (!isConnected)
        {
            // 指定されたIPアドレスに接続
            udp = new System.Net.Sockets.UdpClient(0xC001);
            udp.Connect(textIPAddress.Text, REMOTE_PORT);

            timer.Start();
            buttonConnect.Text = "Disconnect";
            isConnected = true;
        }
        // 切断
        else
        {
            udp.Close();

            timer.Stop();
            buttonConnect.Text = "Connect";
            isConnected = false;
        }
    }

    // 送信
    private void buttonSend_Click(object sender, EventArgs e)
    {
        if (isConnected)
        {
            Byte[] data = System.Text.Encoding.ASCII.GetBytes(textCommand.Text);
            udp.Send(data, data.Length);
        }
    }

    // タイマハンドラで受信
    private void timer_Tick(object sender, EventArgs e)
    {
        if (udp.Available > 0)
        {
            // 受信
            System.Net.IPEndPoint ipAny =
                new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
            Byte[] data = udp.Receive(ref ipAny);

            textLog.Text += System.Text.Encoding.ASCII.GetString(data) 
                            + Environment.NewLine;
        }
    }
}