Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


Форум

Вы не вошли.

 Поиск | Регистрация | Вход 

#1 Re: Техническая поддержка и выбор оборудования » Временами LTR*_Stop() завершается по таймауту. » 17.10.2025 13:53:16

Алексей L Card пишет:

Вы вроде сами приводите порядок вызова функций, поэтому не совсем понятно, как у Вас может вызываться Stop лишний раз или без Start.

У нас команды выполняются по нажатию на кнопки, грубо говоря. И бывали случаи, когда кнопки нажимали не по порядку. Видимо, таким образом и словили ошибку, описанную выше.

Возник еще один вопрос, косвенно связанный с данной темой.
Мы хотим делать инициализацию, подключение и конфигурацию модуля(1-3 пункты выше) в одно время(нам это нужно, чтобы гарантировать, что мы ввели корректные параметры и что в целом присутствует связь с модулем), а запуск измерения(4-5пункты) и ,соответственно, остановку в другое. При этом допускается, что разница во времени между этими двумя шагами в теории может достигать 2 и более часов.
Возможно ли таким образом организовать работу(т.е. в два шага выше, при этом с большой задержкой между ними) и не возникнет ли в таком случае каких-нибудь ожидаемых(для Вас) проблем?
Меня, в первую очередь, интересует закрытие соединения между клиентом и ltrd из-за длительной неактивной сессии. Возможно ли такое?
Соединение между крейтом и ltrd "пропинговывается", судя по настройкам ltrd в xml файле, а вот про соединение с клиентом я информации не нашел.
Если разрыв соединения возможен, то есть ли какая-нибудь "холостая" команда в рамках соединения с модулей, которую бы мы могли использовать, чтобы поддерживать активность?
Я думал использовать TCP_KEEPALIVE опцию. Для этого её вроде как надо "включить" для нужного сокета, но ссылку на клиентский сокет внутри л-кард структур я не нашел.

#2 Re: Техническая поддержка и выбор оборудования » LTR114: 5022 ОМ при вытыкании резисторов » 14.10.2025 21:31:17

КириллК пишет:

Спасибо за ответы,

По поводу моего общего вопроса - понял, вопросов нет.

По поводу основного вопроса - я понял, что в случае оборванных входов следует ожидать некоторый набор значений, где, например, для нашего случая в этот набор входит 0, 5022 Ом и, возможно, другие значения.
Вопрос: а как определить этот набор значений? Какие значения могут входить, а какие входить не могут?

По вопросу отмена. Перечитал ответ и понял, что в набор могут входить абсолютно все значения.
Проверку на оборванные входы проверяем через специальные функции проверки.

#3 Техническая поддержка и выбор оборудования » LTR114,51,27: вопросы по движению кадров из модуля до клиента » 14.10.2025 17:43:33

КириллК
Ответов: 1

Добрый день,

Дано:
    1. LTR-EU-16-1 16-местный крейт
    2. Модуль LTR114 с поверкой
    3. Модуль LTR27 c поверкой
    4. Модуль LTR51 с поверкой
    5. Субмодуль H-27I-20
    6. Субмодуль H-27T
    7. Субмодуль H-27U-10
    8. Субмодуль H-51FL
    9. Работаем в одном из Debian подобных дистрибутивов Linux, ядро сконфигурировано на частоту 250HZ т. е. Один тик ядра = 4мс.

Пишем программу, которая с настраиваемой частотой одновременно собирает данные со всех модулей.
Чтобы написать все корректно, вероятно, нужно понимать, как в целом двигаются данные от модулей до клиента(нашей программы).

Насколько я понял из разных документаций, примерно по такому сценарию двигаются данные наших модулей(LTR114, LTR,27, LTR51).
1. После конфигурации модулей и запуска сбора данных(LTR*_Start()), модули начинают генерировать данные(которые приходят в ltrd и позже к клиенту в виде слов).
Для LTR114 единица данных, насколько я понял - это данные только с одного из всех каналов, которые мы опрашиваем.
Для LTR27 единица данных - это полноценный кадр, то есть, грубо говоря, снимок данных со всех 16 физ.каналов модуля/сабмодуля.
Для LTR51 единица данных - это параметры частотного сигнала {N,M}, которые генерятся с частотой F_Base.
2. Поскольку у наших модулей нет внутреннего буфера, то далее данные со всех модулей сразу же отправляются в единый FIFO буфер, расположенный в контроллере крейта.
3. Далее данные из FIFO буфера отправляются(через ethernet кабель в нашем случае) в ltrd, который в свою очередь фассует данные по своим внутренним буферам, созданным под каждый зарегестрированный модуль.
4. В это время клиент должен откачивать данные из ltrd буферов путем цикличного вызова функции LTR*_Recv(..., timeout_value).

По идее, для того, чтобы циклично отображать актуальные данные с датчиков, подсоединенных к модулям, необходимо грамотно и корректно организовать сбор данных из ltrd буфера.

Если движение данных выше в целом описано корректно, то есть следующие вопросы:
а) я правильно понимаю, что отправка данных из FIFO очереди крейта в ltrd происходит по мере поступления данных из самих модулей?
То есть, если данные пришли от модуля и если очередь пуста, то данные тут же будут отправлены в ltrd.
Если очередь не пуста, данные будут отправлены сразу же после того, как предыдущие данные будут отправлены.

б) насколько я понял, модули, которые мы используем + сам крейт - не являются оборудованием реального времени, соответственно, во время обработки данных внутри крейта(в том числе внутри модулей) возможны некоторые "запоздания".
Есть ли возможность определить максимальные опоздания в обработке данных внутри крейта(сеть, ltrd не берем в расчет)?
Например, если контроллер крейта "тикает" каждые 4мс, то быть может и максимальное опоздание может быть +4мс..?

в) опоздания в сети измерим самостоятельно. опоздания в работе ltrd, судя по коду - минимальные(все работает в одном потоке, но зато без каких-либо блокировок).

г) есть ли возможность определить, сколько слов/кадров/данных в данный момент находится в буфере? Нормально ли использовать информацию о буфере из функции LTR_GetModuleStatistic()?
По идее, если бы постоянно можно было иметь актуальную информацию о ltrd буфере модуля, то тогда бы работа в цикле выглядела бы так:
1. получить кол-во слов, насколько заполнен буфер
2. LTR*_Recv(, <size = кол-во слов из пункта 1>)
Была попытка реализовать что-то подобное, однако это не привело к успеху, потому что в большинстве случае функция статистики по модули выше говорила, что буфер абсолютно пуст(это также подтверждалось в выводе `ltrctl mstat <номер_слота>`). Помимо этого, мы заметили, что статистика по модулю в целом немного "запаздывает"(после 30минутной сессии мы перестали выгребать данные из ltrd буфера, при этом LTR*_Stop не был вызван. В это время `ltrctl mstat <slot>` все еще показывал, что данные отправляются клиенту, что неправда. Через примерно 10-15секунд `ltrctl mstat <slot>` начал показывать актуальное состояние).

д) какие основные принципы нужно соблюдать при цикличном сборе данных из ltrd буфера?
правильно ли я понимаю, что основной алгоритм примерно такой:
1. измерить время между предыдущей и текущей итерацией цикла;
2. на основе измерения из пункта 1 высчитать "потенциальное" кол-во кадров/данных, которое модуль должен сгенерить за это время;
3. вызвать LTR*_Recv() со значениями size = колву данных из пункта 2. Помимо этого, необходимо выставить таймаут такой величины, чтобы он покрывал всевозможные запоздания;

е) если принцип реализации цикличного сбора выше корректен, то есть ли какие то рекомендации по установке таймаута на сбор данных(LTR*_Recv()) ?
Быть может есть какое-то минимальное значение, которое учитывает потенциальные опоздания внутри крейта?
Мы отправляли письмо с таким(и другими) вопросом и нам для частоты опроса 10Гц(наша программа собирает данные каждые 100мс) рекомендовали выставить таймаут в 1 секунду.

#4 Re: Техническая поддержка и выбор оборудования » LTR114: 5022 ОМ при вытыкании резисторов » 14.10.2025 15:31:50

Забыл спросить: а то, что в ltr114_metr программе нельзя одновременно измерять напряжение и сопротивление - это просто ограничение программы или действительно есть какие-то ограничение на "смешанное" измерение?
Мы изначально допускали, что смешение напряжения и измерения имеет какие-то ограничения и именно поэтому в наших сценариях мы имеет разные результаты.

#5 Re: Техническая поддержка и выбор оборудования » LTR114: 5022 ОМ при вытыкании резисторов » 14.10.2025 14:02:08

Спасибо за ответы,

По поводу моего общего вопроса - понял, вопросов нет.

По поводу основного вопроса - я понял, что в случае оборванных входов следует ожидать некоторый набор значений, где, например, для нашего случая в этот набор входит 0, 5022 Ом и, возможно, другие значения.
Вопрос: а как определить этот набор значений? Какие значения могут входить, а какие входить не могут?

#6 Техническая поддержка и выбор оборудования » Временами LTR*_Stop() завершается по таймауту. » 13.10.2025 22:33:32

КириллК
Ответов: 3

Добрый вечер,

Дано:
    1. LTR-EU-16-1 16-местный крейт
    2. Модуль LTR114 с поверкой
    3. Модуль LTR27 c поверкой
    4. Модуль LTR51 с поверкой
    5. Субмодуль H-27I-20
    6. Субмодуль H-27T
    7. Субмодуль H-27U-10
    8. Субмодуль H-51FL

Написали программу, которая работает с модулями выше по аналогии с примерами из документаций
https://www.lcard.ru/download/ltr27api.pdf
https://www.lcard.ru/download/ltr114api.pdf
https://www.lcard.ru/download/ltr51api.pdf

Как и в примерах, каждый модуль проходит по стандартным для него фазам:
1. LTR*_Init()
2. LTR*_Open()
3. Конфигурация модуля и структур
4. LTR*_Start()
5. Собираем и конвертируем данные через LTR*_Recv() и LTR*_ProcessData()
6. LTR*_Stop()
7. LTR*_Close()

Не знаю, важно это или нет, но программа работает со всеми модулями одновременно(в отдельных потоках) и все команды выше также выполняются одновременно в параллели.

Временами при остановке модулей, вызов LTR*_Stop для одного из модулей(вроде как модули всегда разные, закономерности пока не нашел) зависает на 5секунд и возвращает LTR_ERROR_NO_CMD_RESPONSE.

Крейт подключен к ПК с ltrd и нашей программой напрямую через ethernet кабель. Предполагаю, что проблем сетью здесь быть не должно.

Пока по воспроизведениям вижу, что такое может возникнуть в нестандартных или даже некорректных сценариях:
- когда мы доходим до конфигурации модуля(шаг 3), не делаем LTR*_Start(), но делаем LTR*_Stop()
- когда после успешной остановки программы(шаг 6), мы еще раз выполняем  LTR*_Stop()
- видели пару раз такое в моменте, когда был переполнен ltrd буфер для одного(или всех) модуля т.е. зависало при выполнении шага 6.

Обычно, проблема решается повторной отправкой стоп запроса т.е. повторным выполнение функции LTR*_Stop().

Хотелось бы в целом понять, при каких сценариях возможно такое поведение(чтобы быть готовым применить какое то решение) и есть ли еще способы решить проблему, возможно более мягче.

#7 Техническая поддержка и выбор оборудования » LTR114: 5022 ОМ при вытыкании резисторов » 13.10.2025 21:10:51

КириллК
Ответов: 5

Добрый вечер,

Дано:
- LTR-EU-16-1 16-местный крейт
- Модуль LTR114 с поверкой
- к модулю LTR114 подключены 4 резистора (270 Ом, 2000 Ом, 3300 Ом, 510 Ом)


Написали программу по аналогии с примером из документации https://www.lcard.ru/download/ltr114api.pdf.
Разница между нашей программой и примером - в конфигурации(смотри ниже), а также в том, что мы считываем данные в бесконечном цикле каждые 100мс. Если модуль генерирует кадры быстрее нас, то за один LTR114_Recv() мы собираем все, что за это время модуль мог сгенерить.
При этом, если LTR114 модуль генерирует кадр медленнее, чем мы собираем, то мы НЕ выполняем LTR114_Recv() запрос до тех пор, пока не сгенерировался один кадр. К примеру, если частота АЦП = 5Гц, кол-во каналов = 4, межкадровая задержка = 0, то получается, что один кадр МАТЕМАТИЧЕСКИ генерится каждые (1000мс/5гц)*4канала = 800мс и соответственно, наша программа выполнит LTR114_Recv() только на каждой 8й итерации. Безусловно, стоит учитывать, что возможны разные задержки и их мы покрываем большим значением таймаута в  LTR114_Recv().

Во время теста мы запускаем программу, потом вытыкаем клемму с резисторами и через некоторое время втыкаем ее обратно.

На средних и больших частотах все работает так, как мы ожидаем - при втыкании мы получаем нужные значения в Омах. При вытыкании получаем 0.

Непонятное для нас поведение возникает, когда модуль работает на частоте 5Гц:
1) когда вытыкаем резисторы, то в рамках одной итерации(собрали один кадр) видим значения 5022 Ом для всех каналов. В рамках следующих итераций происходит "затухание" до нуля.
2) если в программе при конфигурации логических каналов выставить один из них на измерение напряжения, то после запуска программы и вытыкания клеммы, значения каналов, которые измеряют сопротивления, КОНСТАНТНО показывают 5022 Ом. То есть никакого "затухания" до нуля не происходит.

Как я понял, 5022 Ом - это некий сигнал, указывающий на разрыв цепи. Однако непонятно, почему в одном случае он затухает в 0, а в другом он постоянен.
С чем это связано?

И еще вопрос общего характера - в каком случае на практике имеет смысл выставлять частоту АЦП для LTR114 в 5Гц ?
Выглядит так, будто бы в любом сценарии выгоднее генерировать множество кадров, усреднять их получать корректное значение без лишнего "шума".

Ниже примерный код конфигурации логических каналов:

// измеряем только сопротивление
t114->LChTbl[0] = LTR114_CreateLChannel(LTR114_MEASMODE_R, 1, LTR114_RRANGE_4000);
t114->LChTbl[1] = LTR114_CreateLChannel(LTR114_MEASMODE_R, 2, LTR114_RRANGE_4000);
t114->LChTbl[2] = LTR114_CreateLChannel(LTR114_MEASMODE_R, 3, LTR114_RRANGE_4000);
t114->LChTbl[3] = LTR114_CreateLChannel(LTR114_MEASMODE_R, 4, LTR114_RRANGE_4000);

// меняем сопротивление на напряжение для одного канала
t114->LChTbl[0] = LTR114_CreateLChannel(LTR114_MEASMODE_R, 1, LTR114_RRANGE_4000);
t114->LChTbl[1] = LTR114_CreateLChannel(LTR114_MEASMODE_U, 2, LTR114_URANGE_2);
t114->LChTbl[2] = LTR114_CreateLChannel(LTR114_MEASMODE_R, 3, LTR114_RRANGE_4000);
t114->LChTbl[3] = LTR114_CreateLChannel(LTR114_MEASMODE_R, 4, LTR114_RRANGE_4000);

Контакты

Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4

Многоканальный телефон:+7 (495) 785-95-25

Письма и запросы: lcard@lcard.ru
Отдел продаж: sale@lcard.ru
Техническая поддержка: support@lcard.ru

Время работы: с 9-00 до 19-00 мск