首页 > 其他分享 >mqtt与云服务器

mqtt与云服务器

时间:2024-10-17 16:46:12浏览次数:3  
标签:USART esp -- back mqtt GPIO 服务器

mqtt

目录

mqtt

回顾

云服务器的操作

MQTT协议

-- 将官方库移植到工程

-- 应用

-- 可能会出现的问题:

完整代码


回顾

-- 昨天我们写的AT指令是直接写在main中,在while循环的外面,没有很好的封装,所以今天我们写一个函数来封装AT指令

	//要保证能在while循环中运行
uint8_t state = 0;
void wifi_get_time(void)
{

	uint8_t back = 0;
	switch(state)
	{
		case 0:
			back = SendCmdAndJudgeSuccess("AT\r\n","OK",1000);
		if(back == 1)//返回值如果是1,代表指令执行成功
			state++;
		break;
		case 1:
			back = SendCmdAndJudgeSuccess("AT+RST\r\n","OK",2000);
		if(back == 1)
			state++;
		break;
		case 2:
			back = SendCmdAndJudgeSuccess("AT+CWMODE=1\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 3:
			back = SendCmdAndJudgeSuccess("AT+CIPMUX=0\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 4:
			//在flash里面读取wifi信息esp.wifiname,esp.wifipassword,这里没有用flash,先直接赋值
			strcpy(esp.wifiname,"111"); 
			strcpy(esp.wifipassword,"pimouren"); 
			memset(esp.txbuff,0,1024);
			sprintf(esp.txbuff,"AT+CWJAP=\"%s\",\"%s\"\r\n",esp.wifiname,esp.wifipassword);
			back = SendCmdAndJudgeSuccess(esp.txbuff,"OK",10000);
		if(back == 1)
			state++;
		break;
		case 5:
			memset(esp.txbuff,0,1024);
			//sprintf(esp.txbuff,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",TIMEIP,TIMEPORT);
		if(back == 1)
			state++;
		break;
		case 6:
			back = SendCmdAndJudgeSuccess("AT+CIPMODE=1\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 7:
			back = SendCmdAndJudgeSuccess("AT+CIPSEND\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 8:
			memset(esp.rxbuff,0,1024);
			esp.rxlen = 0;
			esp.rxflag = 0;
			memset(esp.txbuff,0,1024);
			sprintf(esp.txbuff,"%s",GETTIME);	
			uart3_txstr(esp.txbuff);
			Delay_nms(1000);
			state++;

			break;
		case 11:
			back = SendCmdAndJudgeSuccess("AT+CIPCLOSE\r\n","OK",1000);
			if(back == 1)
			state++;
		break;
	}
}

云服务器的操作

-- 云服务器有公有的(阿里云。。)和私有的(公司单独的)。

  • 1、和服务器进行连接(最简单的就是tcp连接,发送请求指令)

有一些服务器通信是比较复杂了
有的通信还要遵循一些协议
比如说mqtt协议

  • 2、如何跟服务器通信

-- 阿里云有很多产品,具体用哪个 -- 打开阿里云,注册并登入,从产品里面选择物联网找到飞燕平台

alt text

-- 进入点击管理控制台 

alt text

-- 注意:进不去就说明账号之前使用过,需要重新注册账号

-- 点击创建新项目 

alt text

-- 双击创建好的项目 

alt text

-- 点击创建产品 

alt text

-- 填写相关信息 

alt text

alt text

-- 其他就不用改了,随后点击确认

-- 添加自定义功能 

alt text

 

alt text

-- 随后在人机交互模块

alt text

-- 配置基础APP 

alt text

-- 

alt text

-- 在设备模块模块点击选择面板 

alt text

-- 注意这里APP的模块官方会提供一些模板,但是有的公司会用自己的

-- 点击创建面板里面的空白面板

-- 进入APP的编辑界面 

alt text

-- 现在右边栏选择一个背景,有很多可以选择,也可选择图片 

alt text

-- 右边的侧边栏有对应的图标,可以直接拖进页面 

alt text

-- 然后点击右上角的保存,并在之后输入面板名称,再次点击确认 

alt text

-- 保存好的APP可以在手机上预览,点击右上角的预览,就会生成二维码,用手机上的云智能软件扫描二维码就可以看到APP 

alt text

-- 重新回到刚刚的选择面板就可以选择刚刚设计的面板了 

alt text

 

alt text

-- 剩下的语音交互和产品说明书可以不用管

-- 随后进入设备调试模块,新增测试设备 

alt text

-- 新增的测试设备可以不写,直接点击确认就会自动生成设备名,复制生成的设备名 

alt text

 

alt text

 

alt text

-- 随后回到人机交互,点击产品说明书,然后点击下载配网二维码 

alt text

-- 用云智能APP扫这个码,可能会产生未激活的情况。

-- 那么怎么才能激活呢?需要底层的硬件的连接

-- 云平台操作完成,回归代码


MQTT协议

-- mqtt

-- 先看mqtt协议的相关手册了解mqtt 

alt text

-- 

alt text

alt text

 

alt text

 -- 注意这里0和15的消息类型不用,所以说mqtt协议拥有14中不同的消息类型。

-- mqtt协议专门连接物联网平台

-- 之前咱们连接时间服务器(用tcp连接)

-- 今天去连接阿里云服务器(也是tcp连接)

-- 关键问题是咱们所使用的是物联网平台,是属于阿里云服务器上的一个功能

-- 让数据显示在云平台

--主要是 和云平台建立通信

-- 不同的云平台建立通信的方式是不一样的

-- 阿里云物联网平台自身有自己的通信协议(mqtt协议)

-- 和物联网平台通信,就要用到mqtt协议

-- MQTT 协议的报文格式:固定报头+可变报头+有效载荷

alt text

对于 PUBLISH 来说有效载荷就是应用消息。

-- wifi模块要先建立tcp连接,然后才能用mqtt

-- mqtt到底应该怎么搭建怎么使用

-- 同官方库


-- 将官方库移植到工程

-- MQTT 库移植介绍

  • 1、找到官方库 

    alt text

     

    alt text

  • 2、 

    alt text

  • 3、在工程里面新建文件夹mqtt 

    alt text

  • 4、将源码里面src文件夹里面的文件整体移入mqtt文件里面 

    alt text

  • 5、将mqtt文件添加进工程 

    alt text

  • 6、添加头文件路径 

    alt text

-- 其实咱们用到的函数也就几个:

MQTTSerialize_connect();建立连接报文
MQTTSerialize_publish();建立发布数据报文
MQTTSerialize_subscribe();建立订阅报文
MQTTSerialize_unsubscribe();取消订阅
MQTTSerialize_disconnect();断开连接

-- 应用

-- 官方库怎么用?可以选择百度

-- 用这个连接去实现了功能 Paho mqtt C语言库介绍-CSDN博客

-- 链接讲的是官方库的使用

-- 各个.c文件的作用 

alt text

-- 这里我们根据例程来编写代码,使用官方库

-- 找到例程(可以参考)

alt text

-- 根据mqtt的官方例程,将我们需要用到的部分代码复制进我们的工程。

-- 编写一个mqtt的连接函数

//mqtt的连接函数

void mqtt_connect(void)
{
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;//定义了一个结构体,下面对结构体参数赋值
	
	
	data.keepAliveInterval = 60;//保持连接时间(60s)
	data.cleansession = 1;
	data.clientID.cstring = CLIENTID;
	data.username.cstring = USERNAME;
	data.password.cstring = PASSWD;
	
	memset(esp.txbuff,0,1024);
	uint32_t len = MQTTSerialize_connect(esp.txbuff, 1024, &data);//返回值就是txbuff的长度
	//发送连接报文
	uart3_txbuff(esp.txbuff,len);
}

-- 其中,mqtt的ID,用户名和密码,在物联网平台里面可以找到

-- 同时打开物联网平台 

alt text

-- 点击管理控制台 

alt text

-- 点击公共实例,没开通的需要开通 

alt text

-- 点击设备,找到之前我们创建的设备,点击查看 

alt text

-- 找到mqtt的连接参数,点击查看(注意:这些参数是会改变的,随着时间有变化,但是只要连接上一次,以后这些参数就不用再改了)

alt text

-- 点击一键复制 

alt text

-- 将这些参数复制到.h中,然后将他分成5份,可以根据逗号来分 

alt text

-- 将这些参数改为宏定义 

alt text

-- 前三个参数也就是刚刚我们需要的mqtt的ID,用户名和密码

alt text

-- 将AT指令的相关参数更改

-- 今天要通过tcp连接阿里云,所以要改为阿里云的IP的端口,也就是刚刚我们复制的部分参数

alt text

 

alt text

-- 将连接时间服务器改为今天写的mqtt连接函数

alt text

-- 之后打开刚刚的物联网平台,点击我们之前创建的产品,查看 

alt text

-- 选择物模型通信Topic,找到主题,复制主题 

alt text

-- 写成宏定义放在工程的.h中 

alt text

-- 中间的参数是设备名称,将自己的设备名称替代 

alt text

 

alt text

-- 将刚刚定义的宏定义写入发布函数的参数中,还有最后两个参数怎么得到 

alt text

 

alt text

-- 这两个参数是主题名称,负载和负载长度,而负载有固定格式 

alt text

-- 这里也就是buff,其中需要更改的就是以下这些 

alt text

-- 这些名称可以在物联网平台中找到 

alt text

-- 这里先写成定值,注意这里如果后面还有要写的数据,就要写",",否则不写,注意这里格式不能错 

alt text

-- 随后根据官方例程找到mqtt的订阅和发布函数,复制到工程中,更改上述得到的相关参数

void mqtt_pub(void)
{
	//返回值长度
		
	  char buff[512] = {0};
    sprintf(buff,"{\"id\":1724227172076,\"params\":\
                  {\"temperature\":20.1,\
                   \"HCHO\":23,\
                   \"CO2\":23\
                   },\"version\":\"1.0\",\
                   \"method\":\"thing.event.property.post\"}");
	MQTTString topicString = MQTTString_initializer;
  topicString.cstring = TOPIC_PUB;
	memset(esp.txbuff,0,1024);
	uint32_t len = MQTTSerialize_publish(esp.txbuff, 1024, 0, 0, 0, 0,topicString, buff, strlen(buff));	//主题名称,负载和负载长度
	uart3_txbuff(esp.txbuff,len);
}

-- 在主函数中调用

if(rtctime >=999)
		{
			rtctime = 0;
			get_time();
		}
		
		
		if(wifitime >=1000)
		{
			wifitime = 0;
			//天气,时间,ap,云服务器
			wifi_get_time();
		}

-- 更改有封装AT指令的函数

	//要保证能在while循环中运行
uint8_t state = 0;
void wifi_get_time(void)
{

	uint8_t back = 0;
	switch(state)
	{
		case 0:
			back = SendCmdAndJudgeSuccess("AT\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 1:
			back = SendCmdAndJudgeSuccess("AT+RST\r\n","OK",2000);
		if(back == 1)
			state++;
		break;
		case 2:
			back = SendCmdAndJudgeSuccess("AT+CWMODE=1\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 3:
			back = SendCmdAndJudgeSuccess("AT+CIPMUX=0\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 4:
			//在flash里面读取wifi信息esp.wifiname,esp.wifipassword,这里没有用flash,先直接赋值
			strcpy(esp.wifiname,"111"); 
			strcpy(esp.wifipassword,"pimouren"); 
			memset(esp.txbuff,0,1024);
			sprintf(esp.txbuff,"AT+CWJAP=\"%s\",\"%s\"\r\n",esp.wifiname,esp.wifipassword);
			back = SendCmdAndJudgeSuccess(esp.txbuff,"OK",10000);
		if(back == 1)
			state++;
		break;
		case 5:
			memset(esp.txbuff,0,1024);
			//sprintf(esp.txbuff,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",TIMEIP,TIMEPORT);	
		//换成阿里云的IP的端口	
		sprintf(esp.txbuff,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",MATTHOSTURL,PORT);
			back = SendCmdAndJudgeSuccess(esp.txbuff,"OK",10000);
		if(back == 1)
			state++;
		break;
		case 6:
			back = SendCmdAndJudgeSuccess("AT+CIPMODE=1\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 7:
			back = SendCmdAndJudgeSuccess("AT+CIPSEND\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 8:
//			memset(esp.rxbuff,0,1024);
//			esp.rxlen = 0;
//			esp.rxflag = 0;
//			memset(esp.txbuff,0,1024);
//			sprintf(esp.txbuff,"%s",GETTIME);	
//			uart3_txstr(esp.txbuff);
//			Delay_nms(1000);
//			state++;
		
		mqtt_connect();
		state++;
		break;
		case 9:
			mqtt_pub();
//			if(esp.rxflag==1)
//			{
//				esp.rxflag=0;	
//				uint8_t timebuff[11] = {0};
//				char *p  = strstr((char *)esp.rxbuff,"time");//strstr找到返回地址,没找到返回空
//				if(p!=NULL)
//				{
//					p+=6;
//					
//					for(uint8_t i=0;i<10;i++)
//					{
//						timebuff[i] = *(p+i);
//						
//					}
//				}
//				uint32_t timesec = atoi(timebuff);
//				printf("time:%s		%ld\r\n",timebuff,(long)timesec);
//				updata_time(timesec);
				//state++;
		//	}
			break;
			case 10:
			uart3_txstr("+++");
			Delay_nms(1000);
				state++;
			break;
		case 11:
			back = SendCmdAndJudgeSuccess("AT+CIPCLOSE\r\n","OK",1000);
			if(back == 1)
			state++;
		break;
	}
}

-- 可能会出现的问题:
  • 1、接收的计数值给的单位太小了,而有的AT指令回复的数据量比较大(会回复乱码),导致接收不到数据 ,所以要将单位改大 

    alt text

  • 2、出现上传一遍数据之后程序就不执行了

-- 出现问题先调试,看在哪个位置卡死了,如果出现不明显的错误,就要考虑数组的大小和空间的大小,适当增加数组的大小。

-- 这里出现的问题就是buff的错误,buff的大小不够大,导致接收不到数据,所以将buff的大小改大,就可以正常接收数据了 

alt text

-- 执行效果

-- 执行代码,该设备显示在线,点击该设备,可以看到数据 

alt text

-- 记得点击实时更新 

alt text

-- 设备在线后,就可以用云智能APP扫码查看APP 

alt text

完整代码

  • esp.c
#include "esp.h"
#include "string.h"
#include "delay.h"
#include "rtc.h"
#include "dht11.h"
#include "MQTTPacket.h"
//#include "transport.h"
ESP esp ={0};

void esp_init(void)
{
	//时钟 B端口  USART3(外设自身也有时钟)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);			//看数据手册在哪条线上 - APB2
	
	//IO PA9/PA10
	GPIO_InitTypeDef GPIO_InitStructure = {0};						//定义结构体变量,并且将结构体变量赋初值
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 						//引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//速度
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//PA9 复用推挽
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; 							//引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		//浮空输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //ESP_EN使能引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_Init(GPIOE, &GPIO_InitStructure);
  
	GPIO_SetBits(GPIOE,GPIO_Pin_6);//置1
	
	USART_InitTypeDef USART_InitStructure = {0};
	USART_InitStructure.USART_BaudRate = 115200;   					 			//波特率  常用的是4800 9600  115200
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	//数据位长度
	USART_InitStructure.USART_StopBits = USART_StopBits_1;			//停止位长度
	USART_InitStructure.USART_Parity = USART_Parity_No;				//奇偶校验(这里写不使用)
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制失能(不使用硬件流控制)
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//模式
	USART_Init(USART3, &USART_InitStructure);
	
	USART_Cmd(USART3,ENABLE);//开启串口    //使能或者失能 USART 外设(一般外设都要写这个)
	
	
	//使能中断源			//串口有10个,用哪一个就要开哪一个中断源
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
	
	USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);		//空闲中断怎么开
	
	//中断
	NVIC_InitTypeDef NVIC_InitStructure = {0}; 
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能(使能哪个中断通道,就要写哪个(必须写)中断服务函数)
	NVIC_Init(&NVIC_InitStructure);
	
}

void USART3_IRQHandler(void)//串口收到1字节数据,中断就会被触发一次
{
	uint8_t data = 0;
	//判断接收中断是否发生
	if(USART_GetITStatus(USART3, USART_IT_RXNE) == SET)
	{
		//处理中断:保存数据
			data = USART_ReceiveData(USART3);
		USART_SendData(USART1, data);
		
		esp.rxbuff[esp.rxlen++] = data;
		esp.rxlen%=1024;				//计数值最大是1024(前面一堆乱码也会存在buff里面,要控制数据)
		
		//清理终端
		USART_ClearITPendingBit(USART3,USART_IT_RXNE);
	}
	
	
	
	if(USART_GetITStatus(USART3, USART_IT_IDLE) == SET)
	{
		esp.rxflag=1;
		
		//清理空闲中断标志(比较特殊)
		data = USART_ReceiveData(USART3);
		
	}
}

//应用函数

//发送
void uart3_tx(uint8_t data)
{
	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET){}
	USART_SendData(USART3, data); 
}

void uart3_txbuff(uint8_t *buff,uint32_t len)
{
	for(uint32_t i=0;i<len;i++)
		uart3_tx(buff[i]);
}

//发送不定长数组
void uart3_txstr(uint8_t *buff)
{
	while( *buff )
	{
		uart3_tx(*buff);
		buff++;
	}
}


//判断指令是否发送成功
uint8_t SendCmdAndJudgeSuccess(uint8_t *cmd,uint8_t * ack,uint16_t outtime)//指令和回复的,超时时间(每条指令都有最大的超时时间)
{
	//清空缓冲区
	
	memset(esp.rxbuff,0,1024);
	esp.rxlen = 0;
	esp.rxflag = 0;
	
	
	//1、发送指令
	uart3_txstr(cmd);
	
	//2、判断接收数据中是否有对应的ack
	while(outtime--)
	{
		if(esp.rxflag==1)
		{
			esp.rxflag=0;							//接受两次数据,一次是(前三句话)disconnect会触发,没有OK,然后退出,后面输出ok会再次触发
			if(strstr((char *)esp.rxbuff,(char *)ack)!=NULL)//strstr找到返回地址,没找到返回空
			return 1;
		}
		Delay_nms(1);
	}
	
	return 0;
}
	//要保证能在while循环中运行
uint8_t state = 0;
void wifi_get_time(void)
{

	uint8_t back = 0;
	switch(state)
	{
		case 0:
			back = SendCmdAndJudgeSuccess("AT\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 1:
			back = SendCmdAndJudgeSuccess("AT+RST\r\n","OK",2000);
		if(back == 1)
			state++;
		break;
		case 2:
			back = SendCmdAndJudgeSuccess("AT+CWMODE=1\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 3:
			back = SendCmdAndJudgeSuccess("AT+CIPMUX=0\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 4:
			//在flash里面读取wifi信息esp.wifiname,esp.wifipassword,这里没有用flash,先直接赋值
			strcpy(esp.wifiname,"111"); 
			strcpy(esp.wifipassword,"pimouren"); 
			memset(esp.txbuff,0,1024);
			sprintf(esp.txbuff,"AT+CWJAP=\"%s\",\"%s\"\r\n",esp.wifiname,esp.wifipassword);
			back = SendCmdAndJudgeSuccess(esp.txbuff,"OK",10000);
		if(back == 1)
			state++;
		break;
		case 5:
			memset(esp.txbuff,0,1024);
			//sprintf(esp.txbuff,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",TIMEIP,TIMEPORT);	
		//换成阿里云的IP的端口	
		sprintf(esp.txbuff,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",MATTHOSTURL,PORT);
			back = SendCmdAndJudgeSuccess(esp.txbuff,"OK",10000);
		if(back == 1)
			state++;
		break;
		case 6:
			back = SendCmdAndJudgeSuccess("AT+CIPMODE=1\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 7:
			back = SendCmdAndJudgeSuccess("AT+CIPSEND\r\n","OK",1000);
		if(back == 1)
			state++;
		break;
		case 8:
//			memset(esp.rxbuff,0,1024);
//			esp.rxlen = 0;
//			esp.rxflag = 0;
//			memset(esp.txbuff,0,1024);
//			sprintf(esp.txbuff,"%s",GETTIME);	
//			uart3_txstr(esp.txbuff);
//			Delay_nms(1000);
//			state++;
		
		mqtt_connect();
		state++;
		break;
		case 9:
			mqtt_pub();
//			if(esp.rxflag==1)
//			{
//				esp.rxflag=0;	
//				uint8_t timebuff[11] = {0};
//				char *p  = strstr((char *)esp.rxbuff,"time");//strstr找到返回地址,没找到返回空
//				if(p!=NULL)
//				{
//					p+=6;
//					
//					for(uint8_t i=0;i<10;i++)
//					{
//						timebuff[i] = *(p+i);
//						
//					}
//				}
//				uint32_t timesec = atoi(timebuff);
//				printf("time:%s		%ld\r\n",timebuff,(long)timesec);
//				updata_time(timesec);
				//state++;
		//	}
			break;
			case 10:
			uart3_txstr("+++");
			Delay_nms(1000);
				state++;
			break;
		case 11:
			back = SendCmdAndJudgeSuccess("AT+CIPCLOSE\r\n","OK",1000);
			if(back == 1)
			state++;
		break;
	}
}

//mqtt的连接函数

void mqtt_connect(void)
{
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;//定义了一个结构体,下面对结构体参数赋值
	
	
	data.keepAliveInterval = 60;//保持连接时间(60s)
	data.cleansession = 1;
	data.clientID.cstring = CLIENTID;
	data.username.cstring = USERNAME;
	data.password.cstring = PASSWD;
	
	memset(esp.txbuff,0,1024);
	uint32_t len = MQTTSerialize_connect(esp.txbuff, 1024, &data);//返回值就是txbuff的长度
	//发送连接报文
	uart3_txbuff(esp.txbuff,len);
}

void mqtt_pub(void)
{
	//返回值长度
		
	  char buff[512] = {0};
    sprintf(buff,"{\"id\":1724227172076,\"params\":\
                  {\"temperature\":20.1,\
                   \"HCHO\":23,\
                   \"CO2\":23\
                   },\"version\":\"1.0\",\
                   \"method\":\"thing.event.property.post\"}");
	MQTTString topicString = MQTTString_initializer;
  topicString.cstring = TOPIC_PUB;
	memset(esp.txbuff,0,1024);
	uint32_t len = MQTTSerialize_publish(esp.txbuff, 1024, 0, 0, 0, 0,topicString, buff, strlen(buff));	//主题名称,负载和负载长度
 	uart3_txbuff(esp.txbuff,len);
}



  • esp.h
#ifndef _ESP_H_
#define _ESP_H_

#include "STM32f10x.h"

void esp_init(void);

void USART3_tx(uint8_t data);

void uart3_txbuff(uint8_t *buff,uint32_t len);

void uart3_txstr(uint8_t *buff);

typedef struct {
	uint8_t rxbuff[1024];//接收缓冲区 
	uint16_t rxlen;		//接收计数值
	uint8_t rxflag;
	
	uint8_t txbuff[1024];//发送缓冲区 
	uint8_t txlen;		//发送计数值
	
	uint8_t wifiname[20];
	uint8_t wifipassword[20];
}ESP;
extern ESP esp;

#define TIMEIP "pinduoduo.com"
#define TIMEPORT 80
#define GETTIME "GET http://api.pinduoduo.com/api/server/_stm\r\n"
void wifi_get_time(void);
uint8_t SendCmdAndJudgeSuccess(uint8_t *cmd,uint8_t * ack,uint16_t outtime);

void AP();
void STA();
void mqtt_pub(void);
void mqtt_connect(void);

//前三个参数是mqtt
#define CLIENTID "a11eYOq0ru1.P6WNlYrtAnbisS3rfMEm|securemode=2,signmethod=hmacsha256,timestamp=1729079936092|"
#define USERNAME "P6WNlYrtAnbisS3rfMEm&a11eYOq0ru1"
#define PASSWD  "a4a4e8eec7638bc2c74fc057c5e311051261e38f1a2d1730f32191a475f90011"
#define MATTHOSTURL "a11eYOq0ru1.iot-as-mqtt.cn-shanghai.aliyuncs.com"//阿里云ip地址
#define PORT 1883//端口号

#define TOPIC_PUB "/sys/a11eYOq0ru1/P6WNlYrtAnbisS3rfMEm/thing/event/property/post"

//{"clientId":"a11eYOq0ru1.P6WNlYrtAnbisS3rfMEm|securemode=2,signmethod=hmacsha256,timestamp=1729059510986|",
//	"username":"P6WNlYrtAnbisS3rfMEm&a11eYOq0ru1",
//	"mqttHostUrl":"a11eYOq0ru1.iot-as-mqtt.cn-shanghai.aliyuncs.com",
//"passwd":"a9d11176d0ff901a8e93b3d2cb1eebc64b665f1dda595d1532a4d2ed6a97366c",
//"port":1883}

#endif

标签:USART,esp,--,back,mqtt,GPIO,服务器
From: https://blog.csdn.net/m0_71813740/article/details/142998083

相关文章

  • ACME续签证书在Linux云服务器上安装指南
    环境供应商;阿里云服务器操作系统:LinuxCentosStream9操作系统静态代理:Nginx前言我这边使用https://get.acme.sh方式无法正常使用,会卡在这个页面,无任何进度的信息。最终我使用了gitclone的方式进行安装。正文clone项目下来,并进行install初始安装ACME环境gitcloneht......
  • web服务器静态资源下载
    1.使用Beego实现静态文件下载Beego是一个强大的GoWeb框架,提供了处理静态文件的功能。通过简单的配置,我们可以将本地文件夹作为静态资源目录,并为用户提供下载链接。1.1配置静态文件路径首先,在main.go中,我们使用SetStaticPath将本地的staticfiles目录映射为可以通......
  • 了解专用代理服务器的功能
    在当今数字化的环境中,确保安全高效的互联网连接变得至关重要。这种需求催生了专用代理服务器,这是一种确保在线隐私、安全和可访问性的强大工具。了解专用代理服务器的细微差别和功能对于寻求增强在线保护和访问的个人和企业是十分重要的。一、什么是专用代理服务器?专用代理服......
  • 2-STM32F103+ML307(中移4G Cat1)OTA升级篇(自建物联网平台)-STM32通过ML307使用http或
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ZLIOTB/ML307/myota.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  说明前面......
  • Linux服务器上安装git(运维向)
    (1).参考文献官网在线教程:https://git-scm.com/book/zh/v2官方网站:https://git-scm.com/(2).实验环境2核2GCentOS7.6.1810(3).安装git1)yum或dnf安装[root@VM-0-17-centos~]#dnf-yinstallgit-all2)源码安装安装依赖包[root@VM-0-17-centos~]#dnf......
  • 千千静听歌词搜索:第三方歌词服务器使用方法
    因为千千静听官方服务器已经停用,因此只能使用第三方歌词服务器资源都来自于网络,本人只是搬运工,两个个方法。方法一:修改配置文件ttp_lrcsh.ini配置文件如下,txt另存为ttp_lrcsh.ini,要把ttp_lrcsh.ini文件属性只读模式,软件后台会自动删除此文件。下载歌词配置并放入AddIn文件夹即可使......
  • PTP授时同步时钟介绍 PTP授时服务器 PTP主时钟
    移动运营商向4G网络的升级,对于业务性能监测,随时获得高精度时间信号的需求也越来越高。而PTP授时同步主时钟为此提供了一个完美的解决方案。如果不能满足这样的要求,移动运营商会面对很大的挑战,网络会变得很不稳定。PTP时间同步解决方案为移动支撑网络提供了完善的同步解决方案,包括了......
  • 异步服务器编写过程
    boost::asio::io_context的作用boost::asio::io_context是Boost.Asio库中的一个核心组件,主要用于管理异步事件和任务的执行。它在网络编程、并发编程和异步操作中发挥着重要作用。主要作用事件循环:io_context提供了一个事件循环,可以调度和处理异步操作。当有事件发......
  • Zabbix进阶实战!将告警推送到Syslog服务器详细教程
    需求场景:用户需要将zabbix产生的告警事件推送给rsyslog服务器,syslog服务器再对事件日志进行分析处理.环境配置信息服务器IP地址ZabbixServer192.168.200.195Rsyslog服务器192.168.200.128*Rsyslog服务器防火墙需要放通UDP/514端口推送脚本需要修......
  • 基于RabbitMQ(windows)的MQTT(WSS)的安装配置和使用
    RabbitMQ官网地址https://www.rabbitmq.com/1.安装Erlang/OTP2.安装RabbitMQ3.开启后台管理rabbitmq-pluginsenablerabbitmq_managementhttp://127.0.0.1:15672/#/ 用户名密码默认guest4.开启mqttrabbitmq-pluginsenablerabbitmq_mqtt开启webmqttrabbitmq-pluginsenab......