Отбрасывается. При экспорте сейчас математических операций не осуществляется, просто берется последнее значение на момент соответствующей строки.
Если нужно понижение частоты с усреднением, то для этого можно создать соответствующий расчетный канал в закладке "Обработка данных". Ограничение демо-версии на количество каналов относятся только к исходным каналам ввода-вывода устройств, расчетные Вы можете добавлять в любом количестве. Сперва нужно создать на закладке "Кадр" блок "Периодическая выборка кадра", в котором будут определены как по времени делится исходный сигнал на отдельные временные отрезки для дальнейшей обработки. Т.е. в вашем случае "Длительность кадра" - время, за которое выполняется усреднение. "Период следования кадров" - временной шаг между последующими точками вычисления усреднения (в Вашем случае равен длительности кадра). К блоку выбора кадров нужно подключить на вход канал на большей частоте, для которого хотите сделать усреднение. Потом создать в "Модули обработки" модуль "Среднее" и подключить на вход полученный канал от выборки кадра. Результирующий канал можно использовать аналогично исходному (добавить на графики, экспортировать с него данные при экспорте и т.д.).
А каким браузером пользуетесь?
Если Chrome и по нажатию ссылки ничего не происходит, попробуйте нажать правой кнопкой мыши на нее и выбрать "Сохранить ссылку как...." и если после выбора папки для скачивания будет отображаться снизу "Невозможно безопасно скачать", то нажать на стрелку рядом с надписью и выбрать "Сохранить". Судя по всему браузер может блокировать скачивание .exe файлов (или архивов с .exe файлами) и не давать скачивать их автоматом по нажатию. По крайней мере в Chrome у меня сейчас поведение такое.
При этом те же файлы с общей страницы "Поддержка -> Библиотека файлов" без проблем скачиваются по нажатию....
При экспорте в параметрах Вы выбираете частоту экспорта данных (интервал между отсчетами). По умолчанию там выбрана максимальная из выбранных для экспорта каналов, но можно задать и вручную.
Далее по сути с этим шагом по времени программа проходит по экспортируемым сигналам и берет последнее известное значение на момент этой точки во времени. Аппроксимация при экспорте в текущей версии не выполняется.
Т.е. если допустим у Вас частота одного канала в 10 раз больше частоты другого и Вы экспортируете по максимальной частоте, то в первом столбце у Вас будут по первой измеренной точке каждого канала, далее для медленного канала будут 9 повторов, потом вторая точка и т.д.
При выборе меньшей частоты для экспорта, точки наоборот будут отбрасываться.
Попробуйте версию 1.58.3, там вроде указанные проблемы уже были исправлены. Можно взять готовые пакеты (описано в https://www.lcard.ru/download/lcard_lin … utions.pdf, пакеты lcomp-dkms и liblcomp1-dev), При установке пакетов драйвер загружается автоматически. Исходники есть на git (драйвер https://gitlab.com/l-card/acq/devices/e … iver_linux, библиотека https://gitlab.com/l-card/acq/devices/e … mp_library).
Добрый день.
Попробовал собрать, результат для теста выложил сюда: https://lcard.ru/download/ltr_x502_netcoreapp.zip
Если подтвердите, что работает и это то, что нужно, потом могу включить в следующие версии штатных установщиков.
Закинул на сервер сборки пакетов версию 1.58.3 для lcomp-dkms, должно быть доступно обновление в ближайшее время, тогда попробуйте - решится ли проблема.
У меня этот режим теперь заработал, проверял для достоверности корректной работы, что за несколько проверок после дохождения до конца буфера позиция остается равной размеру буфера, а также, что первый отсчет остается неизменный, с момента прихода первых данных.
Точно. Смутил вывод, но видимо за время отладочного вывода adc_buffer_offset значение самого adc_buffer_offset успевает изменится на IrqStep, поэтому при выводе adc_buffer_offset == 106496 (_buffer_size) сбор продолжается (т.к. за время вывода до проверки успевает IrqStep стать 4096), а при выводе 102400 - останавливается (т.к. до проверки успевает стать 106496).
По сути действительно сейчас автостоп не работает в этой версии и модуль продолжает собирать данные, а выполнится останов или нет зависит от того, попадете Вы при проверки на значение 106496 или нет. Тогда как поправлю выложу новую версию.
Теперь понял, проблема в том, что при AutoInit = 0 не выполняется останов на конце буфера. Тогда посмотрю, видимо действительно в нем проблема с работой в текущей версии. А как именно Вы проверяете, что сбор буфера завершился и по какому условию вызывается e2010::stop()?
Если я правильно понял, исходя из настроек Вы по первому фронту на DI16 запускаете сбор, который дальше уже идет непрерывно (судя по StopCnt = 0) с частотой 10 МГц независимо от внешних импульсов.
Далее не совсем понятно, вы пишите про вызов check_ready() по таймеру. Каким образом и с каким периодом это происходит? Надо учитывать, что программный таймер имеет задержку (случайно меняющуюся от вызова к вызову) и на пути данных от модуля до буфера и проверки программой тоже могут быть задержки, поэтому если таймер выставлен исходя из IrqStep, то в общем в зависимости от соотношения задержек он может в каждую итерацию сработать чуть раньше или чуть позже, чем пришел новый пакет данных, что в общем и соответствует выводу, когда сперва значение счетчика повторяется (таймер сработал чуть раньше), а затем увеличивается сразу на два (пришел пропущенный ранее пакет и новый).
При этом если частота у Вас 10 МГц, то время IRQStep 4096 получается вообще меньше пол мс? Не совсем понятно, как Вы его контролируете, ОС общего назначения может задерживаться и на более длительные времена.
Также не совсем понял про "раз в несколько импульсов" - как контролируется число импульсов, т.к. сбор у Вас после первого фронта идет непрерывно?
Это связано с представлением отрицательных чисел, значения представлены в дополнительном коде, т.е. отрицательное значение кодируется как 65536 - модуль числа, т.е. 65535 - это -1, 65534 - это -2 и т.д.). Это соответствует кодированию чисел со знаком для стандартных типов языков программирования, поэтому для корректного вывода Вам должно быть достаточно преобразовать тип переменной отсчета из беззнакового в знаковый (unsigned short в short), чтобы язык понял, что это число в дополнительном коде.
Т.е. по идее достаточно изменить вывод на:
printf(" shared word %d %d \n", *pp, (short)p[(*pp-1)]);
Ну или просто использовать short для описания переменной p, если работаете только с этим модулем (представление числа может зависеть от модуля, а пример обобщенный).
Драйвера на 32-ную систему встали без проблем (кстати, с 64-ой системе почему то выскакивала ошибка даже на версии библиотеки 1.58). Пример из папки test успешно компилируется.
Можете написать подробнее, какая ошибка возникает и при установке чего (драйвера или библиотеки, если драйвера, то лог сборки).
Сами функции библиотеки lcomp под Linux в целом соответствуют аналогичным под Windows, как и подход к работе аналогичный, отличается главным образом только начальная загрузка библиотеки, которая делается API ОС (Вместо LoadLibrary и GetProcAddress - dlopen и dlsym).
Опять же, не понятно, что конкретно у Вас не получается.
По поводу того, где лежат данные, то для приема данных выделяется буфер (массив отсчета). Выделяется он при вызове pI->SetParametersStream в примере и указатель на него сохраняется в переменную p, в size возвращается его размер, а в pp - указатель на память, где создана переменная синхронизации. В переменной синхронизации хранится номер отсчета в массиве данных, куда будет сохранен следующий пришедший отсчет.
Изначально значение переменной 0, затем когда будет запущен сбор и придет первый отсчет он станет 1 (что означает, что в p[0] появился первый действительный отсчет), второй - 2 (сохранены p[0] и p[1]) и т.д. пока не будет заполнен весь буфер, после чего сохранение следующих элементов начнется по кругу с начала массива (т.е. после *pp == size-1 идет *pp == 0). Но это для случая изменения по 1 отсчету, реально может быть сохранено сразу несколько отсчетов за раз драйвером. Программа смотрит за изменением значения переменной синхронизации, помнит с какой позиции она считывала данные и понимает сколько появилось данных в буфере, после чего их обрабатывает. Обработать она их должна до того, как они будут перезатерты при записи новых отсчетов по следующему кругу. В примере на экран выводится значение этой переменной синхронизации, которое должно меняться, а в отдельном потоке (thread_func) идет сохранение данных в файл по половинке буфера.
После создания структуры TLTR и перед вызовом любых других функций должен быть еще вызов LTR_Init(&hsrv).
Попробуйте, исправит ли это ситуацию.
По управляющим соединениям служба может работать одновременно с несколькими программами, так что закрывать LTR Manager не нужно.
Да, все функции, доступные в LTR Manager, можно выполнить с помощью функций ltrapi (он по сути через ltrapi со службой и работает).
Для этого используются функции общей библиотеки ltrapi (https://www.lcard.ru/download/ltrapi.pdf) из раздела "5.3.5 Функции управления подключением крейтов по Ethernet" через управляющее соединение со службой ltrd (4.2.1).
Можете сообщить версию прошивки FPGA модуля (должна отображаться в x502studio при успешной загрузке)
Ну как именно dmesg получает время не очень понятно, но в описании опции явно написано про время 'may be inaccurate!'. По этой теме есть ряд обсуждений (например https://serverfault.com/questions/57613 … uMC4wLjA.), где тоже вначале предполагали, что dmesg использует аппаратное время и тоже это не помогло. Почему так не могу сказать, возможно на уровне ядра нет возможности доступа к системному времени, и видимо для корректной привязки ко времени нужно использовать сообщения системного журнала а не напрямую dmesg. Для вывода сообщений ядра из системного журнала можно использовать journalctl -k (с возможностью выбора интервала с помощью опций -S и -U), можете проверить соответствие времен этим способом.
И если роутер всегда включен, не очень понятно, почему при включении оборудования в 16:03 тоже были пропадания и восстановления сетевого интерфейса? (причем тогда видимо автоматическое переподключение как и требовалось не запустилось и через 1.5 минуты видимо было ручное подключение).
Роутер входит в экспериментальное оборудование и включается вместе с крейтом или работает всегда?
В частности, я после подачи питания на крейт установил в LTR Manager соединение с ним, щёлкнув мышкой, и проверил отсутствие галочек А и R в строчке с этим крейтом.
Это было когда в этот день? В 16:03? Или другое время?
По разнице во времени, то больше похоже на какое-то расхождение времени dmesg и системного времени, которое использует LTR Manager.
Предположу, что dmesg использует аппаратный клок (можно посмотреть через вызов hwclock и сравнить с системным), который может отличаться от системного времени, если используется например синхронизация по времени через NTP и т.п.
Я попробую посмотреть внимательно по коду, как возможна установка флага A, но сходу мне у себя добиться самопроизвольного ее восстановления мне не удалось. Если у Вас получится это воспроизвести и понять последовательность действий, что на это влияет в какой последовательности, то было бы более понятно, куда смотреть.
А только Вы работаете с LTR Manager за этим компом, не мог кто-то еще установить?
Как вообще штатно у Вас происходит процедура подключение крейта? Вы после запуска ПК вручную выполняете подключение крейта из LTR Manager каждый раз? В 16:03 в журнале подключение чему соответствует? Включению ПК? Она тогда уже была установлена?
С появлением самой по себе галочки "A" не совсем конечно понятно. У Вас в программе функции вроде LTR_SetIPCrateFlags или LTR_AddIPCrate не используются?
Но в любом случае, основная проблема это не сам флаг A (без него просто бы подключение не восстановилось бы), а как и в прошлый раз возникновение строки:
19:29:19, 5.01.2023 Информация Service:New host address: intf name: eno1, addr 192.168.0.99, msk 255.255.255.0
которая говорит, что в самой системе исчезал сетевой интерфейс, и с самим ПО LTR не связана.
Если посмотреть через dmesg или журнал системы (journalctl) сообщения за интервал где-то от 19:29:00 до 19:29:19, будет там что-то про отключение сетевого интерфейса? У самого роутера есть какой-то журнал, возможно ли определить, не перезагружался ли сам роутер?
А в версии 1.58 это проявляется? Можно взять либо готовые пакеты для Debian aarch64 (описано в https://www.lcard.ru/download/lcard_lin … utions.pdf, пакеты lcomp-dkms и liblcomp1-dev), либо исходники есть на git (драйвер https://gitlab.com/l-card/acq/devices/e … iver_linux, библиотека https://gitlab.com/l-card/acq/devices/e … p_library)
А какую версию исходников lcomp (по какой ссылке скачивали) пытаетесь собрать?
1,3 пункт: Все сделал. Единственное, что называется не X502_SetExtRefFreqValue(), а просто ExtRefFreqValue()?
Да, я просто написал имя из C-библиотеки, функции в LabView идут без префикса X502_ (т.к. уже сгруппированы внутри класса).
По 2 пункту: Под частотой кадра Вы имели ввиду установленную частоту на канал?
Да
И еще по второму пункту, разве не надо после Recv вызывать ProcessAdcData? а уже после StreamsStop()?
Да, правильно, принятые данные с помощью Recv нужно всегда обрабатывать ProcessAdcData для получения значений в Вольтах. Действительно в моем описании я это не написал, но по сути везде, где идет Recv, подразумевается, что это вызовы Rev + ProcessAdcData.
Как я понимаю, чтобы произошла остановка нужно нажать на кнопку стоп, которая находится в цикле где вызывается Recv. Не подскажите как это сделать?
Ну это в примере в качестве условия выхода используется кнопка (точнее там сделан выход или по нажатию кнопки или по ошибке - логика в правом верхнем углу цикла в примере), аналогично Вы можете вместо кнопки или дополнительно к кнопке (просто новым входом в "или") сделать условие по завершению приема заданного числа отсчетов.
Т.е. например создать переменную вне цикла для хранения оставшегося числа отсчетов, присвоить ей перед циклом количество отсчетов, которое нужно принять (исходя из времени, размера кадра, и частоты на канал). Далее в цикл ее завести как shift regiseter (https://www.ni.com/docs/en-US/bundle/la … cepts.html), чтобы в новом цикле использовалось значение, полученное на предыдущем, а не сбрасывалось каждую итерацию в начальное. В самом цикле в качестве size на Recv можно передавать MIN(размер массива на вход, количество оставшихся отсчетов), чтобы не принимать лишний данных, при некратном соотношении блока приема и общего требуемого числа отсчетов, и после Recv вычитать из этой переменной (с количеством оставшихся отсчетов) результат Recv, если он больше 0, и в качестве условия выхода из цикла использовать, что значение этой переменной равно 0.
Да, QueryInterface() возвращает S_OK (0) в случае успеха, или код ошибки (в lcomp только E_NOINTERFACE) (тут QueryInterface повторяет стандартную функцию COM-объектов Windows и коды ошибки HRESULT переопределены из Windows, дальше функции самих интерфейсов уже возвращают свои коды ошибки в виде типа ULONG, где L_SUCCESS (0) - успех, остальные коды ошибок см ioctl.h)
Немного ошибся в предыдущем ответе, интервал между кадрами считается от выдачи последнего измерения в кадре до выдачи первого измерения следующего кадра, т.е. до конца первого измерения, а не до его начала. Таким образом, в него входит еще время преобразования первого измерения в кадре. В этом смысле минимальное значение dKadr = 1/Rate (в этом случае измерения идут подряд и время между последним измерением и первым следующего аналогично времени между измерениями внутри кадра и соответствует времени преобразования АЦП).
Здравствуйте.
Во-первых dRate у Вас должно быть не совсем любое. Каналы АЦП опрашиваются последовательно и АЦП должно успеть опросить все 25 каналов за кадр. Если у Вас частота АЦП 1КГц, т.е. время одного измерения занимает 1 мс, то 25 каналов будут опрошены за 25 мс, т.е. максимальная допустимая частота кадра (при нулевой задержке между кадрами) будут всего 40 Гц, а не нужная Вам 100 Гц. Т.е. dRate должна быть больше требуемой Вам частоты сбора кадра хотя бы в количество раз, равное числу опрашиваемых каналов.
Допустим Вы выбрали частоту 10 КГц ( dRate = 10), тогда dKadr это дополнительная задержка от последнего отсчета предыдущего кадра до начала следующего, а не общий интервал сбора кадров. Для AdcRate 10 КГц время опроса 25 каналов будет 2.5 мс, если Вам нужна частота кадра 100 Гц, то общее время кадра должно быть 10 мс, т.е. дополнительно нужна задержка на 10 - 2.5 = 7.5 мс, т.е. dKadr = 7.5.
P.S.: устройства E14-400 нет, есть либо E14-440, либо E14-140.
Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4, стр. 2
Многоканальный телефон:
+7 (495) 785-95-25
Факс: +7 (495) 785-95-14
Отдел продаж: sale@lcard.ru
Техническая поддержка: support@lcard.ru
Время работы: с 9-00 до 19-00 мск