STM32 MQTT协议 连接中国移动OneNet服务器 上传接收数据(三)STM32部分

STM32 MQTT协议 连接中国移动OneNet服务器 上传接收数据(三)STM32部分

关于单片机部分主要使用ESP8266 WIFI模块进行联网,单片机采用STM32ZET6

ESP8266部分

在这里插入图片描述

ESP8266是一款使用非常广泛的WIFI模块,这里我们通过单片机的AT指令来控制它
这里有8266的AT指令手册:https://www.espressif.com/sites/default/files/documentation/2a-esp8266-sdk_getting_started_guide_cn.pdf
在进行程序测试之前,推荐使用串口调试助手直接连接8266测试AT指令,和检查模块是否可用
在这里插入图片描述

关于ESP8266的具体细节可以查看官网接下来来讲解STM32程序部分

STM32程序

因为MQTT的协议建立在TCP的连接之上,所以我们要用8266建立一个TCP连接,我们对照手册进行设置

我们首先把8266初始化

	UsartPrintf(USART_DEBUG, "1. AT\r\n");//检查AT指令是否可用
	while(ESP8266_SendCmd("AT\r\n", "OK"))
		DelayXms(500);
	
	UsartPrintf(USART_DEBUG, "2. CWMODE\r\n");//将8266设置为STA模式
	while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))
		DelayXms(500);
	
	UsartPrintf(USART_DEBUG, "3. AT+CWDHCP\r\n");//开启DHCP
	while(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK"))
		DelayXms(500);
		

	UsartPrintf(USART_DEBUG, "4. CWJAP\r\n");//设置要连接的WIFID的SSID和密码
	//ESP8266_WIFI_INFO		"AT+CWJAP=\"Lord AC\",\"19981220\"\r\n"
	while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "OK"))
		DelayXms(500);
	
	UsartPrintf(USART_DEBUG, "5. CIPSTART\r\n");//设置为TCP连接,并设定IP和端口号
	//ESP8266_ONENET_INFO		"AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002\r\n"
	while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))
		DelayXms(500);
	
	UsartPrintf(USART_DEBUG, "6. ESP8266 Init OK\r\n");//初始化完成

完成以上步骤TCP连接就成功建立了,将产品ID等写成宏定义,通过函数封装连接平台(具体的封装函数不做详解,都是C语言的知识,之后会将整个工程放到Github)

#define PROID		"367119"

#define AUTH_INFO	"test"

#define DEVID		"619588959"

	if(MQTT_PacketConnect(PROID, AUTH_INFO, DEVID, 256, 0, MQTT_QOS_LEVEL0, NULL, NULL, 0, &mqttPacket) == 0)
	{
		ESP8266_SendData(mqttPacket._data, mqttPacket._len);			//上传平台
		
		dataPtr = ESP8266_GetIPD(250);									//等待平台响应
		if(dataPtr != NULL)
		{
			if(MQTT_UnPacketRecv(dataPtr) == MQTT_PKT_CONNACK)
			{
				switch(MQTT_UnPacketConnectAck(dataPtr))
				{
					case 0:UsartPrintf(USART_DEBUG, "Tips:	连接成功\r\n");status = 0;break;
					
					case 1:UsartPrintf(USART_DEBUG, "WARN:	连接失败:协议错误\r\n");break;
					case 2:UsartPrintf(USART_DEBUG, "WARN:	连接失败:非法的clientid\r\n");break;
					case 3:UsartPrintf(USART_DEBUG, "WARN:	连接失败:服务器失败\r\n");break;
					case 4:UsartPrintf(USART_DEBUG, "WARN:	连接失败:用户名或密码错误\r\n");break;
					case 5:UsartPrintf(USART_DEBUG, "WARN:	连接失败:非法链接(比如token非法)\r\n");break;
					
					default:UsartPrintf(USART_DEBUG, "ERR:	连接失败:未知错误\r\n");break;
				}
			}
		}
		
		MQTT_DeleteBuffer(&mqttPacket);								//删包
	}

串口1会打印调试信息,我们可以看到已经成功连接,并且我们打开OneNET后台,也可以看到设备上线
在这里插入图片描述
在这里插入图片描述

发送数据

采用JSON格式将数据封成包,然后上传

unsigned char OneNet_FillBuf(char *buf)
{
	char text[48];
	
	memset(text, 0, sizeof(text));
	
		strcpy(buf, "{");
	
    memset(text, 0, sizeof(text));
		sprintf(text, "\"test\":%d,",666); 
    strcat(buf, text);
		
		memset(text, 0, sizeof(text));
		sprintf(text, "\"test2\":%d",888); 
    strcat(buf, text);
	
		strcat(buf, "}");
	
	return strlen(buf);
}


void OneNet_SendData(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};												//协议包
	
	char buf[128];
	
	short body_len = 0, i = 0;
	
	UsartPrintf(USART_DEBUG, "Tips:	OneNet_SendData-MQTT\r\n");
	
	memset(buf, 0, sizeof(buf));
	
	body_len = OneNet_FillBuf(buf);																	//获取当前需要发送的数据流的总长度
	
	if(body_len)
	{
		if(MQTT_PacketSaveData(DEVID, body_len, NULL, 3, &mqttPacket) == 0)							//封包
		{
			for(; i < body_len; i++)
				mqttPacket._data[mqttPacket._len++] = buf[i];
			
			ESP8266_SendData(mqttPacket._data, mqttPacket._len);									//上传数据到平台
			UsartPrintf(USART_DEBUG, "Send %d Bytes\r\n", mqttPacket._len);
			
			MQTT_DeleteBuffer(&mqttPacket);															//删包
		}
		else
			UsartPrintf(USART_DEBUG, "WARN:	EDP_NewBuffer Failed\r\n");
	}
	
}

同时我们可以在后台查看到刚刚上传的数据
在这里插入图片描述

至此我们成功完成上传数据

项目文件地址

附上整个项目的github地址https://github.com/DevilAC/MQTT-STM32-ESP8266/tree/master

### 关于 Token 无效错误的分析 当处理 JSON 数据时,`SyntaxError: Unexpected token u in JSON at position X` 的错误通常表明在尝试解析 JSON 字符串的过程中遇到了非法字符或格式问题。具体到 `position 32` 这一位置上的错误,可能的原因包括但不限于以下几种情况: 1. **JSON 格式不合法**:输入字符串并非有效的 JSON 格式,可能是由于拼写错误、多余的逗号或其他语法问题引起的。 2. **未转义特殊字符**:某些特殊字符(如双引号 `"`, 反斜杠 `\` 等)如果没有被正确转义,则可能导致解析失败。 3. **数据源为空或损坏**:如果传入的数据源本身为空或者已经损坏,在调用 `JSON.parse()` 方法时会引发异常。 针对上述提到的一元一次方程场景下的 JSON 解析错误,可以采取类似的预防措施来避免此类问题的发生。例如,在实际应用之前先验证并清理接收到的数据流,确保它们符合预期的标准后再继续后续操作[^1]。 以下是改进后的代码实现方式: ```javascript if (this.detail && this.detail.otherInfo) { try { const parsedData = JSON.parse(this.detail.otherInfo); if (parsedData.token !== undefined && typeof(parsedData.token) === 'string') { console.log('Validated token:', parsedData.token); // 继续其他逻辑... } else { throw new Error("Invalid or missing token field"); } } catch (error) { console.error(`Failed to parse JSON data due to ${error.message}`); this.jdList = []; // 或者设置默认值以防崩溃 } } else { console.warn('No valid otherInfo found.'); } ``` 通过增加非空检测以及利用 `try-catch` 块捕获潜在异常的方式能够有效提升程序健壮性,减少因意外输入而导致的应用中断风险。 另外需要注意的是,虽然这里讨论的重点在于前端开发环境中的解决方案,但如果涉及更复杂的图形渲染需求比如移动端设备上的高质量反射效果,则还需要考虑硬件兼容性和特定配置选项的影响因素][^[^23]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值