问题
我的床头没有电灯开关,躺床上玩累了还要下床去关灯,极为不爽。就想着整一个手机关灯的功能。
准备
计划使用 web 来控制灯,所以选用了带有 wifi 模块的 wemos d1 r1 开发板。
除此之外还需要 电阻x2(其中一个为下拉电阻),继电器x1,门铃面板x1(模仿按钮输入高低电平),若干根导线。ps.我是电路渣渣,电阻都是随机选择QAQ
计划
要实现以下控制方法
- 按钮控制
- 串口控制
- socket 控制(弃坑)
- websocket 控制
- 蓝牙控制(还没搞)
电路
鸽了
代码
需要先在库管理器中安装ArduinoWebsockets和Chrono。
ps. 以下代码都是东拼西凑的OVO
#include <ESP8266WiFi.h>
#include <ArduinoWebsockets.h>
#include <Chrono.h>
char *ssid = "wifissid";
char *passwd = "wifipass";
bool state = false;
int ecr = 16;
int button = 5;
int buttonOld = 0;
const uint16_t port = 9999; //socket端口
const char *host = "10.0.0.254"; //socket主机
const char *websockets_server_host = "10.0.0.254"; //websocket主机
const uint16_t websockets_server_port = 8000; //websocket端口
const char *websockets_server_path = "/ws"; //websocket路径
bool websockets_connected;
WiFiClient wific;
websockets::WebsocketsClient wsc;
Chrono chronoA;
Chrono chronoB;
Chrono chronoC;
Chrono chronoD;
void setup()
{
Serial.begin(115200);
pinMode(ecr, OUTPUT);
pinMode(button, INPUT);
digitalWrite(ecr, LOW);
setupNetwork();
setupWebsocket();
}
void loop()
{
if (chronoA.hasPassed(100))
{
chronoA.restart();
physicsSwitch();
}
if (chronoB.hasPassed(100))
{
chronoB.restart();
serialSwitch();
}
if (websockets_connected)
{
if (chronoC.hasPassed(100))
{
chronoC.restart();
websocketSwitch();
}
if (chronoD.hasPassed(1000))
{
chronoD.restart();
websocketWatcher();
}
}
}
bool changeState()
{
Serial.print("change state to ");
state = !state;
if (state)
{
digitalWrite(ecr, HIGH);
Serial.println("on");
}
else
{
digitalWrite(ecr, LOW);
Serial.println("off");
}
return state;
}
bool setState(bool seto)
{
if (state != seto)
{
changeState();
}
}
void setupNetwork()
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, passwd);
Serial.println("connecting to wifi... ");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.print("wifi connected, local IP address: ");
Serial.println(WiFi.localIP());
delay(500);
}
void bluetoothSwitch()
{
}
void physicsSwitch()
{
int buttonState = digitalRead(button);
if (buttonOld == 0 && buttonState == 1)
{
changeState();
}
buttonOld = buttonState;
}
void serialSwitch()
{
int input = Serial.read();
if (input == 'y')
{
setState(true);
}
if (input == 'n')
{
setState(false);
}
}
void socketSwitch()
{
String recv_data = wific.readStringUntil('\r');
if (recv_data == "on")
{
setState(true);
}
if (recv_data == "off")
{
setState(false);
}
}
void setupSocket()
{
Serial.print("connecting to ");
Serial.println(host);
if (!wific.connect(host, port))
{
Serial.println("connection failed");
Serial.println("wait 5 sec...");
delay(5000);
return;
}
else
{
Serial.println("connect to tcp server success.");
Serial.println("Send this data to tcp server");
wific.println(String("hello tcp server"));
}
}
void setupWebsocket()
{
Serial.print("connecting to websocket server");
Serial.println(websockets_server_host);
websockets_connected = wsc.connect(websockets_server_host, websockets_server_port, websockets_server_path);
if (websockets_connected)
{
Serial.println("connecetd to websocket server");
}
else
{
Serial.println("connect to websocket server fail!");
}
wsc.onMessage([&](websockets::WebsocketsMessage message) {
String recv_data = message.data();
if (recv_data == "on")
{
wsc.send(setState(true) ? "{\"state\":1}" : "{\"state\":0}");
}
if (recv_data == "off")
{
wsc.send(setState(false) ? "{\"state\":1}" : "{\"state\":0}");
}
});
}
void websocketSwitch()
{
if (wsc.available())
{
wsc.poll();
}
}
void websocketWatcher()
{
wsc.send(state ? "{\"state\":1}" : "{\"state\":0}");
}
说明
按下按钮切换电灯状态。
串口发送 'y' 开灯,发送 'n' 关灯。
websocket 发送 'on' 开灯,发送 'off' 关灯。
文章评论