Arduino串口字符串处理:用char数组提取指定区间前4个字符
用Char数组实现Arduino串口字符串提取的清晰方案
你好!作为Arduino新手,选择用char数组替代String类是个非常明智的决定——char数组在内存管理上更可控,能避免String类可能带来的内存碎片化问题,特别适合资源有限的Arduino设备。咱们先梳理下你现有代码的小问题,再一步步实现符合需求的功能。
现有代码的几个待优化点
- 你用了固定字符串
s,但实际需求是从串口动态读取数据,这部分逻辑需要补充 loop()里直接return 0会让程序停止运行,Arduino的loop()应该是持续循环执行的- 使用
malloc动态分配内存虽然可行,但对于简单场景,用静态缓冲区更安全,避免内存泄漏风险 - 提取前4个字符的逻辑可以更直接,无需先存储整个
!和#之间的内容,节省内存
改进后的完整代码
下面是适配串口读取、用char数组实现需求的代码,每一步都加了详细注释:
#define BUFFER_SIZE 64 // 定义串口接收缓冲区大小,根据需求调整,不要超过Arduino内存 char serialBuffer[BUFFER_SIZE]; // 存储串口接收的字符串 int bufferIndex = 0; // 缓冲区当前的写入位置 void setup() { Serial.begin(9600); memset(serialBuffer, 0, BUFFER_SIZE); // 初始化缓冲区为全0 } void loop() { // 持续读取串口数据,直到收到换行符(或缓冲区满) while (Serial.available() > 0) { char incomingChar = Serial.read(); // 收到换行/回车符,说明一条完整指令接收完成 if (incomingChar == '\n' || incomingChar == '\r') { processReceivedString(serialBuffer); // 处理接收到的字符串 // 重置缓冲区,准备接收下一条指令 bufferIndex = 0; memset(serialBuffer, 0, BUFFER_SIZE); } // 如果缓冲区还没满,就把字符存入缓冲区 else if (bufferIndex < BUFFER_SIZE - 1) { // 留一个位置存字符串结束符'\0' serialBuffer[bufferIndex++] = incomingChar; } } } // 核心处理函数:提取!和#之间的前4个字符 void processReceivedString(char* input) { // 查找起始标记'!'的位置 char* startMarker = strstr(input, "!"); if (startMarker == NULL) { Serial.println("未找到起始标记'!'"); return; } startMarker++; // 跳过'!',指向后续内容的第一个字符 // 查找结束标记'#'的位置 char* endMarker = strstr(startMarker, "#"); if (endMarker == NULL) { Serial.println("未找到结束标记'#'"); return; } // 计算!和#之间的字符长度,确保最多取4个(如果不足4个就取全部) int contentLength = endMarker - startMarker; int outputLength = min(contentLength, 4); // 输出结果 Serial.print("提取到的字符:"); for (int i = 0; i < outputLength; i++) { Serial.print(startMarker[i]); } Serial.println(); }
关键逻辑解释
- 串口接收缓冲区:用静态数组
serialBuffer存储串口数据,避免动态内存分配的风险,缓冲区大小可根据你实际接收的字符串长度调整(Arduino Uno的SRAM只有2KB,别设太大) - 标记查找:用标准库函数
strstr查找!和#的位置,这个函数会返回匹配字符的指针,非常适合字符串分割场景 - 边界安全:加入了缓冲区满的判断、标记是否存在的判断,避免数组越界或空指针错误
- 结果输出:直接从
startMarker指针开始取前4个字符,无需额外存储整个区间,节省内存
测试方法
打开Arduino串口监视器,发送类似234124!3455addg#5867的字符串,记得勾选串口监视器右下角的“换行”选项,程序会输出3455;如果发送的字符串中!和#之间不足4个字符(比如abc!12#def),会输出12。
内容的提问来源于stack exchange,提问作者ReduX Completedy
相关产品推荐
相关产品推荐

