STM32与ESP8266-MQTT固件的应用

2023-11-20

本文以Clion作为编译器,STM32F407作为芯片,通过串口以AT指令与ESP8266-01S进行通信,让其连接到腾讯云物联网平台。

一、ESP8266-01S

ESP8266-01S

ESP8266-01S原本固件是不支持MQTT的,因此需要在安信可官网去下载MQTT透传AT固件。AT固件汇总
再通过固件烧录工具将适用于ESP8266-01S的MQTT固件下载进其中。将ESP8266-01S进行上电测试,输入AT指令,有返回OK,说明此时ESP8266-01S是用的。
在这里插入图片描述

二、STM32CubeMx的配置

1.时钟树

在这里插入图片描述

2.RCC、SYS、Project Name…(略)

3.USART1、USART6

USART1选择异步通信方式,其余默认
在这里插入图片描述
USART6选择异步通信方式,打开更新中断,设置DMA,其余默认

在这里插入图片描述
在这里插入图片描述

4设置引脚

USART6_Rx默认PC7改为PG14
USART6_Tx默认PC6改为PG9
将PE2、PE3设置为GPIO输出

STM32 ESP8266
3.3V VCC
GND GND
PE2 EN
PE3 RST
Rx PG14
Tx PG9

5 设置TIM8定时器

在这里插入图片描述
在这里插入图片描述

三、STM32程序

1. usart.c


/* USER CODE BEGIN 1 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE {
    HAL_UART_Transmit(&huart1, (uint8_t *) &ch, 1, 0xFFFF);
    return ch;
}
/* USER CODE END 1 */

usart.h 文件中加入:

#include "stdio.h"

2.stm32f4xx_it.c

#define BUFFER_SIZE 1024
uint8_t rx_len;            
uint8_t recv_end_flag;   
uint8_t usart6_rxbuf[1024];
 void USART6_IRQHandler(void) {
    /* USER CODE BEGIN USART6_IRQn 0 */
    uint32_t tmp_flag = 0;
    uint32_t temp;
    recv_end_flag = 0;
    tmp_flag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);
    if ((tmp_flag != 0)) {    
        __HAL_UART_CLEAR_IDLEFLAG(&huart6); 
        HAL_UART_DMAStop(&huart6);
        temp = hdma_usart6_rx.Instance->NDTR;
        rx_len = BUFFER_SIZE - temp;
        recv_end_flag = 1;

        uint8_t i;
        for (i = 0; i < 250; i++)    
        {
            esp_rxbuf[i] = usart6_rxbuf[i];
        }
        printf("\r\n◇:%s \r\n", usart6_rxbuf);
        memset(&usart6_rxbuf, 0, sizeof(usart6_rxbuf));
        HAL_UART_Receive_DMA(&huart6, usart6_rxbuf, BUFFER_SIZE);
    }
    /* USER CODE END USART6_IRQn 0 */
    HAL_UART_IRQHandler(&huart6);
    /* USER CODE BEGIN USART6_IRQn 1 */

    /* USER CODE END USART6_IRQn 1 */
  }
}

3.创建ESP8266.c.h文件

ESP8266.c

#include "Esp8266.h"
#include "stdio.h"
#include "usart.h"
#include "string.h"
#include "Time.h"


uint8_t send_device_buf[1024];
uint8_t esp_rxbuf[1024];                //ESP数据接收缓冲区
uint8_t esp_wxbuf[1024];                //ESP数据发送缓冲区
EspCode Esp_One;
extern float Temperature, Distance;
unsigned int mqttPacketLen = 0;
float Temperature = 9, Distance = 8;

void ESP_Connect_Server() {
    ESP_Init();
    ESP8266_Connect_Wifi(Esp_One.WIFI_NAME, Esp_One.WIFI_PASSWORD);
    ESP_Mqtt_Connection(Esp_One.ClientID, Esp_One.UserName, Esp_One.PassWord);
    ESP_CONNECT_SERVER(Esp_One.ServerIP, Esp_One.Port);
    ESP_Mqtt_Subscribe(Esp_One.Topic);
    ESP_Send_Data(Esp_One.TopicPost);

}

void ESP_Init() {
    ESP_RST_Pin_SetH;
    ESP_CH_PD_Pin_SetH;
    Esp_One.WIFI_NAME = "要连接的WIFI名";
    Esp_One.WIFI_PASSWORD = "要连接的WIFI密码";
    Esp_One.ServerIP = "U9849JAYEY.iotcloud.tencentdevices.com";
    Esp_One.Port = "1883";
    Esp_One.ClientID = "客户端ID";
    Esp_One.UserName = "用户名";
    Esp_One.PassWord = "用户密码";
    Esp_One.Topic = "$thing/down/property/客户端ID/项目名";
    Esp_One.TopicPost = "$thing/up/property/客户端ID/项目名";
    printf("ESP_Init_Success\r\n");
}

uint8_t ESP8266_Connect_Wifi(char *WIFI_NAME, char *WIFI_PASSWORD) {
    int Ti = 1;
    memset(esp_rxbuf, 0, sizeof(esp_rxbuf));
    memset(&send_device_buf, 0, sizeof(send_device_buf));
    sprintf((char *) send_device_buf, "AT+CWMODE=3\r\n");//设置为STA和AP模式
    HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 100);
    HAL_Delay(1000);
    memset(&send_device_buf, 0, sizeof(send_device_buf));
    sprintf((char *) send_device_buf, "AT+CWJAP=\"%s\",\"%s\"\r\n", WIFI_NAME, WIFI_PASSWORD);
    HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 100); //输入路由ssid和密码
    HAL_Delay(1000);
    Set_TimeC_value(60);
    while (Ti) {
        if (Time_C == 0) {
            Ti = 0;
        }
        if (strstr((const char *) esp_rxbuf, "FAIL") != NULL ||
            strstr((const char *) esp_rxbuf, "ERROR") != NULL)        //如果检索到关键词
        {
            HAL_Delay(1000);
            memset(&send_device_buf, 0, sizeof(send_device_buf));
            sprintf((char *) send_device_buf, "AT+CWJAP=\"%s\",\"%s\"\r\n", WIFI_NAME, WIFI_PASSWORD);
            HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 100); //输入路由ssid和密码
        }
        if (strstr((const char *) esp_rxbuf, "WIFI GOT IP") != NULL)        //如果检索到关键词
        {
            printf("WIFI_Connect_Succeeded\r\n");
            break;
        }
    }

}

uint8_t ESP_Mqtt_Connection(char *ClientID, char *UserName, char *PassWord) {
    int Ti = 1;
    memset(esp_rxbuf, 0, sizeof(esp_rxbuf));
    Set_TimeC_value(30);
    while (Ti) {
        if (Time_C == 0) {
            Ti = 0;
        }
        HAL_Delay(1000);
        if (strstr((const char *) esp_rxbuf, "OK") != NULL)        //如果检索到关键词
        {
            return 0;
        } else {
            memset(send_device_buf, 0, 200);
            sprintf((char *) send_device_buf,
                    "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n", ClientID, UserName, PassWord);
            HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 1000);
        }
    }
    return 1;
}

uint8_t ESP_CONNECT_SERVER(uint8_t *ServerIP, uint8_t *Port) {
    int Ti = 1;
    memset(esp_rxbuf, 0, sizeof(esp_rxbuf));
    Set_TimeC_value(30);
    while (Ti) {
        if (Time_C == 0) {
            Ti = 0;
        }
        HAL_Delay(1000);
        if (strstr((const char *) esp_rxbuf, "OK") != NULL)        //如果检索到关键词
        {
            return 0;
        } else {
            memset(send_device_buf, 0, sizeof(send_device_buf));
            sprintf((char *) send_device_buf, "AT+MQTTCONN=0,\"%s\",%s,1\r\n", ServerIP, Port);
            HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 1000);
        }
    }
    return 1;
}

uint8_t ESP_Mqtt_Subscribe(char *Topic) {//订阅
    int Ti = 1;
    memset(esp_rxbuf, 0, sizeof(esp_rxbuf));
    Set_TimeC_value(3);
    while (Ti) {
        if (Time_C == 0) {
            Ti = 0;
        }
        HAL_Delay(1000);
        if (strstr((const char *) esp_rxbuf, "OK") !=
            NULL)        //如果检索到关键词
        {
            return 0;
        } else {
            memset(send_device_buf, 0, sizeof(send_device_buf));
            sprintf((char *) send_device_buf, "AT+MQTTSUB=0,\"%s\",0\r\n", Topic);
            HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 1000);
        }
    }
    return 1;
}

uint8_t ESP_Send_Data(char *TopicPost) {
    int Ti = 1;
    memset(esp_rxbuf, 0, sizeof(esp_rxbuf));
    Set_TimeC_value(10);
    while (Ti) {
        if (Time_C == 0) {
            Ti = 0;
        }
        HAL_Delay(1000);
        if (strstr((const char *) esp_rxbuf, "{\"method\":\"report_reply\",\"code\":0,\"status\":\"success\"}") !=
            NULL)        //如果检索到关键词
        {
            return 0;
        } else {
            memset(send_device_buf, 0, sizeof(send_device_buf));
            sprintf((char *) send_device_buf,
                    "AT+MQTTPUB=0,\"%s\",\"{\\\"method\\\":\\\"report\\\"\\,\\\"params\\\":{\\\"Temperature\\\":%.2f\\,\\\"Distance\\\":%.2f}}\",0,0\r\n",
                    TopicPost, Temperature, Distance);
            HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 1000);
        }
    }
    return 1;
}

uint8_t ESP_DisConnect() {
    int Ti = 1;
    memset(esp_rxbuf, 0, sizeof(esp_rxbuf));
    Set_TimeC_value(10);
    while (Ti) {
        if (Time_C == 0) {
            Ti = 0;
        }
        HAL_Delay(1000);
        if (strstr((const char *) esp_rxbuf, "OK") !=
            NULL)        //如果检索到关键词
        {
            return 0;
        } else {
            memset(send_device_buf, 0, sizeof(send_device_buf));
            sprintf((char *) send_device_buf,
                    "AT+MQTTCLEAN=0\r\n");
            HAL_UART_Transmit(ESP_UART, send_device_buf, strlen((const char *) send_device_buf), 1000);
        }
    }
    return 1;
}

ESP8266.h

#ifndef __ESP8266_H__
#define __ESP8266_H__

#include "main.h"

#define ESP_RST_Pin_SetH     HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_SET)
#define ESP_RST_Pin_SetL     HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_RESET)

#define ESP_CH_PD_Pin_SetH   HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET)
#define ESP_CH_PD_Pin_SetL   HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET)
extern uint8_t send_device_buf[1024];
extern uint8_t esp_rxbuf[1024];                //ESP数据接收缓冲区
extern uint8_t esp_wxbuf[1024];                //ESP数据发送缓冲区
#define ESP_UART &huart6
typedef struct _EspCode {

    char *WIFI_NAME;
    char *WIFI_PASSWORD;
    uint8_t *ServerIP;
    uint8_t *Port;
    char *UserName;
    char *PassWord;
    char *ClientID;
    char *Topic;
    char *TopicPost;

} EspCode;
extern EspCode Esp_One;

void ESP_Init(void);

uint8_t ESP8266_Connect_Wifi(char *WIFI_NAME, char *WIFI_PASSWORD);

uint8_t ESP_CONNECT_SERVER(uint8_t *ServerIP, uint8_t *Port);

uint8_t ESP_Mqtt_Connection(char *ClientID, char *UserName, char *PassWord);

void ESP_Connect_Server();

uint8_t ESP_Mqtt_Subscribe(char *Topic);

uint8_t ESP_Send_Data(char *TopicPost);

#endif

4.创建Time.c/.h文件

Time.c

#include "Time.h"
#include "tim.h"

int Time_C = 0;

void Set_TimeC_value(int value) {
    Time_C = value;
    HAL_TIM_Base_Start_IT(&htim8);
    if (Time_C == 0) {
        HAL_TIM_Base_Stop_IT(&htim8);
    }
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器回调函数,用于计算速度
{

 if (htim->Instance == TIM8) {
        Time_C--;
        if (Time_C <= 0) {
            Time_C = 0;
        }
    }
}

Time.h

#ifndef F407_BLANCE_CAR_TIME_H
#define F407_BLANCE_CAR_TIME_H
#include "main.h"
extern int Time_C;
void Set_TimeC_value(int value);
#endif

5.main.c

#define BUFFER_SIZE 1024
extern uint8_t usart6_rxbuf[1024];
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_USART6_UART_Init();
  MX_TIM8_Init();
  /* USER CODE BEGIN 2 */
    __HAL_UART_ENABLE_IT(&huart6, UART_IT_IDLE);//使能IDLE线检测中断
    HAL_UART_Receive_DMA(&huart6, usart6_rxbuf, BUFFER_SIZE);
    HAL_TIM_Base_Stop_IT(&htim8);
    ESP_Connect_Server();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    while (1) {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    }
  /* USER CODE END 3 */
}

四、结果

上下行数据皆成功
在这里插入图片描述
在这里插入图片描述


总结

使用ESP8266-01S的MQTT固件连接腾讯云物联网平台,简单数据上下行的应用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32与ESP8266-MQTT固件的应用 的相关文章

  • 多线程(九):JUC组件

    在来时juc组件前 我们先把上一章遗漏的部分给补上 synchronized 实现策略 锁升级 无锁 gt 偏向锁 gt 轻量级锁 gt 重量级锁 还有一个 锁消除 锁消除即删除不必要的加锁操作 JVM在运行时 对一些 在代码上要求同步 但

随机推荐

  • sort快速排序

    sort快速排序 使用sort必须要有相应的头文件 include
  • 中标麒麟系统把玩记录

    1 指令发送邮件 echo content mail vs this is title a a sh XXX XX com 其中 content代表发送的内容 thisistitle代表邮件主题 a sh为附件 2 开机运行脚本 在etc
  • 田忌赛马java代码算法,AcWing 1489. 田忌赛马——Java版代码

    import java io import java util public class 田忌赛马 public static void main String args throws IOException BufferedReader
  • Thrift快速入门

    文章目录 Thrift的安装 windows下安装 Linux下安装 Thrift的使用 编写IDL文件 命名空间 namespace 基本数据类型 类型定义 typedef 结构体类型 struct 枚举类型 enum 异常类型 exce
  • MybatisX简介

    MybatisX简介 前言 一 什么是MybatisX 二 如何使用 1 安装插件 2 创建一个mybatis项目或者于项目中引入mybatis依赖 3 快速生成示例 3 1 快速生成mapper方法 3 2 MybatisX Genera
  • 使用lattice包的bwplot函数绘制箱图比较多个模型在不同指标上的性能差异(R语言)

    使用lattice包的bwplot函数绘制箱图比较多个模型在不同指标上的性能差异 R语言 箱图是一种常用的数据可视化方法 用于表示一组数据的分布特征 包括中位数 四分位数 异常值等 在比较多个模型在多个指标上的性能差异时 箱图可以提供直观的
  • NCCL相关笔记

    本文仅代表个人观点 不保证正确性 一 NCCL简介 1 什么是NCCL NCCL是NVIDIA集合通信库 NVIDIA Collective Communications Library 的简称 是用于加速多GPU之间通信的库 能够实现集合
  • #css# 【四】如何使用hover,实现父对子的样式改变?

    css 如何使用hover 实现父对子的样式改变 思路及做法 鼠标移动到父盒子的时候 里面所有的子盒子的样式都发生变化的 只需要直接在hover后面加上空格 并且加上子盒子的类名 里面再写其他样式 父盒子的类名 hover 子盒子的类名 这
  • iOS系统网络抓包方法

    原文地址 http www cnblogs com ydhliphonedev archive 2011 10 27 2226935 html 在进行iOS开发过程中 经常会遇到各种各样的网络访问问题 以前苦于没有抓包工具 很多网络问题解决
  • 【python-opencv】硬币检测

    使用 python3 8 x opencv 硬币检测 问题描述 设计思路1 使用简单特征识别 具体操作 部分代码 设计思路2 模板匹配 源码 模板制作 完整代码 问题描述 使用图像处理技术 从照片中识别硬币的个数 并判断总价值 设计思路1
  • ESP32开发阶段启用 Secure Boot 与 Flash encryption

    Secure Boot 与 Flash encryption详情 请参考 https blog csdn net espressif article details 79362094 1 开发环境 AT版本 2 4 0 0 发布 IDF 与
  • git忽略文件地址

    git忽略文件地址 Objective C gitignore gitignore
  • String和StringBuffer的常见用法

    链接 https www nowcoder com questionTerminal fe6b651b66ae47d7acce78ffdd9a96c7 answerType 1 f discussion来源 牛客网 String的用法 ja
  • dubbo配置提供者和消费者

    1 找到对应的文件 提供者 消费者 参考dubbo官网 http dubbo apache org zh cn docs user quick start html
  • 【NLP】第 6 章 :微调预训练模型

    到目前为止 我们已经了解了如何使用包含预训练模型的huggingface API 来创建简单的应用程序 如果您可以从头开始并仅使用您自己的数据来训练您自己的模型 那不是很棒吗 如果您没有大量空闲时间或计算资源可供使用 那么使用迁移学习 是最
  • 连接池

    总结 1 连接池 java对外提供了连接的接口 连接池的存在就省去了每次创建和释放连接 2 连接池的连接条件 1 将commons pool 1 5 6 jar的jar包引进java项目下的lib文件夹 3 用连接池对象代替dao 层的Co
  • TP6.0 自定义命令创建类文件

    一 修改框架核心扩展包 1 新增指令配置项 2 创建逻辑层类文件模板 3 创建 Logic php 文件 4 执行命令 创建逻辑层类文件 二 不用修改框架源码 推荐 1 创建一个自定义命令类文件 以逻辑层类文件为例 2 复制创建模型类的命令
  • 解决 npm或pnpm : 无法加载文件 C:\Users\bts\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本

    vscode 使用 npm 或 pnpm打开网页时出现此问题 解决方法 点击左下角开始 找到Windows PowerShell 点击右键找到更多 找到以管理员身份运行 输入命令 set ExecutionPolicy RemoteSign
  • 使用禅道 api 添加用户完整流程与分析

    在使用禅道系统时 有时为了方便 需要与其他系统对接 如其他系统添加用户后可以直接同步到禅道系统 而不是在禅道系统重新添加一遍用户 禅道系统提供了二次开发的api 但是里面的内容并不详细 故笔者写这篇文章进行记录 这里先以 postman进行
  • STM32与ESP8266-MQTT固件的应用

    本文以Clion作为编译器 STM32F407作为芯片 通过串口以AT指令与ESP8266 01S进行通信 让其连接到腾讯云物联网平台 一 ESP8266 01S ESP8266 01S原本固件是不支持MQTT的 因此需要在安信可官网去下载