|
- Участник
- Здесь с 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);
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,316
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Добрый день. Нет, не совсем так. tout - это просто предельное время, которое будет ожидать функция данные от модуля после запуска сбора кадра. При этом если данные придут раньше, то и функция вернет управление раньше. При нормальной работе функция должна завершится по приему кадра (который должен прийти быстрее установленного таймаута), поэтому таймаут должен быть взят с неким запасом. Вообще асинхронный ввод нужен для одиночного ввода кадра (когда между кадров время строго не задано и достаточно большое - определено жестко только время между отсчетами внутри кадра) и приводит к запуску сбора, приему, останову каждый раз, задержки этих операций могут варьироваться и это может вполне занимать и десятки милисекунд. Для приема кадров с нужной частотой между ними как раз нужен синхронный сбор.
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Алексей L Card пишет:Добрый день. Для приема кадров с нужной частотой между ними как раз нужен синхронный сбор.
Спасибо, понятно. При синхронном сборе, когда я забираю часть данных из буфера модуля Е502 он автоматически ужимается на размер изъятых данных? И следующую порцию мне следует забирать снова с начала буфера модуля?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,316
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Да, буфер по сути работает как очередь. Приходящие данные ставятся в конец, при чтении данные извлекаются из начала (и после чтения их место освобождается)
|
|
- Участник
- Здесь с 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? Какая связь с разрядностью АЦП?
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: E502 Асинхронный ввод одного кадра АЦП.
сделал так: err = X502_AsyncGetAdcFrame(hndX502, 0, 100, kadr_data);
Получил вроде как массив int64
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,316
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Функция возвращает значения в double, но если нет преобразования в вольты, то возвращает просто код, полученный от модуля приведенный к double, т.е. дробная часть этого double будет всегда нулевая, и каждое значение можно просто привести к целому (можно и к int32, т.к. код 24-битный), т.е. массив нужно передвать в функцию все равно double, а потом привести при желании отдельно каждый элемент (а не массив int64, приведенный к указателю на массив double). Модуль возвращает 24 битный код, полученный как 16-битный код АЦП, дополненный слева 8 битами нулей и после применением калибровочных коэффициентов в 24 битных числах. Если нужен вообще код АЦП без применения калибровок, то нужно установить перед сбором текущие калибровочные коэффициенты k = 1 и offs = 0 через X502_SetAdcCoef() (см. описание функции).
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Спасибо, по разрядности понятно. Но все же: если я прописываю в вызове X502_AsyncGetAdcFrame параметр flags=0 err = X502_AsyncGetAdcFrame(hndX502, 0, 100, kadr_data);
то что я получу на выходе: код АЦП, после применения калибровочных коэффициентов или без применения калибровок?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,316
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Код после применения калибровочных коэффициентов (так как они применяются на уровне самого модуля, а не в библиотеке, т.е. модуль уже передает отсчеты с примененными коэффициентами ). Поэтому как я написал, если нужно без калибровочных коэффициентов, то нужно их установить равными 1 и 0, чтобы их применение не изменяло код, один раз после открытия перед сбором данных.
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Добрый день. Алексей, X502_SetAdcCoef() сбрасывает значения калибровочных коэффициентов на один сеанс? Или таки этот сброс пропишется в ПЗУ карты?
|
|
- Участник
- Здесь с 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-памяти модуля и записывает их в ПЛИС для выполнения калибровки на лету.
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,316
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Да, на один сеанс - в ПЗУ не прописывается. При закрытии и открытии связи с модулем коэффициенты снова будут заменены на заводские из ПЗУ.
|
|
- Участник
- Здесь с 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к и так далее ?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,316
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Да, все правильно. Ну только под "uint32_t* src очищается" правильнее сказать, что сами значения src не меняются, но по сути после ProcessData данные в src уже не используются для этого блока.
|
|
- Участник
- Здесь с 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 отсчетов.
Или это будут уже совершенно новые отчеты?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,316
|
Re: E502 Асинхронный ввод одного кадра АЦП.
ну точнее даже 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().
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: E502 Асинхронный ввод одного кадра АЦП.
Ясно, спасибо за развернутый ответ.
|