You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F103F使用HAL_UART_Transmit发送含NULL(0x00)数据时ESP无法完成MQTT发布的问题求助

问题分析与解决方案

核心原因

你遇到的问题本质是字符串解析依赖0x00作为结束符,不管是C语言的字符串函数,还是ESP的AT指令解析逻辑,都会把0x00当成字符串的终止标志:

  • 虽然你的代码里用for循环完整拷贝了包含0x00的CMD2数据,但ESP在解析AT+MQTTPUB指令中被双引号包裹的消息内容时,会在第一个0x00处停止解析,直接忽略后面的所有内容(包括你补的结尾双引号和换行),导致AT指令不完整,ESP无法执行发布操作。
  • 哪怕你最后指定了正确的串口发送长度,ESP的AT指令解析器仍然会按字符串规则处理消息字段,不会识别后面的字节。

解决方法

改用ESP AT指令的二进制数据发布模式,直接指定要发布的数据长度,让ESP按字节数读取数据,而不是按字符串解析。这种模式下,0x00会被当作普通二进制字节处理,不会触发截断。

修改后的代码示例

// 1. 构造AT指令前缀:明确指定要发布的数据长度
char PubPrefix[64]; // 根据你的SerialNumber长度调整缓冲区大小
// 使用snprintf获取实际写入的前缀长度(避免strlen可能的问题)
int prefixLen = snprintf(PubPrefix, sizeof(PubPrefix), "AT+MQTTPUB=0,\"Data/%s\",%d,", SerialNumber, DataLength);

// 2. 发送AT指令前缀
HAL_UART_Transmit(huart, (uint8_t *)PubPrefix, prefixLen, 10);

// 3. 发送CMD2中的原始二进制数据(包含0x00也没问题)
HAL_UART_Transmit(huart, (uint8_t *)CMD2, DataLength, 10);

// 4. 发送指令结束的换行符
char cmdEnd[] = "\r\n";
HAL_UART_Transmit(huart, (uint8_t *)cmdEnd, sizeof(cmdEnd)-1, 10);

关键说明

  • 这个方案不再把二进制数据放到双引号里,而是通过%d告诉ESP要发布的数据字节数,ESP会严格按照这个长度读取后面的二进制内容,完全不受0x00影响。
  • 确保PubPrefix的缓冲区足够容纳你的SerialNumber和DataLength的字符串形式,避免缓冲区溢出。
  • 原代码中的Appendix是用来补全字符串形式的消息结尾,现在用二进制模式不需要这部分,可以直接删除。

内容的提问来源于stack exchange,提问作者M.Navidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 11:28:12