Пропуск данных при приеме через UART средствами VISA
-
- assistant
- Сообщения: 122
- Зарегистрирован: 24 апр 2017, 22:27
- Версия LabVIEW: 2016
- Благодарил (а): 1 раз
- Поблагодарили: 1 раз
- Контактная информация:
Пропуск данных при приеме через UART средствами VISA
Доброго времени уважаемые форумчане. Столкнулся со сложностью синхронизации приема и обработки данных,а именно мне нужно принимать данные с учетом синхробайта AAE5,например,средствами LV я написал Vi, картинку прилагаю ниже,в результате все вродебы работает,но со сбоями,периодически получаю не все данные,у меня всего 14 байт с синхробайтом AAE5 вместе,т. е. нужно засинхронизироваться и принять 12 байт информации.Может кто знает где ошибка в моей реализации или в методе,буду признателен.
-
IvanLis
- guru
- Сообщения: 5598
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 34 раза
- Поблагодарили: 113 раз
Re: Пропуск данных при приеме через UART средствами VISA
Ну так и принимайте 12byte.
Дело в том, что там может быть например 10byte (или любое другое число).
Нужно или вычитывать весь буфер до следующей синхро последовательности, или читать необходимое число byte.
Так Вы еще и записываете в порт еще после этого что-то, наверное писать нужно по факту (условию), а не каждую итерацию цикла. Получается, что 2byte еще не получили, а уже новый пакет отправили.
А вообще, я например не могу гарантировать, что "AA" не встречается в теле посылки.
По этому для синхронизации и указана последовательность "AAE5", по идее, если в протоколе так написано, то только эта комбинация не может встречаться нигде, кроме как в начале пакета.
1. Я бы искал именно эту последовательность byte и если нашел, то считаем, что синхронизация установлена.
2. Читаем 12byte - информация.
3. Читаем 2byte и сверяем их с "AAE5", если совпадают, то все Ok и переходим на 2. Если нет, то синхронизация нарушена и переходим на 1.
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
-
- assistant
- Сообщения: 122
- Зарегистрирован: 24 апр 2017, 22:27
- Версия LabVIEW: 2016
- Благодарил (а): 1 раз
- Поблагодарили: 1 раз
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
Да,я пробовал и так и так,все равно есть пропуски,вариант считывания всего сразу что есть это отличный вариант ,но как определить начало приема,на LV не понимаю, на С# в VS private voidIvanLis писал(а): ↑03 июл 2024, 14:08 Ну так и принимайте 12byte.
Дело в том, что там может быть например 10byte (или любое другое число).
Нужно или вычитывать весь буфер до следующей синхро последовательности, или читать необходимое число byte.
Так Вы еще и записываете в порт еще после этого что-то, наверное писать нужно по факту (условию), а не каждую итерацию цикла. Получается, что 2byte еще не получили, а уже новый пакет отправили.
Код: Выделить всё
SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (!IsReceiving)
return;
byte[] buffer = new byte[serialPort.BytesToRead];
serialPort.Read(buffer, 0, buffer.Length);
// Ensure the data is correctly aligned by checking the header
if (buffer.Length >= 14 && buffer[0] == 0xAA && buffer[1] == 0xE5)
{
var parser = new DataParser();
var data = parser.ParseData(buffer);
DataReceived?.Invoke(this, new DataReceivedEventArgs(data.accelX, data.accelY, data.accelZ, data.totalAcc, data.compAngleX, data.compAngleY));
}
}
-
- assistant
- Сообщения: 122
- Зарегистрирован: 24 апр 2017, 22:27
- Версия LabVIEW: 2016
- Благодарил (а): 1 раз
- Поблагодарили: 1 раз
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
Сделал некое подобие Сишарковского кода,но работает еще хуже чем первый вариант(
-
IvanLis
- guru
- Сообщения: 5598
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 34 раза
- Поблагодарили: 113 раз
Re: Пропуск данных при приеме через UART средствами VISA
Удивительно, что оно вообще заработало

Вот мы ищем синхро последовательность, для этого организовали FIFO на два байта.
Если нашли - читаем информацию, если нет - продолжаем искать. Читаем 12byte.
Следующий этап - проверка синхронизации. Если синхро последовательность - читаем информацию, если нет - ищем синхронизацию. Как-то так, но нужно проверить, т.к. делал без запусков, по наитию

Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
-
- assistant
- Сообщения: 122
- Зарегистрирован: 24 апр 2017, 22:27
- Версия LabVIEW: 2016
- Благодарил (а): 1 раз
- Поблагодарили: 1 раз
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
Ок,спасибо,попробую отпишусь)IvanLis писал(а): ↑03 июл 2024, 17:42 Вот мы ищем синхро последовательность, для этого организовали FIFO на два байта.
Если нашли - читаем информацию, если нет - продолжаем искать.
1.png
Читаем 12byte.
Следующий этап - проверка синхронизации.
2.png
Если синхро последовательность - читаем информацию, если нет - ищем синхронизацию.
3.png
Как-то так, но нужно проверить, т.к. делал без запусков, по наитию
Serial.vi
-
- assistant
- Сообщения: 122
- Зарегистрирован: 24 апр 2017, 22:27
- Версия LabVIEW: 2016
- Благодарил (а): 1 раз
- Поблагодарили: 1 раз
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
Идея рабочая,подправил немного код,нужно было регистр добавить для автомата,небольшой артефакт остался с данными,но похоже вы правы последовательность AAE5 в данных все же есть,добавлю контрольную сумму чтобы пропускать моменты рассинхронизации или синхробайт поменяю на другой,спасибо,так процесс идет веселей)
-
IvanLis
- guru
- Сообщения: 5598
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 34 раза
- Поблагодарили: 113 раз
Re: Пропуск данных при приеме через UART средствами VISA
Да, что-то я проморгал этот момент.
Если Вы сами проектируете протокол, то лучше наверное использовать терминальный бит, так нет необходимости самостоятельно делать синхронизацию. Достаточно каждый пакет завершать "терминатором" и нет необходимости соблюдать определенную длину.
Но необходимо контролировать, что бы он не встречался нигде в данных при передаче.
Как правило, используется "перевод строки" = LF (0xA)
viewtopic.php?p=65849#p65849
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
-
- doctor
- Сообщения: 2287
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 33 раза
- Поблагодарили: 33 раза
Re: Пропуск данных при приеме через UART средствами VISA
За использование BytesAtPort надо линейкой по рукам бить.
-
- professor
- Сообщения: 3574
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 57 раз
- Поблагодарили: 193 раза
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
А что с ним не так? Был даже вебинар от NI, где жёстко критиковались примеры с этой функцией, но аргументы мне показались не убедительны.
Да, в каких-то случаях оно неуместно, но может быть вполне применимо с какими-то протоколами.
-
- VIP
- Сообщения: 1421
- Зарегистрирован: 03 фев 2010, 00:42
- Награды: 8
- Версия LabVIEW: 6.1 - 2025
- Откуда: Германия
- Благодарил (а): 1 раз
- Поблагодарили: 78 раз
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
Там есть один ярый противник (он не сотрудник NI). Как-то я его попросил объяснить, почему же он так против, и он мне написал, там мол состояние гонки. Я попросил его продемонстрировать примером, он не смог. Основной же его аргумент в том, что новички используют эту функция неправильно (бывает так и есть). Обычно они пишут что-то в порт и железка должна ответить, скажем двумя десятками байтов, новичок тут же вызывает эту функцию, она возвращает ноль. Он что делает? Ставит перед ней паузу. Получает десять байтов. Говорит "ага" и увеличивает паузу. С этого места оно спонтанно то работает то нет. Он ставил паузу лошадиных размеров и оно как-то работает. В этом и проблема.
Кстати, официальный пример в общем не самый удачный, он вот так выглядит:

Если нужно получить определённое количество байт, то его можно указать сразу при чтении и таймаут. Если данные терминированы - можно указать терминатор, и т.д.
А так функция вполне удобная, особенно если данные прилетают нерегулярно и должны обрабатываться пакетами переменной длины, всегда можно глянуть, сколько там набежало и дальше действовать по обстоятельствам, либо читать уже, либо ещё подождать. Но надо понимать, что если функция говорит мне, что в порту двадцать байт и следом я и читаю двадцать, то не факт, что между запросом количества байт и их чтением туда между делом ещё не прилетит. Но они никуда не потеряются, состояния гонки там нет. Оно примерно как очередь работает, и никто не возражает против функции, просто возвращающей количество элементов в очереди без их извлечения. Но используется ну очень редко.
-
- professor
- Сообщения: 3574
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 57 раз
- Поблагодарили: 193 раза
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
Вот да, я что-то такое помню. "новички используют это не правильно, поэтому это зло". Так про каждую вторую функцию сказать можно.AndreyDmitriev писал(а): ↑04 июл 2024, 13:58 Основной же его аргумент в том, что новички используют эту функция неправильно (бывает так и есть).
Яркий пример - по дефолту события имею таймаут. Я много раз слышал "нельзя его удалять, работать не будет". Или то, что это событие якобы случается всегда в обязательно порядке по расписанию.
Я о том же.А так функция вполне удобная, особенно если данные прилетают нерегулярно и должны обрабатываться пакетами переменной длины, всегда можно глянуть, сколько там набежало и дальше действовать по обстоятельствам
-
- doctor
- Сообщения: 2287
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 33 раза
- Поблагодарили: 33 раза
Re: Пропуск данных при приеме через UART средствами VISA
С ним не так то, что
1. это пуллинг (требующий определенного ресурса), тогда как следующая за опросом функция использует прерывание, совмещенного с заданием нужного числа байт и таймаутом. Получается дублирование.
2. В процессе получения числа байт в буфере их значение может измениться. И тогда ее работа теряет смысл. С тем же успехом можно запрашивать чтения фиксированного числа байт, все равно будет выдано реально вычитанное.
Мало того, напомню. Работа COM порта критически зависит от размера FIFO буфера драйвера. Потому что отдача в буфер VISA идет по заполнению FIFO плюс таймаут (~50мс), если посылка не кратна размеру буфера FIFO. Рекомендую выставлять размер FIFO либо наименьшим общим кратным посылке, либо вообще = 1.
Если размер посылки фиксирован, и выдача несинхронна с работой ПО, то после открытия порта необходимо выполнить синхронизацию - вычитать порт до первой полной посылки. Далее опрос производится функцией чтения полной посылки, разом. После чего производится контроль начала и конца посылки. Если выявляются ошибки, то выполняется синхронизация. Но в исправных системах, с целыми проводами, это практически невозможное событие, особенно связанное с потерями целого байта.
Если данные нерегулярного размера, то тем более глупо использовать вычитывание того, что в буфере. Надо ставить таймаут меньше возможной паузы и вычитывать в цикле фиксированное число байт. И не заморачиваться пуллингом. Если функция закончится таймаутом, то просто возвратит то, что было вычитано. Минимальный цикл УЖЕ регулируется установленным таймаутом
-
- professor
- Сообщения: 3574
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 57 раз
- Поблагодарили: 193 раза
- Контактная информация:
Re: Пропуск данных при приеме через UART средствами VISA
Спасибо за полезную инфу.
В целом согласен.
Кроме этого.
Ну если автор придумал протокол, когда, например, числа сыпятся сплошным потоком, тогда хочется вытащить из буфера всё, что уже прилетело. И не важно, что уже долетает новое.2. В процессе получения числа байт в буфере их значение может измениться. И тогда ее работа теряет смысл.
Читать очень много - вариант, конечно же. Пересмотрю свои подходы в будущем.
-
- doctor
- Сообщения: 2287
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 33 раза
- Поблагодарили: 33 раза
Re: Пропуск данных при приеме через UART средствами VISA
Когда прилетает сплошным потоком, абсолютно неважно сколько вычитывать за раз. Главное успевать (это легко рассчитывается по максимальной скорости приема). Поэтому сколько там сейчас в буфере - бесполезная информация.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
- 3 Ответы
- 9382 Просмотры
-
Последнее сообщение IvanLis
-
- 2 Ответы
- 7245 Просмотры
-
Последнее сообщение Sergey Puzanov
-
- 5 Ответы
- 10633 Просмотры
-
Последнее сообщение IvanLis
-
- 8 Ответы
- 15294 Просмотры
-
Последнее сообщение Artem.spb
-
- 22 Ответы
- 7720 Просмотры
-
Последнее сообщение Borjomy_1