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

Arduino串口字符串处理:用char数组提取指定区间前4个字符

用Char数组实现Arduino串口字符串提取的清晰方案

你好!作为Arduino新手,选择用char数组替代String类是个非常明智的决定——char数组在内存管理上更可控,能避免String类可能带来的内存碎片化问题,特别适合资源有限的Arduino设备。咱们先梳理下你现有代码的小问题,再一步步实现符合需求的功能。

现有代码的几个待优化点

  1. 你用了固定字符串s,但实际需求是从串口动态读取数据,这部分逻辑需要补充
  2. loop()里直接return 0会让程序停止运行,Arduino的loop()应该是持续循环执行的
  3. 使用malloc动态分配内存虽然可行,但对于简单场景,用静态缓冲区更安全,避免内存泄漏风险
  4. 提取前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();
}

关键逻辑解释

  1. 串口接收缓冲区:用静态数组serialBuffer存储串口数据,避免动态内存分配的风险,缓冲区大小可根据你实际接收的字符串长度调整(Arduino Uno的SRAM只有2KB,别设太大)
  2. 标记查找:用标准库函数strstr查找!和#的位置,这个函数会返回匹配字符的指针,非常适合字符串分割场景
  3. 边界安全:加入了缓冲区满的判断、标记是否存在的判断,避免数组越界或空指针错误
  4. 结果输出:直接从startMarker指针开始取前4个字符,无需额外存储整个区间,节省内存

测试方法

打开Arduino串口监视器,发送类似234124!3455addg#5867的字符串,记得勾选串口监视器右下角的“换行”选项,程序会输出3455;如果发送的字符串中!和#之间不足4个字符(比如abc!12#def),会输出12。

内容的提问来源于stack exchange,提问作者ReduX Completedy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 09:52:40