从串口读取多行

时间:2016-10-27 12:22:41

标签: arduino

我试图通过串口在液晶显示屏上显示64行最多16个字符。这些行必须在启动期间给出。我得到了以下内容,大多数情况下都有效:

unsigned char textMatrix[64][17];
unsigned char lineCount = 0;
void readLines(){
  Serial.println("Send up to 64 lines of up to 16 characters. Send an empty line to stop sending lines. Make sure to use \\n (newline) as line terminator!");
  Serial.setTimeout(10000);
  bool receiving = true;
  while (receiving){
    if(Serial.available() > 0) {
      textMatrix[lineCount][0] = '\0';
      char res = Serial.readBytesUntil('\n',textMatrix[lineCount],16);
      if (res == 0){
        if (textMatrix[lineCount][0] != '\0'){
          continue;
        }
        Serial.println("Received empty line");
        receiving = false;
        break;
      }
      textMatrix[lineCount][16] = '\0';
      Serial.print("Received line: ");
      Serial.println((const char*)textMatrix[lineCount]);
      lineCount++;
      if (lineCount >= 63){
        receiving = false;
      }
    }
  }
}

发送以下行时会出现问题:

  

好的,那是

这一行长度恰好是16个字符。我假设这导致readBytesUntil触发两次,导致它与按两次输入相同。我似乎无法在认真发送空行或发送正好16个字符的行之间找到区别。解决这个问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

发送行

  

好的,那是一个

这不是16个字符而是17个,因为最后有\n个字符。 Serial.readBytesUntil('\n',textMatrix[lineCount],16);在这种情况下的作用是从缓冲区中取出前16个字符。在该操作之后,唯一剩下的就是新行\n,它在循环的下一次迭代中被读作空行。

要解决此问题,您可以检查res变量,如果您发现它等于16,则放弃下一次读取。或者在有超过16 +新行的字符串时再做一些检查。

答案 1 :(得分:0)

这是一种方式......只需自己阅读字符:

unsigned char textMatrix[64][17];
const uint8_t MAX_WIDTH = sizeof( textMatrix[0] );
const uint8_t MAX_LINES = sizeof( textMatrix ) / MAX_WIDTH;

unsigned char lineCount = 0;

void readLines(){

  uint32_t startTime = millis();
  uint8_t  column    = 0;

  do {
    if (Serial.available()) {
      char c = Serial.read();

      if (c == '\n') {
        if ((lineCount >= MAX_LINES) || (column == 0))
          break; // too many lines or empty line

        textMatrix[ lineCount ] [ column ] = '\0'; // NUL-terminate

        lineCount++; // start accumulating a new line
        column = 0;

      } else if (column < MAX_WIDTH-1) {
        // room for another char on this line
        textMatrix[ lineCount ] [ column ] = c;
        column++;

      } // else
        //   ignore rest of line
    }
  } while (millis() - startTime < 10000UL); // TIMEOUT == 10s

} // readLines