STM32与ESP8266之间使用MQTT协议的通信方式详解

文章目录

  • 前言
  • 一、MQTT协议简介
  • 二、STM32与ESP8266的结合
  • 1.配置ESP8266为MQTT客户端
  • 2.STM32与ESP8266的串口通信
  • 3.STM32作为MQTT发布者:
  • 3.STM32作为MQTT订阅者:
  • 三、温度监测与远程控制系统框架
  • 1.配置串口通信
  • 2.配置ESP8266作为MQTT客户端(AT指令方式)
  • 3. STM32作为MQTT发布者将温度数据发送到MQTT服务器
  • 4.STM32作为MQTT订阅者接收并处理温度数据
  • 总结

  • 前言

    在物联网应用中,设备之间的可靠通信是至关重要的。MQTT(Message Queuing Telemetry Transport)协议作为一种轻量级、灵活且可靠的通信协议,被广泛应用于物联网场景中。本文将着重介绍如何在STM32微控制器和ESP8266无线模块上实现MQTT通信,探讨其在物联网应用中的优势和应用案例。


    一、MQTT协议简介

    MQTT协议是基于发布/订阅模型的机制,采用非常简洁的设计,适用于低带宽和不稳定网络环境。它具有两个核心概念:发布者(Publisher)和订阅者(Subscriber)。发布者将数据发布到特定的主题(Topic),而订阅者可以选择订阅感兴趣的主题,从而接收相关信息。

    二、STM32与ESP8266的结合

    1.配置ESP8266为MQTT客户端

    代码如下:

    // 使用STM32向ESP8266发送AT指令设置MQTT参数
    USART_SendString("AT+CWMODE=1\r\n"); // 设置为Station模式
    USART_SendString("AT+CWJAP=\"SSID\",\"password\"\r\n"); // 连接WiFi网络
    USART_SendString("AT+CIPSTART=\"TCP\",\"mqtt_server_ip\",1883\r\n"); // 连接MQTT服务器
    USART_SendString("AT+MQTTUSERCONFIG=0,\"username\",\"password\"\r\n"); // 设置MQTT用户名和密码
    USART_SendString("AT+MQTTCLIENTCONFIG=0,\"client_id\",300,0\r\n"); // 配置MQTT客户端ID和心跳时间
    
    

    2.STM32与ESP8266的串口通信

    代码如下:

    // 初始化STM32的串口
    void USART1_Init()
    {
        // 设置引脚、波特率等参数
        ...
    }
    
    // 向ESP8266发送数据
    void USART1_SendString(char* str)
    {
        while (*str != '\0')
        {
            USART_SendData(USART1, *str);
            while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
            str++;
        }
    }
    
    // 接收ESP8266发送的数据
    char USART1_ReceiveByte()
    {
        while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
        return USART_ReceiveData(USART1);
    }
    
    

    3.STM32作为MQTT发布者:

    代码如下:

    // 从传感器获取数据
    float getSensorData()
    {
        // 获取传感器数据
        ...
    }
    
    // 将数据通过ESP8266发送到MQTT服务器
    void publishData(float data)
    {
        char buffer[50];
        sprintf(buffer, "%.2f", data); // 将浮点数转换为字符串
    
        // 构建MQTT发布消息
        char mqttMessage[100];
        sprintf(mqttMessage, "AT+MQTTPUBLISH=0,\"topic\",\"%s\"\r\n", buffer);
    
        // 发送MQTT发布消息
        USART1_SendString(mqttMessage);
    }
    
    // 主程序循环中的调用
    void mainLoop()
    {
        float sensorData = getSensorData();
        publishData(sensorData);
    }
    
    

    3.STM32作为MQTT订阅者:

    代码如下:

    // 处理收到的MQTT订阅消息
    void processMQTTMessage(char* message)
    {
        // 处理收到的消息
        ...
    }
    
    // 接收并处理ESP8266接收到的MQTT订阅消息
    void receiveAndProcessMQTTMessage()
    {
        while (1)
        {
            char receivedData = USART1_ReceiveByte();
            if (receivedData == '+')  // 收到MQTT订阅消息的开始符号
            {
                char mqttMessage[100];
                int i = 0;
                while (receivedData != '\n')  // 持续接收消息内容直到换行符
                {
                    receivedData = USART1_ReceiveByte();
                    mqttMessage[i++] = receivedData;
                }
                processMQTTMessage(mqttMessage);
            }
        }
    }
    
    // 主程序循环中的调用
    void mainLoop()
    {
        receiveAndProcessMQTTMessage();
    }
    

    三、温度监测与远程控制系统框架

    1.配置串口通信

    // 温度传感器引脚定义
    #define TEMPERATURE_SENSOR_GPIO      GPIOA
    #define TEMPERATURE_SENSOR_PIN       GPIO_PIN_0
    
    // 初始化温度传感器IO口
    void Temperature_Sensor_Init()
    {
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.Pin = TEMPERATURE_SENSOR_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        HAL_GPIO_Init(TEMPERATURE_SENSOR_GPIO, &GPIO_InitStruct);
    }
    
    // 获取温度传感器数据
    float Get_Temperature()
    {
        ADC_ChannelConfTypeDef sConfig;
        uint16_t adcRawData;
        float temperature;
    
        // 配置ADC通道和转换参数
        sConfig.Channel = ADC_CHANNEL_0;
        sConfig.Rank = 1;
        sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
        sConfig.SingleDiff = ADC_SINGLE_ENDED;
        sConfig.OffsetNumber = ADC_OFFSET_NONE;
        sConfig.Offset = 0;
    
        // 启动ADC转换
        HAL_ADC_ConfigChannel(&hadc1, &sConfig);
        HAL_ADC_Start(&hadc1);
        HAL_ADC_PollForConversion(&hadc1, 10);
    
        // 读取ADC转换值
        adcRawData = HAL_ADC_GetValue(&hadc1);
    
        // 根据ADC转换值计算温度
        // ...
    
        return temperature;
    }
    

    2.配置ESP8266作为MQTT客户端(AT指令方式)

    // 使用STM32向ESP8266发送AT指令设置MQTT参数
    void Configure_ESP8266_MQTT()
    {
        USART1_SendString("AT+CWMODE=1\r\n"); // 设置为Station模式
        USART1_SendString("AT+CWJAP=\"SSID\",\"password\"\r\n"); // 连接WiFi网络
        USART1_SendString("AT+CIPSTART=\"TCP\",\"mqtt_server_ip\",1883\r\n"); // 连接MQTT服务器
        USART1_SendString("AT+MQTTUSERCONFIG=0,\"username\",\"password\"\r\n"); // 设置MQTT用户名和密码
        USART1_SendString("AT+MQTTCLIENTCONFIG=0,\"client_id\",300,0\r\n"); // 配置MQTT客户端ID和心跳时间
    }
    
    

    3. STM32作为MQTT发布者将温度数据发送到MQTT服务器

    // 将温度数据通过ESP8266发送到MQTT服务器
    void Publish_Temperature(float temperature)
    {
        char buffer[50];
        sprintf(buffer, "%.2f", temperature); // 将浮点数转换为字符串
    
        // 构建MQTT发布消息
        char mqttMessage[100];
        sprintf(mqttMessage, "AT+MQTTPUBLISH=0,\"topic\",\"%s\"\r\n", buffer);
    
        // 发送MQTT发布消息
        USART1_SendString(mqttMessage);
    }
    
    // 主程序循环中的调用
    void Main_Loop()
    {
        float temperature = Get_Temperature();
        Publish_Temperature(temperature);
    }
    
    

    4.STM32作为MQTT订阅者接收并处理温度数据

    // 处理收到的MQTT订阅消息
    void Process_MQTT_Message(char* topic, char* message)
    {
        if (strcmp(topic, "temperature") == 0)
        {
            float temperature = atof(message); // 将字符串转换为浮点数
            // 温度处理逻辑
            // ...
        }
    }
    
    // 接收并处理ESP8266接收到的MQTT订阅消息
    void Receive_And_Process_MQTT_Message()
    {
        while (1)
        {
            char receivedData = USART1_ReceiveByte();
            if (receivedData == '+')  // 收到MQTT订阅消息的开始符号
            {
                char mqttTopic[50], mqttMessage[100];
                int i = 0;
    
                // 解析MQTT主题
                while (receivedData != ',')
                {
                    receivedData = USART1_ReceiveByte();
                    mqttTopic[i++] = receivedData;
                }
                mqttTopic[i - 1] = '\0';
    
                // 解析MQTT消息内容
                receivedData = USART1_ReceiveByte();
                i = 0;
                while (receivedData != '\n')
                {
                    receivedData = USART1_ReceiveByte();
                    mqttMessage[i++] = receivedData;
                }
                mqttMessage[i - 1] = '\0';
    
                Process_MQTT_Message(mqttTopic, mqttMessage);
            }
        }
    }
    
    // 主程序循环中的调用
    void Main_Loop()
    {
        Receive_And_Process_MQTT_Message();
    }
    
    

    总结

    STM32微控制器与ESP8266无线模块的结合为物联网应用提供了强大的通信能力。借助MQTT协议作为通信协议,实现了可靠、灵活和高效的设备间通信。这种组合具有广泛的应用前景,能够支持各种物联网场景的开发和实施。

    通过STM32与ESP8266的MQTT协议在物联网应用中的应用案例,我们可以看到其在实现远程监测、远程控制和数据交互等方面的优势。随着物联网技术的不断发展和成熟,这种组合将继续为物联网应用提供强大的支持,并推动物联网技术的进一步创新和应用。

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32与ESP8266之间使用MQTT协议的通信方式详解

    发表评论