描述
本项目展示了通过Machinechat的JEDI Pro仪表板上的虚拟切换开关控制的无线机电继电器。无线继电器硬件由ESP32微控制器板和Seeed Grove继电器组成。ESP32订阅运行在Machinechat JEDI Pro上的MQTT代理的主题,并根据主题值更改Grove继电器的状态。订阅的MQTT主题是JEDI Pro仪表板上虚拟切换开关控件的值。Arduino用于实现ESP32继电器应用程序,JEDI Pro安装并运行在运行Ubuntu Linux的Seeed Odyssey Blue x86迷你PC上。
硬件
- Seeed Odyssey Blue x86迷你PC
四核赛扬J4105迷你PC,配备128GB外部SSD - DFRobot Beetle ESP32C3
Beetle ESP32-C ESP32-C3(版本2)收发器;802.11 a/b/g/n(Wi-Fi,WiFi,WLAN)2.4GHz评估板 - Seeed Grove继电器
机电继电器Grove平台评估扩展板
软件
- JEDI Pro
适用于物联网数据收集、可视化、监控和数据存储的灵活软件,可集成到物联网解决方案中。功能包括:从传感器、设备和机器收集数据;构建直观的实时和历史数据及系统视图仪表板;创建规则以自动监控和响应数据条件;通过电子邮件和短信接收警报通知。 - Arduino
Arduino是一个基于易用硬件和软件的开源电子平台。
背景
Machinechat JEDI Pro是物联网应用软件,能够从多个来源收集数据,包括HTTP、串行、LoRaWAN、MQTT和内部。收集的数据可以通过运行在JEDI上的MQTT代理进行可视化、存储、操作和访问。JEDI MQTT主题包括从任何来源(不仅仅是MQTT)进入JEDI的所有数据。
在3.1版本中,JEDI引入了向数据仪表板添加控件的能力。通过控件,用户可以通过仪表板图形输入一个值,然后将其保存到预定义的数据指标中。生成的数据指标可以通过运行在JEDI上的MQTT代理访问(参见Machinechat文章《向数据仪表板添加控件》)
实现
本项目使用Beetle ESP32C3模块和Grove机电继电器板实现支持WiFi的继电器。使用Arduino PubSub库在ESP32模块上实现MQTT客户端。ESP32客户端订阅JEDI上的虚拟切换开关值,并根据开关值更改继电器的状态(打开/关闭)。
以下原理图和相关BOM可在Scheme-it项目链接BeetleESP32relay中访问。
设置基于 ESP32 的 WiFi 继电器 Arduino 应用程序
1 - 在Beetle ESP32C3模块上设置Arduino。参见链接Beetle ESP32C3 Wiki链接
2 - 安装应用程序所需的库。通过Arduino的库管理器添加这些库:
3 - 代码讲解 (文件名: BeetleESP32cMqttRelay1.ino)
连接到WiFi网络,连接到JEDI MQTT代理并解析JSON MQTT消息
/*
WiFi/MQTT enabled relay example implemented on DFRobot Beetle ESP32C3
filename: BeetleESP32cMqttRelay1.ino
project hardware: DFRobot Beetle ESP32C3 board and Seeed Grove Relay board
project function: ESP32 mqtt client connects to the Machinechat MQTT broker and subscribes to multiple topics (including a
virtual toggle switch on the JEDI data dashboard with two states "true" and "false").
The virtual toggle switch value topic is monitored and used to control the state of the relay.
*/
#include "WiFi.h"
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "arduino_secrets.h"
// Update these with values suitable for your network.
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
// MQTT server info for JEDI Pro on Odyssey Ubuntu machine
const char* mqttServer = "192.168.1.23";
const int mqttPort = 1883;
StaticJsonDocument<256> doc;
int led = 10;
int data1 = 5; //data1 of MQTT json message
int data2 = 5; //data2 of MQTT json message
int data3 = 5; //data3 of MQTT json message
int data4 = 5; //data3 of MQTT json message
bool button = true; //boolean variable of MQTT message
int msg = 0;
const char* timestamp = "dummy data"; //the is the MQTT message timestamp (this works)
String recv_payload;
const char* subtopic1 = "datacache/Button1boolean"; //test button control
const char* subtopic2 = "datacache/SeeedLoRaE5sensorTwo"; //LoRaE5 temp humidity sensor
const char* subtopic3 = "datacache/A84041F1B186136D"; //LHT65N garage temp humidity sensor
// wio terminal wifi
// Beetle esp32c3 wifi
WiFiClient wclient;
PubSubClient client(wclient); // Setup MQTT client
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
// mqtt message callback
void callback(char* topic, byte* payload, unsigned int length) {
//print out message topic and payload
Serial.print("New message from Subscribe topic: ");
Serial.println(topic);
Serial.print("MQTT payload length = ");
Serial.println(length);
Serial.print("Subscribe JSON payload: ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]); // print mqtt payload
//if payload[i] == "t"
}
Serial.println();
msg = 1; //set message flag = 1 when new subscribe message received
//check subscribe topic for message received and decode
//********************************//
//if message from topic subtopic1
//********************************//
if (strcmp(topic, subtopic1)== 0) {
Serial.print("decode payload from topic ");
Serial.println(topic);
deserializeJson(doc, (const byte*)payload, length); //parse MQTT message
button = doc["value"]; // boolean button value
Serial.print("Button boolean value = ");
Serial.println(button);
//control state of relay
if (button == 1)
{
digitalWrite(led, HIGH);
digitalWrite(6, HIGH);
delay(100);
}
else
{
digitalWrite(led, LOW);
digitalWrite(6, LOW);
delay(100);
}
}
//********************************//
//if message from topic subtopic2
//********************************//
if (strcmp(topic, subtopic2)== 0) {
Serial.print("decode payload from topic ");
Serial.println(topic);
deserializeJson(doc, (const byte*)payload, length); //parse MQTT message
data1 = doc["temperature"];
data2 = doc["humidity"]; //
Serial.print("data1 is LoRaE5 temperature = ");
Serial.println(data1);
Serial.print("data2 is LoRaE5 humidity = ");
Serial.println(data2);
}
//********************************//
//if message from topic subtopic3
//********************************//
if (strcmp(topic, subtopic3)== 0) {
Serial.print("decode payload from topic ");
Serial.println(topic);
deserializeJson(doc, (const byte*)payload, length); //parse MQTT message
data3 = doc["TempF"];
data4 = doc["Hum_SHT"];
Serial.print("data3 = TempF = ");
Serial.println(data3);
Serial.print("data4 = Hum_SHT = ");
Serial.println(data4);
}
}
//connect to mqtt broker on JEDI One and subscribe to topics
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a unique client ID using the Wio Terminal MAC address
String MACadd = WiFi.macAddress();
MACadd = "WioTerminal" + MACadd;
String clientID = MACadd;
// Attempt to connect
if (client.connect(clientID.c_str())) {
Serial.println("connected");
// set up MQTT topic subscription note: topic needs to be "datacache/" + Device on JEDI One
Serial.println("subscribing to topics:");
Serial.println(subtopic1);
client.subscribe(subtopic1);
Serial.println(subtopic2);
client.subscribe(subtopic2);
Serial.println(subtopic3);
client.subscribe(subtopic3);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(led,OUTPUT);
//pinMode(7, INPUT); //switch input
pinMode(6, OUTPUT); //relay control input
Serial.begin(115200);
setup_wifi();
client.setServer(mqttServer, 1883); //set mqtt server
client.setCallback(callback);
}
主循环检查是否连接,检查MQTT消息并更新Grove继电器板状态
void loop() {
// try reconnecting to WiFi if not connected
if (WiFi.status() != WL_CONNECTED) {
Serial.println("not connected to WiFi, try reconnecting");
WiFi.disconnect();
delay(5000);
setup_wifi();
}
// check if connected to mqtt broker
if (!client.connected()) {
reconnect();
}
if (msg == 1) { // check if new callback message
msg = 0; // reset message flag
}
Serial.println("debug - in main loop");
delay(1000);
client.loop();
}
4 - Arduino代码订阅MQTT主题时的串口监视器输出示例
在示例Arduino代码中插入了多个Print语句,以帮助调试和代码修改。订阅主题接收到的串口监视器输出示例如下所示。
5 - BeetleESP32cMqttRelay1.ino应用程序的最新源代码在github上的链接如下:
安装 JEDI Pro
如果尚未安装Machinechat JEDI,请参见以下内容:
JEDI MQTT 代理 - 订阅主题
JEDI主题包括从任何来源进入JEDI One的所有数据。在MQTT客户端代码或应用程序中,按如下方式订阅主题:
对于特定的数据流:
datacache/TargetID
其中datacache是JEDI One的固定顶级主题,TargetID 是感兴趣数据流的TargetID或IP地址。
对于此项目示例:
datastream将为datacache/Button1boolean
mqttServer为192.168.1.23
mqttPort为1883
(注意:更多信息请参见Machinechat文章《向数据仪表板添加控件》)
设置 JEDI Pro
1 - 创建控件时,需要创建一个数据指标来保存控件的值。从JEDI 左侧导航面板中选择设备仪表板
2 - 添加数据源
3 - 添加Control JEDI仪表板
4 - 在JEDI仪表板上添加虚拟切换开关
5 - JEDI虚拟切换开关控制示例。
结论
一个灵活且功能强大的WiFi机电继电器可以轻松地通过两个小型开发板实现,即DFRobot BeetleESP32模块和Grove继电器板。WiFi继电器的虚拟切换开关控制是通过JEDI数据仪表板的控制功能和JEDI的MQTT代理实现的。在ESP32上运行的MQTT客户端通过JEDI数据仪表板上的虚拟切换开关控制提供对WiFi继电器的MQTT控制。Machinechat的JEDI物联网数据管理提供对任何收集数据的MQTT访问,以及根据需要进行的额外处理、警报或其他操作。
参考资料
- DFRobot - Beetle ESP32C3 Wiki链接
- Seeed - Grove继电器产品页面
- Seeed - Grove继电器Wiki页面
- 开始使用Machinechat的JEDI One物联网平台
- Arduino - 如何将ArduinoJson与PubSubClient一起使用?
- Machinechat产品指南 - 内置MQTT代理 - 数据收集器
- Machinechat产品指南 - MQTT代理 - 订阅主题
- HIVEMQ - MQTT基础
- Machinechat文章 - 向数据仪表板添加控件







