Пропуск данных при приеме через UART средствами VISA

VISA, TCP/IP, USB, CAN, GPIB и подобные протоколы
AndryG
assistant
assistant
Сообщения: 122
Зарегистрирован: 24 апр 2017, 22:27
Версия LabVIEW: 2016
Благодарил (а): 1 раз
Поблагодарили: 1 раз
Контактная информация:

Пропуск данных при приеме через UART средствами VISA

Сообщение AndryG »

Доброго времени уважаемые форумчане. Столкнулся со сложностью синхронизации приема и обработки данных,а именно мне нужно принимать данные с учетом синхробайта AAE5,например,средствами LV я написал Vi, картинку прилагаю ниже,в результате все вродебы работает,но со сбоями,периодически получаю не все данные,у меня всего 14 байт с синхробайтом AAE5 вместе,т. е. нужно засинхронизироваться и принять 12 байт информации.Может кто знает где ошибка в моей реализации или в методе,буду признателен.
Вложения
vi_pic.png
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5598
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 34 раза
Поблагодарили: 113 раз

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение IvanLis »

AndryG писал(а): 03 июл 2024, 12:47 т. е. нужно засинхронизироваться и принять 12 байт информации.Может кто знает где ошибка в моей реализации или в методе,буду признателен.
Ну так и принимайте 12byte.
Дело в том, что там может быть например 10byte (или любое другое число).
Нужно или вычитывать весь буфер до следующей синхро последовательности, или читать необходимое число byte.
Так Вы еще и записываете в порт еще после этого что-то, наверное писать нужно по факту (условию), а не каждую итерацию цикла. Получается, что 2byte еще не получили, а уже новый пакет отправили.

А вообще, я например не могу гарантировать, что "AA" не встречается в теле посылки.
По этому для синхронизации и указана последовательность "AAE5", по идее, если в протоколе так написано, то только эта комбинация не может встречаться нигде, кроме как в начале пакета.

1. Я бы искал именно эту последовательность byte и если нашел, то считаем, что синхронизация установлена.
2. Читаем 12byte - информация.
3. Читаем 2byte и сверяем их с "AAE5", если совпадают, то все Ok и переходим на 2. Если нет, то синхронизация нарушена и переходим на 1.
AndryG
assistant
assistant
Сообщения: 122
Зарегистрирован: 24 апр 2017, 22:27
Версия LabVIEW: 2016
Благодарил (а): 1 раз
Поблагодарили: 1 раз
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение AndryG »

IvanLis писал(а): 03 июл 2024, 14:08 Ну так и принимайте 12byte.
Дело в том, что там может быть например 10byte (или любое другое число).
Нужно или вычитывать весь буфер до следующей синхро последовательности, или читать необходимое число byte.
Так Вы еще и записываете в порт еще после этого что-то, наверное писать нужно по факту (условию), а не каждую итерацию цикла. Получается, что 2byte еще не получили, а уже новый пакет отправили.
Да,я пробовал и так и так,все равно есть пропуски,вариант считывания всего сразу что есть это отличный вариант ,но как определить начало приема,на LV не понимаю, на С# в VS private void

Код: Выделить всё

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));
        }
    } 
все работает ок,простейший код и ни каких проблем,а в LV сразу не получается.
AndryG
assistant
assistant
Сообщения: 122
Зарегистрирован: 24 апр 2017, 22:27
Версия LabVIEW: 2016
Благодарил (а): 1 раз
Поблагодарили: 1 раз
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение AndryG »

AndryG писал(а): 03 июл 2024, 15:28 Да,я пробовал и так и так,все равно есть пропуски,вариант считывания всего сразу что есть это отличный вариант ,но как определить начало приема,на LV не понимаю, на С# в VS
Сделал некое подобие Сишарковского кода,но работает еще хуже чем первый вариант(
image-removebg-preview (20).png
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5598
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 34 раза
Поблагодарили: 113 раз

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение IvanLis »

AndryG писал(а): 03 июл 2024, 16:08 Сделал некое подобие Сишарковского кода,но работает еще хуже чем первый вариант(image-removebg-preview (20).png
Удивительно, что оно вообще заработало :wink:

Вот мы ищем синхро последовательность, для этого организовали FIFO на два байта.
Если нашли - читаем информацию, если нет - продолжаем искать.
1.png
Читаем 12byte.
Следующий этап - проверка синхронизации.
2.png
Если синхро последовательность - читаем информацию, если нет - ищем синхронизацию.
3.png
Как-то так, но нужно проверить, т.к. делал без запусков, по наитию :dntknw:
Serial.vi
lv2015
(10.98 КБ) 173 скачивания
AndryG
assistant
assistant
Сообщения: 122
Зарегистрирован: 24 апр 2017, 22:27
Версия LabVIEW: 2016
Благодарил (а): 1 раз
Поблагодарили: 1 раз
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение AndryG »

IvanLis писал(а): 03 июл 2024, 17:42 Вот мы ищем синхро последовательность, для этого организовали FIFO на два байта.
Если нашли - читаем информацию, если нет - продолжаем искать.
1.png
Читаем 12byte.
Следующий этап - проверка синхронизации.
2.png
Если синхро последовательность - читаем информацию, если нет - ищем синхронизацию.
3.png

Как-то так, но нужно проверить, т.к. делал без запусков, по наитию :dntknw:
Serial.vi
Ок,спасибо,попробую отпишусь)
AndryG
assistant
assistant
Сообщения: 122
Зарегистрирован: 24 апр 2017, 22:27
Версия LabVIEW: 2016
Благодарил (а): 1 раз
Поблагодарили: 1 раз
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение AndryG »

AndryG писал(а): 03 июл 2024, 18:02 Ок,спасибо,попробую отпишусь)
Идея рабочая,подправил немного код,нужно было регистр добавить для автомата,небольшой артефакт остался с данными,но похоже вы правы последовательность AAE5 в данных все же есть,добавлю контрольную сумму чтобы пропускать моменты рассинхронизации или синхробайт поменяю на другой,спасибо,так процесс идет веселей)
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5598
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 34 раза
Поблагодарили: 113 раз

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение IvanLis »

AndryG писал(а): 03 июл 2024, 18:28 Идея рабочая,подправил немного код,нужно было регистр добавить для автомата
Да, что-то я проморгал этот момент.
AndryG писал(а): 03 июл 2024, 18:28 или синхробайт поменяю на другой,спасибо,так процесс идет веселей)
Если Вы сами проектируете протокол, то лучше наверное использовать терминальный бит, так нет необходимости самостоятельно делать синхронизацию.
Снимок экрана от 2024-07-04 08-42-24.png
Снимок экрана от 2024-07-04 08-42-24.png (2.66 КБ) 23293 просмотра
Достаточно каждый пакет завершать "терминатором" и нет необходимости соблюдать определенную длину.
Но необходимо контролировать, что бы он не встречался нигде в данных при передаче.
Как правило, используется "перевод строки" = LF (0xA)
viewtopic.php?p=65849#p65849
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2287
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 33 раза
Поблагодарили: 33 раза

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение Borjomy_1 »

За использование BytesAtPort надо линейкой по рукам бить.
Artem.spb

Activity Автор
professor
professor
Сообщения: 3574
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 57 раз
Поблагодарили: 193 раза
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение Artem.spb »

Borjomy_1 писал(а): 04 июл 2024, 08:58 За использование BytesAtPort надо линейкой по рукам бить.
А что с ним не так? Был даже вебинар от NI, где жёстко критиковались примеры с этой функцией, но аргументы мне показались не убедительны.
Да, в каких-то случаях оно неуместно, но может быть вполне применимо с какими-то протоколами.
AndreyDmitriev

Activity Professionalism Tutorials Gold Black
VIP
VIP
Сообщения: 1421
Зарегистрирован: 03 фев 2010, 00:42
Награды: 8
Версия LabVIEW: 6.1 - 2025
Откуда: Германия
Благодарил (а): 1 раз
Поблагодарили: 78 раз
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение AndreyDmitriev »

Artem.spb писал(а): 04 июл 2024, 12:39
Borjomy_1 писал(а): 04 июл 2024, 08:58 За использование BytesAtPort надо линейкой по рукам бить.
А что с ним не так? Был даже вебинар от NI, где жёстко критиковались примеры с этой функцией, но аргументы мне показались не убедительны.
Да, в каких-то случаях оно неуместно, но может быть вполне применимо с какими-то протоколами.
Там есть один ярый противник (он не сотрудник NI). Как-то я его попросил объяснить, почему же он так против, и он мне написал, там мол состояние гонки. Я попросил его продемонстрировать примером, он не смог. Основной же его аргумент в том, что новички используют эту функция неправильно (бывает так и есть). Обычно они пишут что-то в порт и железка должна ответить, скажем двумя десятками байтов, новичок тут же вызывает эту функцию, она возвращает ноль. Он что делает? Ставит перед ней паузу. Получает десять байтов. Говорит "ага" и увеличивает паузу. С этого места оно спонтанно то работает то нет. Он ставил паузу лошадиных размеров и оно как-то работает. В этом и проблема.
Кстати, официальный пример в общем не самый удачный, он вот так выглядит:
Изображение
Если нужно получить определённое количество байт, то его можно указать сразу при чтении и таймаут. Если данные терминированы - можно указать терминатор, и т.д.
А так функция вполне удобная, особенно если данные прилетают нерегулярно и должны обрабатываться пакетами переменной длины, всегда можно глянуть, сколько там набежало и дальше действовать по обстоятельствам, либо читать уже, либо ещё подождать. Но надо понимать, что если функция говорит мне, что в порту двадцать байт и следом я и читаю двадцать, то не факт, что между запросом количества байт и их чтением туда между делом ещё не прилетит. Но они никуда не потеряются, состояния гонки там нет. Оно примерно как очередь работает, и никто не возражает против функции, просто возвращающей количество элементов в очереди без их извлечения. Но используется ну очень редко.
Artem.spb

Activity Автор
professor
professor
Сообщения: 3574
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 57 раз
Поблагодарили: 193 раза
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение Artem.spb »

AndreyDmitriev писал(а): 04 июл 2024, 13:58 Основной же его аргумент в том, что новички используют эту функция неправильно (бывает так и есть).
Вот да, я что-то такое помню. "новички используют это не правильно, поэтому это зло". Так про каждую вторую функцию сказать можно.
Яркий пример - по дефолту события имею таймаут. Я много раз слышал "нельзя его удалять, работать не будет". Или то, что это событие якобы случается всегда в обязательно порядке по расписанию.
А так функция вполне удобная, особенно если данные прилетают нерегулярно и должны обрабатываться пакетами переменной длины, всегда можно глянуть, сколько там набежало и дальше действовать по обстоятельствам
Я о том же.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2287
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 33 раза
Поблагодарили: 33 раза

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение Borjomy_1 »

Artem.spb писал(а): 04 июл 2024, 12:39 А что с ним не так? Был даже вебинар от NI, где жёстко критиковались примеры с этой функцией, но аргументы мне показались не убедительны.
Да, в каких-то случаях оно неуместно, но может быть вполне применимо с какими-то протоколами.
С ним не так то, что
1. это пуллинг (требующий определенного ресурса), тогда как следующая за опросом функция использует прерывание, совмещенного с заданием нужного числа байт и таймаутом. Получается дублирование.
2. В процессе получения числа байт в буфере их значение может измениться. И тогда ее работа теряет смысл. С тем же успехом можно запрашивать чтения фиксированного числа байт, все равно будет выдано реально вычитанное.

Мало того, напомню. Работа COM порта критически зависит от размера FIFO буфера драйвера. Потому что отдача в буфер VISA идет по заполнению FIFO плюс таймаут (~50мс), если посылка не кратна размеру буфера FIFO. Рекомендую выставлять размер FIFO либо наименьшим общим кратным посылке, либо вообще = 1.

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

Если данные нерегулярного размера, то тем более глупо использовать вычитывание того, что в буфере. Надо ставить таймаут меньше возможной паузы и вычитывать в цикле фиксированное число байт. И не заморачиваться пуллингом. Если функция закончится таймаутом, то просто возвратит то, что было вычитано. Минимальный цикл УЖЕ регулируется установленным таймаутом
Artem.spb

Activity Автор
professor
professor
Сообщения: 3574
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 57 раз
Поблагодарили: 193 раза
Контактная информация:

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение Artem.spb »

Borjomy_1 писал(а): 04 июл 2024, 14:43 С ним не так то, что
Спасибо за полезную инфу.
В целом согласен.
Кроме этого.
2. В процессе получения числа байт в буфере их значение может измениться. И тогда ее работа теряет смысл.
Ну если автор придумал протокол, когда, например, числа сыпятся сплошным потоком, тогда хочется вытащить из буфера всё, что уже прилетело. И не важно, что уже долетает новое.
Читать очень много - вариант, конечно же. Пересмотрю свои подходы в будущем.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2287
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 33 раза
Поблагодарили: 33 раза

Re: Пропуск данных при приеме через UART средствами VISA

Сообщение Borjomy_1 »

Когда прилетает сплошным потоком, абсолютно неважно сколько вычитывать за раз. Главное успевать (это легко рассчитывается по максимальной скорости приема). Поэтому сколько там сейчас в буфере - бесполезная информация.
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Коммуникация с приборами»