Arduino UDP接收ASCII与十六进制混合数据问题:LED Cube显示异常
问题根源分析
核心错误是将十六进制字符串的ASCII字符直接作为数值赋值给LED颜色通道,而非将十六进制字符串解析为对应的字节值。
比如传入data:000000时,payload指向的是字符串"000000",其中每个字符'0'的ASCII码是0x30(十进制48),直接取payload[0]得到的是48而非0,这就导致LED的RGB通道被设置为非0值,从而显示彩色。
代码修正方案
1. 添加十六进制字符串转字节的工具函数
实现两个辅助函数,完成单个十六进制字符到数值、双字符到字节的转换:
// 将单个十六进制字符转换为0-15的数值 uint8_t hexCharToByte(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); return 0; // 非法字符默认返回0 } // 将两个十六进制字符组成的字符串转换为0-255的字节 uint8_t hexStrToByte(const char* str) { uint8_t high = hexCharToByte(str[0]); uint8_t low = hexCharToByte(str[1]); return (high << 4) | low; }
2. 修改data指令的处理逻辑
替换原有的data循环代码,使用工具函数正确解析十六进制字符串:
else if(strcmp(command,"data")==0){ // 校验payload长度:每个LED需要6个十六进制字符(RGB各2个) if(strlen(payload) != NUM_LEDs * 6){ if(DEBUG) Serial.println("Error: payload length mismatch"); return; } for(int i = 0; i< NUM_LEDs; i++){ // 定位当前LED对应的十六进制字符串起始位置 const char* ledHex = &payload[i*6]; int r = hexStrToByte(ledHex); int g = hexStrToByte(ledHex + 2); int b = hexStrToByte(ledHex + 4); rCurr[i] = map(r, 0,255, 0, MAX_BRIGHTNESS); gCurr[i] = map(g, 0,255, 0, MAX_BRIGHTNESS); bCurr[i] = map(b, 0,255, 0, MAX_BRIGHTNESS); if(DEBUG){ Serial.print(r); Serial.print(","); Serial.print(g); Serial.print(","); Serial.println(b); } } }
额外注意事项
- 确保UDP数据包中
data指令的payload无空格、无换行,严格遵循每个LED用6个十六进制字符表示的格式(比如黑色为000000,红色为FF0000)。 - 可通过DEBUG输出查看解析后的r/g/b值,确认是否正确转换为0-255的范围。
- 若数据包末尾存在换行符等多余字符,需提前去除,避免解析错误。
内容的提问来源于stack exchange,提问作者Collin
相关产品推荐
相关产品推荐

