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

Синхронизация начала съема с двух АЦП в крейте

Вы не вошли.

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

09.04.2019 23:21:19
#1

Участник
Здесь с 28.10.2015
Сообщений: 22

Синхронизация начала съема с двух АЦП в крейте

Здравствуйте! Приобрели два АЦП LTR24 в крейте LTR-EU-2-5  и хотим сделать синхронный съем данных по шести каналам. Для этого в программе делаем подключения к крейту (для генерирования синхрометок) и к каждому модулю АЦП в крейте, задаем одинаковую частоту дискретизации(код LTR24_FREQ_58K) для каждого АЦП. В одном из них инициализируем и разрешаем все четыре канала в другом только два. Далее пытаемся в качестве теста запустить съем, послать синхрометку и выбрать стартовые отсчеты в каждом из двух массивов отсчетов, которые помечены синхрометкой. Вот ключевой участок кода (на Delphi):

	........
      N := 2048 * 4;
      N2 := 2048 * 2;
	........
      sResult := LTR24_Start(ltrModule1); // Запускаем съем с первого АЦП
      sResult := LTR24_Start(ltrModule2); // Запускаем съем со второго АЦП
      sResult := LTR_MakeStartMark(ltrCrate, LTR_MARK_INTERNAL); // Генерируем синхрометку СТАРТ
      sResult := LTR24_Recv(ltrModule1, rBuf, tmark, N, 0); // Принимаем данные от первого АЦП
      sResult := LTR24_Recv(ltrModule2, rBuf2, tmark2, N2, 0); // Принимаем данные от второго АЦП
      sResult := LTR24_Stop(ltrModule1); // Останавливаем съем с первого АЦП
      sResult := LTR24_Stop(ltrModule2); // Останавливаем съем со второго АЦП

Сразу оговорюсь код сугубо тестовый без всяких проверок. пытаюсь считать 2048 отсчетов. При этом возникают ситуации когда синхрометка вообще не успевает прийти в один из АЦП или в другом приходит практически после половины принятых отсчетов. Я отслеживаю приход синхрометки по изменению счетчика в массивах tmark и tmark2. С чем это может быть связано ? Действительно настолько долго происходит генерация синхрометки ? Или нужно как то по иному программировать синхронный съем данных ? В принципе в этой задаче я могу обойтись и без синхронного съема, но, в будущем, боюсь без этого будет трудно обойтись. Буду рад любой информации.

10.04.2019 14:07:46
#2

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,291

Re: Синхронизация начала съема с двух АЦП в крейте

Добрый день.
Вопрос скорее не только во времени генерации синхрометки, а также во времени запуска модулей. При вызове LTR24_Start() происходит обмен команд с модулем (при этом модуль запускается и Вы еще в Start должны принять ответ, когда модуль уже собирает), затем Вы вызываете второй LTR24_Start() и происходит обмен команд для запуска второго модуля (первый при этом  собирает данные), затем передача команды в крейт для генерации синхрометки, которая должна дойти до крейта.

2048 отсчетов на частоте 58КГц - это всего 35 мс. В общем для Windows  (которая вообще не ОСРВ и не гарантирует задержки) это не такое большое время, и вполне может пройти за время ожидания ответа от запуска первого модуля, обмен команд для запуска второго и передачу команды крейту на генерацию синхрометки, даже при подключении по USB (а по Ethernet могут быть еще свои задержки).

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

10.04.2019 23:21:03
#3

Участник
Здесь с 28.10.2015
Сообщений: 22

Re: Синхронизация начала съема с двух АЦП в крейте

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

Добрый день.

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

Спасибо большое, Алексей! В принципе по сути текущей задачи съемы данных нужны в определенные моменты времени а не непрерывно. Поэтому изначально была мысль сделать считывание данных между LTR24_Start и LTR24_Stop. Но, помимо необходимости синхронизации потока данных от двух разных АЦП в одном крейте,  мы заметили что функция LTR24_Stop занимает довольно продолжительное время. Поэтому скорее склоняемся к мысли сделать непрерывное считывание данных в течение всего цикла работы, а использовать считанные данные в нужные моменты времени. А в процессе начального запуска программы дать команды на старт считывания и, после посылки синхрометки, в цикле ждать изменения счетчиков меток для обоих АЦП, чтобы синхронизировать считываемые потоки.
Алексей, но вот возникает такой вопрос, а не может ли сложиться такая ситуация, что для какого - нибудь из АЦП синхрометка прийдет либо раньше, либо вместе с первым же отсчетом первого канала ? То есть не может ли сложиться так, что ожидание изменения счетчика меток для этого АЦП будет бессмысленным ?

11.04.2019 10:34:37
#4

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,291

Re: Синхронизация начала съема с двух АЦП в крейте

В Вашем случае такого быть не должно, все же Вы сперва запускаете сбор, а затем уже делаете генерацию метки, когда сбор идет.
Единственное, для некоторых модулей после запуска может проходить время установки фильтров и время первого преобразования и при низких частотах сбора можно представить ситуацию, что хотя модуль уже запущен, первый отсчет будет позже, чем придет команда генерации синхрометки в крейт.
Чтобы гарантированно избежать такого варианта при любом случае, надежным (хотя более долгим) может быть вариант запуска модулей, затем приема одного кадра от каждого модуля с запоминанием значения tmark для этого кадра, после чего посылается команда генерация метки и уже далее прием до изменения tmark относительно начального (проверка изменения tmark конечно должна быть и между блоками, если прием идет за несколько Recv, так как понятно, что изменение tmark может быть в первом семпле следующего Recv по сравнению с предыдущем).

11.04.2019 23:40:05
#5

Участник
Здесь с 28.10.2015
Сообщений: 22

Re: Синхронизация начала съема с двух АЦП в крейте

Спасибо большое, Александр!
Теперь понятно как использовать синхрометки. Подскажите я правильно понимаю, что далее, после того как я получил позицию прихода синхрометки в каждом из буферов АЦП, я должен далее найти относительно этих позиций начало ближайшего следующего кадра с помощью функций LTR24_FindFrameStart, и обрабатывать данные уже начиная с этих новых позиций, обеспечивая синхронную обработку по времени? Вот примерный алгоритм:

     
if (i1 > -1) And (i0 > -1) then
begin
        sResult := LTR24_FindFrameStart(ltrModule1, rBuf[i0], N - i0, i00);
        sResult := LTR24_FindFrameStart(ltrModule2, rBuf2[i1], N2 - i1, i11);
        Inc(i00, i0);
        Inc(i11, i1);

        Move(rBuf[i00], rBuf[0], (N - i00) SHL 2);
        LTR24_Recv(ltrModule1, rBuf[N - i00], tmark, i00, 0);
        Move(rBuf2[i11], rBuf2[0], (N2 - i11) SHL 2);
        LTR24_Recv(ltrModule2, rBuf2[N2 - i11], tmark2, i11, 0);
end;

Далее уже можно считывать данные побуферно без сдвижек. И вот еще хотел узнать, можно ли вызывать далее функцию LTR24_ProcessData обычным образом, несмотря на то что для первых нескольких вызовов LTR24_Recv во время поиска синхрометки я ее не вызывал? Не будет ли ошибки при ее вызове? Понятно что в дальнейшей обработке я буду вызывать ее для каждого вызова LTR24_Recv.

12.04.2019 10:58:49
#6

Участник
Здесь с 28.10.2015
Сообщений: 22

Re: Синхронизация начала съема с двух АЦП в крейте

Алексей, извините, назвал Вас Александром. Под вечер уже путаться начинаю smile

12.04.2019 11:35:39
#7

Участник
Здесь с 28.10.2015
Сообщений: 22

Re: Синхронизация начала съема с двух АЦП в крейте

Извините, что сыплю вопросы, но обнаружил еще один непонятный момент. Для теста написал тако

12.04.2019 11:43:59
#8

Участник
Здесь с 28.10.2015
Сообщений: 22

Re: Синхронизация начала съема с двух АЦП в крейте

Извините, что сыплю вопросы, но обнаружил еще один непонятный момент. Для теста написал такой вот код

if (i1 > -1) And (i0 > -1) then
begin
        sResult := LTR24_FindFrameStart(ltrModule1, rBuf[i0], N - i0, i00);
        sResult := LTR24_FindFrameStart(ltrModule2, rBuf2[i1], N2 - i1, i11);
        Inc(i00, i0);
        Inc(i11, i1);

        Move(rBuf[i00], rBuf[0], (N - i00) SHL 2);
        LTR24_Recv(ltrModule1, rBuf[N - i00], tmark, i00, 0);
        Move(rBuf2[i11], rBuf2[0], (N2 - i11) SHL 2);
        LTR24_Recv(ltrModule2, rBuf2[N2 - i11], tmark2, i11, 0);

       sX := N;
        sResult := LTR24_ProcessData(ltrModule1, rBuf, vBuf, sX,
          LTR24_PROC_FLAG_CALIBR Or //LTR24_PROC_FLAG_VOLT Or
            LTR24_PROC_FLAG_AFC_COR_EX);

        sX := N2;
        sResult := LTR24_ProcessData(ltrModule2, rBuf2, vBuf, sX,
          LTR24_PROC_FLAG_CALIBR Or //LTR24_PROC_FLAG_VOLT Or
            LTR24_PROC_FLAG_AFC_COR_EX);

        sResult := LTR24_Recv(ltrModule1, rBuf, tmark, N, 0);
        sResult := LTR24_Recv(ltrModule2, rBuf2, tmark2, N2, 0);

        sResult := LTR24_Recv(ltrModule1, rBuf, tmark, N, 0);
        sResult := LTR24_Recv(ltrModule2, rBuf2, tmark2, N2, 0);

      sX := N;
      sResult := LTR24_ProcessData(ltrModule1, rBuf, vBuf, sX,
        LTR24_PROC_FLAG_CALIBR Or //LTR24_PROC_FLAG_VOLT Or
          LTR24_PROC_FLAG_AFC_COR_EX);

      sX := N2;
      sResult := LTR24_ProcessData(ltrModule2, rBuf2, vBuf, sX,
        LTR24_PROC_FLAG_CALIBR Or //LTR24_PROC_FLAG_VOLT Or
          LTR24_PROC_FLAG_AFC_COR_EX);
end;

Первые два вызова LTR24rocessData проходят успешно. Ожидал получить ошибку при вызове функций LTR24_ProcessData после двух подряд вызовов LTR24_Recv. Вроде бы нарушается непрерывность потока данных для обработки. Но почему то функции вернули 0. Ошибки не возникло. Это нормальное поведение ?

12.04.2019 14:33:03
#9

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,291

Re: Синхронизация начала съема с двух АЦП в крейте

Сам алгоритм описан Вами в общем правильно.

По поводу нескольких Recv без ProcessData, насколько я вижу, для LTR24 в LTR24_ProcessData проверяется непрерывность данных в самом обрабатываемом блоке, что внутри блока не было разрывов данных, а также что данные выровнены на границу кадра, именно отсутствия разрыва данных между вызовами сейчас не проверяется, т.е. что новый блок, обрабатываемый с ProcessData идет сразу за предыдущем, поэтому ошибку функция не возвращает. Тут не совсем корректно это описано в документации.

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

13.04.2019 23:03:14
#10

Участник
Здесь с 28.10.2015
Сообщений: 22

Re: Синхронизация начала съема с двух АЦП в крейте

Алексей, спасибо большое! В принципе вся схема обработки понятна. И еще один вопрос возник. Если я в функции LTR24_ProcessData  не ставлю флаг перевода в вольты, что за значения я получаю после преобразования? Это знаковые числа в рамках разрядной сетки АЦП? То есть если я ставлю формат 24 бита то это 23 бита со знаком ? Просто мне желательно после съема данных сохранять их в формате wav. И хотелось бы понять как лучше преобразовывать данные после обработки.

15.04.2019 13:18:34
#11

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,291

Re: Синхронизация начала съема с двух АЦП в крейте

У ProcessData возвращаемый тип всегда double.

Если Вы используете калибровку, но отключен перевод в Вольты, и включен режим 24 бита, то у Вас значение 2^23 соответствует значению +диапазон (2 или 10 В, какой выставлен), соответственно -2^23 - минус диапазон. При этом т.к. идет умножение на калибровочные коэф, то у этого числа есть и дробная часть, а также, т.к. разрядная сетка АЦП несколько превышает сам диапазон (т.е., например, в 10В диап. реально есть запас и можно падать чуть выше 10В), то для значений на входе выше диапазона будет возвращен код больше 2^23.

Если калибровку не используете, то будет возвращен в чистом виде код АЦП (от -2^23 до 2^23-1 с нулевой дробной частью), но не будет учитываться коэф. передачи входного тракта конкретного модуля, который за счет разбросов элементов может быть разный у разных модулей (для компенсации которого и используются индивидуальные калибровочные коэффициенты).

Для 20-битного режима все тоже, но степень не 23 а 19.

Контакты

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

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

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

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