一、前言
最近在网上看到了某家智能插座的结构,大概是下面图片的样子,感觉也不是很复杂,于是自己也想做一个。
由于不会画PCB,只能找模块草草地设计一个,原理图如下:
OK,可以开始在某宝上选择对应的模块了。
二、准备环境
(一)、硬件环境:
1. WIFI继电器模块(含wifi模块)
2. AC转DC模块(220V转5V)
3. 普通插座
(二) 软件环境:
1. arduino IDE
2. 必要的库:
(1) arduino json库:https://www.ardu-badge.com/ArduinoJson/6.10.1 (2) arduino mqtt库:https://github.com/knolleary/pubsubclient
三、实施步骤
第一步: 把插座拆开,准确来说下面这个是插头转换器
如果选的这种,拆开可能是最难的一步了,虽然背部有螺丝孔,楼主拿到的不是十字,也不是一字,孔径很长,最后用的工具切开插座盖板,比较丑就不上图了。。
第二步: 接线
按照上面的原理图接好线后,样子大概如下:
这是体育老师教的焊接
第三步: 烧录代码
代码比较简单,先连接wifi、mqtt服务器,订阅指定的消息后轮循判断wifi,服务器连接是否断开并重连(封装在库里),按照json格式解析接收到消息,向GPIO0 发送对应的高/低电平信号控制插座通/断电,具体代码如下:
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include "EspMQTTClient.h"
#define Pin 0
/*******************STA模式**********************/
//设置STA网络参数,静态IP(按照自己的网段填写)
IPAddress staticIP(192, 168, 43, 199); //本地静态IP
IPAddress gateway(192, 168, 43, 1); //本地网关
IPAddress subnet(255, 255, 255, 0); //本地子网掩码
//设置STA连接热点
const char *ssid = "meizu"; //填写自己的WiFi名
const char *password = "ljd1234567"; //填写自己的WiFi密码
/*****************MQTT服务器*******************/
const char *MQTTBroker = "j8home.cn"; //可以更换为其他开源的MQTT服务器
const int brokerPort = 1883;
const char *MQTTUsername = "admin"; //不限制,可以是任意用户名
const char *MQTTPassword = "admin"; //不限制,可以是任意密码
const char *ClientName = "TestClient"; //不限制,可以是任意客户端名
const char *subTopic = "v1/devices/me/relay1";
WiFiClient Client;
bool first_set = false;
EspMQTTClient client(
ssid, //wifi ssid
password, //wifi passwd
MQTTBroker, // MQTT Broker server ip
MQTTUsername, // Can be omitted if not needed
MQTTPassword, // Can be omitted if not needed
ClientName, // Client name that uniquely identify your device
brokerPort // The MQTT port, default to 1883.
);
int status = WL_IDLE_STATUS; //保存wifi状态
char recv_data[1024]; //存入服务器下发的数据
void connect_wifi(); //wifi初始化
void analy_recv_data(char *msg, int len); //解析服务器数据
void setup() {
Serial.begin(115200); //波特率为9600
pinMode(Pin, OUTPUT); //初始化控制引脚
connect_wifi(); // 连接WiFi
first_set = true;
client.enableDebuggingMessages(); // Enable debugging messages sent to serial output
}
void loop() {
status = WiFi.status(); //获取wifi状态
if ( status != WL_CONNECTED) {
connect_wifi();
}
client.loop();
}
/****************************
MQTT订阅函数
****************************/
void onConnectionEstablished()
{
//订阅消息
client.subscribe(subTopic, [](const String & payload) {
char cArr[payload.length() + 1];
payload.toCharArray(cArr, payload.length() + 1);
analy_recv_data(cArr);
});
//发布消息
client.executeDelayed(5 * 1000, []() {
client.publish("mytopic/test", "This is a message sent 5 seconds later");
});
}
/****************************
WIFI软串口通信初始化函数
****************************/
void connect_wifi()
{
WiFi.begin(ssid, password);
if(!first_set)
WiFi.config(staticIP, gateway, subnet);
Serial.print("Is connecting routing,please wait");
while (WiFi.status() != WL_CONNECTED) //等待连接路由
{
delay(500);
Serial.print(". ");
}
Serial.println("");
Serial.println("WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
/*****************************
分析tcp数据
****************************/
void analy_recv_data(char *msg) {
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, msg);
// 判断是否解析成功
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
//开始获得每个对象
char id = doc["id"];
char status = doc["status"];
char data[2];
data[0] = id;
data[1] = status;
for (int data_i = 0; data_i < 2; data_i++) {
Serial.write(data[data_i]); //向串口发送读取的每个字节
}
if (id == 1) {
if (status == 1) {
digitalWrite(Pin, HIGH);//开
delay(200);
} else if (status == 0) {
digitalWrite(Pin, LOW);//开
delay(200);
}
}
}