php与硬件通过wifi对接,基于ESP8266的WiFi排插接入贝壳互联实现天猫精灵控制
认识众多玩家高手/拆客/DIYer,查阅更多资源,一起学习技术知识
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 hzy3774 于 2020-1-8 00:45 编辑
* 实验的对象是一个基于ESP8266的WiFi排插,目标是通过Arduino编程实现天猫精灵语音控制排插每个插孔的通断电功能。* 编写程序主要需关心的硬件配置是:ESP-12模块x1,轻触按键x1,220V插口x4,USB接口x2,Wifi信号LEDx1,电源LEDx1
* 实物如图
DSC04258.JPG (88.44 KB, 下载次数: 0)
2020-1-7 22:54 上传
* 先来看看最终效果吧,一看就明白怎么回事了。点击观看视频
* 模块与IO连接如图:
微信图片编辑_20200107233554.jpg (35.75 KB, 下载次数: 0)
2020-1-7 23:37 上传
* 下面开始写程序,首先是使用WifiManager库配网:
// 设置Wifi
WiFiManager wifiManager;
wifiManager.autoConnect();复制代码
* 之后是来初始化中断,因为插板上有一个按钮,使用中断来处理按钮事件,处理的逻辑是:如果插座全关的情况下按下按钮,则变为全开,否则就变为全关。
// 中断响应
ICACHE_RAM_ATTR void onKeyClick() {
// 全关的状态全部打开,否则都是全关闭
if ((portStatus & 0B1111000) == 0B1111000) {
portStatus &= 0B0000111;
} else {
portStatus |= 0B1111000;
}
refreshOutput();
}
void initPanelKey() {
attachInterrupt(digitalPinToInterrupt(5), onKeyClick, FALLING);
}复制代码
* 我们使用了一个变量portStatus来表示用到的所有插孔和LED的开关状态,这样我们只要修改portStatus,再调用refreshOutput()就可以改变所有输出IO状态:
//7个端口分别对应 K1, K2, K3, K4,USB,LED_WIFI, LED_ROUND
char swPorts[portNum] = {14, 12, 13, 4, 16, 0, 3};
//除了USB充电口,其他都是低电平有效
int portStatus = 0B0000110; //7个IO开关
//======================================
// 初始化插板
void initOutputMode() {
for (int i = 0; i < portNum; i++) {
pinMode(swPorts[i], OUTPUT);
}
}
// 根据开关状态刷新IO电平
void refreshOutput() {
int c = 1;
for (int i = portNum - 1; i >= 0; i--) {
digitalWrite(swPorts[i], (c & portStatus) ? HIGH : LOW);
c <<= 1;
}
}复制代码
* 有了中断,也可以修改IO输出状态,下面就是对接贝壳互联平台。
* 对接详情可以参考我的另一片帖子:ESP8266基于Arduino接入贝壳物联,使用天猫精灵控制WS2812B灯带
* 但是与其他单设备不同,我们一个设备上有4个开关,就会麻烦一点,我的做法是使用子设备:
* 先添加一个设备,设备的类型必须要选择万能遥控器,万能遥控器的子设备才会生效:
微信截图_20200108000733.png (50.39 KB, 下载次数: 0)
2020-1-8 00:09 上传
* 之后在子设备栏里添加4个子设备,当然,子设备的数量取决于主设备有多少路控制IO,这些子设备的ID会在之后编程中用到:
微信截图_20200108001109.png (52.23 KB, 下载次数: 0)
2020-1-8 00:11 上传
* 然后我们在手机天猫精灵APP里绑定账号之后,设备里一下子就会多出来4个设备:
* 在天猫精灵里可以给这些子设备设置不同的类型,冰箱,电视,空调啊,可以随意设置,不过设置了什么类型,到时候和天猫精灵语音控制的时候就要说对应的设备类型,比如:“天猫精灵,打开空调”
* 但是如果我想4路开关一起控制,那我就说“天猫精灵,打开万能遥控器”即可。
设置完成后,我们来继续写云平台相关代码:
* 一样的套路,在loop循环中,主要做两件事,定期向服务端发送心跳包,每个循环中收一下消息,再处理一下消息。
void loop() {
// 检测网络是否通畅
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
// 检测是否连接到服务器
if (!client.connected()) {
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
delay(5000);
return;
}
}
// 检测是否需要发送心跳包
if (millis() - lastCheckInTime > postingInterval || lastCheckInTime == 0) {
Serial.println("Send HeartBeat!!");
sendHeartBeat();
}
// 检测是否收到服务器推送
if (client.available()) {
String inputString = client.readStringUntil('\n');
onMessageReceive(inputString);
}
}复制代码
* 发送心跳包的代码:
void sendHeartBeat() {
String msg = "{"M":"checkin","ID":"" + DEVICEID + "","K":"" + APIKEY + ""}\n";
client.print(msg);
lastCheckInTime = millis();
}复制代码
* 处理推送消息的代码:
void onMessageReceive(String msg) {
msg.trim();
Serial.println(msg);
if (msg.startsWith("{") && msg.endsWith("}")) {
DynamicJsonDocument doc(1024);
deserializeJson(doc, msg);
JsonObject obj = doc.as();
String M = obj["M"];
if (M == "say") {
String S = obj["S"];
String C = obj["C"];
int device = 0B1111000;
if (S == "D1160") {
device = 0B1000000;
} else if (S == "D1161") {
device = 0B0100000;
} else if (S == "D1162") {
device = 0B0010000;
} else if (S == "D1163") {
device = 0B0001000;
}
if (C == "play") {
portStatus &= ~device;
} else if (C == "stop") {
portStatus |= device;
}
refreshOutput();
} else if (M == "checkinok") {
portStatus &= 0B1111101;
refreshOutput();
}
}
}复制代码
解释一下消息处理部分的代码:我目前只处理了say和checkinok的消息。
* checkinok消息:由于刚起机连上网的时候,设备并不能马上连接上推送服务,一般要等待几十秒到数分钟才能链接完成,连接成功后云平台会发送checkinok消息,所以收到checkinok消息时,我们把WIFI_LED点亮,表示设备联网成功了。
* say消息:表示设备需要响应命令,两个参数比较重要:C和S,
S表示子设备的id,通过S便可以知道需要操作哪个子设备(为空的话表示操作所有设备)
C表示动作,play表示打开设备,stop表示关闭设备。
当然这些都是我根据串口打印消息内容猜测的,具体情况还要参考天猫精灵和贝壳互联的说明才比较准确。
完整的代码如下,需对应修改DEVICE ID和API KEY:
#include
#include
#include
//============= 此处必须修该============
String DEVICEID = "00000"; // 你的设备编号 ==
String APIKEY = "000000000"; // 设备密码==
unsigned long lastCheckInTime = 0; //记录上次报到时间
const unsigned long postingInterval = 40000; // 每隔40秒向服务器报到一次
const char* host = "www.bigiot.net";
const int httpPort = 8181;
WiFiClient client;
//======插座控制端口=======
const int portNum = 7;
//7个端口分别对应 K1, K2, K3, K4,USB,LED_WIFI, LED_ROUND
char swPorts[portNum] = {14, 12, 13, 4, 16, 0, 3};
//除了USB充电口,其他都是低电平有效
int portStatus = 0B0000110; //7个IO开关
//======================================
// 初始化插板
void initOutputMode() {
for (int i = 0; i < portNum; i++) {
pinMode(swPorts[i], OUTPUT);
}
}
// 根据开关状态刷新IO电平
void refreshOutput() {
int c = 1;
for (int i = portNum - 1; i >= 0; i--) {
digitalWrite(swPorts[i], (c & portStatus) ? HIGH : LOW);
c <<= 1;
}
}
// 中断响应
ICACHE_RAM_ATTR void onKeyClick() {
// 全关的状态全部打开,否则都是全关闭
if ((portStatus & 0B1111000) == 0B1111000) {
portStatus &= 0B0000111;
} else {
portStatus |= 0B1111000;
}
refreshOutput();
}
void initPanelKey() {
attachInterrupt(digitalPinToInterrupt(5), onKeyClick, FALLING);
}
void setup() {
// 设置串口
Serial.begin(115200);
//初始化输出端口
initOutputMode();
refreshOutput();
//初始化按键中断
initPanelKey();
// 设置Wifi
WiFiManager wifiManager;
wifiManager.autoConnect();
}
void loop() {
// 检测网络是否通畅
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
// 检测是否连接到服务器
if (!client.connected()) {
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
delay(5000);
return;
}
}
// 检测是否需要发送心跳包
if (millis() - lastCheckInTime > postingInterval || lastCheckInTime == 0) {
Serial.println("Send HeartBeat!!");
sendHeartBeat();
}
// 检测是否收到服务器推送
if (client.available()) {
String inputString = client.readStringUntil('\n');
onMessageReceive(inputString);
}
}
void onMessageReceive(String msg) {
msg.trim();
Serial.println(msg);
if (msg.startsWith("{") && msg.endsWith("}")) {
DynamicJsonDocument doc(1024);
deserializeJson(doc, msg);
JsonObject obj = doc.as();
String M = obj["M"];
if (M == "say") {
String S = obj["S"];
String C = obj["C"];
int device = 0B1111000;
if (S == "D1160") {
device = 0B1000000;
} else if (S == "D1161") {
device = 0B0100000;
} else if (S == "D1162") {
device = 0B0010000;
} else if (S == "D1163") {
device = 0B0001000;
}
if (C == "play") {
portStatus &= ~device;
} else if (C == "stop") {
portStatus |= device;
}
refreshOutput();
} else if (M == "checkinok") {
portStatus &= 0B1111101;
refreshOutput();
}
}
}
void sendHeartBeat() {
String msg = "{"M":"checkin","ID":"" + DEVICEID + "","K":"" + APIKEY + ""}\n";
client.print(msg);
lastCheckInTime = millis();
}复制代码
基于ESP8266的WiFi排插拆机加装USB调试板,改造成Arduino开发板结束
php与硬件通过wifi对接,基于ESP8266的WiFi排插接入贝壳互联实现天猫精灵控制相关推荐
- android系统wifi控制风扇,(开源)ESP8266改装小风扇,app远程控制+天猫精灵控制...
本帖最后由 bemfa 于 2020-6-16 10:07 编辑 教程 =教程 =教程 =两个ESP8266通过云端实现远程数据交互 教程 =利用天猫精灵控制NodeMCU(ESP8266) f.pn ...
- (含代码)ESP8266+舵机 制作wifi灯控开关(arduino,点灯科技,小爱同学/天猫精灵实现)
目录 项目涉及的主代码 前言 一.环境搭建 二.开发步骤 1.注册点灯科技平台 2.在点灯科技平台注册设备,获取Secret Key 3.在Arduino IDE中编写代码,写入ESP8266 4.编 ...
- 使用ESP8266通过Blinker平台接入天猫精灵控制电视/空调
目录 `演示视频` 1.准备工作 1.1 `原理` 1.2 `使用的硬件以及硬件连接图` 1.3 `开发环境准备` 2.解码空调红外键值 2.1 `把ESP8266红外接收的实例,上传到NodeMCU ...
- 使用ESP8266接入“天猫精灵”控制七彩灯(WS2812)的颜色/亮度-开源
目录 `演示视频` 1.准备工作 1.1 `原理` 1.2 `使用的硬件以及硬件连接图` 1.3 `开发环境准备` `Arduino开发环境` `安装ESP8266的扩展` `安装blinker Ar ...
- ESP8266开发、ESP8266连接阿里云物联网、天猫精灵控制esp8266、esp8266一键配网、智能家居
ESP8266开发.ESP8266连接阿里云物联网.天猫精灵控制esp8266.esp8266一键配网.智能家居 项目介绍 最近会 将arduino IDE开发ESP8266中一些值得记录得部分写下来 ...
- (开源)ESP8266改装小风扇,手机app远程控制+天猫精灵控制
ESP8266改装小风扇,app远程控制+天猫精灵控制 材料准备 拆解风扇 第一 下载ESP8266示例(arduino ide 编程开发) 第二 修改demo例程 关于主题topic 第三 app ...
- 天猫精灵 python_利用天猫精灵控制ESP8266(NodeMCU开发板)arduino ide开发
第一 下载demo例程 下载地址: 点击下载 本demo 是利用arduino IDE开发,关于arduino IDE 的ESP8266环境配置可参考:环境配置: 点击跳转 第二 修改demo例程 需 ...
- ESP8266改装小风扇,手机app远程控制+天猫精灵控制
材料准备 拆解风扇 ESP8266一块 3)3.3继电器一块 主要步骤 1) 下载ESP8266示例(arduino ide 编程开发) 下载地址 2) 修改demo例程 关于主题topic 3) a ...
- 天猫精灵 python_天猫精灵控制ESP8266(Django+micropython)第一节
前几天 有位大哥给我的文章打赏了2块钱的小礼物,让我整整高兴了一整天,让我有动力继续写作,感谢那位大哥. 前面写了很多文字,其实都是为了连接天猫精灵,不然要ESP8266在局域网内自己玩吗? 准备事项 ...
最新文章
- 无向图的最小生成树(prim算法)
- Python 之 matplotlib (七)Scatter
- devexpress chart 柱形图
- Eclipse Android编程快捷键
- MOOON-scheduler核心设计图(初稿)
- python里的resize_Python玩转蔡徐坤
- java 线程池 状态_【Java多线程】线程状态、线程池状态
- mysql 参数化 c_MySQL(16):参数化、封装
- 几位大佬启蒙老师和女神启蒙老师的博客,大家可以多关注下
- gson-2.2.api简单
- java项目上线mysql查询慢_Java Web应用程序在缓慢的MySQL查询中停滞不前
- 【报告分享】中国老龄化社会的潜藏价值系列报告:第三篇章-银发经济的基本盘和新常态.pdf...
- php ajax 懒加载demo,lazyload懒加载,怎么支持ajax获得的新内容?
- iconfont-阿里巴巴矢量图标库使用教程
- 语法分析:自上而下分析
- 谁是 GameFi 3 月最大的赢家| March Monthly Report
- 室内全景图数据集的设计及制作流程
- 邮件群发平台是什么意思?如何选择邮件群发平台
- ZOJ - 3713 In 7-bit 进制转换
- MATLAB 用高斯消元法求解线性方程组
热门文章
- 检测Web浏览器上的内存泄漏
- 实现机器学习的循序渐进指南X——KMeans
- 学习Azure Functions:在Visual Studio 2017中创建Azure Functions
- 读取文本节点_TextRank抽取型文本摘要
- pandas nan判断_【跟着stackoverflow学Pandas】 删除带有NaN的行
- SQLServerAgent 当前未运行,因此无法将此操作通知它。
- c语言 勒让德多项式,2406: C语言习题 求n阶勒让德多项式(示例代码)
- 霍夫变换检测圆c 语言,c++ 霍夫变换检测直线
- 最优阈值生长算法_手淘搜索阈值刻度表:让你更加清楚类目搜索增长的规律
- python df head_在方法()中调用时,Pandas Df.head()不显示?