我试图通过串口在液晶显示屏上显示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个字符的行之间找到区别。解决这个问题的最佳方法是什么?
答案 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