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

Синхронизация АЦП и ЦАП E14-440

Вы не вошли.

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

11.11.2019 10:22:09
#1

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

Синхронизация АЦП и ЦАП E14-440

Добрый день.
Конфигурация: E14-440, библиотека lcomp, Qt,  Windows 7.
ЦАП генерирует синусоидальный сигнал, который подаётся на вход цепи. На один канал АЦП подаётся сигнал со входа цепи, на другой с выхода.
Когда я использую интерфейс pI, то ЦАП и АЦП почему то работают в разное время, т.е. ЦАП генерирует сигнал некоторое время, а потом АЦП считывает сигнал, когда на входе уже не синусоида, а сигнал постоянного уровня соответствующий последнему выведенному значению.
Когда я использую интерфейс pI2, фаза сигнала на входе цепи имеет случайное значение. Видимо из-за того, что АЦП и ЦАП инициализируются по очереди, и это занимает разное время.
1. Что я делаю не так при использовании pI?
2. Можно ли как-то синхронизировать АЦП и ЦАП, чтобы сигнал на АЦП со входа цепи (с ЦАП) всегда имел одинаковую фазу?

Ниже приведены основные части кода.

void device::setup() // слот для первоначальной настройки
{
    CallCreateInstance(L"lcomp.dll");
    pIUnknown = CreateInstance(0);
    pIUnknown->QueryInterface(IID_ILDEV,(void**)&pI);
    pIUnknown->Release();
    if(con_int>0)
    pI->QueryInterface(IID_ILDEV2,(void**)&pI2);
    pI->OpenLDevice();
    pI->GetSlotParam(&sl);
    pI->LoadBios("E440");
    pI->PlataTest(); 
    pI->ReadPlataDescr(&ph); 

adcPar.t1.s_Type = L_ADC_PARAM;
adcPar.t1.AutoInit = 0;
adcPar.t1.dRate = 200.0;
adcPar.t1.dKadr = 0.0;
adcPar.t1.dScale = 0;
adcPar.t1.SynchroType = 0;
adcPar.t1.SynchroSensitivity = 0;
adcPar.t1.SynchroMode = 0;
adcPar.t1.AdChannel = 0;
adcPar.t1.AdPorog = 0;
adcPar.t1.NCh = 2;
adcPar.t1.Chn[0] = 0x0;
adcPar.t1.Chn[1] = 0x1;
adcPar.t1.FIFO = 2048;
adcPar.t1.IrqStep = 2048;
adcPar.t1.Pages = 2;
adcPar.t1.IrqEna = 1;
adcPar.t1.AdcEna = 1;

    ULONG tm = 512000;  // выделили память словах (2 байта)
    pI->RequestBufferStream(&tm,L_STREAM_ADC);
    pI->FillDAQparameters(&adcPar.t1);
    pI->SetParametersStream(&adcPar.t1, &tm, (void **)&data, (void **)&sync,L_STREAM_ADC);

dacPar.t1.s_Type = L_DAC_PARAM;
dacPar.t1.AutoInit=0;
dacPar.t1.dRate=100.0;
dacPar.t1.FIFO=512;
dacPar.t1.IrqStep=512;
dacPar.t1.Pages=8;
dacPar.t1.IrqEna=1;
dacPar.t1.DacEna=1;
dacPar.t1.DacNumber=0;

    pI->FillDAQparameters(&dacPar.t1);

    ULONG db=512000;
    pI->RequestBufferStream(&db, L_STREAM_DAC);
    pI->SetParametersStream(&dacPar.t1,&db, (void **)&data1, (void **)&sync1,L_STREAM_DAC);
    for(int i=0;i<4096;i++) data1[i]=((USHORT)(100*sin((2.0*(3.1415926*i)/8)))&0xFFF)|0x0000;

    pI->EnableCorrection();
    hEventData = CreateEvent(0,FALSE,FALSE,NULL);
    pI->SetLDeviceEvent(hEventData);
    qRegisterMetaType <HANDLE>("HANDLE");
    Overflow.setHandle(hEventData); // в Qt для объекта класса QWinEventNotifier задаю событие, о котором будет выдан соответствующий сигнал
}

void device::start() // слот, запускающий поток
{
        if(con_int>0)  // con_int - переменная для выбора интерфейса
        {
    pI2->InitStartLDeviceEx(L_STREAM_ADC);
    pI2->InitStartLDeviceEx(L_STREAM_DAC);
    pI2->StartLDeviceEx(L_STREAM_DAC);
    pI2->StartLDeviceEx(L_STREAM_ADC);}
        else
        {
            pI->InitStartLDevice();
            pI->StartLDevice();
        }
    Overflow.setEnabled(true);
}

void device::run() // слот, связанный с сигналом о переполнении буфера
{
        if(con_int>0)
        {
        pI2->StopLDeviceEx(L_STREAM_ADC);
        pI2->StopLDeviceEx(L_STREAM_DAC);
        }
        else
        pI->StopLDevice();
        for(int i=0;i<2048;i++)
            {
            Signal[0][i] = ((short *)(data))[2*i];
            Signal[1][i] = ((short *)(data))[2*i+1];
            }
// Тут идёт обработка сигнала и вычисления
        if(con_int>0)
        {
        pI2->InitStartLDeviceEx(L_STREAM_ADC);
        pI2->InitStartLDeviceEx(L_STREAM_DAC);
        pI2->StartLDeviceEx(L_STREAM_DAC);
        pI2->StartLDeviceEx(L_STREAM_ADC); 
        }
        else
        {
        pI->InitStartLDevice();
        pI->StartLDevice();
        }
}
11.11.2019 11:51:44
#2

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: Синхронизация АЦП и ЦАП E14-440

pI умеет только из внутреннего буфера ЦАП и циклические будет гонять только если AutoInit в 1 (обычно это один период синуса напрмер ). pI2 умеет с подкачкой из буфера PC. Синхронизации между этими двумя потоками  нет.

13.12.2019 11:45:56
#3

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

Re: Синхронизация АЦП и ЦАП E14-440

Poul пишет:

pI умеет только из внутреннего буфера ЦАП и циклические будет гонять только если AutoInit в 1 (обычно это один период синуса напрмер ). pI2 умеет с подкачкой из буфера PC. Синхронизации между этими двумя потоками  нет.

Я правильно понял, что под "этими двумя потоками" вы имеете ввиду АЦП и ЦАП?
Я попробовал включить внешнюю синхронизацию старта АЦП по свободному каналу, на который подключил ЦАП. Попробовал разные типы синхронизации. Фаза перестала быть совсем случайной. Но к сожалению, фаза всё равно получается недостаточно стабильной, скачет в пределах нескольких градусов.
Насколько я понял, у вас в принципе нет модулей с явной синхронизацией АЦП и ЦАП.

13.12.2019 12:31:29
#4

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

Re: Синхронизация АЦП и ЦАП E14-440

Данила пишет:

Насколько я понял, у вас в принципе нет модулей с явной синхронизацией АЦП и ЦАП.

Если вообще про модули L-CARD, то например есть модуль E-502, у которого запуск АЦП и ЦАП выполняется одновременно с явно описанными задержками относительно друг друга (пункт 3.3.8 в https://www.lcard.ru/download/e-502_users_guide.pdf). Правда там библиотека используется другая.

Контакты

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

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

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

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