esp32/网络开机/远程开机/WOL
本帖最后由 吹向陆地的风 于 2020-3-20 10:46 编辑最近看到好几个人想用Blinker做远程开机,但都因为种种原因放弃了,网上也没人分享代码,所以花了一晚上用ESP32做了个开机棒。
原理就是广播一个特殊的数据包给目的主机,前提是目的主机的主板支持wake on lan并在BIOS里已经设置好,还有就是要知道目的主机的MAC地址。这个特殊的数据包叫做magic packet,它由102个字节组成,最前面六个字节为0xFF,其他字节为目的主机的MAC地址(6个字节为一组,共16组),如下图所示:
(z这一段是复制大佬介绍的,地址https://blog.csdn.net/dyllove98/article/details/9002969)
知道这个原理之后,只要向目的地址发送一个指定格式的magic packet就可以实现远程开机了。如果家里有公网ip的话下面的步骤都不需要了,找一个网络唤醒的程序直接使用就好,但大部分人家里都没有公网ip,无法从外网连接。
远程开机的思路是利用Blinker的Button组件,控制esp32发送开机数据,解决了没有公网ip不能通信的问题。
void wol()//开机代码部分
{
int i, k, j = 0;
udp.beginPacket(udpAddress, udpPort);//准备发送,设置地址和端口
//下面构建magic packet
for (i = 0; i < 6; i++, j++)
{
package = 0xFF;
}
for (i = 0; i < 16; i++) {
for ( k = 0; k < 6; k++, j++)
package = MAC;
}
udp.write((byte*)package, 102);//将数组package放入缓冲区,准备发送
udp.endPacket();//发送
Blinker.delay(1000);
}
这个是远程开机的核心代码,先构建magic packet数组,然后将该数组以udp方式发送出去,其中MAC数组为你要开机目标的MAc号,端口不重要,只要是合法的都可以,package为被构建的数组,用于存储magic packet,之后发送出去,完成开机操作。
下面是全部代码
#define BLINKER_WIFI
#include <Blinker.h>
#include <WiFi.h>
#include <WiFiUdp.h>
//引用各类库
char auth[] = "auth";
char ssid[] = "ssid";
char pswd[] = "key";
//Blinker常规操作
#define BUTTON_1 "WOL"//定义按键
BlinkerButton Button1(BUTTON_1);
void button1_callback(const String & state)//回调函数
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
BLINKER_LOG("get button state: ", state);
if(state == BLINKER_CMD_ON) {
BLINKER_LOG("Toggle on!");
wol();
Button1.print("on");
Blinker.delay(2000);
Button1.print("off");//返回关闭状态,方便下一次使用。
}
}
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
Blinker.vibrate();
uint32_t BlinkerTime = millis();
Blinker.print("millis", BlinkerTime);
}
const char * udpAddress = "192.168.0.255";//udp接收地址,我这里是使用的广播
const int udpPort = 2333;//udp端口
byte MAC = {0x00, 0x10, 0x12, 0xD0, 0x9C, 0x6D};//MAC号
byte package;
//The udp library class
WiFiUDP udp;
void setup() {
//WiFi.begin(ssid,pswd);
Blinker.begin(auth,ssid,pswd);
Blinker.attachData(dataRead);
Button1.attach(button1_callback);//注册回调函数
}
void loop() {
Blinker.run();
}
void wol()//开机代码部分
{
int i, k, j = 0;
udp.beginPacket(udpAddress, udpPort);//准备发送,设置地址和端口
//下面构建magic packet
for (i = 0; i < 6; i++, j++)
{
package = 0xFF;
}
for (i = 0; i < 16; i++) {
for ( k = 0; k < 6; k++, j++)
package = MAC;
}
udp.write((byte*)package, 102);//将数组package放入缓冲区,准备发送
udp.endPacket();//发送
Blinker.delay(1000);
}
在Blinker中新建一个WOL的按键,类型设置为开关。
这里udp发送的是广播,所以不用在路由器设置ip与mac绑定,只需要知道mac号就可以了,自己只需要修改mac和udpAddress,记得分192.168.0和192.168.1的区别。
由于我只有一个手机,无法拍摄开机过程视频,就不放了,本人亲测可以成功开机,前提是主板支持网络唤醒并正确配置,具体配置方法可以根据主板类型自行百度,这里就不做赘述。
n1001 发表于 2020-3-26 16:38
我直接塞机箱里,拉个天线出来。如果是笔记本电脑等,楼主的方法显然更好 ...
然而笔记本大部分都不支持wol,即使支持也要插电源插网线,和台式机没什么区别了,wol不需要拆机箱也算好处:lol。 还能实现关机,需要找我 我直接塞机箱里,拉个天线出来。如果是笔记本电脑等,楼主的方法显然更好 cdb 发表于 2020-3-26 16:15
还能实现关机,需要找我
除了remote desktop和ssh还有啥方法能实现远程关机,求教,之前没找到方案。 吹向陆地的风 发表于 2020-3-27 08:48
然而笔记本大部分都不支持wol,即使支持也要插电源插网线,和台式机没什么区别了,wol不需要拆机箱也算好 ...
对于不方便拆开的电脑WOL优势挺大的:lol 吹向陆地的风 发表于 2020-3-27 08:44
除了remote desktop和ssh还有啥方法能实现远程关机,求教,之前没找到方案。
在电脑上安装关机服务程序,通过接口触发关机指令。周末我发个教程吧 你好,复制程序到ide编译显示错误,可以发个可用的ino文件吗?谢谢了 794736229 发表于 2020-5-1 17:54
你好,复制程序到ide编译显示错误,可以发个可用的ino文件吗?谢谢了
文件已上传
吹向陆地的风 发表于 2020-5-3 22:08
文件已上传
收到了,谢谢!变编译还是出错,可能是以为我用8266的原因吧?有没有办法适配8266呢
页:
[1]
2