2016-10-27 4 views
0

Я пытаюсь получить до 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

При отправке линии

Хорошо, что один

Это не 16 символов, а 17, потому что есть \n характер, в конце концов. Что делает Serial.readBytesUntil('\n',textMatrix[lineCount],16);, в этом случае он вынимает первые 16 символов из буфера. После этой операции остается только новая строка \n, которая в следующей итерации цикла считывается как пустая строка.

Чтобы противостоять этому, вы можете проверить переменную res, и если вы увидите, что она равна 16, отмените следующее чтение. Или выполните еще несколько проверок в случае, если строка длиннее 16 + новой строки.

0

Вот один из способов ... просто читать CHARS себя:

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 
Смежные вопросы