Форум: Техническая поддержка

Тема: Е-502 синхронный ввод

Вы не вошли.

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

25.04.2017 17:06:35
#1

Участник
Здесь с 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 логических каналах?

25.04.2017 17:53:59
#2

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

Re: Е-502 синхронный ввод

stix_s пишет:

Как ее перехватить?

Ее возвращает функция 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

25.04.2017 19:15:27
#3

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

Re: Е-502 синхронный ввод

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

Как ее перехватить?

Ее возвращает функция ProcessData (или ProcessAdcData), а уже что делать, если ProcessData вернула не 0, это уже зависит от того как написана Ваша программа.

Ммм, я так понял, что при ошибке ProcessData (или ProcessAdcData) самостоятельно вываливает окошко с Error.
Спасибо за ответы, буду смотреть.

25.04.2017 20:11:33
#4

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

Re: Е-502 синхронный ввод

Там в примере в основном окне есть обработчик завершения потока (OnThreadTerminate), и по завершению потока сбора он проверяет, завершился ли тот по ошибке и выводит окно.

26.04.2017 06:49:57
#5

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

Re: Е-502 синхронный ввод

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

Там в примере в основном окне есть обработчик завершения потока (OnThreadTerminate), и по завершению потока сбора он проверяет, завершился ли тот по ошибке и выводит окно.

Точно, слона-то я и не заметил sad
Просто пока именно Ваш тест использую для издевательств над модулем.
Но главное, как я понял функции API модуля окошек с ошибками не выводят, только код результата?

26.04.2017 09:25:23
#6

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

Re: Е-502 синхронный ввод

Да, именно так

27.04.2017 09:30:03
#7

Участник
Здесь с 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 разрядных слов? )

27.04.2017 10:48:32
#8

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

Re: Е-502 синхронный ввод

Мда, еще:

3.6.2 Настройка частоты синхронного ввода/вывода
Все частоты потокового сбора и выдачи данных основываются на опорной частоте
синхронизации. В качестве опорной частоты может использоваться внутренний источ-
ник частоты или внешний. В первом случае, опорная частота может быть 2МГц либо
1.5МГц. По умолчанию используется 2МГц. Изменить ее можно с помощью функции
X502_SetRefFreq().

А как узнать текущую опорную?

27.04.2017 11:29:55
#9

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

Re: Е-502 синхронный ввод

stix_s пишет:

получено 17280 (и интересно это байт или 32 разрядных слов? )

Это в 32-битных словах. Recv() ожидает либо завершения таймаута, либо появления запрашиваемого числа слов в буфере. Соответственно за RECV_TOUT у Вас набралось столько слов.

stix_s пишет:

А как узнать текущую опорную?

Есть функция X502_GetRefFreqValue(), хотя в принципе Вы сами тоже знаете, какую частоту установили.

27.04.2017 12:38:51
#10

Участник
Здесь с 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 при использовании внутренней синхронизации?

27.04.2017 16:20:09
#11

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

Re: Е-502 синхронный ввод

На момент вызова X502_Recv у Вас 0 слов в буфере, но X502_Recv() ждет указанное время (RECV_TOUT) прихода недостающих данных. За RECV_TOUT у Вас накапливается столько данных и Recv() выходит по таймауту.

stix_s пишет:

А что передавать в качестве параметра freq при использовании внутренней синхронизации?

В freq возвращается установленная частота (это выходной параметр, входное значение не важно). Для внутренней тут будет установленно 2000000 или 1500000.

27.04.2017 19:31:46
#12

Участник
Здесь с 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.

27.04.2017 21:37:23
#13

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

Re: Е-502 синхронный ввод

stix_s пишет:

Ведь она декларируется - как проверяющая на готовность в буфере определенного количества данных.

Она получает количество данных, которые пришли от модуля и еще не были прочитаны, т.е. количество данных, которое можно получить в настоящий момент через Recv() без ожидания (с нулевым таймаутом). Также эта функция работает только для USB (и для PCI-E для L502) и не работает при работе по Ethernet.

28.04.2017 06:54:24
#14

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

Re: Е-502 синхронный ввод

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

Также эта функция работает только для USB (и для PCI-E для L502) и не работает при работе по Ethernet.

У меня именно USB
E-502-X-U-D
№2T253133

12.05.2017 13:18:58
#15

Участник
Здесь с 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
Что я делаю не так?

12.05.2017 13:22:48
#16

Участник
Здесь с 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);
						}
12.05.2017 19:16:12
#17

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

Re: Е-502 синхронный ввод

Поставил в штатном примере перед Recv Sleep на 100 мс и X502_GetRecvReadyCount() вернул не нулевое адекватное значение. Точно запустили сбор и не вычитываете данные из буфера без isReady?

15.05.2017 07:36:51
#18

Участник
Здесь с 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

15.05.2017 07:39:38
#19

Участник
Здесь с 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;
}

15.05.2017 07:42:26
#20

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

Re: Е-502 синхронный ввод

хм, с задержкой процесс пошел ... непонятно

15.05.2017 07:57:09
#21

Участник
Здесь с 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);

я не вызываю

15.05.2017 15:08:06
#22

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

Re: Е-502 синхронный ввод

даже и без Sleep(100);
возвращается rcv_count
но до определенного предела
на 400 кГц и 12,5 кГц на канал это 673152 (я так понимаю 32-х разрядных слов)

15.05.2017 15:36:37
#23

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

Re: Е-502 синхронный ввод

В самой библиотеке буфер ограничен, поэтому это значение будет увеличиваться до определенного предела, пока не заполнится буфер в библиотеке.

Поэтому правильнее откачивать в свой буфер данные частями до достижения нужного количества данных в своем буфере, чем просто ждать, пока значение из RecvRdyCount достигнет нужного размера. Буфер в библиотеке используется больше для того, чтобы не потерять данные из-за задержек между вызовом Recv()

Контакты

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

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

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

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