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

E502 Асинхронный ввод одного кадра АЦП.

Вы не вошли.

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

07.03.2017 11:03:08
#1

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

E502 Асинхронный ввод одного кадра АЦП.

Добрый день
по поводу
X502_EXPORT(int32_t) X502_AsyncGetAdcFrame(t_x502_hnd hnd, uint32_t flags,
                                       uint32_t tout, double* data);
Поясните значение параметра

@param[in]  tout        Таймаут на выполнение функции в мс

Я могу запрашивать кадр с частотой в 1 мс?
Например:
err = X502_AsyncGetAdcFrame(hndX502, X502_PROC_FLAGS_VOLT, 1,
            kadr_data);

07.03.2017 12:52:08
#2

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

Re: E502 Асинхронный ввод одного кадра АЦП.

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

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

07.03.2017 13:59:09
#3

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

Re: E502 Асинхронный ввод одного кадра АЦП.

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

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

Спасибо, понятно.
При синхронном сборе, когда я забираю часть данных из буфера модуля Е502 он автоматически ужимается на размер изъятых данных?
И следующую порцию мне следует забирать снова с начала буфера модуля?

07.03.2017 14:03:00
#4

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

Re: E502 Асинхронный ввод одного кадра АЦП.

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

24.03.2017 07:30:18
#5

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Добрый день.
Возникло еще пару вопросов:
1)

4.1.11 Флаги, управляющие обработкой принятых данных
Тип: t_x502_proc_flags
Описание: Флаги, управляющие обработкой принятых данных
Константа Значение Описание
X502_PROC_FLAGS_VOLT 0x00000001
Признак, что нужно преобразовать
значения АЦП в вольты

А если НЕ нужно? какой флаг выставлять?
2) В каком формате передаются данные, НЕ преобразованные в вольты?
Судя по всему:

X502_EXPORT(int32_t) X502_AsyncGetAdcFrame(t_x502_hnd hnd, uint32_t flags,
                                       uint32_t tout, double* data);

double* data
Предполагается, что это просто 8 байт или действительно double?
Какая связь с разрядностью АЦП?

24.03.2017 09:04:32
#6

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

Re: E502 Асинхронный ввод одного кадра АЦП.

сделал так:

err = X502_AsyncGetAdcFrame(hndX502, 0, 100, kadr_data);

Получил вроде как массив int64

24.03.2017 10:20:22
#7

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Функция возвращает значения в double, но если нет преобразования в вольты, то возвращает просто код, полученный от модуля приведенный к double, т.е. дробная часть этого double будет всегда нулевая, и каждое значение можно просто привести к целому (можно и к int32, т.к. код 24-битный), т.е. массив нужно передвать в функцию все равно double, а потом привести при желании отдельно каждый элемент (а не массив int64, приведенный к указателю на массив double).

Модуль возвращает 24 битный код, полученный как 16-битный код АЦП, дополненный слева 8 битами нулей и после применением калибровочных коэффициентов в 24 битных числах.

Если нужен вообще код АЦП без применения калибровок, то нужно установить перед сбором текущие калибровочные коэффициенты k = 1 и offs = 0 через X502_SetAdcCoef() (см. описание функции).

24.03.2017 11:13:03
#8

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Спасибо, по разрядности  понятно.
Но все же:
если я прописываю в вызове X502_AsyncGetAdcFrame параметр flags=0

err = X502_AsyncGetAdcFrame(hndX502, 0, 100, kadr_data);

то что я получу на выходе:
код АЦП, после применения калибровочных коэффициентов
или без применения калибровок?

24.03.2017 11:23:33
#9

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

Re: E502 Асинхронный ввод одного кадра АЦП.

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

27.03.2017 11:20:32
#10

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Добрый день.
Алексей, X502_SetAdcCoef() сбрасывает значения калибровочных коэффициентов на один сеанс?
Или таки этот сброс пропишется в ПЗУ карты?

27.03.2017 11:22:32
#11

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

Re: E502 Асинхронный ввод одного кадра АЦП.

4.3.4.20 Установить коэффициенты для калибровки значений АЦП.
Формат: int32_t X502_SetAdcCoef (t_x502_hnd hnd, uint32_t range,
double k, double offs)
Описание:
Функция записывает в ПЛИС коэффициенты для калибровки значений
АЦП. При открытии модуля, библиотека считывает калибровочные коэффи-
циенты из защищенной области Flash-памяти модуля и записывает их в ПЛИС
для выполнения калибровки на лету.

27.03.2017 11:34:48
#12

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Да, на один сеанс - в ПЗУ не прописывается. При закрытии и открытии связи с модулем коэффициенты снова будут заменены на заводские из ПЗУ.

29.03.2017 14:54:01
#13

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Добрый день.
Хотелось бы уточнить для уверенности:
В демо примере на Х502
#define RECV_BUF_SIZE  8*1024*1024
1) размер буфера составляет 1 МБ?
и это никак не связано с частотой опроса АЦП при синхронном вводе - просто в качестве примера.
2) данные в выходном буфере после выполнения

X502_EXPORT(int32_t) X502_ProcessData(t_x502_hnd hnd, const uint32_t* src, uint32_t size,
                     uint32_t flags, double *adc_data, uint32_t *adc_data_size,
                     uint32_t *din_data, uint32_t *din_data_size);

из
uint32_t* src
переносятся 
double *adc_data
uint32_t* src очищается

Пусть у нас 4 физических и 4 логических  канала заданы, тогда данные в adc_data располагаются следующим образом:
первый отчет 1к,2к,3к,4к,  затем идет второй отчет 1к,2к,3к,4к и так далее ?

29.03.2017 16:25:13
#14

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Да, все правильно.
Ну только под "uint32_t* src очищается" правильнее сказать, что сами значения src не меняются, но по сути после ProcessData данные в src уже не используются для этого блока.

30.03.2017 07:01:25
#15

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

Re: E502 Асинхронный ввод одного кадра АЦП.

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

Да, все правильно.
Ну только под "uint32_t* src очищается" правильнее сказать, что сами значения src не меняются, но по сути после ProcessData данные в src уже не используются для этого блока.

Ммм, я вроде тут обсчитался вчера:

#define RECV_BUF_SIZE  8*1024*1024
1) размер буфера составляет 1 МБ?

Может 8 Мбайт?
размер double*1024*1024 ... или все же 1 Мбайт?
2)

сами значения src не меняются, но по сути после ProcessData данные в src уже не используются для этого блока

Если, скажем в буфере  модуля накопилось 2000 отчетов, а я забираю ProcessData только 1000 ... При следующем вызове я недобранную 1000 заберу?

@param[in,out] adc_data_size На входе в данном параметре передается резмер
                          буфера adc_data. Если данных от АЦП во входном массиве
                          будет больше adc_data_size, то в adc_data  будет
                          сохранено только первые adc_data_size отсчетов.

Или это будут уже совершенно новые отчеты?

30.03.2017 12:09:03
#16

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

Re: E502 Асинхронный ввод одного кадра АЦП.

stix_s пишет:

Может 8 Мбайт?

ну точнее даже 8 млн. отсчетов, хотя в действительности если речь идет про пример на C++ Builder/Delphi, то полностью он не используется, его можно было бы сделать меньше.
Тут т.к. функция X502_Recv() возвращает управление либо когда истечет указанный таймаут, либо когда в буфере принятых от модуля данных будет запрошенное кол-во данных, то тут есть два подхода: можно определить заданный размер блока какими Вы будете принимать данные с модуля, в этом случае Вы передаете таймаут с запасом и при нормальной работе Recv выдает сколько Вы запрашивали данных (например, если частота сбора 2 МГц и обрабатывать данные вы хотите блоками за секунду, то размер буфера может быть 2*1000*1000 отсчетов, а таймаут выбран с запасом) - этот путь используется в консольном примере на msvc.  Второй вариант, вызывать Recv(), которому передан буфер с запасом, но ограниченный таймаут, в этом случае Recv() выходит по таймауту и возвращает, сколько принято было данных. Так сделано в примере - делается Recv с временем в 250 мс, т.е. вычитываются все данные из модуля, которые накопятся в буфере за 250мс и уже анализируется размер, который вернула Recv.

stix_s пишет:

Если, скажем в буфере  модуля накопилось 2000 отчетов, а я забираю ProcessData только 1000 ... При следующем вызове я недобранную 1000 заберу?

Данные из буфера модуля получаются через Recv() и он работает как Вы написали - считывает самые старые не вычитанные отсчеты из буфера модуля, который работает как очередь и по сути очищает их. ProcessData (если у Вас только данные АЦП, то можно использовать более простой вариант ProcessAdcData()) же просто переводить принятых массив из формата модуля, где каждый отсчет - int32 со служебной информацией в отсчеты, соответствующие кодам АЦП или Вольтам (если не только данные АЦП, то еще разбивает их на данные АЦП и данные с цифровых линий). Соответственно он выполняет разбор с начала переданного массива. Если Вы передали на вход 2000 отсчетов, а размер выходного указали 1000, то чтобы потом преобразовать оставшиеся 1000, нужно подать вторую половину массива (т.е. указатель на элемент с номером 1000), или просто принимать через Recv() по 1000 отсчетов и все передавать в ProcessData().

30.03.2017 15:40:08
#17

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

Re: E502 Асинхронный ввод одного кадра АЦП.

Ясно, спасибо за развернутый ответ.

Контакты

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

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

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

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