当前位置:网站首页>ESP32(基于Arduino)连接EMQX的Mqtt服务器上传信息与命令控制
ESP32(基于Arduino)连接EMQX的Mqtt服务器上传信息与命令控制
2022-07-06 03:46:00 【昊月光华】
前言:
EMQX开源版提供了免费的本地的局域网下的mqtt服务器,可以通过订阅主题与发布主题下的信息实现物联网的诸多操作。什么操作?如通过订阅将设备采集的传感器信息转储到本地数据库。通过发布来实现对设备的开关进行控制。
上传信息和命令控制都基于我本地搭建的一个客户端来作为中间枢纽。本地客户端开启一个web的服务并提供了接口访问。
上传信息:
由于我已经在本地写了一个客户端订阅ESP32的发布信息的主题 device/date,esp32每对device/date发布一次信息,客户端收到后就转储到mysql数据库。
命令控制:
esp32订阅esp32/dev/# ,不完全匹配 ,这里的#可以是1,2,3代表esp32的控制器dev1,dev2,dev3(对于esp32外接的led灯,电机,蜂鸣器等等)。这里的控制是最直接的控制,为了达到间接控制比如安卓端,web端控制可通过接口传参数让本地客户端发布esp32/dev/#所对应主题下的信息以此来控制ESP32。
问题:
1:esp32的json数据发送让客户端接收。
参考
Arduino-ESP32中的Json构造与解析_星水瓜瓜的博客-CSDN博客_arduino esp32 json
添加库
#include <ArduinoJson.h>
发送的是以字符串为形式的json数据
StaticJsonDocument<200> sensor_json;
sensor_json["sensor_val"] = hallRead();
sensor_json["sensor_val"] = cnt;
sensor_json["to"] = "starmelon";
String msg;
serializeJson(sensor_json, msg);
2:esp32连接不上emqx的mqtt服务器。
因为是在局域网下,emqx下的mqtt服务器就有其局域网地址,此局域网地址也就是emqx所在主机的ip地址,如果用的是路由器搭建的本地局域网且以IP自动分配的方式,每次都需要改服务器地址,连接手机热点也是一样。
默认域名:"broker-cn.emqx.io" 字符串格式
问题来了,当我用这个默认域名做服务器地址,esp32确实能给设置的主题发消息,但我主机上的poho(一个监听软件)和客户端竟然确收不到消息了。
而只有当我回到最初的状态,使用局域网地址192.168.43.234,esp32能正常工作,poho和客户端也能正常工作。
正常的消息上报
实现:
#include <WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>
#include <ArduinoJson.h>
StaticJsonDocument<200> sensor_json;
String realmsg="";
int LED=2;
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "realme";
const char* password = "12345678";
const char* mqttServer = "192.168.43.246";//本机ip地址
//发布的消息字段
typedef struct {
int msg1;
int msg2;
int msg3;
}msg;
int count=0;//发布消息间隔
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
//------------------全局变量定义-----------------
msg mymsg={123,45,6};//定义消息结构体
Ticker ticker;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
//------------------全局变量定义-----------------
void tickerCount(){//Ticker回调函数
count++;
//数据测试
sensor_json["msg1"] = 12;
sensor_json["msg2"] =21;
sensor_json["msg3"] = 98;
serializeJson(sensor_json, realmsg);
}
void pubmsg( const String &topicString, const String &messageString){
char publishTopic[topicString.length() + 1];
strcpy(publishTopic, topicString.c_str());
char publishMsg[messageString.length() + 1];
strcpy(publishMsg, messageString.c_str());
// 实现ESP8266向主题发布信息
if(mqttClient.publish(publishTopic, publishMsg)){
Serial.println("Publish Topic:");Serial.println(publishTopic);
Serial.println("Publish message:");Serial.println(publishMsg);
} else {
Serial.println("Message Publish Failed.");
}
}
void setup() {
pinMode(LED, OUTPUT); // 设置板上LED引脚为输出模式
digitalWrite(LED, LOW); // 启动后关闭板上LED
Serial.begin(9600); // 启动串口通讯
// Ticker定时对象
ticker.attach(2, tickerCount); //每过2s调用其回调函数
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
// 连接WiFi
connectWifi();
// 设置MQTT服务器和端口号
mqttClient.setServer(mqttServer, 1883);
mqttClient.setCallback(receiveCallback);
// 连接MQTT服务器
connectMQTTserver();
}
void loop() {
if (mqttClient.connected()) { // 如果开发板成功连接服务器
if (count >= 2){
pubmsg("device/date",realmsg);
realmsg="";
count = 0;
}
mqttClient.loop(); // 处理信息以及心跳
} else { // 如果开发板未能成功连接服务器
connectMQTTserver(); // 则尝试连接服务器
}
}
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
// 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
String clientId = "esp8266-" + WiFi.macAddress();
// 连接MQTT服务器
if (mqttClient.connect(clientId.c_str())) {
Serial.println("MQTT Server Connected.");
Serial.println("Server Address:");
Serial.println(mqttServer);
Serial.println("ClientId: ");
Serial.println(clientId);
subscribeTopic(); // 订阅指定主题
} else {
Serial.print("MQTT Server Connect Failed. Client State:");
Serial.println(mqttClient.state());
delay(5000);
}
}
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message Received [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println("");
Serial.print("Message Length(Bytes) ");
Serial.println(length);
int temp=0;
while(*topic){
temp++;
topic++;
}
Serial.println("主题长度:");
Serial.println(temp);
if(temp>11){
if((char)topic[11]=='1'){
if ((char)payload[0] == 'O' && (char)payload[1] == 'F') { // 如果收到的信息以“1”为开始
digitalWrite(LED, LOW); // 则点亮LED。
} else {
digitalWrite(LED, HIGH); // 否则熄灭LED。
}
}
}
}
// 订阅指定主题
void subscribeTopic(){
// 通过串口监视器输出是否成功订阅主题1以及订阅的主题1名称
if(mqttClient.subscribe("device/dev/#")){
Serial.println("Subscrib Topic:");
Serial.println("device/action");
} else {
Serial.print("Subscribe Fail...");
}
// 通过串口监视器输出是否成功订阅主题2以及订阅的主题2名称
}
// ESP8266连接wifi
void connectWifi(){
WiFi.begin(ssid, password);
//等待WiFi连接,成功连接后输出成功信息
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected!");
Serial.println("");
}
效果:
在poho上发布控制信息即可实现控制板载LED灯。
参考:
边栏推荐
- 施努卡:3d视觉检测应用行业 机器视觉3d检测
- Facebook等大厂超十亿用户数据遭泄露,早该关注DID了
- How to modify field constraints (type, default, null, etc.) in a table
- Schnuka: visual positioning system working principle of visual positioning system
- C#(二十八)之C#鼠标事件、键盘事件
- On Data Mining
- Failure causes and optimization methods of LTE CSFB
- The solution of permission denied (750 permissions should be used with caution)
- 2.1 rtthread pin设备详解
- C#(二十九)之C#listBox checkedlistbox imagelist
猜你喜欢
Facebook and other large companies have leaked more than one billion user data, and it is time to pay attention to did
On Data Mining
Edcircles: a real time circle detector with a false detection control translation
Blue style mall website footer code
C mouse event and keyboard event of C (XXVIII)
Remote Sensing Image Super-resolution and Object Detection: Benchmark and State of the Art
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Remote Sensing Image Super-resolution and Object Detection: Benchmark and State of the Art
【SLAM】ORB-SLAM3解析——跟踪Track()(3)
3.1 detailed explanation of rtthread serial port device (V1)
随机推荐
MySQL reads missing data from a table in a continuous period of time
Schnuka: 3D vision detection application industry machine vision 3D detection
The solution of permission denied (750 permissions should be used with caution)
Remote Sensing Image Super-resolution and Object Detection: Benchmark and State of the Art
MySQL 中的数据类型介绍
KS008基于SSM的新闻发布系统
2.2 fonctionnement stm32 GPIO
Facebook and other large companies have leaked more than one billion user data, and it is time to pay attention to did
JVM的手术刀式剖析——一文带你窥探JVM的秘密
Plus d'un milliard d'utilisateurs de grandes entreprises comme Facebook ont été compromis, il est temps de se concentrer sur le did
Align items and align content in flex layout
登录mysql输入密码时报错,ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: NO/YES
Prime protocol announces cross chain interconnection applications on moonbeam
Flask learning and project practice 9: WTF form verification
Cross origin cross domain request
[optimization model] Monte Carlo method of optimization calculation
KS003基于JSP和Servlet实现的商城系统
BUAA喜鹊筑巢
【Qt5】Qt QWidget立刻出现并消失
有条件地 [JsonIgnore]