Serial.read: почему разбивается строка приема?
- Войдите на сайт для отправки комментариев
Чт, 20/09/2018 - 09:50
Никак не при ходит в голову почему так. Отправляю в Serial строку, программа выдает два результата: первый байт как отдельную строку и остаток строки отдельно. А нужна строка целиком.
uint8_t bytes; char buffer[255]; void setup() { Serial.begin (115200); delay(3000); Serial.println ("Ready!"); buffer[0] = 0; } void loop() { bytes = Serial.available(); if (bytes > 0) { Serial.println (); Serial.print (">>> Bytes: "); Serial.println (bytes); uint8_t i = 0; while (i < bytes) { buffer[i] = (char) Serial.read(); Serial.print (">>> Copying "); Serial.print (i); Serial.print (" byte "); Serial.println (buffer[i]); i++; delay (10); } buffer[i] = 0; Serial.print (">>> Buffer: "); Serial.println (buffer); Serial.println(); } }
Простое совпадение.
Поставьте скорость меньше, уберите delay(), переставьте операторы местами - картина изменится. RX буфер объекта Serial заполняется по прерыванию. Поэтому он может быть дополнен на середине любой операции не блокирующей прерывания.
Нужна строка целиком - используйте терминатор строки или ловите паузу (за секунду не увеличился буфер - значит передача окончена).
или используйте строки фиксированной длинны, и вычитывайте буфер когда в нем уже накопилось необходимое количество байт.
Возможно пока вы что-то "обрабатываете" приходят ешё данные?
То есть вы не всю сторку считали.....
Попробуйте всавить после 23 строчки две вот таких:
Serial.println (bytes);
Serial.println (Serial.available());
Отправляю в Serial строку
Надо для себя ответить на вопрос: что есть строка. Например, если вы отправляете "Hello, world!", а в буфер на момент проверки попало только "Hell" - это строка? Формально - да, т.к. строка - это набор символов. Понимаете, о чём я? Надо иметь признак - что вот, данные ПОЛНОСТЬЮ упали в приёмный буфер. Что будет этим признаком - выбирать вам, например, этим признаком может служить символ перевода строки '\n', или ещё чего.
Сделал так:
Сделал так:
по-моему, никакой разницы с первоначальным - строка ровно точно так же может биться на части.
Вы поняли, что вам писал DIYMan о признаке конца строки? И где это в коде?
Работает однако. Serial.available() возвращает нужное количество байт, их количество и читаем.
Работает однако. Serial.available() возвращает нужное количество байт, их количество и читаем.
Случайность. Идея все равно неверная. 100% потом будет глючить.
Serial.available() у вас возвращает то количество байт, которое уже лежит в буфере. Если строка к этому моменту еще не пришла целиком - получите только часть.
Единственный рабочий метод - тот. что описал DIYMan.
Единственный рабочий метод - тот. что описал DIYMan.
категорично !
я уже писал как делаю, шлю (допустим) 0х55,0хАА это типа синхронизации, далее байт с длиной пакета, далее данные.
этот метод не рабочий ?
Единственный рабочий метод - тот. что описал DIYMan.
категорично !
я уже писал как делаю, шлю (допустим) 0х55,0хАА это типа синхронизации, далее байт с длиной пакета, далее данные.
этот метод не рабочий ?
Это ровно то же самое, что описал я: у тебя признак конца пакета - вычисляемый от "байт с длиной пакета". Но - признак конца пакета - ЕСТЬ. У ТС - нет. В твоём случае код будет таким, навскидку:
Чисто для демонстрации, что и при таком подходе есть ОДНОЗНАЧНЫЙ признак конца пакета с данными. О чём я и писал.
Работает однако. Serial.available() возвращает нужное количество байт, их количество и читаем.
Это до чтения, а после чтения должен быть ноль.
прочитал еще раз, ключевые слова "Что будет этим признаком - выбирать вам,"
согласен ! :)
Более того: в продвинутых случаях (например, при включении устройства в шину с данными в любой момент времени) - зачастую требуется синхронизация по началу пакета, т.е.: мы должны однозначно синхронизироваться так, чтобы буть уверенными - мы на начале пакета с данными. Для этого тоже есть простые механизмы поиска фрейма синхронизации в потоке принятых данных. Иначе - легко получить поведение, когда вроде бы устройство в сети, получает данные - но, не реагирует, потому что при включении просохатило первые два байта.