认识众多玩家高手/拆客/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排插接入贝壳互联实现天猫精灵控制相关推荐

  1. android系统wifi控制风扇,(开源)ESP8266改装小风扇,app远程控制+天猫精灵控制...

    本帖最后由 bemfa 于 2020-6-16 10:07 编辑 教程 =教程 =教程 =两个ESP8266通过云端实现远程数据交互 教程 =利用天猫精灵控制NodeMCU(ESP8266) f.pn ...

  2. (含代码)ESP8266+舵机 制作wifi灯控开关(arduino,点灯科技,小爱同学/天猫精灵实现)

    目录 项目涉及的主代码 前言 一.环境搭建 二.开发步骤 1.注册点灯科技平台 2.在点灯科技平台注册设备,获取Secret Key 3.在Arduino IDE中编写代码,写入ESP8266 4.编 ...

  3. 使用ESP8266通过Blinker平台接入天猫精灵控制电视/空调

    目录 `演示视频` 1.准备工作 1.1 `原理` 1.2 `使用的硬件以及硬件连接图` 1.3 `开发环境准备` 2.解码空调红外键值 2.1 `把ESP8266红外接收的实例,上传到NodeMCU ...

  4. 使用ESP8266接入“天猫精灵”控制七彩灯(WS2812)的颜色/亮度-开源

    目录 `演示视频` 1.准备工作 1.1 `原理` 1.2 `使用的硬件以及硬件连接图` 1.3 `开发环境准备` `Arduino开发环境` `安装ESP8266的扩展` `安装blinker Ar ...

  5. ESP8266开发、ESP8266连接阿里云物联网、天猫精灵控制esp8266、esp8266一键配网、智能家居

    ESP8266开发.ESP8266连接阿里云物联网.天猫精灵控制esp8266.esp8266一键配网.智能家居 项目介绍 最近会 将arduino IDE开发ESP8266中一些值得记录得部分写下来 ...

  6. (开源)ESP8266改装小风扇,手机app远程控制+天猫精灵控制

    ESP8266改装小风扇,app远程控制+天猫精灵控制 材料准备 拆解风扇 第一 下载ESP8266示例(arduino ide 编程开发) 第二 修改demo例程 关于主题topic 第三 app ...

  7. 天猫精灵 python_利用天猫精灵控制ESP8266(NodeMCU开发板)arduino ide开发

    第一 下载demo例程 下载地址: 点击下载 本demo 是利用arduino IDE开发,关于arduino IDE 的ESP8266环境配置可参考:环境配置: 点击跳转 第二 修改demo例程 需 ...

  8. ESP8266改装小风扇,手机app远程控制+天猫精灵控制

    材料准备 拆解风扇 ESP8266一块 3)3.3继电器一块 主要步骤 1) 下载ESP8266示例(arduino ide 编程开发) 下载地址 2) 修改demo例程 关于主题topic 3) a ...

  9. 天猫精灵 python_天猫精灵控制ESP8266(Django+micropython)第一节

    前几天 有位大哥给我的文章打赏了2块钱的小礼物,让我整整高兴了一整天,让我有动力继续写作,感谢那位大哥. 前面写了很多文字,其实都是为了连接天猫精灵,不然要ESP8266在局域网内自己玩吗? 准备事项 ...

最新文章

  1. 无向图的最小生成树(prim算法)
  2. Python 之 matplotlib (七)Scatter
  3. devexpress chart 柱形图
  4. Eclipse Android编程快捷键
  5. MOOON-scheduler核心设计图(初稿)
  6. python里的resize_Python玩转蔡徐坤
  7. java 线程池 状态_【Java多线程】线程状态、线程池状态
  8. mysql 参数化 c_MySQL(16):参数化、封装
  9. 几位大佬启蒙老师和女神启蒙老师的博客,大家可以多关注下
  10. gson-2.2.api简单
  11. java项目上线mysql查询慢_Java Web应用程序在缓慢的MySQL查询中停滞不前
  12. 【报告分享】中国老龄化社会的潜藏价值系列报告:第三篇章-银发经济的基本盘和新常态.pdf...
  13. php ajax 懒加载demo,lazyload懒加载,怎么支持ajax获得的新内容?
  14. iconfont-阿里巴巴矢量图标库使用教程
  15. 语法分析:自上而下分析
  16. 谁是 GameFi 3 月最大的赢家| March Monthly Report
  17. 室内全景图数据集的设计及制作流程
  18. 邮件群发平台是什么意思?如何选择邮件群发平台
  19. ZOJ - 3713 In 7-bit 进制转换
  20. MATLAB 用高斯消元法求解线性方程组

热门文章

  1. 检测Web浏览器上的内存泄漏
  2. 实现机器学习的循序渐进指南X——KMeans
  3. 学习Azure Functions:在Visual Studio 2017中创建Azure Functions
  4. 读取文本节点_TextRank抽取型文本摘要
  5. pandas nan判断_【跟着stackoverflow学Pandas】 删除带有NaN的行
  6. SQLServerAgent 当前未运行,因此无法将此操作通知它。
  7. c语言 勒让德多项式,2406: C语言习题 求n阶勒让德多项式(示例代码)
  8. 霍夫变换检测圆c 语言,c++ 霍夫变换检测直线
  9. 最优阈值生长算法_手淘搜索阈值刻度表:让你更加清楚类目搜索增长的规律
  10. python df head_在方法()中调用时,Pandas Df.head()不显示?