2016-10-27 9 views
0

Ich versuche, bis zu 64 Zeilen von maximal 16 Zeichen auf einem LCD-Bildschirm über serielle angezeigt werden. Diese Zeilen müssen beim Start angegeben werden. Ich habe die folgende bekam, die in den meisten Fällen funktioniert:Lesen mehrerer Zeilen von der seriellen

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; 
     } 
    } 
    } 
} 

Das Problem tritt auf, wenn ich die folgende Zeile an:

Okay, das ist ein

Diese Linie ist genau 16 Zeichen lang. Ich nehme an, dass dies dazu führt, dass readBytesUntil zweimal ausgelöst wird, was dazu führt, dass es dasselbe ist, als würde man zweimal Enter drücken. Es scheint mir nicht möglich zu sein, einen Unterschied zwischen dem Senden einer leeren Zeile oder dem Senden einer Zeile mit genau 16 Zeichen zu finden. Was wäre der beste Weg, dies zu lösen?

Antwort

0

Wenn Sie die Linie

Ordnung senden, das ist ein

, die nicht 16 Zeichen ist, aber 17, weil es \n Charakter am Ende ist. Was Serial.readBytesUntil('\n',textMatrix[lineCount],16); tut, ist in diesem Fall, dass es die ersten 16 Zeichen aus dem Puffer herausnimmt. Nach dieser Operation ist nur noch die neue Zeile \n übrig, die in der nächsten Iteration der Schleife als Leerzeile gelesen wird.

Um dem entgegenzuwirken, können Sie res Variable überprüfen, und wenn Sie sehen, dass es 16 entspricht, verwerfen Sie den nächsten Lesevorgang. Oder führen Sie weitere Überprüfungen durch, falls eine Zeichenfolge länger als 16 + neue Zeile vorhanden ist.

0

Hier ist eine Möglichkeit, ... Lesen Sie die Zeichen selbst:

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 
Verwandte Themen