1.效果实现
源码资料下载
链接:https://pan.baidu.com/s/1ne6Nlz2bZ27wMcNSFxf5Qw
提取码:5l30
通过MQTTX上位机能够控制最小系统板的LED灯的亮灭,value后面的值写0/1即可控制亮灭
2.硬件连接
需要查找资料根据具体的WIFI模块引脚连接用CubeMX去进行配置,我用的是ESP-12F模块用CubeMX引脚配置具体如下
根据下图可知我们需要连接7根线除RST外按图接线,RST我们接上配置的PA4引脚,配置的为GPIO-output模式,然后就可以开始编写代码,我这里使用的是ESP-12F,换成ESP-01S也可以
注意接线除RST外要按图接好,否则会连不上网
3.代码编写(按照网盘下载的工程为例,这里写的比较简略)
将网盘的代码下载下来,将其中的USER代码复制到自己的工程文件夹下面
然后在项目中开始编写代码,可以按照我的工程文件的main.c添加的代码来编写
//1
/* USER CODE BEGIN Includes */
#include "MQTT_Conf.h"//头文件包含
/* USER CODE END Includes */
//2
///重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口DEBUG_USART */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return (ch);
}
int main(void)
{
/* USER CODE BEGIN 1 */
char PUB_BUF[256];//上传数据的buf
/* 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_USART1_UART_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
unsigned char *dataPtr = NULL;
const char *topics[] = {SUB_TOPIC};
ESP8266_LINK_Init();
OneNet_Subscribe(topics, 1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);//要调试MQTTX能否接受到单片机发的消息时候可以取消注释查看,能够通过MQTTX收到hello的消息
// sprintf(PUB_BUF,"hello");
// OneNet_Publish(PUB_TOPIC,PUB_BUF);
HAL_Delay(2000);
dataPtr = ESP8266_GetIPD(3); // 完成需要15个毫秒,三次循环,一次5个毫秒
if (dataPtr != NULL)
OneNet_RevPro(dataPtr); //获取数据并在里面进行解析
HAL_Delay(10);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
main.c编写好代码后要找到MQTT_Conf.h的头文件打开
里面进行esp8266的通信串口选择和复位引脚的设置,里面的ESP8266_WIFI_INFO改成对应自己的WIFI名称和密码,"AT+CWJAP=\"WIFI名称\",\"WIFI密码\"\r\n"
ESP8266_ONENET_INFO用的是公共服务器可以进这个网址查看免费的公共 MQTT 服务器 | EMQ
/***********************************************************************************************
* ESP8266 连接MQTT配置文件
* 端口占用如下:
* 1:一个GPIO复位引脚
* 2:一个串口
* 3:3V3 和GND
* 使用说明如下:
* 1:更改复位引脚和选定的串口
* 2:更换自己的串口重定向
* 3:更换订阅和发布的主题
* 4:配置设备ID信息
* 5:配置wife密码和MQTT服务器
* 6:调用 ESP8266_LINK_Init()连接函数
* 7:根据所需调用esp8266.h和onenet.h的函数
************************************************************************************************/
#ifndef __MQTT_CONF_H
#define __MQTT_CONF_H
#include "stdio.h"
#include "string.h"
#include "onenet.h"
#include "Common.h"
#include "esp8266.h"
#include "mqttkit.h"
#include "cJSON.h"
#include "main.h"
#define ESP8266_REST_Pin GPIO_PIN_4 //复位引脚设置为PA4
#define ESP8266_REST_GPIO_Port GPIOA
#define ESP_UART huart2 //esp8266的通信串口
#define USER_PRINTF printf //定义用户自己的串口重定向函数
//#define SUB_TOPIC "lls_app_v0" //订阅主题(需要加引号)
#define SUB_TOPIC "iot/160/ggf" //订阅主题(需要加引号)
#define PUB_TOPIC "iot/160/wsd" //发布主题
//#define PUB_TOPIC "Taichi-Maker-Sub-C8:C9:A3:5D:A1:A4" //发布主题
#define PROID "446433vyug" //设备ID(可随便)
#define AUTH_INFO "123" //密码 (可随便)
#define DEVID "742860946" //(可随便)
#define ESP8266_WIFI_INFO "AT+CWJAP=\"Xiaomi_3CDA\",\"15270605571\"\r\n" //TP-LINK_5D25是wife名称 18296885326是wife密码
//#define ESP8266_WIFI_INFO "AT+CWJAP=\"oplus_co_apecsu\",\"123456789.\"\r\n" //TP-LINK_5D25是wife名称 18296885326是wife密码
//#define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"mqtt.llsmqttport.xyz\",1883\r\n"//broker-cn.emqx.io 是mqtt服务器地址,1883是端口号
#define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"broker.emqx.io\",1883\r\n"//broker-cn.emqx.io 是mqtt服务器地址,1883是端口号
extern unsigned char a_esp8266_buf; //ESP8266 01s串口通信缓冲区
//esp8266连接初始化
#define ESP8266_LINK_Init() \
do { \
HAL_UART_Receive_IT(&ESP_UART, (uint8_t *)&a_esp8266_buf, 1);\
ESP8266_Init();\
while (OneNet_DevLink())\
{\
HAL_Delay(500);\
}\
} while(0U)
#endif
4.MQTTX的配置
下载安装软件----->MQTTX:全功能 MQTT 客户端工具进去点击右上角的Download下载安装
打开软件新建连接配置
点击添加订阅添加
5.实现效果
打开主函数循环中的注释,烧录程序
连接上网络后收到一次hello的显示如下,就代表代码没有问题,实现了接收单片机的数据
用MQTTX控制单片机,以下代码在onenet.c的OneNet_RevPro函数中,通过以下代码即可实现控制LED的亮灭
case MQTT_PKT_PUBLISH: //接收的Publish消息
result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);
if(result == 0)
{
USER_PRINTF( "topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",
cmdid_topic, topic_len, req_payload, req_len);
//解析数据包
json=cJSON_Parse(req_payload);
if(!json)USER_PRINTF("Error before:[%s]\n",cJSON_GetErrorPtr());
else
{
//解析开关值
json_vlaue=cJSON_GetObjectItem(json,"target");
USER_PRINTF("json_target= %s\r\n",json_vlaue->string);//先把键值输出来,就是看看叫什么名字
USER_PRINTF("json_vlaue= %s\r\n",json_vlaue->valuestring);//接着看看数值是多少
// json_vlaue=cJSON_GetObjectItem(json,"value");
// USER_PRINTF("josn_value=%d",json_vlaue->valueint);
//从value-int中获取结果
if(strstr(json_vlaue->valuestring,"led")!=NULL)//标准字符串判断,这个就是判断是不是控制LED
{
json_vlaue=cJSON_GetObjectItem(json,"value");
if(json_vlaue->valueint)//对0/1进行判断
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
};
}
}
cJSON_Delete(json);
}
break;
以上内容均为个人实践加理解写出,供大家参考,有帮助到大家可以点赞支持。