Подскажите , пожалуйста, как решить такой вопрос? в Serial Arduino Nano по команде приходит такой пакет байтов от устройства: Код (C++): 0:00AA4029066244 1:0000000000312A 2:2D760000310001 3:000000486809C8 4:2D760000680001 5:0000004800312A 6:00000000680001 7:00AA4000AA0001 8:00031001006001 9:09AA00486809C8 ... и так далее еще 10 строк Просто чтение буфера UART не не работает, последние строки обрезаются. Как вытащить байты из последних строк пакета? Именно в них содержится нужные данные. Пример чтения пакета байтов небольшого размера рабоает без проблем: Код (C++): while (Serial.available()) { char inChar = (char)Serial.read(); inputString += inChar; if (inChar == '\n') Serial.println(inputString); Ткните ссылку, где почитать? Спасибо.
Нет в потоке строк, все это байты и перевод строки тоже определенный байт. Могу предположить, что используя string вы просто не успеваете опустошать буфер приема, буфер переполняется и информация теряется (не вытаскивается из регистра приема, так как буфер переполнился ). Для начала попробуйте снизить скорость обмена между устройствами.
длина пакета данных всегда одинаковая? Если да - то просто пропускайте ненужные байты, не записывая. Если пакеты разные - то для начала нужно разобраться, как определить длину пакета.
Здесь вы накапливаете массив (строку) байт размером минимум 14х20=280. Плюс служебные байты. Что-то вспоминаются ограничения (256 символов) на длину строки !!! Ему места зарезервировано ? А если не накапливать массив, а печатать каждый байт ?
Я же написал, избавьтесь от String, он тут не нужен, а операция добавления символа в строку типа String - не быстрое дело связанное с выделением новой динамической памяти и перетаскиванием накопленных символов в новую память. Убирайте String, выделите массив байт char, судя по вашему примеру - 20 байт должно хватить. Считали новое значение. Получили '\n' - записали в массив 0, вывели массив, сбросили указатель на последний байт в 0. Получили НЕ '\n' - Записывайте байт в массив, увеличиваем указатель на последний байт (сдвигаемся на следующий байт). В коде будет выглядеть как то так: Код (C++): static unsigned char i = 0; static char buff[20]; while (Serial.available()) { char inChar = (char)Serial.read(); if (inChar == '\n') { buff[i] = 0; Serial.println(buff); i = 0; } else buff[i++] = inChar; }
Заголовки у пакетов разные. И размер разный. Номера нужных байтов в пакете заранее известны. Нужно лишь пару байт из середины и конца пакета взять . Остальное - мусор. Большая часть там нули...
тогда еще раз повторю предыдущий совет - пропускайте ненужные байты и буфер увеличивать не нужно будет
Спасибо за советы. Завести счетчик байтов ? или лучше счетчик '\n', что бы сразу пропускать ненужную "строку" целиком?
Так кто же тут знает, что вам нужно. Код из вашего вопроса выше, тоже не имеет особого смысла: получаем байты посимвольно, дожидаемся '\n' отправляем их обратно
Читать непосредственно из приемного регистра UART. Как только поняли, что приняли первый пакет (с этим проблем нет?), включаем счётчик байтов и все лишние байты пропускаем (даже не читая из регистра) по флагу приема байта (можно мониторить этот флаг, но лучше зайти в прерывание). Но ой - это выходит за рамки дурины. Она не для таких задач. Поэтому читаем Евстифеева. Ну и никакие мегабуферы здесь не нужны. Только то, что нам надо принять.
Спасибо за советы. Немного не понятно, как делать пропуск байтов. Но понятно одно- мой подход в корне не верный, есть более простое решение. Буду читать, искать дальше.
А я бы все таки смотрел, что приходит. Может ведь прийти и начало пакета раньше времени, например, если сбой какой-то, и байт не будет принят. Но тут нужно смотреть спеку по протоколу обмена.
Нашел интересный пример чтения из Serial по прерыванию https://wikihandbk.com/wiki/Arduino:Примеры/SerialEvent Используется для разбора данных с устройств типа gps приемников, когда данный поступают постоянно и в большом количестве. Пишет в массив построчно до символа '\n'. Код (C++): [code] static char buff[90]; static unsigned char i = 0; boolean Complete = false; // флаг заполнения void setup() { Serial.begin(38400); } void loop() { // выводим пакет построчно: if (Complete) { Complete = false; Serial.print(buff); } } void serialEvent() { while (Serial.available()) { char inChar = (char)Serial.read(); buff[i++] = inChar; // заполняем условную строку из пакета if (inChar == '\n') {//обнуляем после перевода строки buff[i] = 0; i = 0; Complete = true; } } } [/code] Все таки, по прерыванию гораздо удобнее. Осталось разобраться, как отсечь ненужные "строки" (хотя конечно же там не строки ) и вытащить нужный байт. Код (C++): 0:00AA4029066244 1:0000000000312A 2:2D760000310001 3:000000486809C8 4:2D760000680001 5:0000004800312A 6:00000000680001 7:00AA4000AA0001 8:00031001006001 9:09AA00486809C8
Я понимаю, что это ваша работа- оставлять комментарии к любым сообщениям, тем самым направляя на саморазвитие. Но прочитав много форумов за эту неделю, я так и не нашел решения вопроса. Как же вытащить нужный байт из конца большого массива данных? Подскажите, пожалуйста, с примером кода.