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


LCOMP

Вы не вошли.

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

Василий
12.07.2006 12:52:37
#1

Гость

LCOMP

Как сделать одновременный ввод-вывод DAC/ADC с помощью функций LCOMP? Режим АЦП однофазный, без синхронизации. ЦАП - уровень.
На сколько я понял там речь идет о создании двух разных массивов данных и конфигурирование ADC_PAR, DAC_PAR?
Можно ли пример на две строчки, т.е. суть - "КАК"?

12.07.2006 20:24:21
#2

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

Re: LCOMP

пример l7xx.osc смотрите

Василий
13.07.2006 12:36:26
#3

Гость

Re: LCOMP

Посмотрел, спасибо!
Сделал. Удивился. Почитал форум, удивился еще больше...
Вопросы.
Плата 783. ЦАП есть. Я использую один канал X1 АЦП и один 0-й канал ЦАП. Пишу на Дельфи.
const
  FIFO: USHORT = 1024;
  IrqStep: USHORT = 1024;
  pages: USHORT = 32;
type
  WA = array of SHORT;
var
  data, data1: WA;
  sync, sync1: PULONG;
  ap: ADC_PAR;
  da: DAC_PAR;
  tm, pm: integer;
  Voltage: SHORT = 1024;

procedure StartADC_DAC (Volt: integer);
begin
...
if(CallCreateInstance('lcomp.dll')=Slot) then begin
      LogAp.Lines.Append('Поток создан успешно.');
      pIUnknown:=CreateInstance(0);
      hr := pIUnknown.QueryInterface(IID_ILDEV,pLDev);
       if(not Succeeded(hr)) then MessageBox(0,'Нет устройства','Error',MB_OK)
       else begin pIUnknown.Release;
       dev:=pLDev.OpenLDevice;
       pLDev.LoadBios('l783')= L_SUCCESS)
       plDev.ReadPlataDescr(pd);
       ap.t1.s_Type:= L_ADC_PARAM;
       ap.t1.AutoInit:= 1;
       ap.t1.dRate:= 100.0;
       ap.t1.dKadr:= 0.0;
       ap.t1.dScale:= 0;
       ap.t1.SynchroType:= 3;
       ap.t1.SynchroSensitivity:= 0;
       ap.t1.SynchroMode:= 0;
       ap.t1.AdChannel:= 0;
       ap.t1.AdPorog:= 0;
       ap.t1.NCh:= 1;
       ap.t1.Chn[0]:= 0;
// инициализирую только X1 - Остальные не нужны
       ap.t1.FIFO:= FIFO;
       ap.t1.IrqStep:= IrqStep;
       ap.t1.Pages:= pages;
       ap.t1.IrqEna:= 1;
       ap.t1.AdcEna:= 1;

       pLDev.FillDAQparameters(ap.t1);
 
       da.t1.s_Type = L_DAC_PARAM;
       da.t1.AutoInit=0;
       da.t1.dRate=50;
       da.t1.FIFO=512;
       da.t1.IrqStep=512;
       da.t1.Pages=2;
       da.t1.IrqEna=1;
       da.t1.DacEna=1;
       da.t1.DacNumber=0;
       pLDev.FillDAQparameters (da.t1);
       plDev.RequestBufferStream(data1,L_STREAM_DAC);
       plDev.SetParametersStream(da.t1,pm,data1,sync1,L_STREAM_DAC);
       // хочу чтобы ЦАП выдавал постоянное напряжение из переменной Volt.
       data1[0]=Volt;
       tm:= 100000; // отсчеты АЦП
       pLDev.RequestBufferStream(tm, L_STREAM_ADC);                                 
       pLDev.SetParametersStream(ap.t1, tm, data, sync,L_STREAM_ADC);
       pLDev.EnableCorrection(0);
               
// считыванеи по таймеру - как в примере
       Timer1.Enabled:=True;
       pLDev.InitStartLDevice;
       pLDev.StartLDevice;
end;
//=== Старт
procedure TMain.ButtonStartClick (Sender: TObject)
begin
       StopADC_DAC;
       SartADC_DAC(Voltage); // стартую на выходе ЦАП - первый раз уровень 1024
end;

procedure StopADC_DAC;
begin
       Timer1.Enabled:= false;
       data:=NIL;
       sync:=NIL;
       data1:= NIL;
       sync1:= NIL;
       pLDev.StopLDevice;
       pLDev.CloseLDevice;
       pLDev.Release;
       plDev:= NIL;
end;

//=== Стоп
procdure TMain.ButtonStopClick (Sender: TObject)
begin
       StopADC_DAC;
end;

procedure TMain.Timer1Timer(Sender: TObject);
begin
// Вывожу c АЦП на график
if((data<>NIL) and (sync<>NIL)) then
      ChartAD.Series[0].AddY(data[0],'',1);
end;

// Хочу изменить напряжение на выходе ЦАП
procdure TMain.ChangeDAC(Sender: TObject)
begin
       StopADC_DAC;
       if Voltage <=4096 then
            Voltage:= Voltage + 1;
       StartADC_DAC (Voltage);
end;

Вопросы.
АЦП - работает.
Цап работает перманентно - захочет поставит напряжение , захочет нет, причем какое захочет такое и поставит.... Такое впечатление, что это зависит от количества отсчетов ЦАП.
Куда копать-то?????

13.07.2006 14:53:18
#4

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

Re: LCOMP

для постояноого надо IoAsync вызвать однократно  с данными для цапа... а так Вы поток запрограммировали с одним числом и остальным мусором....
Пример вызова l790.osc ну и описание функции...

Василий
13.07.2006 16:39:01
#5

Гость

Re: LCOMP

По поводу мусора - согласен, но .. не до него сейчас. Надо сделать хоть вольтметр + источник регулируемого напряжения... А в DSP полезем потом...

Ясно, спасиб, значит изучаем IOAsync.

Не влияет ли количество отсчетов на данные с АЦП. (Бредово, но почему-то влияет... Или она не на то влияет? А это то влияет на это?...)
Я запускаю и вижу каждый раз совершенно разные значения....
Откуда они беруться?
Падаю на АЦП снаружи напряжение с регулируемого источника питания - постоянно, скажем 1,25 В. Смотрю что получается. Стартую и останавливаю несколько раз с инициализацией - вижу разную картинку... Отчего ? Ведь на входе напряжение не изменилось?

Т.е. числа с АЦП лежат в разных диапазонах при каждом старте, (может что-то в памяти?)
а порой начинаю меняться - в то время как на входе постоянное напряжение... (это вообще не понятно...)
Исходник я приводил выше.

Василий
17.07.2006 01:20:19
#6

Гость

Re: LCOMP

Внимательно все просмотрел, прочитал и попробовал. Но не разобрался.
Ну всеж таки!
1. Почему данные в примере LXX.DPR снимаются из Data[0]? Сего не просек..
Сделал так:
const
FIFO: USHORT = 1024;
IrqStep: USHORT = 1024
pages: USHORT = 32;
multi: USHORT = 64;

type
WA = array of SHORT;

... init ...
ap.t1.s_Type:= L_ADC_PARAM;
                ap.t1.AutoInit:= 0;
                ap.t1.dRate:= 100.0;
                ap.t1.dKadr:= 0.0;
                ap.t1.dScale:= 0;
                ap.t1.SynchroType:= 3;
                ap.t1.SynchroSensitivity:= 0;
                ap.t1.SynchroMode:= 0;
                ap.t1.AdChannel:= 0;
                ap.t1.AdPorog:= 0;
                ap.t1.NCh:= 1;
                ap.t1.Chn[0]:= 0;
                ap.t1.FIFO:= FIFO;
                ap.t1.IrqStep:= IrqStep;
                ap.t1.Pages:= pages;
                ap.t1.IrqEna:= 1;
                ap.t1.AdcEna:= 1;
end;

{... timer 1 мс ...}
procedure TMainForm.Timer1Timer(Sender: TObject);
var i: integer;
    halfbuffer: ULONG;
    pBuffer : ^WA;
begin
  if((data<>NIL) and (sync<>NIL)) then begin
       pBuffer:= @Data;
       halfbuffer:= pages*FIFO/2;
       for i:=0 to multi-1 do begin
         ChartAD.Series[0].AddY(round(pBuffer^[i]));
       end;
  end;
end;

Получается что-то похожее...
Однако почему в момент рестарта - НОВЫЕ данные смещаются по оси Y в неизвестном направлении то вверх, то вниз и бегут дальше нормально? Ведь с АЦП приходит целочисленное значение, откуда смещение идет раз-от-раза?

2. Ну дайте наконец последовательность инициализации команд для работы с DAC. Не получается по примеру поток... ни в какую, а асинхронный вывод описанный в L791 касается только TTL. Посмотрел попробовал - по аналогии не работет.
Вот это я пробую - это не верно! На выходе "0". Но иного из Вашей документации не почерпнуть.

var da: ASYNC_PAR;
    daq: DAC_PAR;
begin
if(CallCreateInstance('lcomp.dll')=Slot) then begin
      pIUnknown:=CreateInstance(0);
      hr := pIUnknown.QueryInterface(IID_ILDEV,pLDev);
       if(not Succeeded(hr)) then MessageBox (...)       else begin
            pIUnknown.Release;
                dev:=pLDev.OpenLDevice;

                daq.t2.s_Type:= L_DAC_PARAM;
                daq.t2.AutoInit:=0;
                daq.t2.dRate:=10;
                daq.t2.FIFO:=512;
                daq.t2.IrqStep:=512;
                daq.t2.Pages:=32;
                daq.t2.IrqEna:=0;
                daq.t2.DacEna:=1;
                pLDev.FillDAQparameters(daq.t2);

                db:=512000;
                plDev.RequestBufferStream(db, L_STREAM_DAC);
                plDev.SetParametersStream(daq.t2,db, data1, sync1,L_STREAM_DAC);

                pLDev.InitStartLDevice;
                pLDev.StartLDevice;

               for i:=0 to 128*1024 do Data1[i]:= 2047;
{пробовал и просто Data1[0]:= $FFFF и := 2047 - тот же эффект.. 0 и все.}
                da.s_Type:= L_ASYNC_DAC_OUT;
                da.Mode:= 1;
                plDev.IoAsync(da);
           end;
end;

17.07.2006 09:13:45
#7

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

Re: LCOMP

в пример просто читается первый элемент массива отсчетов. Нарисуйте график и смотрите что там реально идет. А так данные от Data[0] до Data[<конец буфера>] циклически заполняются.... следите за заполнением буфера и выбирайте ту половину где данные уже положены...

ну буфер для цап заполнять надо до старта если поток. Если 780 платы то класть надо в буфер данные типа SHORT в формате отсчета ЦАП, те 12 бит отсчета и бит номера канала... если 780С и потоковый вывод с подкладыванием данных, то кластьт надо LONG в буфер и опят таки в фрмате отсчета ЦАП. IoAsync вызывается просто
   ASYNC_PAR pp;
   pp.s_Type = L_ASYNC_DAC_OUT;
   pp.Mode = 0/1; /*номер канала*/
   pp.Data[0] = <значение>;
   pI->IoAsync(&pp);

Василий
17.07.2006 13:41:18
#8

Гость

Re: LCOMP

Ды про данные - это понятно.
При асинхронном выводе нужно ли структуру DAС_PAR заполнять и FillDAQparameters делать?
Когда это делается ? Каждый раз после StopDevice???
В какой последоватедльности подавать команды-то?

OpenLDevice;
daq.t2.s_Type:= L_DAC_PARAM;
...
pLDev.FillDAQparameters(daq.t2);
pLDev.InitStartLDevice;
pLDev.StartLDevice;

а потом IOAsync
Или как-то иначе????

Кстати zoomer-то будет в исходниках планируется выложить в принципе?

17.07.2006 14:40:00
#9

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

Re: LCOMP

для IoAsync ничего не нужно...очно также как впример с TTL...