|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Е-502 синхронный ввод
Добрый день. Вопрос 1. Прошу уточни по ошибке /** Неверный номер канала в обрабатываемом потоке синхронного ввода */ X502_ERR_PROC_INVALID_CH_NUM = -140,
Как ее перехватить? Дело в том, что мне не нужно модальное окошко, а нужно вывести в строку состояния. Вопрос 2 По какому принципу формируется частота при использовании Функция подбирает делитель частоты АЦП так, чтобы полученная частота сбора была наиболее близка к указанной в параметре f_acq
X502_EXPORT(int32_t) X502_SetAdcFreq(t_x502_hnd hnd, double *f_acq, double *f_frame);
Если я завожу изначально 32 канала физических, привязываю их на 32 логических, то при вводе параметра f_acq = 160 кГц, f_frame - 2 кГц, получаю дробные значения. Какова кратность f_acq для получения НЕ дробной частоты? Вопрос 3 Так же функция может подобрать значение межкадровой задержки так, чтобы частота следования кадров (частота сбора на логический канал) была наиболее близка к указанному значению.
По какой формуле производится расчет межкадровой задержки? Если к примеру я укажу f_acq 200 кГц, а f_frame 3 кГц при 32 логических каналах?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
Ее возвращает функция ProcessData (или ProcessAdcData), а уже что делать, если ProcessData вернула не 0, это уже зависит от того как написана Ваша программа. stix_s пишет:Какова кратность f_acq для получения НЕ дробной частоты?
Частота определяется как Fref/K, где Fref - опорная частота (2 или 1.5 МГц), а K - целое число. Соответственно функция подбирает K, чтобы частота была наиболее близка к переданной в функцию. stix_s пишет:По какой формуле производится расчет межкадровой задержки? Если к примеру я укажу f_acq 200 кГц, а f_frame 3 кГц при 32 логических каналах?
Это будет означать, что внутри кадра измерения разных каналов делаются с частотой 200 кГц, а затем вставляется задержка, так что частота следования кадров будет 3 кГц. Т.е. если нужно время межкадровой задержки (от последнего измерения кадра до первого следующего), то это будет 1./f_frame - Nch/f_acq (где Nch - количество каналов в кадре). Соответственно f_frame также берется из сетки Fref/K
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Алексей L Card пишет:Ее возвращает функция ProcessData (или ProcessAdcData), а уже что делать, если ProcessData вернула не 0, это уже зависит от того как написана Ваша программа.
Ммм, я так понял, что при ошибке ProcessData (или ProcessAdcData) самостоятельно вываливает окошко с Error. Спасибо за ответы, буду смотреть.
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
Там в примере в основном окне есть обработчик завершения потока (OnThreadTerminate), и по завершению потока сбора он проверяет, завершился ли тот по ошибке и выводит окно.
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Алексей L Card пишет:Там в примере в основном окне есть обработчик завершения потока (OnThreadTerminate), и по завершению потока сбора он проверяет, завершился ли тот по ошибке и выводит окно.
Точно, слона-то я и не заметил Просто пока именно Ваш тест использую для издевательств над модулем. Но главное, как я понял функции API модуля окошек с ошибками не выводят, только код результата?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Возник еще один вопрос В синхронном потоке забираю 32 канала АЦП, пытаюсь узнать, сколько получил while (!stop && (err == X502_ERR_OK)) {
// Функция возвращает количество отсчетов, которые были приняты из модуля
// во внутренний буфер и готовы для считывания
err = X502_GetRecvReadyCount(threadHndX502, &rcv_count);
// принимаем данные синхронного ввода
// RECV_BUF_SIZE Количество считываемых отсчетов (32-битных слов)
// функция возвратит столько отсчетов, сколько было в буфере
rcv_size = X502_Recv(threadHndX502, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
// значение меньше нуля означает ошибку...
ради интереса записываю данные в файл
2017.04.27 11:11:28 ;2,6000 2,6000 2,6000 2,6000 2,6000 - это 5 измерений на 0 канал с шагом 100 lch_cnt:32 firstLch:0 adcSize:17280 rcv_count:0 rcv_size:17280 - это переменные и их текущие значения в потоке (наименования, как у Вас в тесте), записанные в файл
Получается, что по итогам err = X502_GetRecvReadyCount(threadHndX502, &rcv_count);
в буфере 0 отчетов а по итогам rcv_size = X502_Recv(threadHndX502, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
получено 17280 (и интересно это байт или 32 разрядных слов? )
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Мда, еще: 3.6.2 Настройка частоты синхронного ввода/вывода Все частоты потокового сбора и выдачи данных основываются на опорной частоте синхронизации. В качестве опорной частоты может использоваться внутренний источ- ник частоты или внешний. В первом случае, опорная частота может быть 2МГц либо 1.5МГц. По умолчанию используется 2МГц. Изменить ее можно с помощью функции X502_SetRefFreq().
А как узнать текущую опорную?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
stix_s пишет:получено 17280 (и интересно это байт или 32 разрядных слов? )
Это в 32-битных словах. Recv() ожидает либо завершения таймаута, либо появления запрашиваемого числа слов в буфере. Соответственно за RECV_TOUT у Вас набралось столько слов. stix_s пишет:А как узнать текущую опорную?
Есть функция X502_GetRefFreqValue(), хотя в принципе Вы сами тоже знаете, какую частоту установили.
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Алексей L Card пишет:Соответственно за RECV_TOUT у Вас набралось столько слов.
Спасибо, понятно, но почему err = X502_GetRecvReadyCount(threadHndX502, &rcv_count);
дает мне rcv_count = 0, а следующая следом rcv_size = X502_Recv(threadHndX502, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
количество считанных из буфера слов? Алексей L Card пишет: Есть функция X502_GetRefFreqValue(), хотя в принципе Вы сами тоже знаете, какую частоту установили.
Я планирую перепроверять. int32_t X502_GetRefFreqValue (t_x502_hnd hnd, double *freq) Параметры: hnd — Описатель модуля. freq — Значение внешней опорной частоты в Гц.
А что передавать в качестве параметра freq при использовании внутренней синхронизации?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
На момент вызова X502_Recv у Вас 0 слов в буфере, но X502_Recv() ждет указанное время (RECV_TOUT) прихода недостающих данных. За RECV_TOUT у Вас накапливается столько данных и Recv() выходит по таймауту. stix_s пишет:А что передавать в качестве параметра freq при использовании внутренней синхронизации?
В freq возвращается установленная частота (это выходной параметр, входное значение не важно). Для внутренней тут будет установленно 2000000 или 1500000.
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Алексей L Card пишет:На момент вызова X502_Recv у Вас 0 слов в буфере, но X502_Recv() ждет указанное время (RECV_TOUT) прихода недостающих данных. За RECV_TOUT у Вас накапливается столько данных и Recv() выходит по таймауту.
Но я не говорю о полном накоплении буфера. Почему err = X502_GetRecvReadyCount(threadHndX502, &rcv_count);
rcv_count=0 ? Хоть байт-то в буфере должен быть. Иначе какой смысл в данной функции? Ведь она декларируется - как проверяющая на готовность в буфере определенного количества данных. Или я не прав? Идущая следом rcv_size = X502_Recv(threadHndX502, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
Вываливает мне уже килобайты. Или необходимо вызывать X502_GetRecvReadyCoun уже после X502_Recv? Но смысл не понятен. Алексей L Card пишет:В freq возвращается установленная частота (это выходной параметр, входное значение не важно). Для внутренней тут будет установленно 2000000 или 1500000.
Алексей, я пробовал передать freq равное 0 и в ответ получил 0.
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
stix_s пишет:Ведь она декларируется - как проверяющая на готовность в буфере определенного количества данных.
Она получает количество данных, которые пришли от модуля и еще не были прочитаны, т.е. количество данных, которое можно получить в настоящий момент через Recv() без ожидания (с нулевым таймаутом). Также эта функция работает только для USB (и для PCI-E для L502) и не работает при работе по Ethernet.
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Алексей L Card пишет:Также эта функция работает только для USB (и для PCI-E для L502) и не работает при работе по Ethernet.
У меня именно USB E-502-X-U-D №2T253133
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Добрый день. Пытаюсь использовать /***************************************************************************//** @brief Получить количество отсчетов в буфере потока на ввод. Функция возвращает количество отсчетов, которые были приняты из модуля во внутренний буфер и готовы для считывания с помощью X502_Recv(). То есть если в X502_Recv() передать значение, которое вернула данная функция, то X502_Recv() вернет это количество данных без ожидания (так как они уже в буфере). При работе по Ethernet данная функция возвращает корректное значение только для ОС Windows. @param[in] hnd Описатель модуля. @param[out] rdy_cnt Количество готовых к приему отсчетов. @return Код ошибки. ***************************************************************************/ X502_EXPORT(int32_t) X502_GetRecvReadyCount(t_x502_hnd hnd, uint32_t *rdy_cnt);
Но в тестовом примере: ..........
if (err == X502_ERR_OK) {
/* выполняем прием пока не произойдет ошибка или
не будет запроса на останов от основного приложения */
while (!stop && (err == X502_ERR_OK)) {
err = X502_GetRecvReadyCount(hnd, &rcv_count);
if (rcv_count > RECV_BUF_SIZE) {
isReady = true;
}
else {
isReady = false;
}
/* принимаем данные синхронного ввода */
int32_t rcv_size = X502_Recv(hnd, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
/* значение меньше нуля означает ошибку... */
if (rcv_size < 0) {
err = rcv_size;
......
}
rcv_count - всегда=0 Что я делаю не так?
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Пардон, код привел неверный, поправил: не будет запроса на останов от основного приложения */
while (!stop && (err == X502_ERR_OK)) {
err = X502_GetRecvReadyCount(hnd, &rcv_count);
if (rcv_count > 0){//RECV_BUF_SIZE - 1000) {
isReady = true;
}
else {
isReady = false;
}
if (isReady) {
/* принимаем данные синхронного ввода */
int32_t rcv_size = X502_Recv(hnd, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
/* значение меньше нуля означает ошибку... */
if (rcv_size < 0) {
err = rcv_size;
}
else if (rcv_size > 0) {
/* если больше нуля - значит приняли новые данные */
dinSize = RECV_BUF_SIZE;
adcSize = RECV_BUF_SIZE;
/* получаем номер лог. какнала, соответствующий первому
отсчету АЦП, так как до этого могли обработать
некратное количество кадров */
err = X502_GetNextExpectedLchNum(hnd, &firstLch);
if (err == X502_ERR_OK) {
/* разбираем данные на синхронный ввод и отсчеты АЦП и
переводим АЦП в Вольты */
err = X502_ProcessData(hnd, rcv_buf, rcv_size, L502_PROC_FLAGS_VOLT, adcData, &adcSize, dinData, &dinSize);
}
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
Поставил в штатном примере перед Recv Sleep на 100 мс и X502_GetRecvReadyCount() вернул не нулевое адекватное значение. Точно запустили сбор и не вычитываете данные из буфера без isReady?
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
Алексей L Card пишет:Поставил в штатном примере перед Recv Sleep на 100 мс и X502_GetRecvReadyCount() вернул не нулевое адекватное значение.
Попробую ваш вариант. Изначально задержку не ставил, поскольку предполагал, что на 2-3 ... проходах задержка образуется сама собой. Алексей L Card пишет:Точно запустили сбор и не вычитываете данные из буфера без isReady?
Да, сбор запущен, сначала идет err = X502_GetRecvReadyCount(hnd, &rcv_count);
по ответу выставляется isReady если что-то есть rcv_count>0 (isReady=true), то запускаем rcv_size = X502_Recv(hnd, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
по итогам rcv_count=0 и до вызова rcv_size = X502_Recv(hnd, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
не доходим но в случае, если я хотя бы раз без учета isReady запускаю rcv_size = X502_Recv(hnd, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
то вот на следующем проходе получаю после err = X502_GetRecvReadyCount(hnd, &rcv_count); rcv_count>0
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
void __fastcall X502_ProcessThread::Execute() { /* выделяем буферы под принимаемые данные */ uint32_t *rcv_buf = new uint32_t[RECV_BUF_SIZE]; dinData = new uint32_t[RECV_BUF_SIZE]; adcData = new double[RECV_BUF_SIZE]; uint32_t rcv_count = -1; bool isReady = false; if (!rcv_buf || !dinData || !adcData) { err = X502_ERR_MEMORY_ALLOC; } else { /* запускаем синхронные потоки */ err = X502_StreamsStart(hnd); if (err == X502_ERR_OK) { /* выполняем прием пока не произойдет ошибка или не будет запроса на останов от основного приложения */ while (!stop && (err == X502_ERR_OK)) { Sleep(100); err = X502_GetRecvReadyCount(hnd, &rcv_count); if (rcv_count > 0){//RECV_BUF_SIZE - 1000) { isReady = true; } else { isReady = false; } if (isReady) { /* принимаем данные синхронного ввода */ int32_t rcv_size = X502_Recv(hnd, rcv_buf, RECV_BUF_SIZE, RECV_TOUT); /* значение меньше нуля означает ошибку... */ if (rcv_size < 0) { err = rcv_size; } else if (rcv_size > 0) { /* если больше нуля - значит приняли новые данные */ dinSize = RECV_BUF_SIZE; adcSize = RECV_BUF_SIZE; /* получаем номер лог. какнала, соответствующий первому отсчету АЦП, так как до этого могли обработать некратное количество кадров */ err = X502_GetNextExpectedLchNum(hnd, &firstLch); if (err == X502_ERR_OK) { /* разбираем данные на синхронный ввод и отсчеты АЦП и переводим АЦП в Вольты */ err = X502_ProcessData(hnd, rcv_buf, rcv_size, L502_PROC_FLAGS_VOLT, adcData, &adcSize, dinData, &dinSize); } if (err == X502_ERR_OK) { /* обновляем значения элементов управления */ Synchronize(updateData); } } } } /* по выходу из цикла отсанавливаем поток. Чтобы не сбросить код ошибки (если вышли по ошибке) результат останова сохраняем в отдельную переменную */ int32_t stop_err = X502_StreamsStop(hnd); if (err == X502_ERR_OK) err = stop_err; } } /* освобождаем выделенную память */ delete rcv_buf; delete dinData; delete adcData; }
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
хм, с задержкой процесс пошел ... непонятно
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
но почему-то rcv_count достигает только определенного размера гораздо меньшего RECV_BUF_SIZE, причем int32_t rcv_size = X502_Recv(hnd, rcv_buf, RECV_BUF_SIZE, RECV_TOUT);
я не вызываю
|
|
- Участник
- Здесь с 19.01.2017
- Сообщений: 82
|
Re: Е-502 синхронный ввод
даже и без Sleep(100); возвращается rcv_count но до определенного предела на 400 кГц и 12,5 кГц на канал это 673152 (я так понимаю 32-х разрядных слов)
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,293
|
Re: Е-502 синхронный ввод
В самой библиотеке буфер ограничен, поэтому это значение будет увеличиваться до определенного предела, пока не заполнится буфер в библиотеке. Поэтому правильнее откачивать в свой буфер данные частями до достижения нужного количества данных в своем буфере, чем просто ждать, пока значение из RecvRdyCount достигнет нужного размера. Буфер в библиотеке используется больше для того, чтобы не потерять данные из-за задержек между вызовом Recv()
|