LoginSignup
6
4

More than 5 years have passed since last update.

ESP8266搭載ボード(¥422)でWOL中継機を作ってみた

Last updated at Posted at 2019-04-08

外出先からWOLでPCやHDDレコーダーの電源ON

外出先からスマホでPCやHDDレコーダーの電源をONし、外出先から機器を遠隔操作できるようにしています。インターネットからWOLパケットを送信し、パケットのフォワーディングで、自宅内LANへブロードキャストすることで実現していました。
[送信機器] ---> [ルーター] ---ブロードキャスト---> [PC1], [PC2]
のような構成です。

引越し後に問題発生

引越し先はJ:COMのCATVインターネットが無料で使え、WiFi親機付きのルーターも無料でレンタルできますが、ここで問題発生。引っ越し前と同じくWiFi親機からWOLパケットのフォワーディングを設定し、転送先をブロードキャストアドレスにしたのですが、WOLパケットが転送されません。どうやらJ:COMのWiFi親機の問題のようです。

Wake On LANリピータ?

http://www.starstonesoft.com/WOLRepeater.htm
のような機器を使えば、問題を解決できそうです。
つまり、
[ルーター] ---ブロードキャスト---> [PC1], [PC2]
が無理なので、ルーターから先を
[ルーター] ---ユニキャスト---> [WOL中継機] ---ブロードキャスト---> [PC1], [PC2]
とすればよいはずです。

PC1, PC2に対して何故ブロードキャストでないといけないのかというと、ルーターやスイッチングハブはある程度時間が経過すると、電源OFFの機器のMACアドレスを忘れてしまうからです。忘れてしまうとユニキャストの場合は転送されません。ブロードキャストなら転送されるのでこれを利用しています。

WOL中継機の仕事は、特定のポート宛のUDPパケットをブロードキャストアドレス宛に転送するだけです。つまり、右から来たものを左に受け流す仕事をします。通信ライブラリ等が整備されたボードでなら機能を絞れば簡単に作れそうです。

ESP8266搭載ボード

安いものを探したところ、これを見付けました。
https://www.amazon.co.jp/gp/product/B07K2VQ4J7/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

最初はEthernet搭載ボードを探していたのですが、WiFi搭載のほうが安いということに気付きました。まあ性能は低いでしょうが、今回の目的には十分ですし、何と言っても激安です。¥422で1個注文したのですが、何故か2個セットが届きました(支払いは1個分だけです)。因みに、中国からの発送で、届くまでに約3週間かかりました。

Arduino IDE

Arduino IDEで開発できますが、とにかく簡単に作れます。nodeMCU 1.0を指定し、正味わずか50行足らずでWOLリピータのようなものができました(WOL_helperと名付けました)。
以下、ソースコードです。

WOL_helper.ino
// WOL_helper
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>

// Settings
#define SSID        "SSIDをここに書く"
#define PASSWORD    "パスワードをここに書く"
#define SRC_PORT    8888    // 待受ポート番号
#define DST_PORT    9

WiFiUDP UDP;
IPAddress broadcastIP;

void setup(void)
{ 
  Serial.begin(115200);
  // Connect to WiFi
  WiFi.begin(SSID, PASSWORD);

  // while wifi not connected yet, print '.'
  // then after it connected, get out of the loop
  while (WiFi.status() != WL_CONNECTED) {
     delay(500);
     Serial.print(".");
  }
  broadcastIP = (uint32_t)WiFi.localIP() | ~(uint32_t)WiFi.subnetMask();
  UDP.begin(SRC_PORT);

  //print a new line, then print WiFi connected and the IP address
  Serial.println("\nWiFi connected");
  // Print the IP address
  Serial.print(WiFi.localIP());
  Serial.printf(":%d->", SRC_PORT);
  Serial.print(broadcastIP);
  Serial.printf(":%d\n", DST_PORT);
}

void loop()
{
  static unsigned char buf[200];
  int packetSize = UDP.parsePacket();
  if (0 < packetSize && packetSize <= sizeof(buf)) {
    int len = UDP.read(buf, packetSize);
    Serial.print(UDP.remoteIP());
    Serial.print(" /");
    for (int i = 0; i < len; i++) {
      Serial.printf(" %02X", buf[i]);
    }
    Serial.println("");
    UDP.beginPacket(broadcastIP, DST_PORT);
    UDP.write(buf, len);
    UDP.endPacket();
  } else {
    delay(1000);
  }
}

以上

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4