数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 1181|回复: 19

[家电] 智能家居第二步DIY:MQTT协议远程控制电器

[复制链接]
发表于 2025-9-28 08:18:50 | 显示全部楼层 |阅读模式
第一步传送门:https://www.mydigit.cn/thread-547971-1-1.html
继使用STM32模拟EV1527后,智能家居的DIY进入第二步,使用MQTT协议进行远程遥控继电器通断来控制一个220V设备的开启和关闭。

### 电路:

使用串口屏的E1扩展端口进行继电器的控制

### 成品效果


### 代码实现:

这是一个mqtt连接的测试程序,在此界面之前,已经在开机的界面用下面的语句完成了wifi的连接,SNTP互联网时间获取,以及mqtt服务器的连接:
  1. void init()
  2. {        str ssid;
  3.     str pwd;
  4.     ssid=bind_get("wifissid");  //获取存储的wifi AP的SSID
  5.     pwd=bind_get("wifipass");   //获取存储的wifi密码
  6.     wifi_connect(ssid,pwd);     //wifi连接
  7.     gpio_mode(0,1);        //E1端口 设置成输出模式
  8.     app.setio(0); //E1低电平,继电器关闭
  9. }
复制代码

wifi连接时异步事件,在异步回调之后再依次处理,以下是部分核心代码:
  1. void app.onASYNC(int m){
  2.     if (m==1){
  3.         //已经WIFI连接成功,需要进入下一步:获取互联网时间
  4.         wifi_sntp("ntp.aliyun.com","CST-8");
  5.     }
  6.     if (m==2){
  7.         //获取网络时间OK,在此书写连接服务器的代码
  8.         mqtt_init();    //配置文件初始化
  9.             //mqtt_setv(0,"mqtt://user:pwd@host.com"); //使用自有的mqtt服务器
  10.             mqtt_setv(2,"");//使用SHMICTRL官网提供的免费服务器
  11.             mqtt_connect(); //连接mqtt服务器
  12.     }
  13.     if (m==3){
  14.             //mqtt服务器连接完成
  15.             gopage(2); //直接调整到第2个页面
  16.     }
  17.     super.onASYNC(m);        //调用appbase父类继续处理其他消息
  18. }
复制代码


可以看到连接mqtt服务器后,会跳转的第二个页面,实际效果如下:


在此界面中,点按钮“开关”可以实现继电器的开关,然后界面处于mqtt协议的连接状态,当收到mqtt消息的时候,会将消息显示在左侧的调试消息显示框中,并且对消息命令进行处理:

- RS:读取状态
- S1: 打开继电器
- S0:关闭继电器
- 返回: 0- 继电器当前是关闭状态 1-开启状态

同时,界面中生成一个二维码,对应服务器上的一个URL程序,该程序是PHP编制,使用PHP连接mqtt服务器发送相应的消息,用于控制继电器的开关

本页面完整代码如下:

  1. class app=loadcom(appbase);  //加载全局控制控件
  2. class page=loadcom(page);    //加载页面控制控件
  3. class s1=loadcom(skinwindows);  //加载窗体控件
  4. class m1=loadcom(memo); //左侧的大文本显示控件
  5. class s2=loadcom(skinbutton); //按钮"开"
  6. class s3=loadcom(skinbutton); //按钮"测试发布"
  7. class s4=loadcom(skinbutton); //按钮"返回"
  8. class s5=loadcom(skinbutton); //按钮"清空"
  9. class q1=loadcom(QRcode);     //二维码控件

  10. str retstr= "";  //反馈字符串
  11. str maintopic=""; //主topic
  12. io=0;   //端口状态
  13. void app.onASYNC(int m){
  14.         if (m==200){
  15.                 //收到消息后,如果有反馈字符串,则发布消息,返回反馈字符串
  16.                 if (retstr!=""){
  17.                         mqtt_pub(maintopic,0,retstr); //发布一条消息
  18.                         retstr="";
  19.                 }
  20.         }

  21. }

  22. //mqtt传来的消息命令执行函数
  23. void mqtt_work(str topic,str data){
  24.         if (data=="S1"){
  25.                 gpio_out(0,1); //E1端口高电平
  26.                 retstr="1";    //返回1
  27.                 io=1;
  28.         }
  29.         if (data=="S0"){
  30.                 gpio_out(0,0);  //E1端口低电平
  31.                 retstr="0";     //返回0
  32.                 io=0;
  33.         }
  34.         if (data=="RS"){    //读取继电器状态,也就是E1的端口电平
  35.                 retstr=""+io;
  36.         }
  37.         if (retstr!=""){
  38.                 async_run(200);  //如果有返回信息,则执行异步反馈发送消息
  39.         }
  40. }


  41. void app.onWIFI32(int m){
  42.     //在此书写有关m对应的wifi异步执行结果的处理代码
  43.     str s;
  44.     int msgnum;
  45.         msgnum=wifi_getinfo(2);
  46.     if (m==7){//m==7 表示收到的是mqtt消息事件
  47.                    if (msgnum==6){  //msgnum==6 表示事件是收到mqtt消息
  48.                            //收到消息
  49.                            str topic;
  50.                            str data;
  51.                            int qos;
  52.                            topic=wifi_getinfo(23); //获取消息的topic
  53.                            data=wifi_getinfo(24);  //获取消息的实际内容
  54.                            qos=wifi_getinfo(4);    //获取qos,可以不处理
  55.                            //---在此书写收到的mqtt消息处理
  56.                            s="RECV:"+data+"\r\n";
  57.                            m1.text=m1.text+s; //将收到的消息字符串累加到屏幕左侧的大文本控件,用于显示
  58.                            mqtt_work(topic,data); //处理传来的消息命令
  59.                    }
  60.     }
  61.     super.onWIFI32(m); //调用appbase的父类,继续处理其他的wifi事件
  62. }

  63. void s2.onclick()
  64. {   //返回按钮的点击事件
  65.     gopage(1); //跳到页面1(菜单界面)
  66. }
  67. void s3.onclick()
  68. {   //发布按钮
  69.         mqtt_pub(app.maintopic,0,"testmessage");//发布一条测试消息
  70. }
  71. void s4.onclick()
  72. {   //卡关按钮
  73.         if (s4.text=="开"){
  74.                 s4.text="关";  //点击后改变按钮上显示内容
  75.                 gpio_out(0,1); //E1输出高电平
  76.                 io=1;
  77.         }
  78.         else{
  79.                 s4.text="开";
  80.                 gpio_out(0,0); //E1输出低电平
  81.         io=0;
  82.         }
  83. }
  84. void s5.onclick()
  85. {   //清空按钮
  86.         m1.text="";  //清空大文本控件的显示内容
  87. }
  88. void init(){
  89.         //刚进入页面时的初始化函数
  90.         q1.text="http://shmictrl.com/wifi/shmi-R1.php?id="+getsn(6); //生成二维码的url
  91.         maintopic="shmi-R1/"+getsn(6); //生成mqtt消息的topic
  92. }
  93. init(); //调用init()函数,初始化一些参数
  94. start(); //进入页面的消息循环,处理页面的显示与触摸事件
复制代码


### 内部结构

### 主要BOM:


器件 |说明
---|---
串口屏|SHMICTRL 神秘魔控 ESP32-40ATP
AC电源模块|薄款 25X15mm  220-5V1A
继电器|SRD-05V  5V控制
光耦|PC817C SMD-4P
AC输入座|RT-C14-C0B-AA
AC输出座|DB-F-C3-C
外壳|铝型材外壳,厂家打孔

DIY下来总成本元器件不超过120元,不含PCB和外壳;

下一步:需要书写正式程序,并把多段定时程序加上,这样就可以控制热水器等设备了;
再远一点,将本控制器和前面做的自学习遥控器合并,用于控制各个灯具。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 2家元 +102 收起 理由
不长叶子的树 + 90
jf201006 + 12 謝謝分享

查看全部打赏

发表于 2025-9-28 08:54:27 | 显示全部楼层
MQTT服务器 是自建的吗   什么架构

串口屏  和你前面帖子里的不一样  看来串口屏用得很顺溜了    茶最近在单色屏上调试了一个控制终端  显示范围还是偏小了点






回复 支持 反对

使用道具 举报

发表于 2025-9-28 08:59:34 | 显示全部楼层
装上这个 高大上了
回复 支持 反对

使用道具 举报

发表于 2025-9-28 09:05:40 | 显示全部楼层

好复杂的。。。。先前的远程插座,在本地没任何界面,只有一个按键——还是原来的按键改的。
回复 支持 反对

使用道具 举报

发表于 2025-9-28 09:25:51 | 显示全部楼层
谢谢分享,学习知识。
回复 支持 反对

使用道具 举报

发表于 2025-9-28 09:27:33 | 显示全部楼层

这个用的上吗?
STC12C5A60S2-35I-LQFP44


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-28 09:51:03 | 显示全部楼层
茶壹杯 发表于 2025-9-28 08:54
MQTT服务器 是自建的吗   什么架构

串口屏  和你前面帖子里的不一样  看来串口屏用得很顺溜了    茶最近在 ...

mqtt服务器很容易建啊,找一个阿里云的linux服务器,然后执行:
yum install mosquitto -y
就搞定了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-28 09:55:34 | 显示全部楼层
devcang 发表于 2025-9-28 09:05
好复杂的。。。。先前的远程插座,在本地没任何界面,只有一个按键——还是原来的按键改的。 ...

这只是一个验证版本,加上定时,解决我家的热水器问题,开发商给配的热水器太烂,上电加热,断电停止,无节能选项,其实我们就早晨用一下热水,加上定时与远程开关,基本能解决问题;下一步和学习遥控器搞一块,就可以解决全部问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-28 09:57:04 | 显示全部楼层
abc2018zh 发表于 2025-9-28 09:27
这个用的上吗?
STC12C5A60S2-35I-LQFP44

用的是ESP32,这个能联网,经过串口屏语句封装后,基本几十行语句就搞定了,顺便还解决了界面问题
回复 支持 反对

使用道具 举报

发表于 2025-9-28 11:02:54 | 显示全部楼层
路过~进来学习一下
回复 支持 反对

使用道具 举报

发表于 2025-9-28 11:44:42 | 显示全部楼层
学习知识,谢谢分享。
回复 支持 反对

使用道具 举报

发表于 2025-9-28 13:12:38 | 显示全部楼层
apachectl 发表于 2025-9-28 09:51
mqtt服务器很容易建啊,找一个阿里云的linux服务器,然后执行:
yum install mosquitto -y
就搞定了 ...

服务器每年都要交钱。
回复 支持 反对

使用道具 举报

发表于 2025-9-28 16:05:24 | 显示全部楼层
一看就是大佬
回复 支持 反对

使用道具 举报

发表于 2025-9-28 16:07:06 | 显示全部楼层
九都多平 发表于 2025-9-28 13:12
服务器每年都要交钱。

建家里就行,我就是建在路由器上的,电话问联通要了外网IP,
再用免费的3322动态域名
回复 支持 反对

使用道具 举报

发表于 2025-9-28 17:23:42 | 显示全部楼层
可惜只有开和关,想要那种卷闸门控制的,估计复杂多了!
回复 支持 反对

使用道具 举报

发表于 2025-9-28 22:33:47 | 显示全部楼层
就一个esp32来控制?
回复 支持 反对

使用道具 举报

发表于 2025-9-28 23:19:37 来自手机浏览器 | 显示全部楼层
这个是大佬建的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-29 08:55:04 | 显示全部楼层
九都多平 发表于 2025-9-28 13:12
服务器每年都要交钱。

一台服务器可以装很多不同的服务,一年千把块,还可以吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-29 08:56:23 | 显示全部楼层
lzj504 发表于 2025-9-28 17:23
可惜只有开和关,想要那种卷闸门控制的,估计复杂多了!

不复杂,mqtt协议可以远程控制;卷帘门一般也是315或者433Mhz遥控的,因此结合第一步的项目,应该是很容易控制的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-11-14 16:59 , Processed in 0.124800 second(s), 9 queries , Gzip On, Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表