STM32 + ESP8266 通过固件方式实现MQTT 连接服务器

一、 ESP8266 烧录固件

1.1 烧录

ESP8266中原本的固件是没有MQTT相关的AT指令的,需要通过烧录固件使其支持对应的AT指令。
参考链接:https://blog.csdn.net/qq_43819071/article/details/132111194

2.2 烧录过程中需要注意的问题

烧录之前确保ESP8266的各个引脚必须连接正确,I0必须接地。
3.3V/5V ------ 3.3V/5V
​RX ------ TX
​TX ------ RX
GND ------ GND
I0 ------ GND
在烧录成功之后,拔掉I0接口,使其进去工作模式,通过串口工具测试MQTT的AT指令能否正确连接。

二、STM32连接MQTT服务器

2.1 通过AT指令将ESP8266 设置为客户端

先将STM32 与ESP8266连接的串口初始化。我这里采用的是UART4,连接到的MQTT服务器是巴法云,官网:https://cloud.bemfa.com/,注册后即可正常连接
代码如下:
void Configure_ESP8266_MQTT(void)
{
    rst_wifi();
    delay_ms(500);
    ESP8266_Clear();

//1 AT
    while(ESP8266_SendCmd("AT\r\n\r", "OK", 200))
    {
        printf("AT  Failed\r\n");
    }

    //2 将Wi-Fi模块设置为Station(STA)模式
    while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK", 50))
    {
        printf("STA Failed\r\n");
    }

    //3 连接WIFI的用户名和密码
    while(ESP8266_SendCmd("AT+CWJAP=\"ChinaNet-NrgD\",\"rnq265xq\"\r\n", "OK", 500))
    {
        printf("WIFI Failed\r\n");
    }

    //4 设置MQTT相关属性
    while(ESP8266_SendCmd("AT+MQTTUSERCFG=0,1,\"clientid\",\"username\",\"password\",0,0,\"\"\r\n", "OK", 500))
    {
        printf("MQTT Failed\r\n");
    }

    //5 连接MQTT的ip
    while(ESP8266_SendCmd("AT+MQTTCONN=0,\"bemfa.com\",9501,1\r\n", "OK", 500))
    {
        printf("MQTT Failed\r\n");
    }

    //6 订阅主题
    while(ESP8266_SendCmd("AT+MQTTSUB=0,\"LED2002\",0\r\n", "OK", 50))
    {
        printf("Sub Failed\r\n");
    }

    //6 订阅主题
    while(ESP8266_SendCmd("AT+MQTTSUB=0,\"LED1002\",0\r\n", "OK", 50))
    {
        printf("Sub Failed\r\n");
    }

    //6 订阅主题
    while(ESP8266_SendCmd("AT+MQTTSUB=0,\"RGB1002\",0\r\n", "OK", 50))
    {
        printf("Sub Failed\r\n");
    }

}

在连接之前,必须先将ESP8266模块Reset ,即代码中的 rst_wifi()函数,才能保证能正常连接。

void rst_wifi(void)
{
    GPIO_ResetBits(GPIOI, GPIO_Pin_10);
    delay_ms(1000);
    GPIO_SetBits(GPIOI, GPIO_Pin_10);
}

其中ESP8266_SendCmd()函数采用的是正点原子ESP8266资料中的与之相关函数。

2.2 接收数据分析

代码如下:

//==========================================================
//	函数名称:	ESP8266_AnalyzeMessagv
//
//	函数功能:	处理平台返回的数据
//
//==========================================================
void ESP8266_AnalyzeMessagv(void)
{
    if(ESP8266_WaitRecive() == REV_OK)								//如果接收完成
    {
        if(strstr((char *)esp8266_buf, "+MQTTSUBRECV"))
        {
           ......//在这里写接收到的命令分析
        }
    }
}

三、QT上的显示效果

3.1 QT编译MQTT相关库

参考链接:https://blog.csdn.net/LclLsh/article/details/126536614
需要注意的是,需要下载与自己QT版本相同的QtMqtt库,编译时使用release。在编译完成后,将对应的库放到对应的编译器下,MINGW和MSVC、32位和64位必须一一对应。

3.2 QT的MQTT使用

在mainwindow.h中插入需要的头文件

#include <QMainWindow>
#include <QtMqtt/qmqttclient.h>
#include<QtMqtt/qmqttmessage.h>
#include <QtMqtt/qmqtttopicname.h>
#include<QtMqtt/qmqtttopicfilter.h>
#include <QtMqtt/qmqttglobal.h>

MQTT链接部分代码:
在构造函数中添加以下代码

	m_client = new QMqttClient(this);
    hostPort = 9501;
    hostName ="bemfa.com";
    m_client->setHostname(hostName);
    m_client->setClientId("e917d4e4b461831638744a74f2337704");
    m_client->setPort(hostPort);
    m_client->setKeepAlive(120);
    m_client->connectToHost();
    connect(m_client,&QMqttClient::connected,this,&MainWindow::isConnected);
    connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateLogStateChange);
    connect(m_client, &QMqttClient::disconnected, this, &MainWindow::brokerDisconnected);
    connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() {
        const QString content = QDateTime::currentDateTime().toString()
                 +QString("  ")
                + QLatin1String(" PingResponse")
                + QLatin1Char('\n');
        qDebug() << content;
    });

其余函数代码如下:

void MainWindow::isConnected()
{
    QString topic = "dht004";
    if(m_client->state() == QMqttClient::Connected){
        m_client->subscribe(QString(topic), 0);
        connect(m_client, SIGNAL(messageReceived(QByteArray,QMqttTopicName)), this, SLOT(topicMessageReceived(QByteArray,QMqttTopicName)));
    }
}

void MainWindow::brokerDisconnected()
{
   qDebug()<<"Connect disconnected";
}
void MainWindow::updateLogStateChange()
{
    const QString content = QDateTime::currentDateTime().toString()
            + QLatin1String(": State Change")
            +QString("  ")
            + QString::number(m_client->state())
            + QLatin1Char('\n');
    qDebug() << content;
}


void MainWindow::topicMessageReceived(const QByteArray &message,const QMqttTopicName &topic)
{
    if(topic.name() == "dht004")
    {
        int temperature = message.split('#').at(1).toInt();
        int humidity = message.split('#').at(2).toInt();
        ui->gaugeWeather->setOuterValue(humidity);                             //设置外环初始值为0
        ui->gaugeWeather->setInnerValue(temperature);                         //设置内环初始值为0
    }
}

QT显示部分,使用了feiyangqingyun大佬设计的组件,相关链接:https://qtchina.blog.csdn.net/article/details/97565652。
STM32 端代码下载:https://download.csdn.net/download/qq_43579230/75256786

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值