当前位置: 首页 > news >正文

使用虚拟机Ubuntu搭建mosquito服务器 使esp32、上位机通信

一、安装Ubuntu系统

安装的是服务器版本,占用资源较少。

下载地址https://pan.baidu.com/s/1ooi2Aj0Q_R3rVWyvgnz1Tw?pwd=5278我们需要使用FinalShell,一个SSH客户端,可以通过SSH连接我们的Linux系统。

不过记得,要在系统初始化勾选使用SSH功能。

二、网络设置

本文使用 NAT + 端口转发,这样设置的好处就是我们无需知道虚拟机的ip地址,只需要知道主机的ip地址就可以,ip地址是固定的,不需要频繁更改。

这里有一个比较大的坑,因为我在学校使用校园网,主机是一个校园网公有地址。因为我们使用NAT+端口转发的模式,所以消息会率先到达这个地址,但是校园网一般会有防火墙,也就是对陌生的连接请求,会拒绝掉。也就是说我们无法在主机上,使用校园网,

我使用的是手机热点,主机连接到手机热点。这时候主机会被分配一个私有ip,这时候又有一个问题了。如果服务器搭建在私有地址上,那么只有跟他位于一个网络下的设备才可以访问到,也就是说我们需要将esp32连接到手机热点上,才可以访问这个服务器。

三、搭建mosquito服务器

之前勾选系统初始化的mosquito下载,是snap下载的,与传统的管理工具apt有些差别,不太好用,所以下面的指令,都是基于apt下载mosquito的。

1、下载mosquito

sudo apt update && sudo apt install mosquitto mosquitto-clients
  • mosquitto:包含 MQTT 服务器(broker)本体。
  • mosquitto-clients:包含用于测试的客户端工具 mosquitto_pub 和 mosquitto_sub。​

2、配置mosquito

sudo vim /etc/mosquitto/conf.d/default.conf

在配置文件中,确保有以下内容以实现您的需求(允许外部连接并设置认证):

listener 1883 0.0.0.0
allow_anonymous true
password_file /etc/mosquitto/passwd

其中listener非常重要,因为默认情况下,mosquito只会监听本地环回地址下的1883端口。而我们使用NAT+端口转发,也就是消息首先发送到我们的主机ip,再转发到虚拟机ip,这个消息来自于我们主机的ip地址,所以mosquito不会接受。我们需要设置,mosquito监听所有地址的1883端口,这也是第一句代码的意思。

3、创建用户和密码文件

sudo mosquitto_passwd -c /etc/mosquitto/passwd your_username

(将 your_username 替换为您想要的用户名,系统会提示您输入密码)

4、重启服务并验证

sudo systemctl restart mosquitto
sudo systemctl status mosquitto

5、验证安装成功

mosquitto -v

如果安装成功,这次将会显示 Mosquitto 的版本信息和启动日志,而不是 command not found

执行这句代码会有光标一直闪烁,代表这mosquito正在占用命令行,可以尝试用MQTT.fx连接它,会出来相应的连接信息。

输入ctrl + c 会强行中断mosquito程序,我们可以让mosquito作为守护进程在后台运行。

mosquitto -d

四、连接esp32和上位机

1、esp32

下面是我的下位机代码,功能是连接WiFi、服务器后,向test/esp32这个主题每三秒发送一个“1111”数据。

#include <WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>
#include <ArduinoJson.h>void connectWifi();
void subscribeTopic();
void pubMQTTmsg();
void receiveCallback(char *topic, byte *payload, unsigned int length);
void connectMQTTserver();
void tickerCount();
String createJson();// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char *ssid = "zzzz";
const char *password = "12345678";
const char *mqttServer = "192.168.136.55";
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
Ticker ticker;
int count = 0; // Ticker计数用变量// ****************************************************
// 注意!以下需要用户根据然也物联平台信息进行修改!否则无法工作!
// ****************************************************
const char *mqttUserName = "han";                                                                                                                     // 服务端连接用户名(需要修改)
const char *mqttPassword = "123456"; // 服务端连接密码(需要修改)
const char *clientId = "ESP32";                                                                                                                           // 客户端id (需要修改)
const char *subTopic = "test/mqtt_fx";                                                                                        // 订阅主题(需要修改)
const char *pubTopic = "test/esp32";                                                                                       // 订阅主题(需要修改)
const char *willTopic = "/broadcast/h9sj0dFIZzO/test1";                                                                                                      // 遗嘱主题名称(需要修改)
// ****************************************************// 遗嘱相关信息
const char *willMsg = "esp8266 offline"; // 遗嘱主题信息
const int willQos = 0;                   // 遗嘱QoS
const int willRetain = false;            // 遗嘱保留const int subQoS = 1;            // 客户端订阅主题时使用的QoS级别(截止2020-10-07,仅支持QoS = 1,不支持QoS = 2)
const bool cleanSession = false; // 清除会话(如QoS>0必须要设为false)bool ledStatus = HIGH;void setup()
{Serial.begin(115200);          // 启动串口通讯ticker.attach(1, tickerCount); // Ticker定时对象// 设置ESP8266工作模式为无线终端模式WiFi.mode(WIFI_STA);// 连接WiFiconnectWifi();Serial.println(ESP.getChipModel());// 设置MQTT服务器和端口号mqttClient.setServer(mqttServer, 1883);mqttClient.setCallback(receiveCallback);// 连接MQTT服务器connectMQTTserver();
}void loop()
{// 如果开发板未能成功连接服务器,则尝试连接服务器if (!mqttClient.connected()){connectMQTTserver();Serial.println("正在重连");}if (count >= 3){pubMQTTmsg(); // 每隔3秒钟发布一次信息count = 0;}// 定期发送心跳 检查服务器回复的心跳//如果有订阅主题的消息到达 触发回调函数mqttClient.loop();delay(10);
}
// 计时器
void tickerCount()
{count++;
}
// 连接MQTT服务器并订阅信息
void connectMQTTserver()
{if (mqttClient.connect(clientId, mqttUserName,mqttPassword)){Serial.print("MQTT Server Connected. ClientId: ");Serial.println(clientId);Serial.print("MQTT Server: ");Serial.println(mqttServer);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);if ((char)payload[0] == '1'){ // 如果收到的信息以“1”为开始ledStatus = LOW;}else{ledStatus = HIGH;}pubMQTTmsg();
}// 订阅指定主题
void subscribeTopic()
{// 通过串口监视器输出是否成功订阅主题以及订阅的主题名称// 请注意subscribe函数第二个参数数字为QoS级别。这里为QoS = 1if (mqttClient.subscribe(subTopic, subQoS)){Serial.print("Subscribed Topic: ");Serial.println(subTopic);}else{Serial.print("Subscribe Fail...");}
}// 发布信息
void pubMQTTmsg()
{char *pubMessage1 = "{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"number\":{\"value\":2}}}";String jsonStr = createJson(); // 保持String对象存活const char *pubMessage2 = jsonStr.c_str();const char * pubMessage = "1111";// 实现ESP8266向主题发布信息if (mqttClient.publish(pubTopic, pubMessage)){Serial.println("Publish Topic:");Serial.println(pubTopic);Serial.println(pubMessage);}else{Serial.println("Message Publish Failed.");}
}// 根据时间动态创建Json
// 1~100
String createJson()
{DynamicJsonDocument doc(1024);doc["id"] = "123";doc["version"] = "1.0";JsonObject params = doc.createNestedObject("params");JsonObject number = params.createNestedObject("number");static int num = 0;if (count >= 3){num++;num %= 100;}number["value"] = num;String result;serializeJson(doc, result);return result;
}// 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("");
}

这是程序运行起来的样子,可以发现,连接成功,发送也成功了。

2、上位机

这时候没有编写上位机程序,用MQTT.fx,来充当一个上位机。

MQTT.fx出现了些问题,就先不展示连接参数了。

因为我们设置的可以匿名连接,所以只要服务器ip地址和端口没有输错就可以。

这是MQTT.fx收到esp32发来消息的截图。

这是MQTT.fx发送给esp32消息的截图。

可以发现esp32收到了来自上位机发来的消息。

至此,我们打通了下位机 MQTT 上位机 数据传输 的通路。


文章转载自:

http://qToR4TLl.gyfwy.cn
http://bwrRq2nv.gyfwy.cn
http://vdgiWTmX.gyfwy.cn
http://W0IKng3x.gyfwy.cn
http://SDN1OgeH.gyfwy.cn
http://woIIOpsO.gyfwy.cn
http://DAWNc48z.gyfwy.cn
http://Yqixhdem.gyfwy.cn
http://ZT8IlQ81.gyfwy.cn
http://DKFfsHGk.gyfwy.cn
http://FI3Q4gGH.gyfwy.cn
http://Ukcd4aJR.gyfwy.cn
http://GcHffYwh.gyfwy.cn
http://u6JC8tap.gyfwy.cn
http://b2HNJda5.gyfwy.cn
http://dXHbVNPX.gyfwy.cn
http://PljHuqFR.gyfwy.cn
http://UtCfHR0O.gyfwy.cn
http://RiqBiJjx.gyfwy.cn
http://ZqjkNHs8.gyfwy.cn
http://mqvvyBSK.gyfwy.cn
http://qoRQ6BUJ.gyfwy.cn
http://f4fSaStY.gyfwy.cn
http://GDV0HDDk.gyfwy.cn
http://6SvcN69X.gyfwy.cn
http://FOGmNbxc.gyfwy.cn
http://3zBlpJyJ.gyfwy.cn
http://WfBg82Xe.gyfwy.cn
http://QjouUnu5.gyfwy.cn
http://46c1lGUB.gyfwy.cn
http://www.dtcms.com/a/374789.html

相关文章:

  • 云计算技术栈
  • 国产时序数据库选型指南-从大数据视角看透的价值
  • 东京本社招聘 | 财务负责人 多个日本IT岗位(Java/C++/Python/AWS 等),IT营业同步招募
  • AWS ALB 详解:智能流量调度器
  • Django REST框架:ModelViewSet全面解析
  • 基于Centos7.9搭建svn服务端
  • PyTorch 和nn.Conv2d详解
  • pytorch基本运算-分离计算
  • 基于容器化云原生的 MySQL 及中间件高可用自动化集群项目
  • “图观”端渲染场景编辑器
  • 构建分布式京东商品数据采集系统:基于 API 的微服务实现方案
  • HTML5点击转圈圈 | 深入了解HTML5技术中的动态效果与用户交互设计
  • springboot rabbitmq 延时队列消息确认收货订单已完成
  • CString(MFC/ATL 框架)和 QString(Qt 框架)
  • Sklearn(机器学习)实战:鸢尾花数据集处理技巧
  • 工具框架:Scikit-learn、Pandas、NumPy预测鸢尾花的种类
  • AI GEO 优化能否快速提升网站在搜索引擎的排名?​
  • nvm和nrm的详细安装配置,从卸载nodejs到安装NVM管理nodejs版本,以及安装nrm管理npm版本
  • 对口型视频怎么制作?从脚本到成片的全流程解析
  • 从“能说话”到“会做事”:AI Agent如何重构日常工作流?
  • 洛谷 P1249 最大乘积-普及/提高-
  • 小红书获取笔记详情API接口会返回哪些数据?
  • JAVA Spring Boot maven导入使用本地SDK(jar包)
  • Linux/UNIX系统编程手册笔记:SOCKET
  • F5和Nginx的区别
  • 9.9网编简单TCP,UDP的实现day2
  • Day39 SQLite数据库操作与HTML核心API及页面构建
  • Vue3 与 AntV X6 节点传参、自动布局及边颜色控制教程
  • 线程与进程的区别
  • RAC概念笔记