WeMosを使ってみる

UART-Wifi-UART Bridge


2つのマイコンがUARTで通信している場合、
Xbee や Xbee Wifi を使うと、UARTの通信を無線化することができます。
WeMosでも同じようにUART-Wifi-UARTブリッジによるUART通信の無線化ができます。


以下のスケッチを2台のWeMosに書き込みます。
アクセスポイントのssidとパスワードは適当に変更してください。
/*
 * ESP8266 UART <-> WiFi(UDP) <-> UART Bridge
 * ESP8266 TX of Serial1 is GPIO2
 */

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

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

WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
char incomingPacket[255];  // buffer for incoming packets

#define bufferSize 8192
uint8_t buf[bufferSize];
uint8_t iofs=0;
IPAddress remoteIp;
unsigned int remotePort;
char myHostName[16] = {0};
char remoteHostName[16] = {0};

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

  sprintf(myHostName, "ESP_%06X", ESP.getChipId());
  Serial1.print("myHostName: ");
  Serial1.println(myHostName);
  WiFi.hostname(myHostName);

  Serial1.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial1.print(".");
  }
  Serial1.println(" connected");

  Udp.begin(localUdpPort);
  Serial1.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);

  // Start the mDNS responder for ESP_XXXXXX.local
  if (!MDNS.begin(myHostName)) {
    Serial1.println("Error setting up MDNS responder!");
  }
  Serial1.println("mDNS responder started");
  // Announce esp8266_wifi udp service on port 4210
  MDNS.addService("esp8266_wifi", "udp", localUdpPort);
}


void loop()
{
  static int validRemoteIp = 0;
 
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    // receive incoming UDP packets
    Serial1.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(incomingPacket, 255);
    if (len > 0)
    {
      incomingPacket[len] = 0;
    }
    Serial1.printf("UDP packet contents: %s\n", incomingPacket);
    Serial.print(incomingPacket);
  }

  if(Serial.available()) {
 
    while(1) {
      if(Serial.available()) {
        buf[iofs] = (char)Serial.read(); // read char from UART
        if(iofs<bufferSize-1) {
          iofs++;
        }
      } else {
        break;
      }
    }

    if (validRemoteIp == 0) {
      // Send out query for esp8266_wifi udp services
      Serial1.println("Sending mDNS query");
      int n = MDNS.queryService("esp8266_wifi", "udp");
      Serial1.println("mDNS query done");
      if (n == 0) {
        Serial1.println("no services found");
      } else {
        Serial1.print(n);
        Serial1.println(" service(s) found");
        for (int i = 0; i < n; ++i) {
          // Print details for each service found
          Serial1.print(i + 1);
          Serial1.print(": ");
          Serial1.print(MDNS.hostname(i));
          Serial1.print(" (");
          Serial1.print(MDNS.IP(i));
          Serial1.print(":");
          Serial1.print(MDNS.port(i));
          Serial1.println(")");
  
          MDNS.hostname(i).toCharArray(remoteHostName, sizeof(remoteHostName));
          if (strcmp(remoteHostName, myHostName) != 0) {
            remoteIp = MDNS.IP(i);
            remotePort = MDNS.port(i);
            validRemoteIp = 1;
          }
        }
      }
      Serial1.println();
      Serial1.print("remoteIp=");
      Serial1.println(remoteIp);
      Serial1.print("remotePort=");
      Serial1.println(remotePort);
    }
  
    Serial1.print("validRemoteIp=");
    Serial1.println(validRemoteIp);
    if (validRemoteIp) {
      Udp.beginPacket(remoteIp, remotePort); // remote IP and port
      Udp.write(buf, iofs);
      Udp.endPacket();
    }
    iofs = 0;
  }
}

Arduino-IDEでは2つのシリアルコンソールを同時に開くことができないので、TeraTermを2つ開きます。
通信ポートはそれぞれのWeMosのシリアルポート、ボーレートは115200Bpsとしてください。
片方のTeraTermで文字を入力すると、相手側に入力した文字が表示されます。
勝手に相手側のTeraTermに文字が表示されるので、少し気持ち悪いです。

今回も、UART1をデバッグポートとして使っていますので、このポートを使ってデバッグ表示を行うことができます。
デバッグ表示を行うには、TTL-USB変換アダプタを以下のように接続します。
TTL-USB変換アダプタをWindowsPCのUSBポートに入れて、TeraTermでCOMポートを開きます。
COMポートのボーレートは115200bpsです。
ESP8266 TTL-USB変換アダプター
GPIO2 RX
GND GND

送信の前に、 MDNS.queryService() を使って、同じサービス名をもつノードがネットワーク内にいるかどうかを確かめて、
ノードがあるときはそのアドレスにUDPを使ってデータを送っています。


次回はUART→MQTTコンバータを紹介します。

続く....