myiot.pages.dev Open in urlscan Pro
2a06:98c1:3121::3  Public Scan

URL: https://myiot.pages.dev/
Submission: On December 06 via api from US — Scanned from NL

Form analysis 0 forms found in the DOM

Text Content

智能家居项目


一.智能家居设计思路




二.系统方案设计




三.系统框架

系统框架分为:感知层,传输层,应用层







四.硬件篇


准备工作

硬件:MCU(STC89C52/STM32)及USB线、esp8266-01s(wifi模块),温湿度传感器(DHT11),CH340模块(板载)

软件:emqx、keil、cubemax,串口调试助手,ISP下载工具,微信小程序开发者,

链接地址:https://mqttx.app/zh


硬件接线





 



DHT11引脚

接线:

 * 1VCC --- 外接3.3V-5V

 * 2GND--- 外接GND

 * 3DATA --- 接单片机O口(51单片机IO口,STM32开发板接PG11)




4.1DHT11温湿度模块

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。该传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连。



DHT11工作时序




4.2ESP8266-01S模块


1.模块简介

1.1简介

 * Esp8266(NodeMCU)是一款集成了Wifi功能的MCU开发板,可以直接连接wifi,开发环境多元化,也是表较受欢迎的物联网芯片。

 * ESP8266是一款高性能的WIFI串口模块,内部集成MCU能实现单片机之间串口通信,是目前使用最广泛的一种WIFI模块之一。可以简单理解为一个WIFI转串口的设备,不用知道太多WIFI相关知识,只需要知道串口怎么使用就可以。

1.2ESP8266的开发环境:

  1、AT指令开发,开发简单,只需知道AT指令集,以及它的通信方式即可,但是需要MCU与其通信,不能独立完成某项功能,烧录过程相对与其它开发方式来说比较麻烦。
  2、使用lua脚本进行开发,NodeMCU本质也是ESP8266,只是它的固件是与lua脚本语言交互,可以节省资源,开发简单,代码量少,但是lua解释器执行效率较低。
  3、Arduino IDE开发,使用C语言进行编程,集编程和烧录一体,并且还有许多的库函数可以使用。Arduino
IDE相对lua需要写的带代码较长。如果要查看底层的代码,表较麻烦,不容易查看。   4、VS Code 配置Arduino开发环境,可以在VS Code
进行编程和烧录,使用快捷键一键烧录,使用方便,并且还自带代码补全功能,还可以很方便的查看底层原代码,推荐使用这种方式。

1.3开发方式

 * ESP8266系列一般具有两种开发方式:AT指令开发和SDK开发。

 * AT指令:厂家出厂时预先在ESP8266芯片烧入好固件,封装好WiFi的协议栈,内部已经实现透传,而用户只需要使用一个USB转TTL的模块或者单片机的串口就能实现与WiFi模块的通信,发送AT指令来对WiFi模块进行控制。(和蓝牙透传模块类似)

 * SDK开发:由于ESP8266本身即是可编程的芯片,可以把它视为一个带有无线通信的单片机,而用户需要在专门的IDE中编写对应的程序,然后通过烧写固件的方式将程序写入到芯片中,因此,想要实现WiFi通信,需要自定义WiFi协议栈,对用户掌握的相关知识要求更高。


2.AT指令

2.1AT指令类型

AT指令类型:

AT测试指令:AT

AT配置指令:AT+cmd=<值>

AT查询指令:AT+cmd?



注:需要模块升级

TXD-U --- RXD

RXD-U --- TXD

GND --- IO0 --升级的时候需要连接

5V --- 3V3

GND --- GND

2.2常用指令

​x


1

恢复出厂设置 AT+RESTORE 

2

测试模块 AT 

3

关闭回显 ATE0

4

查看版本信息AT+GMR

5

复位模块状态 AT+RST

6

设置客户端模式

7

AT+CWMODE=1 客服端 Station

8

AT+CWMODE=2 服务端 AP

9

AT+CWMODE=3 双端模式

10

查看附近无线网络 AT+CWLAP

11




12

连接WIFI AP

13

AT+CWJAP="wifi名","密码"

14

获取ip地址 AT+CIFSR

15




16

查询网络连接状态 AT+CIPSTATUS

17

开启传透模式 AT+CIPMODE=1

18

关闭穿透模式 AT+CIPMODE=0

19




20

AT+UART=9600,8,1,0,0 设置波特率

21

 

22

UDP连接

23

AT+CIPSTART="UDP","目标IP",目标端口号,本机端口号,0

24

如:AT+CIPSTART="UDP","192.168.1.1",8080,9000,0

25

 

26

TCP连接

27

AT+CIPSTART="TCP","目标IP",目标端口号

28

如:AT+CIPSTART="TCP","192.168.1.1",8080

29

 

30

开启发送 AT+CIPSEND

31

指定发送长度 AT+CIPSEND=num

32

退出发送 +++




2.3MQTT方法发送数据到服务器全流程指令

xxxxxxxxxx

14


1

连接MQTT服务器服务器

2

1.  AT 测试指令

3

2.  AT+RST 复位

4

3.  AT+CWMODE=1 客户端模式

5

4.  AT+CWJAP="wifi名","密码"

6

    eg.AT+CWJAP="iPhone13_yxq","15270910076"

7

5.  AT+MQTTUSERCFG=0,1,"STC89C52","espressif","1234567890",0,0,"" MQTT配置信息

8

6.  AT+MQTTCONN=0,"43.138.234.120",1883,0 连接MQTT服务器地址

9

7.  AT+MQTTSUB=0,"/mcu/sub",1  订阅主题topic

10

8.  AT+MQTTPUB=0,"/mcu/pub","\{\"beep\":0\}",1,0 推送主题topic

11




12

接收到订阅的topic

13

+MQTTSUBRECV:0,"/mcu/sub",26,{"target":"led","value":1}

14

接收到的标志,




2.4UDP方法发送数据到服务器全流程指令

xxxxxxxxxx

14


1

连接服务器

2

1.  AT+CWMODE=1 客服端

3

2.  AT+CIPMODE=1 透传模式1

4

3.  AT+CWJAP="wifi名","密码"

5

4.  AT+CIFSR 获取ip地址

6

5.  AT+CIPSTART="UDP","目标ip地址",目标端口,8266端口默认9000,0

7

发送数据有两种方法

8

一  1.   AT+CIPSEND (开启传输数据)

9

    2.  >  (这个符号代表等待输入,回车发送,在程序里用\r\n转义发送)

10

    3.  +++  (发送+++代表退出发送,串口助手里需要关闭发送新行才能关闭发送,程序里用+++\r\n关闭)

11

二  1.  AT+CIPSEND=num (指定发送数据长度,由于指定长度,达到长度后会自动发送,并退出发送)

12

    2.  >  (这个符号代表等待输入,回车发送,在程序里用\r\n转义发送)

13

 

14

多次发送只需要循环发送数据方法




2.5TCP方法发送数据到服务器全流程指令

xxxxxxxxxx

12


1

连接服务器

2

1.  AT+CWMODE=1 客服端

3

2.  AT+CIPMODE=0 透传模式0

4

3.  AT+CWJAP="wifi名","密码"

5

4.  AT+CIFSR 获取ip地址

6

5.  AT+CIPSTART="TCP","目标ip地址",目标端口

7

发送数据有两种方法

8

一  1.   AT+CIPSEND (开启传输数据)

9

    2.  >  (这个符号代表等待输入,回车发送,在程序里用\r\n转义发送)

10

    3.  +++  (发送+++代表退出发送,串口助手里需要关闭发送新行才能关闭发送,程序里用+++\r\n关闭)

11

二  1.  AT+CIPSEND=num (指定发送数据长度,由于指定长度,达到长度后会自动发送,并退出发送)

12

    2.  >  (这个符号代表等待输入,回车发送,在程序里用\r\n转义发送)




2.6.STC89C516操作ESP8266-01S

总结:上面讲的都是AT指令,真正应用都要在STC89C51中,STC89C51连接ESP8266也是使用串口发送AT指令,与串口助手用法是一样的。

具体实现看下面代码

STC89C516通过串口发送AT指令需要在最后加"\r\n"(0x0D 0x0A)作为回车

2.7 模块测试以及程序设计

xxxxxxxxxx

16


1

1、升级固件,升级到MQTT库文件

2

2、修改默认波特率115200,修改成9600,51单片只能配置成9600

3

3、按照MQTT连接方式进行连接

4

    AT 测试指令

5

    AT+RST 复位

6

    AT+CWMODE=1 客户端模式

7

    AT+CWJAP="wifi名","密码"

8

    eg.AT+CWJAP="iPhone13_yxq","15270910076"

9

    AT+MQTTUSERCFG=0,1,"STC89C52","espressif","1234567890",0,0,"" MQTT配置信息

10

    AT+MQTTCONN=0,"43.138.234.120",1883,0 连接MQTT服务器地址

11

    AT+MQTTSUB=0,"/mcu/sub",1  订阅主题topic

12

    AT+MQTTPUB=0,"/mcu/pub","\{\"beep\":0\}",1,0 推送主题topic

13

4、emqx软件测试

14

链接地址:https://mqttx.app/zh

15

    上行数据和下行数据的测试

16

    Topic




 


五.服务器篇

1.MQTT协议特点

概念:MQTT(Message Queuing Telemetry
Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

特点: MQTT协议运行在TCP/IP或其他网络协议,提供有序、无损、双向连接。其特点包括:

 * 使用的发布/订阅消息模式,它提供了一对多消息分发,以实现与应用程序的解耦。

 * 对负载内容屏蔽的消息传输机制。

 * 对传输消息有三种服务质量(QoS):
   
   * 最多一次,这一级别会发生消息丢失或重复,消息发布依赖于底层TCP/IP网络。即:<=1。
   
   * 最少一次,这一级别会确保消息到达,但消息可能会重复。即:>=1。
   
   * 只有一次,确保消息只有一次到达。即:=1。在一些要求比较严格的计费系统中,可以使用此级别。

 * 数据传输和协议交换的最小化(协议头部只有2字节),以减少网络流量。

 * 通知机制,异常中断时通知传输双方。

2.MQTT协议原理

(1)MQTT实现方式



实现MQTT协议需要:客户端和服务器端
MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
MQTT传输的消息分为:主题(Topic)和负载(payload)两部分
Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)
payload,可以理解为消息的内容,是指订阅者具体要使用的内容

3.MQTT客户端

一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。客户端可以:

 * 发布其他客户端可能会订阅的信息

 * 订阅其它客户端发布的消息

 * 退订或删除应用程序的消息

 * 断开与服务器连接

4 MQTT服务器

MQTT服务器以称为“消息代理”(Broker),可以是一个应用程序或一台设备。它是位于消息发布者和订阅者之间,它可以:

 * 接受来自客户的网络连接

 * 接受客户发布的应用信息

 * 处理来自客户端的订阅和退订请求

 * 向订阅的客户转发应用程序消息

5.搭建自己的MQTT服务器

(1)搭建框图

搭建之前需要在腾讯云服务器上购买一个自己的云服务器(华为云、阿里云、腾讯云、移动云)



(2)当前主流的MQTT服务器代理

 * Mosquitto:https://mosquitto.org/

 * VerneMQ:https://vernemq.com/

 * EMQX:https://www.emqx.io/(本次采用)

(3)云服务器安装EMQX

点击网址连接进入到首页



点击网页左下角切换成中文。



点击立即下载,选择Linux操作系统。



下载安装MQTT,在云服务器中安装后,启动EMQX。

xxxxxxxxxx

12


1

1、配置 EMQX Yum 源 

2




3

curl -s https://assets.emqx.com/scripts/install-emqx-rpm.sh | sudo bash

4




5

2、安装 EMQX 

6




7

sudo yum install emqx -y

8




9

3、启动 EMQX 

10




11

    sudo systemctl start emqx

12







6.服务器开放端口

进入到安全中心,放开端口,增加防火墙放开端口。

(注:每个云服务商不一样,详细见云服务器控制台)

腾讯云服务器如下:



放开以下端口:

EMQX管理界面:18083

ssl:8883 --- 加密通道

Tcp:1883 -- 未加密通道

ws:8083 ---微信小程序

wss:8084 ---微信小程序加密通道

 

7.浏览器登录MQTT管理界面

登录地址:云服务器IP地址:端口号

eg:127.0.0.1:18083

腾讯云服务器地址:http://43.138.234.120:18083/

默认账号密码:admin /public



修改成中文



MQTT服务器测试

连接服务器



订阅默认消息,同时发布消息,显示已接收和已发布则代表测试成功如下图。



8.客户端测试工具

MQTTX

下载方式

链接地址:https://mqttx.app/





 

 

MQTTX软件MQTT协议主题发布/订阅测试

发布主题:/my/sub

订阅主题:/my/Pub

(1)打开软件



(2)订阅主题



向该主题/my/sub发送消息



发送消息hello world情况



 


六.小程序篇


一.注册微信小程序

 * 注册链接地址:https://mp.weixin.qq.com/

点击 “立即注册” 按钮进行注册(右上角)。注册的账号类型可以是订阅号、服务号、小程序以及企业微信,我们选择 “小程序” 即可。



 * 填写注册信息
   
   接着填写账号信息,需要注意的是,填写的邮箱必须是未被微信公众平台注册、未被个人微信号绑定的邮箱,而且每个邮箱仅能申请一个小程序。

激活邮箱之后,选择主体类型为 “个人类型”,并按要求登记主体信息,主体信息提交后不可修改。




二.微信开发者工具

 * 下载的链接地址:

 * https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html



1)新建项目





2)微信小程序页面介绍



3)项目的组成



 

4)页面信息



5)新建页面信息组成

xxxxxxxxxx

5


1

###页面文件具体作用

2

index.js 业务逻辑

3

index.json 页面配置

4

index.wxml 模板文件

5

index.wxss 样式






 * 激活邮箱


三.基本语法

1、基本语法

1)小程序的模板语法约等于vue的模板语法

> xxxxxxxxxx
> 
> 24
> 
> 
> 1
> 
> 1文本渲染
> 
> 2
> 
> {{ msg }}可以执行简单的js表达式
> 
> 3
> 
> {{2+3}}
> 
> 4
> 
> {{msg.length}}
> 
> 5
> 
> 
> 
> 
> 6
> 
> 2条件渲染
> 
> 7
> 
> wx:if=""
> 
> 8
> 
> wx:elif=""
> 
> 9
> 
> wx:else
> 
> 10
> 
> 
> 
> 
> 11
> 
> 3列表渲染
> 
> 12
> 
> wx:for="{{list}}"
> 
> 13
> 
> wx:key="index"
> 
> 14
> 
>     {{item}}
> 
> 15
> 
>     {{index}}
> 
> 16
> 
> 
> 
> 
> 17
> 
> 4自定义列表渲染
> 
> 18
> 
> 定义item与index的名称
> 
> 19
> 
> wx:for="{{list}}}"
> 
> 20
> 
> wx:for-item="myitem"
> 
> 21
> 
> wx:for-index="myidx"
> 
> 22
> 
> {{myidx}}
> 
> 23
> 
> {{myitem}}
> 
> 24

2)导入文件

xxxxxxxxxx

2


1

import { 对象 } from "module";

2

import { connect } from "../../static/mqtt";




3)wxss

xxxxxxxxxx

3


1

微信小程序默认单位是rpx,html默认单位为px

2

750rpx 等于一个屏幕的宽

3

375就是50%的宽




4)事件

xxxxxxxxxx

4


1

bindInput     表单输入时

2

bindconfirm   表单输入确认

3

bindtap       点击时候

4

bindchange    改变时




5)表单的绑定

xxxxxxxxxx

10


1

.wxml文件

2

<input value="{{s1}}" bindinput="inputHd">

3

    

4

.js文件  

5

inputHd(e){

6

 this.setData({s1:e.detail.value})

7

}

8




9

表单的值获取:e.detail.value

10







6)内置的api

xxxxxxxxxx

8


1

#显示提示

2

showToast

3




4

#本地存储

5

wx.setStorageSync(key,value)

6




7

#本地取

8

wx.request 网络请求




7)生命周期

xxxxxxxxxx

4


1

onLoad                      页面加载完毕

2

onShow                      页面显示调用

3

onPullDownRefresh            下拉刷新

4

onReachBottom                触底更新




2、微信小程序内置标签

xxxxxxxxxx

26


1

内置标签:

2




3

(1)view:视图容器,类似div,整体布局使用view搭建框架,原生小程序采用flex布局

4




5

(2)image:图片标签  类似img  src路径,可以相对../   直接绝对   /项目根开始

6




7

(3)text:文本标签  类似span  包裹文字

8




9

页面增加数据

10

Page({

11

  data: {

12

    client: null,//连接的客户端

13

    temp: 23,//温度

14

    humi: 30,//湿度

15

    led: 0,//大灯的状态

16

    beep: 0//蜂鸣器的状态

17

  },

18

    

19

数据的赋值/绑定

20

     this.setData({

21

        //变量名:赋值内容

22

        client:connect('wxs://broker.emqx.io:8084/mqtt')

23




24

    })

25

表单的值获取:

26

event.detail.value   




 

3、微信小程序标题与TABBAR制作

 * iconfont图标下载
   
   阿里巴巴图标:https://www.iconfont.cn/
   
   

 * 小程序标题
   
   xxxxxxxxxx
   
   8
   
   
   1
   
     "window": {
   
   2
   
       "navigationBarBackgroundColor": "#ffffff",
   
   3
   
       "navigationBarTextStyle": "black",
   
   4
   
       "navigationBarTitleText": "单片机智能家居",
   
   5
   
       "backgroundColor": "#eeeeee",
   
   6
   
       "backgroundTextStyle": "light",
   
   7
   
       "navigationStyle": "custom"
   
   8
   
     }
   
   
   

 * tabbar制作

xxxxxxxxxx

13


1

   "tabBar": {

2

    "list": [{

3

      "pagePath": "pages/index/index",

4

      "text": "",

5

      "iconPath": "/image/home.png",

6

      "selectedIconPath": "/image/home_active.png"

7

    },{

8

      "pagePath": "pages/logs/logs",

9

      "text": "",

10

      "iconPath": "/image/user.png",

11

      "selectedIconPath": "/image/user_active.png"

12

    }]

13

  }






4、小程序头部页面制作

wxml文件

xxxxxxxxxx

13


1

<view class="header-container">

2

    <view class="header-title">

3

      <view>空气质量-良</view>

4

      <view>江西赣州</view>

5

    </view>

6

    <view class="header-air">

7

      <view>60</view>

8

      <view>晴</view>

9

    </view>

10

    <view class="header-ad">

11

      <view>今天天气真好,适合远游!</view>

12

    </view>

13

  </view>




wxss文件

xxxxxxxxxx

44


1

.page-container{

2

  /* 外边距 */

3

  margin: 32rpx;

4




5

}

6




7

.head-container{

8

  /* 背景颜色 */

9

  background-color: #44a9f0;

10

  /* 圆角 */

11

  border-radius: 32rpx;

12




13

}

14




15

.head-container .head-title{

16

  display: flex;

17

  /* 分布在两边 */

18

  justify-content: space-between;

19

  /* 字体颜色 */

20

  color: white;

21

  /* 内边距:上下,左右 */

22

  padding: 32rpx 32rpx;

23

}

24




25

.head-container .head-data{

26

  display: flex;

27

  /* 分布在两边 */

28

  justify-content: space-between;

29

  /* 字体颜色 */

30

  color: white;

31

  /* 内边距:上下,左右 */

32

  padding: 0rpx 32rpx;

33

  /* 字体大小 */

34

  font-size: 72rpx;

35




36

}

37




38

.head-container .head-advice{

39

  /* 字体颜色 */

40

  color: white;

41

  /* 内边距:上下,左右 */

42

  padding: 12rpx 32rpx;

43




44

}




5、小程序数据区域制作

wxml文件

xxxxxxxxxx

22


1

 <view class="data-container">

2

    <!-- 温度 -->

3

    <view class="data-card">

4

      <view>

5

        <image class="data-card-icon" src="/image/temp.png" mode="" />

6

      </view>

7

      <view>

8

        <view class="data-card-title">温度</view>

9

        <view class="data-card-data"> {{temp}}°</view>

10

      </view>

11

    </view>

12

     <!-- 湿度 -->

13

    <view class="data-card">

14

      <view>

15

        <image class="data-card-icon" src="/image/humi.png" mode="" />

16

      </view>

17

      <view>

18

        <view class="data-card-title">湿度</view>

19

        <view class="data-card-data"> {{humi}}°</view>

20

      </view>

21

    </view>

22

  </view>




wxss样式

xxxxxxxxxx

34


1

/* 数据样式 */

2

.data-container {

3

  background-color: burlywood;

4

  margin-top: 32rpx;

5

  /*  网格布局 */

6

  display: grid;

7

  justify-content: center;

8

  /* 卡片宽度大小设置 */

9

  grid-template-columns: repeat(auto-fill, 300rpx);

10

  /* 卡片之间间隙 */

11

  grid-gap: 18rpx;

12

}

13




14

.data-container .data-card{

15

  background-color: #fff;

16

  height: 150rpx;

17

  box-shadow:#d6d6d6 0 0 8rpx;

18

  border-radius: 32rpx;

19

  display: flex;

20

  justify-content: space-between;

21

  padding: 16rpx 16rpx;

22

}

23

.data-container .data-card .data-card-icon{

24

  height: 80rpx;

25

  width: 80rpx;

26

  margin-top: 32rpx;

27

}

28




29

.data-container .data-card .data-card-data{

30

  font-size: 48rpx;

31

  font-weight: bold;

32

  margin-top: 32rpx;

33

}

34







6、数据绑定

xxxxxxxxxx

30


1

    <!-- 温度 -->

2

    <view class="data-card">

3

         <!-- 左 -->

4

         <view>  

5

           <!-- icon图片 -->

6

             <image class="data-card-icon" src="/image/temp.png" mode=""/>

7

         </view>

8

         <!-- 右 -->

9

        <view>

10

             <view class="data-card-title">温度</view>

11

             <view class="data-card-value">{{temp}}℃</view>

12

         </view>

13

    </view>

14

 

15

 /**

16

   * 页面的初始数据

17

   */

18

  data: {

19

    //定义一个MQTT客户端

20

    client:null,

21




22

    temp:30,//温度

23

    humi:60,//湿度

24

    led:1,//LED按钮

25

    beep:0//蜂鸣器按钮

26




27

  },

28

  

29

  数据绑定与前端进行交互

30

  定义变量:{{ }} -- 用两对花括号与数据进行绑定。




7、小程序与服务器交互

 * 微信小程序的网络使用



 * MQTT包下载

https://www.emqx.com/zh/mqtt-client-sdk



 * 下载MQTT包文件

下载地址:unpkg.com/mqtt/dist/mqtt.min.js



 * 导入mqtt.js的包

xxxxxxxxxx

3


1

//引入MQTT包文件

2

import {  } from "module";

3

eg:import {  connect } from "../../static/js/mqtt";





四、MQTT 使用

前提:需要导入mqtt包文件至微信小程序。

使用 EMQ X Cloud 提供的 免费公共 MQTT 服务器 作为本次测试的 MQTT 服务器地址,服务器接入信息如下:

1、免费MQTT服务器

 * Broker: broker.emqx.io

 * TCP Port: 1883

 * WebSocket 端口: 8083

 * SSL/TLS Port: 8883

 * WebSocket Secure 端口: 8084
   
    

2、自建腾讯云服务器

 * Broker: www.mqttssl.icu
   
   公网IP:43.138.234.120

 * TCP Port: 1883

 * WebSocket 端口: 8083

 * SSL/TLS Port: 8883

 * WebSocket Secure 端口: 8084
   
    

3、连接MQTT服务器步骤

微信小程序使用 WebSocket 的方式连接到 MQTT 服务器,但连接的 URL 地址中请使用 wxs 协议名称,连接及初始化数据的关键代码:

xxxxxxxxxx

37


1

1、给客户端赋值,给定MQTT服务器地址端口号

2

  that.setData({

3

      //43.138.234.120

4

      //client: connect('wxs://broker.emqx.io:8084/mqtt')

5

      client: connect('wxs://43.138.234.120:8084/mqtt')

6

    })

7

    

8

2、连接回调函数

9

  //连接回调函数

10

    that.data.client.on('connect', function name(params) {

11

      console.log('成功连接到MQTT服务器')

12

      //弹出窗口

13

      wx.showToast({

14

        title: '连接成功',

15

        icon: 'success',

16

        mask: true

17

      })

18

3、订阅主题

19

      //订阅上行数据

20

      that.data.client.subscribe(devicePubTopic, function name(err) {

21

        if (!err) {

22

          console.log("成功订阅上行数据:"+ devicePubTopic)

23

        }

24

      })

25

4、接收订阅的消息

26

    that.data.client.on('message', function name(topic, message) {

27

      console.log(topic)

28

      console.log(message)

29

    })

30

 5、发布消息

31

       that.data.client.publish(mpPubTopic, "open_led", function name(err) {

32

          if (!err) {

33

            console.log("成功下发一条指令:开灯")

34

          }

35

        }

36




37

      )




4、连接MQTT服务器

xxxxxxxxxx

18


1

/**

2

   * 生命周期函数--监听页面显示

3

   */

4

  onShow: function () {

5

    var that = this

6

    //设置连接MQTT服务器的地址和端口号

7

    that.setData({

8

      client:connect('wxs://43.138.234.120:8084/mqtt')

9

    })

10

    //连接MQTT服务器

11

    that.data.client.on('connect',function name(err) {

12

        console.log('成功连接服务器')

13

        //连接成功的弹窗

14

        wx.showToast({

15

          title: '成功连接服务器',

16




17

        })

18

    })




5、订阅主题

xxxxxxxxxx

8


1

    //订阅主题

2

    that.data.client.subscribe('/mcu/pub',function name(err) {

3

        if(!err)

4

        {

5

          console.log('成功订阅主题:/mcu/pub')

6




7

        }

8

    })




6、接收消息

xxxxxxxxxx

15


1

    //接收订阅消息

2

    that.data.client.on('message',function name(topic,message) {

3

      console.log(topic)

4

      //message是一个16进制流

5

      console.log(message)

6

      //把message转换成json

7

      var recData = JSON.parse(message)

8

      console.log(recData)

9

      //设置接收的数据到前端

10

      that.setData({

11

        temp : recData.temp,

12

        humi : recData.humi

13

      })

14




15

    })




7、按键推送消息

xxxxxxxxxx

27


1

 //开关状态,传递值

2

  onledchange(event) {

3

    const that = this

4

    console.log(event.detail.value) //获取按键的值,true,false

5

    const sw = event.detail.value

6

    that.setData({

7

      led: sw

8

    })

9

    //根据开关发送消息至设备

10

    if (sw) {

11

      that.data.client.publish(mpPubTopic, "open_led", function name(err) {

12

          if (!err) {

13

            console.log("成功下发一条指令:开灯")

14

          }

15

        }

16




17

      )

18

    } else {

19

      that.data.client.publish(mpPubTopic, "close_led", function name(err) {

20

          if (!err) {

21

            console.log("成功下发一条指令:关灯")

22

          }

23

        }

24




25

      )

26

    }

27

  },




8、小程序完整代码

1)WXML文件

xxxxxxxxxx

67


1

<!-- index.html -->

2

<view class="page-container">

3

  <!-- 头部 -->

4

  <view class="header-container">

5

    <view class="header-title">

6

      <view>空气质量-良</view>

7

      <view>江西赣州</view>

8

    </view>

9

    <view class="header-air">

10

      <view>60</view>

11

      <view>晴</view>

12

    </view>

13

    <view class="header-ad">

14

      <view>今天天气真好,适合远游!</view>

15

    </view>

16

  </view>

17

  <!-- 数据 -->

18

  <view class="data-container">

19

    <!-- 温度 -->

20

    <view class="data-card">

21

      <view>

22

        <image class="data-card-icon" src="/static/image/temp.png" mode="" />

23

      </view>

24

      <view>

25

        <view class="data-card-title">温度</view>

26

        <view class="data-card-data"> {{temp}}°</view>

27

      </view>

28

    </view>

29

    <!-- 湿度 -->

30

    <view class="data-card">

31

      <view>

32

        <image class="data-card-icon" src="/static/image/humi.png" mode="" />

33

      </view>

34

      <view >

35

        <view class="data-card-title">湿度</view>

36

        <view class="data-card-data"> {{humi}}%</view>

37

      </view>

38

    </view>

39

    <!-- 蜂鸣器 -->

40

    <view class="data-card">

41

      <view>

42

        <image class="data-card-icon" src="/static/image/beep.png" mode="" />

43

      </view>

44

      <view >

45

        <view class="data-card-title">蜂鸣器</view>

46

        <view class="data-card-data"> 

47

          <switch checked="{{beep}}" bindchange="onbeepchange" color="#2A69C7"/>

48

        </view>

49

      </view>

50

    </view>

51

    <!-- 灯 -->

52

    <view class="data-card">

53

      <view>

54

        <image class="data-card-icon" src="/static/image/light.png" mode="" />

55

      </view>

56

      <view >

57

        <view class="data-card-title">灯</view>

58

        <view class="data-card-data"> 

59

        <switch checked="{{led}}" bindchange="onledchange" color="#2A69C7"/>

60

        </view>

61

      </view>

62

    </view>

63

  </view>

64

  <!-- 数据展示 -->

65

  <view id = wx-echart class="echart-container">

66

  </view>

67

</view>




2) WXSS 文件

xxxxxxxxxx

60


1

.page-container {

2

  margin: 36rpx;

3

}

4

/* 头样式 */

5

.header-container {

6

  background-color: #2a69c7;

7

  color: #fff;

8

  border-radius: 24rpx;

9

  padding: 40rpx 48rpx;

10

}

11




12

.header-container .header-air {

13

  display: flex;

14

  justify-content: space-between;

15

  font-size: 64rpx;

16

}

17




18

.header-container .header-title {

19

  display: flex;

20

  justify-content: space-between;

21




22

}

23




24

.header-container .header-ad {

25

  margin-top: 24rpx;

26

  font-size: small;

27

}

28

/* 数据样式 */

29

.data-container {

30

  /* background-color: burlywood; */

31

  margin-top: 32rpx;

32

  display: grid;

33

  justify-content: center;

34

  /* grid-template-columns: auto auto; */

35

  grid-template-columns: repeat(auto-fill, 300rpx);

36

  grid-gap: 18rpx;

37




38

}

39




40

.data-container .data-card{

41

  background-color: #fff;

42

  height: 150rpx;

43

  box-shadow:#d6d6d6 0 0 8rpx;

44

  border-radius: 32rpx;

45

  display: flex;

46

  justify-content: space-between;

47

  padding: 16rpx 16rpx;

48

}

49

.data-container .data-card .data-card-icon{

50

  height: 72rpx;

51

  width: 72rpx;

52

  margin-top: 32rpx;

53

}

54




55

.data-container .data-card .data-card-data{

56

  font-size: 48rpx;

57

  font-weight: bold;

58

  margin-top: 32rpx;

59

}

60







3) JS文件

xxxxxxxxxx

141


1

// index.js

2

import {

3

  echarts

4

} from "../../static/js/echarts";

5




6

const app = getApp()

7




8

//引入MQTT包文件

9

import {

10

  connect

11

} from "../../static/js/mqtt";

12




13

const Host = 'broker.emqx.io' //mqtt服务器

14

const Port = '8084' //mqtt服务器端口

15




16

const deviceSubTopic = '/mcu/sub' //设备订阅Topic (小程序发布命令的Topic)

17

const devicePubTopic = '/mcu/pub' //设备发布Topic (小程序订阅数据的Topic)

18




19

const mpSubTopic = devicePubTopic

20

const mpPubTopic = deviceSubTopic

21




22




23

Page({

24

  data: {

25

    client: null,

26

    temp: 23,

27

    humi: 30,

28

    led: 0,

29

    beep: 0

30

  },

31

  //开关状态,传递值

32

  onledchange(event) {

33

    const that = this

34

    console.log(event.detail.value) //获取按键的值,true,false

35

    const sw = event.detail.value

36

    that.setData({

37

      led: sw

38

    })

39

    //根据开关发送消息至设备

40

    if (sw) {

41

      that.data.client.publish("/mcu/sub", "open_led", function name(err) {

42

          if (!err) {

43

            console.log("成功下发一条指令:开灯")

44

          }

45

        }

46




47

      )

48

    } else {

49

      that.data.client.publish("/mcu/sub", "close_led", function name(err) {

50

          if (!err) {

51

            console.log("成功下发一条指令:关灯")

52

          }

53

        }

54




55

      )

56

    }

57

  },

58




59

  //蜂鸣器

60

    //开关状态,传递值

61

    onbeepchange(event) {

62

      const that = this

63

      console.log(event.detail.value) //获取按键的值,true,false

64

      const sw = event.detail.value

65

      that.setData({

66

        beep: sw

67

      })

68

      //根据开关发送消息至设备

69

      if (sw) {

70

        that.data.client.publish("/mcu/sub", "open_beep", function name(err) {

71

            if (!err) {

72

              console.log("成功下发一条指令:开蜂鸣器")

73

            }

74

          }

75

  

76

        )

77

      } else {

78

        that.data.client.publish("/mcu/sub","close_beep", function name(err) {

79

            if (!err) {

80

              console.log("成功下发一条指令:关蜂鸣器")

81

            }

82

          }

83

  

84

        )

85

      }

86

    },

87




88

    

89

  //事件函数

90

  onShow() {

91

    const that = this

92

    //wxs 实际上就是wss => wss 实际上就是拥有SSL加密的web socket

93

    that.setData({

94

      // client: connect(`wxs://${Host}:${Port}/mqtt`)

95

      client: connect('wxs://broker.emqx.io:8084/mqtt')

96

    })

97

 

98

    //连接回调函数

99

    that.data.client.on('connect', function name(params) {

100

      console.log('成功连接到MQTT服务器')

101

      //弹出窗口

102

      wx.showToast({

103

        title: '连接成功',

104

        icon: 'success',

105

        mask: true

106

      })

107

      //订阅上行数据

108

      that.data.client.subscribe('/mcu/pub', function name(err) {

109

        if (!err) {

110

          console.log("成功订阅上行数据:"+ devicePubTopic)

111

        }

112

      })

113

    })

114




115

    that.data.client.on('message', function name(topic, message) {

116

      console.log(topic)

117

      console.log(message)

118

      //message 是16进制的buffer字节流

119

      let dataFormdev = {}

120

      try {

121

        //解析16进制数据

122

        dataFormdev = JSON.parse(message)

123

        console.log(dataFormdev)

124

        //赋值语句

125

        that.setData({

126

          temp: dataFormdev.temp,

127

          humi: dataFormdev.humi,

128

          led: dataFormdev.led,

129

          beep: dataFormdev.beep

130

        })

131




132

      } catch (error) {

133

        console.log('json解析失败', error)

134




135

      }

136

    })

137




138

  },

139




140

})

141