WOL远程开机——通过ESP8266+blinker(点灯)平台实现

WOL远程开机——通过ESP8266+blinker(点灯)平台实现

之前疫情现在家里,无聊时改装家里的吸顶灯入网时,寻找了各种物联网平台,最终找到了blinker(点灯)这个物联网平台,APP很简洁,同时提供方便的API接口,非常适于DIY。
然后就是这次的想法,开学后已经搞好了Teamview远程连接自己的实验室电脑,使自己在宿舍也能科(hua)研(shui),但又因为实验室电脑总是开着,感觉不舒服(毕竟是自己配的机子,不舍得一直烧着)。于是想着怎么远程开关机,淘宝上的向日葵开机棒一个108,看了看原理,发现身为一个电子专业的科研狗,买了就是交智商税,刚好想到了用前面提到的平台,就可以实现远程开机,最后成本就8块钱(或者不要钱,我的ESP8266是本科玩剩下的,用不完就送学弟了)。

说明

本方法适合没公网IP的、没自己服务器的、没高级路由器的三无玩家,有以上几个的也可以这么搞,但没必要,毕竟(教程一堆):

  1. 宽带是公网IP的直接走内网映射
  2. 有腾讯云、阿里云服务器的直接走转发
  3. 有高级路由器的(带WOL功能)直接设置
    但是如果图方便也可以

预备知识

  1. 计算机网络基本知识
  2. C语言基本知识
  3. Arduino编程经验(没有也行)
    (如果是电子专业的,肯定没啥障碍)

所需材料和前提

前提

  1. 自己的电脑支持WOL
  2. 连着网的路由器
    (没有上面两个前提的可以直接放弃)

材料

  1. 手机APP(blinker,Android & IOS 平台都有)
  2. ESP8266模块一个

调试下载工具

  1. Arduino IDE平台(编译用)
  2. USB转TTL模块(下载用)

原理

如果有上述提到的预备知识,则整体原理会非常简单,一句话概括就是手机APP端发送MQTT包到ESP8266,ESP8266转发WOL的UDP包到本地子网。

WOL

WOL(Wake On LAN) 局域网唤醒,顾名思义,是一种在局域网内唤醒PC的一种技术。其主要原理是向本地子网内的机器广播一个包含有目标机器网卡MAC地址的一个UDP包(WOL魔术包),所有接收到的机器解析包中的MAC地址,匹配成功的网卡发送对应命令,开启电脑。

Blinker平台

Blinker平台简介其官网有具体的介绍(链接在这),在此就大致说明一下本方法所用到的原理即可。
WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第1张图片

大致原理即如图所示,在局域网内网中,手机客户端直接通过局域网与ESP8266通讯,ESP8266接收到指令后进行WOL包的广播发送,在非局域网的远程连接中,ESP8266与Blinker服务器连接,同时手机客户端向Blinker服务器发送相关指令后,服务器转发给远端的ESP8266后,ESP8266发送WOL包唤醒电脑。

步骤

STEP1:设置WOL(实现内网唤醒)

WOL在BIOS中设置,具体的机器需要具体设置,就是在BIOS中打开一个选项开关,具体步骤自己在BIOS中找,我的电脑的设置如下:

其次就是在Windows中设置网卡的步骤,设置步骤如下:
首先在设备管理器中找到自己的以太网卡,找到连网线的那个网卡,进行如下操作:
WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第2张图片

然后继续在此页面下进行已下操作:
WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第3张图片

最后在网络和共享中心中查看自己网卡的MAC地址和IP地址:
WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第4张图片

全部设置正确后,便可以在本地局域网下进行设备唤醒了。
iOS下的Wolow软件可以进行测试,在手机连接路由器后(手机,电脑在同一个子网下,同时路由器没有开启AP隔离功能(一般都不开启)),进入对应设置,点击唤醒电脑就可以唤醒了。

注:最好在路由器中设置PC的IP与MAC绑定,方便后续的开机状态检查功能拓展,若不设置此项,开机功能可以用,但是可能无法进行设备开启状态检查!!!

Wolow软件设置如下:

首先添加新设备,界面如下:

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第5张图片

接下来按照提示进行相关设置的填写,界面如下:

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第6张图片

设置完成后进行测试,若PC没能启动检查是否有设置错误的地方,直到测试成功唤醒。

STEP2:ESP8266程序编写 + Blinker设置(实现外网唤醒)

先贴程序,对着程序进行解释:

/**
 * 本项目简单的利用了blinker的Button例程,在客户端按下按键后,
 * 通过MQTT通知ESP8266触发按键处理函数,按键处理函数主要负责
 * 发送WOL的UDP魔术包,WOL魔术包格式如下
 * FF FF FF FF FF FF ( XX XX XX XX XX XX (网卡的MAC地址)) x 16
 * 包的总大小为 6+6*16 = 102 Byte 
*/

#define BLINKER_WIFI

#include 

//对应客户端的秘钥
char auth[] = "************";
//WIFI SSID
char ssid[] = "XXXX";
//WIFI Password
char pswd[] = "XXXX";

#define BUTTON_1 "OPEN"


WiFiUDP Udp;
//网卡的IP地址
const IPAddress remote_ip(192, 168, 0, 1);
//根据自己的路由器选择子网段的广播地址
#define BROADCAST_ADD "192.168.1.255"
//网卡唤醒端口(一般为9或7,可以在BIOS中查看)
#define REMOTEPORT 9
//ESP8266端口,随便填一个,也填成9
#define LOCALPORT 9
//网卡的MAC地址 6个字节    
char NETCARD_MAC[6] = {
     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};
//WOL包
char WOL_Buffer[102];

//调试开关
//#define WOL_DEBUG

//WOL魔术包初始化
void WOL_packet_init()
{
     
	int i,j;
	for(i=0;i<6;i++)
	{
     
	WOL_Buffer[i] = 0xFF;
	}
	for(i=1;i<17;i++)
	{
     
		for(j=0;j<6;j++)
		{
     
		WOL_Buffer[i*6 + j] = NETCARD_MAC[j];
		}
	}
#ifdef WOL_DEBUG	
	Serial.printf("The WOL packet is :\n");
	for(i=0;i<102;i++){
     
		Serial.printf("%x ",WOL_Buffer[i]);
	}
#endif
}

void WOL_packet_transfer()
{
     
#ifdef WOL_DEBUG	
	Serial.printf("NOW is send WOL packet!\n");
#endif
	Udp.beginPacket(BROADCAST_ADD, REMOTEPORT);
	Udp.write(WOL_Buffer);
	Udp.endPacket();
}

BlinkerButton Button1(BUTTON_1);

void button1_callback(const String & state)
{
     
	BLINKER_LOG("get button state: ", state);

	if (state == BLINKER_CMD_BUTTON_TAP) {
     
		BLINKER_LOG("Button tap!");
		WOL_packet_transfer();
		BLINKER_LOG("WOL Packet Transfer Completed!");
	}
	else {
     
		BLINKER_LOG("Get user setting: ", state);
	}
}

void dataRead(const String & data)
{
     
	BLINKER_LOG("Blinker readString: ", data);
	Blinker.vibrate();
	uint32_t BlinkerTime = millis();
	Blinker.print("millis", BlinkerTime);
}

void setup()
{
     
	Serial.begin(115200);
	BLINKER_DEBUG.stream(Serial);
	Blinker.begin(auth, ssid, pswd);
	Blinker.attachData(dataRead);
	Button1.attach(button1_callback);
	Udp.begin(LOCALPORT);
	WOL_packet_init();
}

void loop()
{
     
	Blinker.run();
#ifdef WOL_DEBUG
	if((Serial.read() == 0x96) || digitalRead(0) == LOW){
     
		WOL_packet_transfer();
		while(digitalRead(0) == LOW){
     }
	}
#endif
}

(1)程序设置

上述程序中,基本功能已经编写好,不想加新东西的话只需要设置以下几项:

  • 客户端相关设置(两项):

设备注册使用:

//对应客户端的秘钥
char auth[] = "************";

客户端里的按键的名字,注册按键处理回调函数使用。

#define BUTTON_1 "OPEN"
  • 路由器相关设置(两项):

路由器SSID:

//WIFI SSID
char ssid[] = "XXXX";

路由器密码:

//WIFI Password
char pswd[] = "XXXX";

路由器子网广播地址,将路由器网关地址最后换成255即就是广播地址

//根据自己的路由器选择子网段的广播地址
#define BROADCAST_ADD "192.168.1.255"
  • PC端相关设置(两项):

网卡端口号,一般为7或者9,之前Wolow软件测试用到过。

//网卡唤醒端口(一般为9或7,可以在BIOS中查看)
#define REMOTEPORT 9

PC网卡的MAC地址,之前测试用到过。

//网卡的MAC地址 6个字节    
char NETCARD_MAC[6] = {
     0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};

除了 客户端 相关的两项设置目前无法填写之外,其余的内容在之前的步骤中已经出现过,可以直接填写。

(2)客户端APP设置

首先打开Blinker的APP,没注册的先注册,然后开始设备申请流程:

Step1:添加设备,选择Arduino设备

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第7张图片

Step2:选择WIFI接入

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第8张图片

Step3:得到设备秘钥,此秘钥对应着程序中的秘钥,直接复制进程序中即可。
WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第9张图片

Step4:返回主界面,点击进入申请号的设备中

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第10张图片

Step5:点击右上角的编辑按键,进入编辑界面,然后添加一个按键,点击出现的按键进入按键设置中

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第11张图片

Step6:在按键的基础设置中,首先设置数据键名,此键名为程序中客户端设置的第二个需要填写的项,将此项填入程序中,接着选择按键类型为普通按键即可,其余项目可以不用在意。设置完后保存,退出编辑界面。

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第12张图片

Step7:完成APP设置后回到设备主界面,如下:

WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第13张图片

至此,已经完成相关客户端的相关项设置。

STEP3:程序烧写

将前两步的相关设置填写入程序中,打开Arduino IDE进行程序烧写,需要提前设置IDE的环境,这里就不多讲了,Blinker的开发说明中有非常详细的安装操作步骤(连接在这),完成后点击编译下载进ESP8266模块中(使用IDE下载或使用官方的下载都行,都是通过串口下载,这个也就不多说了,毕竟网上关于ESP8266的资料漫天飞)。

下载完成后,重新启动模块,等待模块连接WIFI成功,同时,在手机客户端可以看见之前的设备从离线状态变为在线状态,点击进入设备,点击按键(此时手机在内外网均可),不出意外,则PC成功启动。

后续拓展功能

Ping功能添加

利用ESP8266去Ping电脑,在开机后,若可以Ping通,则证明已经开机成功。Ping时需要注意的是需要在开机后等待一段时间在去Ping,可以在APP中再定义一组按键来实现状态查询功能, 在状态检测按键按下后,ESP8266开始Ping主机IP,Ping通则利用Blinker的消息组件进行状态返回。
已经测试成功,下面贴出完整的代码:

#define BLINKER_WIFI

#include 
#include 

//对应客户端的秘钥
char auth[] = "XXXXXX";
//WIFI SSID
char ssid[] = "XXXXXX";
//WIFI Password
char pswd[] = "XXXXXX";

#define BUTTON_1 "OPEN"

#define BUTTON_2 "PC-Status"

WiFiUDP Udp;
//根据自己的路由器选择子网段的广播地址
#define BROADCAST_ADD "192.168.XXX.255"
//网卡唤醒端口(一般为9,可以在BIOS中查看)
#define REMOTEPORT 9
//PC端的IP地址(需要在路由器端进行MAC和IP绑定)
const IPAddress remote_ip(192, 168, XXX, XXX);
//本地UDP端口
#define LOCALPORT 9
//网卡的MAC地址 6个字节    
char NETCARD_MAC[6] = {
     0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
//WOL包
char WOL_Buffer[102];

//WOL包发送完成标志
int complete_flag = 0;
//ping计数
int ping_num = 0;

//WOL魔术包初始化
void WOL_packet_init()
{
     
	int i,j;
	for(i=0;i<6;i++)
	{
     
	WOL_Buffer[i] = 0xFF;
	}
	for(i=1;i<17;i++)
	{
     
		for(j=0;j<6;j++)
		{
     
		WOL_Buffer[i*6 + j] = NETCARD_MAC[j];
		}
	}
#ifdef WOL_DEBUG	
	Serial.printf("The WOL packet is :\n");
	for(i=0;i<102;i++){
     
		Serial.printf("%x ",WOL_Buffer[i]);
	}
#endif
}

void WOL_packet_transfer()
{
     
#ifdef WOL_DEBUG	
	Serial.printf("NOW is send WOL packet!\n");
#endif
	Udp.beginPacket(BROADCAST_ADD, REMOTEPORT);
	Udp.write(WOL_Buffer);
	Udp.endPacket();
}

BlinkerButton Button1(BUTTON_1);

void button1_callback(const String & state)
{
     
	  BLINKER_LOG("get button1 state: ", state);

	  if (state == BLINKER_CMD_BUTTON_TAP) {
     
		BLINKER_LOG("Button1 tap!");
		WOL_packet_transfer();
		BLINKER_LOG("WOL Packet Transfer Completed!");
    complete_flag = 1;
    Blinker.notify("!Opening... Plase wait a moment");
	}
	else {
     
		BLINKER_LOG("Get user setting: ", state);
	}
}


BlinkerButton Button2(BUTTON_2);
void button2_callback(const String & state)
{
     
    BLINKER_LOG("get button2 state: ", state);

    if (state == BLINKER_CMD_BUTTON_TAP) {
     
    BLINKER_LOG("Button2 tap!");
    if(complete_flag){
     
      if(Ping.ping(remote_ip)){
     
        Blinker.notify("!PC Open Successful!");
        ping_num = 0;
        complete_flag = 0;
      }
      else{
     
        Blinker.notify("!Opening... Plase wait a moment");
        ping_num++;
        if(ping_num > 4){
     
          ping_num = 0;
          complete_flag = 0;
          Blinker.print("Open Failed,Plase tap button again!");
          Blinker.notify("!Open Failed,Plase tap button again");
        }
      }
    }
    else{
     
      Blinker.notify("!Plase tap button again!");
    }
  }
  else {
     
    BLINKER_LOG("Get user setting: ", state);
  }
}

void dataRead(const String & data)
{
     
	BLINKER_LOG("Blinker readString: ", data);
	Blinker.vibrate();
	uint32_t BlinkerTime = millis();
	Blinker.print("millis", BlinkerTime);
}

void setup()
{
     
	Serial.begin(115200);
	BLINKER_DEBUG.stream(Serial);
	Blinker.begin(auth, ssid, pswd);
	Blinker.attachData(dataRead);
	Button1.attach(button1_callback);
  	Button2.attach(button2_callback);
	Udp.begin(LOCALPORT);
	WOL_packet_init();
}

void loop()
{
     
	Blinker.run();
}

APP界面如下:
WOL远程开机——通过ESP8266+blinker(点灯)平台实现_第14张图片

补充说明

这只是个简单的开机模块,至于远程开机有什么用,对于我来说就是配合Teamview实现在宿舍科研,远程跑个仿真啥的非常方便,不用的话可以在 power shell 中利用 shutdown -s 指令进行关机,减少机子的空耗时间,增加寿命。这只是个基础的版本,后面可以添加各种功能进行DIY,看各位发挥了!

你可能感兴趣的:(整活小工具,嵌入式,物联网,wifi,网络,路由器)