当前位置:网站首页>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灯。
参考:
边栏推荐
- 施努卡:视觉定位系统 视觉定位系统的工作原理
- Introduction to data types in MySQL
- Shell pass parameters
- 多项目编程极简用例
- 【SLAM】lidar-camera外参标定(港大MarsLab)无需二维码标定板
- 如何修改表中的字段约束条件(类型,default, null等)
- 自动化测试怎么规范部署?
- 数据分析——seaborn可视化(笔记自用)
- SWC introduction
- Ethernet port &arm & MOS &push-pull open drain &up and down &high and low sides &time domain and frequency domain Fourier
猜你喜欢
WPF effect Article 191 box selection listbox
3.1 rtthread 串口设备(V1)详解
1、工程新建
Alibaba testers use UI automated testing to achieve element positioning
简易博客系统
Cubemx transplantation punctual atom LCD display routine
BUAA calculator (expression calculation - expression tree implementation)
Overview of super-resolution reconstruction of remote sensing images
After five years of testing in byte, I was ruthlessly dismissed in July, hoping to wake up my brother who was paddling
mysql从一个连续时间段的表中读取缺少数据
随机推荐
Brush questions in summer -day3
Pytorch load data
MADDPG的pythorch实现——(1)OpenAI MADDPG环境配置
1、工程新建
Cubemx transplantation punctual atom LCD display routine
Image super-resolution using deep convolutional networks(SRCNN)解读与实现
遥感图像超分辨重建综述
潘多拉 IOT 开发板学习(HAL 库)—— 实验9 PWM输出实验(学习笔记)
Introduction to DeNO
[meisai] meisai thesis reference template
Flask learning and project practice 9: WTF form verification
施努卡:3d视觉检测应用行业 机器视觉3d检测
【Qt5】Qt QWidget立刻出现并消失
C#(三十一)之自定义事件
Ethernet port &arm & MOS &push-pull open drain &up and down &high and low sides &time domain and frequency domain Fourier
Quick sort function in C language -- qsort
【SLAM】ORB-SLAM3解析——跟踪Track()(3)
C language -- structs, unions, enumerations, and custom types
Schnuka: what is visual positioning system and how to position it
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