WeMosを使ってみる

UDP-Wifi-UART Bridge


前回、Serial1(UART1)の使い方を紹介しました。
そこで、Serial1(UART1)をデバッグポートとして使ったUDP-Wifi-UART Bridgeを紹介します。
UARTへの入出力をWifi経由でUDPとして扱うことができます。

まず前回と同様に、TTL-USB変換アダプタを以下のように接続します。
TTL-USB変換アダプタをWindowsPCのUSBポートに入れて、TeraTermでCOMポートを開きます。
COMポートのボーレートは115200bpsです。
ESP8266 TTL-USB変換アダプター
GPIO2 RX
GND GND

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

#include <ESP8266WiFi.h>
#include <WiFiUdp.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(255,255,255,255);
unsigned int remotePort = 4210;

#define BAUDRATE 9600

void setup()
{
  delay(1000);
  Serial1.begin(115200); // Debug Print
  Serial.begin(BAUDRATE);

  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 BaudRate=%d\n",
  WiFi.localIP().toString().c_str(), localUdpPort, BAUDRATE);
}


void loop()
{
  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);
    //送信先を固定する場合は以下の2行のコメントを外す
    //応答してきた相手だけにUDP送信する
//    remoteIp = Udp.remoteIP(); // store the ip of the remote device
//    remotePort = Udp.remotePort(); // store the port of the remote device
  }

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

    // now send to WiFi 
    Udp.beginPacket(remoteIp, remotePort); // remote IP and port
    int byte = Udp.write(buf, iofs);
    if (byte != iofs) Serial1.println("UDP write fail");
    Udp.endPacket();
    iofs = 0;
  }
}


スケッチが起動すると、TeraTerm(COMポート)に以下が表示されます。
この表示はUART1を使っています。


TeraTermではUDPの送受信を行うことができません。
そこで、こちらから UDPの送受信が可能なテストツール(SocketTest)をダウンロードして起動します。
テストツールを起動して、Udpタブに切り替え、Server Portに4210を指定して、Start Listeningボタンを押します。


これで4210ポートでのUDPの待ち受け状態となります。


次にIDEのシリアルモニターで適当な文字を入力して送信ボタンを押します。
改行文字の有無はArduino-IDE側の設定で決まります。


テストツールではUDPで受信したIPアドレス、ポート番号、文字を表示します。


最後にClient側のIP AddressとPortにWeMos側のIPアドレスとポート番号を指定して
適当なMessageを指定してSendボタンをします。


Arduino-IDEに受信した文字を表示します。


この時、TeraTerm(COMポート)には送信元情報などがデバッグ表示されます。




2台のWeMosを使って、どの程度のパフォーマンスがあるのか調べてみました。
以下のスケッチを別のWeMosに書き込んで、ブリッジのWeMosとUARTで接続します。
#define BAUDRATE 9600
#define DELAY  900

void setup() {
  delay(1000);
  Serial.begin(BAUDRATE);
}

void loop() {
  static byte ch = 0x30;
  for (int i = 0; i < 10; i++) {
    Serial.write(ch);
  }
  //Serial.write(0x0d);
  //Serial.write(0x0a);
  ch++;
  if (ch == 0x3A) ch = 0x30;
  delay(DELAY);
}

WiFi環境も影響しますが、私の環境ではDELAYの間隔を1000以上にしないと、以下の様に文字落ちします。


次回はUART通信の無線化を紹介ます。

続く....