ZK-VIEW快速接入MQTT教程,实现继电器远程开关与DHT11温湿度采集与传输

通过MQTT使用ESP8266实现继电器远程开关与DHT11温湿度采集与传输,通过Arduino烧录,通过ZK-VIEW低代码Web组态平台快速接入,实现大屏可视化。
所有的示例所用到的程序和代码下载链接
链接:
提取码:agc9
ZK-VIEW在线工业组态低代码平台地址:
压缩包内容如下

注意:程序不要放在中文目录下运行,避免出现不必要的异常
话不多说,正式开始
1. 安装 Arduino IDE 开发环境
双击运行: arduino-ide_2.0.4_Windows_64bit.exe
安装好后,打开软件,如图所示

设置中文
File>Preferences>Language

弹出菜单选择中文(简体),点击OK

第一次安装会多次弹出安装软件驱动,一律点击安装

配置Esp8266管理器地址
文件>首选项>其他开发板管理地址> 填入:
http://arduino.esp8266.com/stable/package_esp8266com_index.json


点击确定
安装Esp8266平台


等待下载安装完成,安装完成后会弹出安装成功小窗,如果有Error,请检查网络环境,重新安装

选择对应开发板,依次点击
工具>开发板>esp8266>NodeMCU 1.0(ESP-12E Module)

安装库文件,依次点击
工具>管理库
在弹出窗口的左侧依次输入以下库的名称进行安装
SimpleDHT、PubSubClient、OneWire、EspMQTTClient、Chrono
全部安装完成后,通过USB连接ESP8266开发板,将以下程序复制到程序框中(压缩包中ESP8266芯片程序)
注意修改 wifi名称、密码、mqtt服务器地址
接线原理图
仅控制4路开关 ESP8266源程序
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Chrono.h>
const char* deviceID = "esp1"; // ESP8266板子编号,不同的板子更换编号,即可增加板子测点
const char* ssid = "lazykee";
const char* password = "123456789";
const char* mqtt_server = "192.168.2.2";
const int SWITCH_PINS[] = { 16, 5, 4, 2 };
const int SWITCH_COUNT = sizeof(SWITCH_PINS) / sizeof(SWITCH_PINS[0]);
WiFiClient espClient;
PubSubClient client(espClient);
Chrono switchStatusChrono;
// 更改开关状态并通过 MQTT 发送状态更新
void changeSwitch(int pin, char receivedChar) {
digitalWrite(pin, receivedChar == '0' ? HIGH : LOW);
int pinIndex = -1;
for (int i = 0; i < SWITCH_COUNT; ++i) {
if (SWITCH_PINS[i] == pin) {
pinIndex = i;
break;
}
}
String data = "switch_" + String(pinIndex + 1) + "," + receivedChar + ";";
client.publish((String("zkup/") + deviceID).c_str(), data.c_str());
}
// MQTT 消息回调函数
void callback(char* topic, byte* payload, unsigned int length) {
char receivedChar = (char)payload[0];
String tp = topic;
Serial.println(tp);
for (int i = 0; i < SWITCH_COUNT; ++i) {
if (tp == (String("zkDown/") + deviceID + "/switch_" + String(i + 1))) {
changeSwitch(SWITCH_PINS[i], receivedChar);
break;
}
}
}
// 用于重新连接到 MQTT 服务器的函数
void reconnect() {
while (!client.connected()) {
// 使用 deviceID 作为客户端ID
if (client.connect(deviceID)) {
String subscriptionTopic = String("zkDown/") + deviceID + "/#";
client.subscribe(subscriptionTopic.c_str());
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
// 发送所有开关的状态数据到 MQTT
void sendSwitchStatus() {
String switchData = "";
for (int i = 0; i < SWITCH_COUNT; ++i) {
switchData += "switch_" + String(i + 1) + "," + (digitalRead(SWITCH_PINS[i]) == LOW ? "1" : "0") + ";";
}
client.publish((String("zkup/") + deviceID).c_str(), switchData.c_str());
}
// 设置函数,用于初始化
void setup() {
Serial.begin(9600);
for (int i = 0; i < SWITCH_COUNT; ++i) {
pinMode(SWITCH_PINS[i], OUTPUT);
digitalWrite(SWITCH_PINS[i], HIGH);
}
WiFi.begin(ssid, password);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// 主循环函数
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// 每5秒向 MQTT 发送一次所有开关的状态数据
if (switchStatusChrono.hasPassed(5000)) {
switchStatusChrono.restart();
sendSwitchStatus();
}
}
DHT11温湿度传感器 + 控制4路开关 ESP8266源程序(根据设备自选)
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <SimpleDHT.h>
#include <Chrono.h>
const char* deviceID = "esp1"; // ESP8266板子编号,不同的板子更换编号,即可增加板子测点
const char* ssid = "lazykee";
const char* password = "123456789";
const char* mqtt_server = "192.168.2.2";
const int DHT_PIN = 14;
const int SWITCH_PINS[] = { 16, 5, 4, 2 };
const int SWITCH_COUNT = sizeof(SWITCH_PINS) / sizeof(SWITCH_PINS[0]);
WiFiClient espClient;
PubSubClient client(espClient);
SimpleDHT11 dht11(DHT_PIN);
Chrono dht11Chrono;
Chrono switchStatusChrono;
// 更改开关状态并通过 MQTT 发送状态更新
void changeSwitch(int pin, char receivedChar) {
digitalWrite(pin, receivedChar == '0' ? HIGH : LOW);
int pinIndex = -1;
for (int i = 0; i < SWITCH_COUNT; ++i) {
if (SWITCH_PINS[i] == pin) {
pinIndex = i;
break;
}
}
String data = "switch_" + String(pinIndex + 1) + "," + receivedChar + ";";
client.publish((String("zkup/") + deviceID).c_str(), data.c_str());
}
// MQTT 消息回调函数
void callback(char* topic, byte* payload, unsigned int length) {
char receivedChar = (char)payload[0];
String tp = topic;
Serial.println(tp);
for (int i = 0; i < SWITCH_COUNT; ++i) {
if (tp == (String("zkDown/") + deviceID + "/switch_" + String(i + 1))) {
changeSwitch(SWITCH_PINS[i], receivedChar);
break;
}
}
}
// 用于重新连接到 MQTT 服务器的函数
void reconnect() {
while (!client.connected()) {
// 使用 deviceID 作为客户端ID
if (client.connect(deviceID)) {
String subscriptionTopic = String("zkDown/") + deviceID + "/#";
client.subscribe(subscriptionTopic.c_str());
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
// 发送 DHT11 传感器数据到 MQTT
void sendDHT11Data() {
byte temperature = 0;
byte humidity = 0;
if (dht11.read(&temperature, &humidity, nullptr) != SimpleDHTErrSuccess) {
return;
}
String data = "temp1," + String(temperature) + ";"
+ "temp1," + String(temperature) + ",100;"
+ "hum1," + String(humidity) + ";"
+ "hum1," + String(humidity) + ",200";
client.publish((String("zkup/") + deviceID).c_str(), data.c_str());
}
// 发送所有开关的状态数据到 MQTT
void sendSwitchStatus() {
String switchData = "";
for (int i = 0; i < SWITCH_COUNT; ++i) {
switchData += "switch_" + String(i + 1) + "," + (digitalRead(SWITCH_PINS[i]) == LOW ? "1" : "0") + ";";
}
client.publish((String("zkup/") + deviceID).c_str(), switchData.c_str());
}
// 设置函数,用于初始化
void setup() {
Serial.begin(9600);
for (int i = 0; i < SWITCH_COUNT; ++i) {
pinMode(SWITCH_PINS[i], OUTPUT);
digitalWrite(SWITCH_PINS[i], HIGH);
}
WiFi.begin(ssid, password);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// 主循环函数
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// 每1秒读取一次 DHT11 传感器数据并发送到 MQTT
if (dht11Chrono.hasPassed(1000)) {
dht11Chrono.restart();
sendDHT11Data();
}
// 每5秒向 MQTT 发送一次所有开关的状态数据
if (switchStatusChrono.hasPassed(5000)) {
switchStatusChrono.restart();
sendSwitchStatus();
}
}
点击 →,完成程序上传

如果输出窗口没有红色报错,则上传成功。
2. 启动MQTT服务器(本例程适用emqx)
进入 emqx-5.0.21-windows-amd64\bin 目录
不要在中文网目录下运行该程序

第一次启动,建议适用cmd命令行终端启动:
emqx start
emqx start
如果启动报下列错误
根据自己的版本下载并安装:
ARM64
最新受支持 ARM64 版本的永久链接 X86 最新受支持 x86 版本的永久链接 X64 最新受支持 x64 版本的永久链接。 X64 可再发行程序包包含 ARM64 和 X64 二进制文件。 当 X64 可再发行程序包安装在 ARM64 设备上时,可以通过此包轻松安装所需的 Visual C++ ARM64 二进制文件。
再次运行
emqx start
,出现如下所示,则服务器启动成功
3. 启动ZK-VIEW数据源
运行 zk-view数据源_MQTT_exe执行程序\ZK-VIEW_MQTT.exe
出现如上图所示内容,无报错信息,则连接成功(同时提供了 MQTT Java 源程序,可自行参考)
4. zk-view添加数据源
打开zk-view官方网站
点击开始使用,进入到登录页面
使用手机号,或微信扫码登录
右侧切换到数据源面板,点击内部数据源按钮
点击添加项目,在弹出框中输入信息,点击添加
按照下图顺序,依次点击按钮,在弹出窗口中输入对应的连接信息,默认连接地址:ws://localhost:8111/zkSource
点击左侧新添加的数据源,点击原始点管理
在弹出框中,项目选择框中选择默认主题 zkup/#,
主题可在第三步config下的application.properties中进行添加
,然后点击全选,保存更改。
点击开始连接,如果右侧出现绿色连接成功,并且测点 value有值,则说明数据源连接成功,此时可以关闭该网页。
5. 添加数据源,单点数据绑定
点击导入我的数据源,
如果找不到数据源面板,则点击图纸空白处则会出现
,按照顺序,将数据源进行图纸导入
点击实时数据查看,检查数据状态,并点击保存参考值。
如果不保存参考值,测点绑定时不方便
单点温度、湿度数据绑定,拖拽开始栏 TEXT 文本元素到图纸上,选中文本元素,右侧面板切换到数据面板,点击添加数据绑定
点击测点选择框,选中真实源,找到单点温度点位
zkup/esp1.temp1
,单击选择圆形按钮,弹窗小时候,点击添加按钮 此时点击实时预览,观察数据是否绑定成功

如果由
Text
变为数字,则说明数据更新成功,此时可以用手捂住传感器,观察数据变化

6. 使用Echarts图表,实现趋势曲线绑定显示
顶部功能栏切换到图表,拖拽折线图到画布上并选中折线图。

按照顺序,点击配置,测点选择点击添加,弹出面板勾选
zkup/esp1.temp1_100
100个缓存值的序列数据,最后点击完成

点击
option配置
,弹出代码编辑框

如下图所示,左侧是静态图表数据,右侧是会更新数据的脚本。

点击右侧
复制绑定数据测点代码
,将光标移动到数据更新脚本编辑器中,粘贴代码

将左侧
初始化参数脚本
代码贴入右侧数据更新脚本
,并稍作改造,代码如下

// bindData["mq.zkup/esp1.temp1_100"].value bindData["mq.zkup/esp1.temp1_100"].time
var data = bindData["mq.zkup/esp1.temp1_100"].value;
option = {
xAxis: {
type: 'time'
},
yAxis: {
type: 'value'
},
series: [
{
type: 'line',
data: data
}
]
};
此时点击报错配置,关闭脚本编辑器,点击实时预览,观察曲线变化
7. 实现简单的开关控制
拖拽如图所示的两个图形作为开关按钮,选中开启按钮方框元素,右侧切换到动画,添加动画,添加事件动画

按照如图所示进行选择,到目标数据源停下,进行发送数据脚本编写

发送数据
脚本编辑器内容填写如下,保存更改后,点击添加完成 第一个按钮的开启控制
return {
name: 'MQTT',
data: {
topic: 'zkDown/esp1/switch_1',
value: 1
}
}
关闭按钮的操作和开启按钮内容一致,仅在发送数据脚本中,将1改为0,代码如下
return {
name: 'MQTT',
data: {
topic: 'zkDown/esp1/switch_1',
value: 0
}
}
此时,就完成了按钮的分开控制,可以在实时预览中进行按钮点击测试
8. 实现带有状态同步的单按钮切换开关控制
共享资源搜索按钮,找到两个相同类型,不同颜色的按钮,拖拽红色关闭按钮到画布上
1. 添加状态监听的动画,实现自动按钮切换,多用户同时响应变化
选中红色按钮,添加
补间动画
启动和停止条件都设置为
数据阈值启动、数据阈值停止
,测点选择都选择
zkup/esp1.switch_1
1号开关的状态汇报测点启动条件(图片由红色按钮切换成绿色按钮的条件)写入
x === 1
启动条件(图片由绿色按钮切换成红色按钮的条件)写入
x === 0
执行动作选择图片切换
图片标识,右键共享资源中的绿色按钮,点击
复制图片标识
,粘贴入输入框中点击添加,完成状态变化动画添加,
点击预览,测试上一步添加的开启关闭方框按钮,查看红色按钮的同步变化
2. 添加点击事件,实现单按钮点击切换动画
继续点击
添加动画
选择
事件动画
启动条件和停止条件都设置为
动作条件启动/停止
动作设置,都设置为
鼠标单击
执行动作选择
自定义事件
启动脚本和停止脚本都写入如下代码
const data = {
name: 'MQTT',
data: {
topic: 'zkDown/esp1/switch_1',
// 全局函数获取该开关的当前状态,如果是开的状态,则点击时,发送关闭的信息
value: window.global.source.getData('mq', 'zkup/esp1.switch_1').value === 0 ? 1: 0
}
}
window.global.socket.sendData('mq', data)
window.global.socket.sendData('qy1', data)
点击添加,在预览窗口进行测试
保存图纸,进行云部署后,在多个网页中进行查看同步变化
左键单击保存的图纸,弹出框中开启云部署,保存更新
再次单击保存的图纸,弹出框中出现访问地址,点击,即可远程访问
打开多个页面,观察同步相应

9. 拔掉ESP8266电源,观察设备离线状态标志

至此全部完成,如果在ZK-VIEW使用过程中有问题,欢迎
。ZK-VIEW网站地址:
教程地址:
更多大屏案例:
综合能耗监控分析系统
智慧水务综合管控平台
数字智慧园区监控平台
地铁大数据管理可视化中心
综合能源监控中心
电厂关键区域智能机器人巡检系统
电厂循环水监视系统