Меню
+7 (495) 785-95-25
sale@lcard.ru
sale@lcard.ru
Версию прошивки можно узнать через функцию ltrapi LTR_GetCrateDescr() (поле soft_ver полученной структуры).
В версии 2.0.0.0 была проблема, что при некорректном закрытия соединения (когда крейту не пришел пакет завершения соединения по TCP, либо если не было физически связи с крейтом во время закрытия соединения, либо зависание/выключение питания ПК без завершения работы, либо еще по каким причинам...) создать новое соединение прошивка крейта не позволяла, соответственно без снятия питания невозможно снова установить соединение. В версиях 3.0.0.x эта проблема должна быть исправлена, но не уверен, что она шьется штатно в крейты (я к этой разработке не отношусь, точно не могу сказать). Обновить ее можно, но только через интерфейс USB.
Если у Вас именно эта проблема, то перезапуск службы тут не поможет (если соединения с крейтом нет, то значит со стороны службы оно закрыто, проблема в том что крейт считает, что оно не закрыто).
Про то, что служба ltrd не запустилась после LTR_ServerRestart() странно, по какой-то причине перезапуск не отрабтал, но тут нужно знать какая версия службы, какая ОС и желательно системный журнал с сообщениями, относящимися к службе ltrd (например через journalctl | grep ltrd , если дистрибутив использует systemd (большинство нынешних)), как ставилась служба - из пакетов или Вы сами собирали?
Про su не совсем понял, про что речь - программе, использующей функции ltrapi не требуются права администратора, она может работать от обычного пользователя.
Запуск/останов службы системными средствами Linux как правило требует специальный прав (например sudo systemctl start ltrd.service).
Для E502 эти коэффициенты записываются при наладке изделия на заводе один раз (если не считать возможной перекалибровки в случае передачи в ремонт и т.п.).
Способ применения коэффициентов описан например в описании функции X502_SetAdcCoef() в руководстве по x502api. Пара коэффициентов (k,offs) идет на каждый диапазон своя, но общая для всех каналов.
Про низкоуровневое описание там глава 5.12 (а не 5.1), где описан формат 32-битного слова. Он идет в главе по BlackFin, т.к. как правило он нужен при написании ручной обработки в нем для разбора слов, но без Blackfin в этом же формате просто слова передаются напрямую и принимаются на верхнем уровне через Recv. В принципе этот формат Вам может быть и не нужен, если используете ProcessData, только если Вы вообще решите не использовать эту функцию, а сразу будете обрабатывать слова из Recv извлекая 24-битный код из 32-битного слова вручную, чтобы не переводить код -> double -> снова код, тогда можно просто проверить правильность информации в типе слова и извлечь нужные 16 бит.
Для E-502 вначале внутри самого модуля идет применение индивидуальных калибровочных коэффициентов данного экземпляра (которые хранятся в энергонезависимой памяти самого модуля) к коду АЦП и чтобы не потерять точность (дробную часть после умножения кода АЦП на вещественный коэффициент), 16-битный код расширяется до 24 битного сдвигом влево. Соответственно уже 24-битные коды после калибровки передаются наверх в виде 32-битных слов, которые состоят из 24-битного кода и дополнительной информации (формат есть в главе 5.12 низкоуровнего описания https://www.lcard.ru/download/x502_low_level.pdf), которые и получает Recv перед передачей в ProcessData. Калибровочные коэффициенты определены таким образом, чтобы после их применения, напряжение на входе, соответствующее номинальной границе используемого диапазона измерения, соответствовало коду X502_ADC_SCALE_CODE_MAX (6000000). Для перевода в Вольты уже библиотека в ProcessData применяет преобразование y = x * range / X502_ADC_SCALE_CODE_MAX, где y - значение в Вольтах, полученное в результате выполнения ProcessData, x - знаковое целое, соответствующее 24-битному коду, полученный от модуля, а range равно 10, 5, 2, 1, 0.5 или 0.2 в зависимости от настроенного диапазона.
Таким образом у Вас есть два варианта:
1. Можно хранить в файле "сырые" 16-битные отсчеты, но с ними хранить и калибровочные коэффициенты данного модуля, и уже вручную выполнять применение калибровочных коэффициентов и переводить в Вольты при чтении, отключив преобразования в модуле и библиотеке. Для этого необходимо:
- считать калибровочные коэффициенты для используемых диапазонов с помощью X502_GetAdcCoef() для сохранения с файлом отсчетов
- установить калибровочные коэффициенты равными k=1 и offs = 0 через X502_SetAdcCoef для используемых диапазонов, чтобы по сути отключить их применение внутри модуля (это не стирает коэффициенты в энергонезависимой памяти и при следующем Open они будут восстановлены).
- Запустить сбор, использовать ProcessData без флага X502_PROC_FLAGS_VOLT, чтобы отключить преобразование в Вольты в библиотеке
- На выходе ProcessData значения double будут соответствовать коду АЦП, сдвинутому вправо на 8 бит (домноженному на 256). Т.е. для получения родного кода нужно сделать преобразование int16_t с = (int16_t)((int32_t)d >> 8)), где d значение на выходе ProcessData типа double, а c - полученный 16-битный исходный код АЦП.
2. Можно сделать обычный прием значений в Вольтах и дальше использовать свое преобразование из Вольт в 16-битный код, считая, что например максимальное значение 16-битного знакового числа (0x7FFF) соответствует максимальному значению диапазона и получить код как c = (d/range)*0x7FFF с проверкой выхода за диапазон и округлением до границ. Тут не будет конечно 1:1 соответствия разряда кода в файле с разрядом АЦП, но не требует сохранения калибровочных коэффициентов и все позволяет добиться 1/2^15 точности от диапазона измерения.
А какая версия прошивки у Ваших крейтов?
В принципе перезапуск сбора работающего модуля через Stop/Start отдельных модулей должен работать без закрытия/открытия соединения. При сбое тут уже вопрос, из-за чего сбой и что при нем происходит с модулями, будет ли достаточно для выхода из этой ситуации перезапуска сбора или потребуется дополнительно переконфигурация (через SetAdc) или сброс модуля и соединения (через Close/Open).
У Вас то сбой как проявляется (с точки зрения результатов функций)? В одном модуле или сразу во всех от одного крейта? Вы пробовали перезапуск через Stop/Start или Stop/SetADC/Start? Если перезапуск не получился, то как это проявляется с точки зрения результатов выполнения функций? Не пропадают ли модули судя по журналу LTR Manger в момент сбоя?
С точки зрения потоков, то для api не принципиально, какая функция вызывается из какого потока, главное обеспечить, что одновременно не выполняется более одной функции (из разных протоков), относящихся к одному и тому же модулю, в остальном это вопрос к способу организации самого приложения.
Здравствуйте!
О каком приложении идет речь?
Можете выложить сюда или прислать на почту техподдержки скрин, как видится крейт с модулями в программе LTR Manager и журнал из LTR Manager после подключения крейта.
Какой у Вас дистрибутив Linux?
Откуда брали lcomp?
Добрый день.
К сожалению для E-502 получить данные одновременно на нескольких ПК непосредственно от одного модуля не получится. Такое возможно для автономно работающих модулей (как в системе L-ViMS), а модуль E-502 предполагает, что все действия выполняются с управляющего ПК и поток данных также может передаваться только на него. Открытие нового соединения для передачи потока данных требует закрытие предыдущего. Если только косвенно, использовать отдельный ПК с ПО, которое принимает данные от модуля и делает их доступными другим ПК по какому-либо интерфейсу (как например OPC-сервер Л Кард, либо свое ПО).
Добрый день.
В библиотеках ltrapi (в данном случае ltr27api) реализуются специфичные для системы LTR функции настройки, управление и получение данных в исходных величинах (для субмодулей LTR27 это напряжение, ток или сопротивление) от модулей. Перевод же в физические величины в соответствии с характеристиками датчика зависит от внешних к LTR факторов (характеристикам датчика, схемы подключения и т.д.) и его реализация в ltrapi не входит. LMS эти преобразования уже реализует отдельно в своем коде, в случае термопар используются полиномы преобразования из ГОСТ Р 8.585-2001. Соответственно, Вы можете самостоятельно реализовать преобразование по ГОСТ, либо при желании можете взять реализацию преобразования по полиномам отсюда https://gitlab.com/l-card/shared/math/subs/lpoly и включить в свою программу (сама функция преобразования отсчета в файле lpoly, а описания полиномов для разных типов термопар для передачи функции преобразования первым параметром - в thermocouples).
P.S.: а у Вас точно субмодуль в LTR27 - H-27U-10, т.к. как правило для подключения термопар используется H-27T?
Можете попробовать обновить прошивку контроллера до 1.0.23 (файл тут - https://www.lcard.ru/download/e502-m4.bin, обновление можно сделать через X502Studio). Остальные прошивки последние.
Можете проверить работу данного режима в бесплатных программах X502Studio или демо LMS (1 канал АЦП + 1 канал ЦАП), для частоты АЦП 1 МГц или ниже должно работать.
А с какого устройства управляете E-502, что используете низкоуровневый доступ вместо готовых библиотек?
А какие у Вас версии прошивок микроконтроллера, FPGA и PLDA?
А какая у Вас частота ввода АЦП?
Для обеспечения непрерывного потокового вывода на ЦАП необходимо, чтобы в буфере на вывод всегда были готовые данные после запуска вывода ЦАП, т.е. модуль должен успеть принять новую порцию данных к моменту их вывода. При потоковом вводе-выводе по Ethernet общая скорость приема и передачи ограничена, и если используется максимальная частота ввода 2 МГц, то модуль может не успевать принимать и обрабатывать данные с нужной скоростью на вывод. Если понизить частоту ввода, то проблема исчезнет? Также на возможность передачи данных могут влить другие передаваемые данные, если это не выделенная сеть для модуля E502.
С другой стороны, если требуется вывести только сигнал длиною в секунду, то это всего 500 тыс точек, в то время как буфер на вывод составляет 3 млн. точек, т.е. весь сигнал можно полностью загрузить до запуска ввода, в этом случае передача данных и прием будут разнесены по времени (передача до старта, прием после) и не будут никак влиять друг на друга и возможно работать на максимальных скоростях ввода-вывода. Но тут надо учитывать, что как правило функция передачи данных по TCP на стороне ПК (как send для TCP-сокетов) при выполнении означает, что данные были только помещены в буфер сокета на передачу, а не были переданы реально в модуль, а учитывая, что для команд используется другое соединение, то вероятнее всего получается так, что хоть данные были посланы модулю, они еще не дошли все до него на момент запуска сбора. Попробуйте вставить значительную задержку после передачи всех данных на вывод и до запуска сбора (установки бита GO в 1), исправит ли это ситуацию?
Если вывод требуется длительный и буфера на вывод в модуле недостаточно, чтобы загрузить сигнал целиком, то можно перед стартом загрузить весь буфер, а дальше уже момент передачи новых данных определять по приему данных АЦП, т.е. как приняты точки АЦП за время например 500 мс посылать новую порцию, соответствующую 500 мс выводимого сигнала на ЦАП и т.д.
Да, в принципе для E-502 это возможно. Можно написать прошивку так, что настраивается сбор как у Вас сейчас для АЦП + DIN, но прошивка Blackfin в обработчике данных DIN обрабатывает сама, а в потоке, который идет дальше в ПК, оставляет только данные АЦП. По данным DIN прошивка Blackfin вычисляет реальную частоту, которую можно либо получать по пользовательской команде к Blackfin, либо вставлять результат в поток данных как слово в пользовательском формате.
Есть еще модули, которые поддерживают синхронизацию времени по Ethernet через PTP (система L-ViMS и должно быть в E-502-P1), но в этом случае и измерительное устройство, и источник времени, и соединяющий из коммутатор должны поддерживать PTP.
1. Если сигнал преобразован в TTL уровни напряжения (UART), то в принципе это должно быть возможно. Но про готовую такую реализацию мне по крайней мере неизвестно.
2. Описанный вариант использования PPS для вычисления опорной частоты E-502 вполне логичен и должен быть рабочим. Про вариант получения числа тактов не совсем понял, между чем число тактов Вы хотите считать и для чего это нужно?
Проблема эта возникает из-за того, что задержка внутри модуля от момента измерения до момента вставки в общий поток данных у данных АЦП и данных DIN разная (у АЦП добавляется задержка выполнения преобразования, дополнительной обработки в виде применения коэффициентов и т.п.), в результате и получается, что к моменту вставки в поток первого отсчета АЦП уже вставлено 2 отсчета DIN. Это особенность аппаратной реализации в модуле и ее приходится учитывать при обработке. Сам отсчет никуда не пропадает, просто получается, что из-за того, что вначале идут подряд два отсчета DIN, то отсчет второго канала последнего кадра уже не вмещается в запрашиваемый блок, но он не пропадает, но будет вычитан при втором чтении. В общем и целом, отдельно данные DIN и отдельно данные АЦП идут всегда в том порядке, как были сделаны измерения в соответствующие моменты времени, но в общем потоке отсчеты АЦП и отсчеты DIN могут при объединении в общий поток смещены относительно друг друга. Поэтому в примере эти два два потока раскладываются на отдельные промежуточные буфера и уже из них берутся данные блоками нужных размеров, а в Recv может читать данные меньшими блоками.
Пример работы на LabView с E-502 есть на странице примеров https://www.lcard.ru/support/developer (https://www.lcard.ru/download/examples/ … abview.zip), там нет правда SyncMode, но установка установка LChannelCount как раз есть.
По сути Вы можете либо уже существующий в примере PropertyNode для установки LChannelTable/LChannelCount потянуть вниз, чтобы увеличить количество задаваемых параметров и выбрать среди них SyncStartMode, либо добавить новый PropertyNode (.Net) до вызова Configure, на вход подать экземпляр объекта x502 (как и для функций, т.е. это property самого x502 объекта) и выбрать параметр SyncStartMode.
А в качестве подаваемого значения, которое в него записать, как раз можете подать созданный объект X502+Sync со значением DI_SYN1_RISE
Здравствуйте.
А штатный пример у Вас работает без ошибок?
Так без самого кода сказать сложно, но проверьте в первую очередь:
1. что после изменения настроек модуля вызывается вызывается X502_Configure() до запуска сбора (иначе настройки не передадутся модулю и настройки в библиотеке будут не соответствовать настройкам модуля).
2. что всегда проверяете результат X502_Recv и в X502_ProcessAdcData передаете именно тот размер, сколько вернул Recv, т.е. что в ProcessData обрабатывается всегда именно данные от Recv и не попадают неинициализированные данные.
Здравствуйте.
Данные установки сделаны через свойства (Properties) SyncMode и SyncStartMode (аналогично, как устанавливается, например, LChannelCount).
И если нужна синхронизация старта (запуск сбора по одному фронту/спаду внешнего сигнала, а дальше уже сбор от внутренней частоты), то нужно использовать именно SyncStartMode (X502_SetSyncStartMode), а X502_SetSyncMode задает по сути внешнюю частоту синхронизации (т.е. нужен фронт/спад на каждое преобразование).
Для синхронизации данных модулей разных крейтов можно использовать механизм синхрометок (см. пункт 4.7 руководства https://www.lcard.ru/download/ltr.pdf) и разъем SYNC крейтов (см рис. 3.6 в пункте 3.2.3 руководства). Необходимо соединить один из выходов DIGOUT этого разъема одного крейта с входом DIGIN другого (с учетом рекомендаций из пункта 3.6.9), после чего настроить один крейт на генерацию импульса по метке старт на соответствующем DIGOUT, а другой - на генерацию метки по сигналу на входе DIGIN. Потом запускаете сбор со всех моделей, подаете программную команду генерации метки на первом крейте, в результате она будет вставлена в потоки всех модулей обоих крейтов и по ней Вы сможет совместить данные с точностью до периода АЦП.
Если Вы сами пишите ПО, то использование функций библиотеки для синхронизации запуска описано в разделе 4.6 руководства ltrapi (https://www.lcard.ru/download/ltrapi.pdf). Для программы LMS этот режим описан в разделе 2.8 документа https://www.lcard.ru/download/lms_users_guide.pdf.
А это Вы видите в своей программе? Можете на всякий случай проверить например на метрологическом ПО (ltr11_metr), проявляется ли этот эффект?
Второй слот - это внутренний "виртуальный" модуль самого крейта LTR-U-1 и он виден всегда, когда подключен крейт, а в слоте 1 должен быть сам измерительный модуль. При этом крейт в LTR-U-1 питается от USB, а для работы измерительного модуля нужно подключение внешнего адаптера питания. Поэтому в первую очередь проверьте, точно ли он подключен и исправен.
1. Если Вы ходите сохранять значения после калибровки, но просто в формате 16-битного целого, то у есть два варианта:
- в ProcessData не передавать флаг VOLT, полученные на выходе значения поделить на 8 (чтобы откинуть младшие 8 разрядов из расширенного до 24-бит кода) и преобразовать в int16. Далее при чтении сохраненных данных для перевода в Вольты считаете, что код (X502_ADC_SCALE_CODE_MAX/8) = 6000000/8 - соответствует номинальному значению используемого диапазона АЦП (далее RANGE).
- в ProcessData использовать с флагом VOLT, но далее преобразовать вольты к нужному масштабу, например ограничить до [-RANGE, +RANGE], далее умножив на (2^15-1) и поделив на RANGE и преобразовав в int16, тогда при обратном переводе при чтении у Вас RANGE будет соответствовать Вашему коду (2^15-1)
2. Обе частоты определяются делением на целое от опорной, и функции подбора выбирают ближайшую частоту. При задании частоты цифрового ввода равной частоте на канал возникает проблема, что на делитель для частоты на канал накладывается еще ограничение, что она должна быть кратна числу каналов (или числу каналов + холостых каналов межкадровой задержки) - в вашем случае 3, а делитель для частоты цифрового ввода этим не ограничен, поэтому для цифрового ввода функция находит более близкую частоту к запрошенным 100 КГц. Если нужна та же частота, что и на канал АЦП, то можно либо явно выбирать те частоты, которые действительно можно получить из опорной, либо можно просто сперва вызвать функцию установки частоты АЦП и полученную от нее скорректированную частоту на канал подать на вход функции установки частоты дискретного ввода вместо того, чтобы брать ее из интерфейса. Для задания частоты цифрового ввода равной частоте АЦП такой проблемы быть не должно, т.к. ограничения на делитель одинаковы.
3. По умолчанию буфер выделяется исходя из скорости ввода, чтобы его хватило на 4 секунды. При желании можно его изменить функцией X502_SetStreamBufSize до запуска сбора данных.
Здравствуйте!
По картинке если модуль исправен, то похоже на проблему с подключением, у Вас сигнал AGND подключен, как в примерах в главе 6 руководства (https://www.lcard.ru/download/e-502_users_guide.pdf)?
1. Да, f_adc = 300000, f_frame может быть либо явно указан как 100000, либо передано значение меньше или равно нуля (в последнем случае выбирается наибольшая частота кадров - без межкадровой задержки)
2. Частота АЦП получается делением опорной частоты на целое число. Опорная частота, если используется внутренняя, может быть либо 2 МГц (по умолчанию), либо 1.5 МГц (устанавливается функцией SetRefFreq - должна вызываться до SetAdcFreq). Реальное значение установленных частот возвращается на выходе SetAdcFreq (в примере отображаются на индикаторах).
3. Размер buf - размер пользовательского буфера, в который будут сохранены данные из буфера драйвера (сам буфер в драйвере значительно больше и от этой функции его размер не зависит), поэтому его не нужно делать с запасом. Recv вернет управление как только произойдет одно из двух событий: либо истечет указанное время, либо если в buf будет сохранено указанное количество отсчетов. Поэтому если хотите принимать данные блоками нужной длины, то можете сделать buf этого размера и указать такой же size в Recv, а таймаут сделать с запасом (чтобы при нормальной работе функция Recv всегда возвращала управление по готовности size данных). Это удобно, когда принимаете данные только с АЦП для обработки фиксированными блоками. Когда прием идет и по АЦП и по дискретным входам, то тут несколько сложнее, т.к. все данные передаются вместе в одном потоке, и размер buf - для суммарного потока, поэтому в примере уже после разбиения в ProcessData данные складываются отдельно в буфер АЦП и в буфер DIN, из которых уже извлекаются фиксированными блоками по мере наполнения этих дополнительных буферов. Можно еще использовать функцию GetRecvReadyCount для получения количества готовых для чтения отсчетов в буфере драйвера, но она работает не для всех интерфейсов подключения (не работает для Ethernet).
Если буфер переполнится то модуль перестанет передавать новые данные до его освобождения и они начнут отбрасываться (т.е. новые данные не затирают старые, пока они не будут приняты с помощью Recv). На месте полученного таким образом разрыва модуль вставит специальное слово, в результате чего при обработке места разрыва в ProcessData будет возвращен соответствующий код ошибки.
Можно не передавать флаг VOLT, тогда функция ProcessData вернет коды, расширенные до 24-бит смещением влево, но тип выходных данных в любом случае будет double, т.е. для получения кода можно разделить на 8 и взять целую часть. Ну либо не использовать ProcessData а вручную разобрать формат данных по описанию из раздела 5.12 низкоуровневого описания (https://www.lcard.ru/download/x502_low_level.pdf).
Но в любом случае еще есть калибровочные коэффициенты АЦП, которые применяются внутри модуля (для чего код и расширяется до 24-бит, чтобы не терять дробную часть), поэтому если Вы хотите коды АЦП без калибровки, то нужно еще до запуска сбора установить калибровочные коэффициенты АЦП равными k=1 и b=0 для используемых диапазонов с помощью функции SetAdcCoef.
4. Частота синхронного ввода настраивается отдельно, но также как деление опорной. Если Вы ее настроили такой же, как f_adc, то да, читаются практически в одно время - с фиксированными задержками, описанными в пункте 3.3.8 руководства пользователя (https://www.lcard.ru/download/e-502_users_guide.pdf). Считываются всегда состояние всех цифровых входов, т.к. состояние всех входов передается одним словом в потоке данных, а уже анализировать в полученном слове Вы можете только интересующие Вас биты, соответствующие нужным дискретным входам.
Здравствуйте.
Попробуйте обновить на машине, на которой плата видится корректно, прошивку ПЛИС до последней версии (0.10) с помощью утилиты <путь установки SDK>/tools/lxfw-update последнего SDK (использование описано в readme.txt в этой директории)
Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4, стр. 2
Многоканальный телефон:
+7 (495) 785-95-25
Отдел продаж: sale@lcard.ru
Техническая поддержка: support@lcard.ru
Время работы: с 9-00 до 19-00 мск