ESP32调用esp_now_send分块传数组时处理非满长度末块的方法
ESP-NOW分块发送整数数组 最后非满分块无0填充修改方案
问题根因
当前实现固定按5个整数的长度做数据拷贝、固定以5*sizeof(int)作为长度参数调用esp_now_send,最后一块不足5个元素时,会把缓冲区里默认填充的0值一并发送,接收端又固定按5个元素解析,就会出现多余的0。
具体修改步骤
- 发送端分块逻辑动态计算每块有效长度
分块遍历原数组时,不要硬编码块长度:- 若当前块起始位置 + 5 不超过数组总长度,当前块有效元素数为5
- 若当前块起始位置 +5 超过数组总长度,当前块有效元素数为「数组总长度 - 当前块起始索引」
调用esp_now_send时,第三个发送长度参数传「有效元素数 * sizeof(int)」,不要硬编码固定长度。
- 接收端按实际接收长度解析数据
接收回调函数里自带recv_len参数,代表实际收到的字节数,用这个值除以sizeof(int)就能得到当前块的有效整数个数,只遍历输出这部分元素即可,不要固定读取5个位置。
参考代码片段
发送端分块发送逻辑
#define CHUNK_FIXED_SIZE 5 int data_array[] = {1,2,3,4,5,6,7,8,9,10,11,12}; int array_total_len = sizeof(data_array) / sizeof(data_array[0]); for (int offset = 0; offset < array_total_len; offset += CHUNK_FIXED_SIZE) { // 计算当前块的实际有效元素数量 int cur_valid_len = (offset + CHUNK_FIXED_SIZE > array_total_len) ? (array_total_len - offset) : CHUNK_FIXED_SIZE; int send_buffer[CHUNK_FIXED_SIZE]; // 仅拷贝有效长度的数据 memcpy(send_buffer, data_array + offset, cur_valid_len * sizeof(int)); // 关键:传入实际有效字节数作为发送长度 esp_now_send(peer_mac_addr, (uint8_t*)send_buffer, cur_valid_len * sizeof(int)); vTaskDelay(pdMS_TO_TICKS(10)); // 加短延时避免发包拥塞丢包 }
接收端回调解析逻辑
void esp_now_recv_callback(const uint8_t *mac, const uint8_t *recv_data, int recv_len) { // 按实际接收字节数计算有效整数个数 int valid_num = recv_len / sizeof(int); int *recv_arr = (int*)recv_data; // 仅遍历有效元素,不会输出多余填充值 for (int i = 0; i < valid_num; i++) { printf("%d ", recv_arr[i]); } printf("\n"); }
注:ESP-NOW单次发送最长支持250字节 payload,只要单块长度不超过该阈值就可以正常传输,不需要强制凑固定块长。
内容的提问来源于stack exchange,提问作者lena
相关产品推荐
相关产品推荐

