Получить всю строку в данных последовательной отправки?

Я подключаю NodeMCU к Arduino Uno. Цель состоит в том, чтобы получать всю строку, например "12", каждую 1 секунду.

Это мой код на стороне Arduino Uno (отправитель)

int mock = 0;

void setup() {
  Serial.begin(115200);
  s.begin(115200);
}

void loop() {
    // Записываем макет в NodeMCU
    s.print((int)mock,DEC);
    s.println();

    mock++;
    delay(1000);
}

На стороне NodeMCU (приемник)

 char data; //Инициализируемая переменная для хранения полученных данных
 String line;
 void setup() {
   Serial.begin(115200);
   s.begin(115200);
   while (!Serial) {
    ; 
  }
}

void loop() {

    if( s.available() >= 2) {
        for (int i = 0; i< 2; i++ ) {
            data = s.read();
            line += data;
        }
        delay(1000);
    }


    Serial.print(line);

}

Но результат на серийной панели не такой, как я ожидал Последовательный терминал

Как мне сделать так, чтобы я мог получать что-то вроде

12
(wait one sec)
13
(wait one sec)
....

Node MCU просто распечатывает все это, я не могу откладывать.

, 👍1

Обсуждение

Я не вижу, чтобы вы печатали то, что прочитали. Также строка не определена в вашем коде. Пожалуйста, предоставьте полный минимальный пример, @chrisl

@chrisl Извините, я забыл включить объявление переменной. Я планирую использовать «линию» для хранения всех полученных данных, а затем выводить их на консоль., @Thang Nguyen


2 ответа


Лучший ответ:

0

при использовании nodemcu

void loop() {
    if(s.readBytesUntil('\n',data ,2)>0)
      Serial.println(data);
    delay(1000);
}

Serial.readBytesUntil(символ, буфер, длина)

Serial.readBytesUntil() считывает символы из последовательного буфера в массив. Функция завершается (проверки выполняются в этом порядке), если определенная длина была прочитана, если истекло время ожидания или обнаружен символ конца (в этом случае функция возвращает символы до последнего символа перед предоставленным терминатором) . Сам терминатор не возвращается в буфер.

Serial.readBytesUntil() возвращает количество символов, считанных в буфер. 0 означает, что параметр длины <= 0, тайм-аут произошел до любого другого ввода или символ завершения был найден до любого другого ввода.

,

readBytesUntil ожидает данные в течение секунды. лучше дождаться первого символа с помощью Serial.available(). и ты не справляешься \r, @Juraj

да, он собирается напечатать это в консоли \r\r означает дважды вернуться к началу строки без разницы в результате если ему нужен лучший подход, ему нужно определить два байта или более заголовка и контрольную сумму, а затем определить пакет постоянного размера, чтобы он мог найти лучшее решение с еще более высокой скоростью, кроме того, я бы изменил отправителя s.print ((int) mock, DEC ); с.принтлн(); to s.print((int)mock,DEC); s.print('\n'), @david


1

Если вы отправляете "12", вы отправляете 4 символа/байта: "1", "2" и новую строку, состоящую из двух символов: ('\r', '\n').

На стороне получателя вы проверяете два символа (а не новую строку), поэтому вам следует принять это во внимание.

На самом деле, поскольку вы в конечном итоге достигнете "100", вы получите 5 символов ("1", "0", "0", "\r", \"n").

Поэтому лучше изменить сторону получателя, чтобы хранить байты в строке ДО получения новой строки (чем вы можете поддерживать значения любой длины).

Также уберите задержку на стороне получателя или, по крайней мере, значительно уменьшите ее, потому что не имеет значения проверка (слишком) часто. если нет доступного байта, он проверит снова. Теперь это может произойти в момент времени 1001 мс, байт будет получен, но в момент времени 1000 мс он будет проверен и не будет проверяться снова до момента времени 2000 мс.

,

println() это \r\n, @Juraj

@Juraj Спасибо (я должен был знать)., @Michel Keijzers