Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Sqaure Waveform Generation with DAQmx

hi,
I would like to know how can I modify the VC_ContGen_IntClk example in C++ to generate a square waveform instead of the sinusoidal wave?
 
Thanks

Message Edited by Rolly on 07-19-2005 04:34 PM

0 Kudos
Message 1 of 17
(5,129 Views)
There should be a call in the beggining of the code that chooses the type of waveform being generated.  These are typically called from a function that
has various types of waveforms to choose from. 
0 Kudos
Message 2 of 17
(5,119 Views)

Hello,

I don't think DAQmx has the sort of function generation to choose from as if LabVIEW, but it is ok, I manage to overcome with proper array data. thx anyway

0 Kudos
Message 3 of 17
(5,117 Views)

Hi all,

I managed to construct square waves of different amplitude (varying voltage output) and I want to change amplitudes on-the-fly using DAQmx C-functions. There is the code and the scope output. There is a gap while I stop the 1st sqwave generation then starts the next, but such gap is not desirable and must be eliminated, can anyone gives me a hand on this issue?

Thanks,

Rolly

Code:

#include "NIDAQmx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{
 int32       error=0;
 TaskHandle  taskHandle;
 float64     data[100];
 int         i=0,j=0;
 int32   written;
 
 for (i=0;i<50;i++)
   data[i]=-1;
 for (i=50;i<100;i++)
   data[i]=1;
 
 //data[0]=-9; 
 //data[50]=9;
 printf("Generating voltage continuously...\n");
 
 DAQmxCreateTask("",&taskHandle);
 DAQmxCreateAOVoltageChan(taskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL);
 DAQmxCfgSampClkTiming(taskHandle,"",200000.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,1000);
 DAQmxWriteAnalogF64(taskHandle,100,0,10.0,DAQmx_Val_GroupByChannel,data,&written,NULL);
 DAQmxStartTask(taskHandle); 
 Sleep(1000);
    DAQmxStopTask(taskHandle);
 DAQmxClearTask(taskHandle);
 for (j=0;j<50;j++)
   data[j]=-5;
 for (j=50;j<100;j++)
   data[j]=5;
 //data[0]=-9; 
 //data[50]=9;
 DAQmxCreateTask("",&taskHandle);
 DAQmxCreateAOVoltageChan(taskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL);
 DAQmxCfgSampClkTiming(taskHandle,"",200000.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,1000);
 DAQmxWriteAnalogF64(taskHandle,100,0,10.0,DAQmx_Val_GroupByChannel,data,&written,NULL);
 DAQmxStartTask(taskHandle);
 Sleep(1000);
 DAQmxStopTask(taskHandle);
 DAQmxClearTask(taskHandle);
 printf("End of program, press Enter key to quit\n");
 getchar();
 return 0;
}
0 Kudos
Message 4 of 17
(5,078 Views)
The only way to do this glitch free is to generate the entire waveform beforehand and load it down to the DAC.  If you have to call a stop
 and start you will get a gap. 

One thing you may consider if it becomes an issue is using the 7831R board.  This has AO's on it that allow you to do just about anything
at any time due to the fact that it's FPGA based.
 
0 Kudos
Message 5 of 17
(5,073 Views)
Allow me to clarify the answer by Super Fly:

It is not possible to get rid of the glitch if you stop, rewrite and then start, but it is possible to write more points while the task is running, with the board you already have.
My suggestion is that you turn off the buffer regeneration by using DAQmxSetWriteRegenMode to DAQmx_Val_DoNotAllowRegen. This will write your buffer down to the board only once. As a consequence, you'll have to continuously write to the buffer. So, instead of calling Sleep within the task itself you'll have to create a while loop, inside of which you'll always be doing DAQmxWriteAnalogF64(taskHandle,100,0,10.0,DAQmx_Val_GroupByChannel,data,&written,NULL);
DAQmx will automatically block the write until the buffer has enough space for new data to be written, so I recommend you put a Sleep(100) right after the WriteAnalogF64 call to prevent your application from locking.
Then  all you have to do is write the new waveform to your "data" array while the other code is sleeping, and it will automatically be updated the next time the while loop runs.
In order to be glitch free make sure you always write either the exact number of points you wrote the first time or a multiple of a square wave cycle, such that the new data end exactly where the old data starts.

Let me know if you need forther assistance.

Greetings

Daniel Domene
Multifunction DAQ R&D
0 Kudos
Message 6 of 17
(5,064 Views)

Hi,

Thanks for your advice, I am trying with no-regeneration mode and I found the following codes from NI website but forget exactly where it from, it compiles ok but as it runs, VC++ prompted with stack overflow error!? Where has it gone wrong? I am using a PCMCIA 6062E with Interrupt...  Thanks!

// DAQmx_wfm_noregen.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <math.h>
#include <NIDAQmx.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define PI 3.141592653
#define DAQmxErrChk(functionCall) { if( DAQmxFailed(error=(functionCall)) ) { goto Error; } }

int main(void)
{
int32 error=0;
TaskHandle taskHandle=0;
char errBuff[2048]={'\0'};
bool32 done=0;
int i=0;
int32 written;

uInt32 writeBufferSpaceAvailable;
float64 data[250000*8];

for(;i<250000*8;i++)
data[i] = 9.95*sin((double)i*2.0*PI/100000.0);

/*********************************************/
/*/ DAQmx Configure Code
/*********************************************/
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
DAQmxErrChk (DAQmxCreateAOVoltageChan(taskHandle,"SCC1Mod17/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL));
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,"",250000,DAQmx_Val_Rising,DAQmx_Val_ContSamps,250000*2));
DAQmxErrChk (DAQmxCfgOutputBuffer (taskHandle, 250000*2));
DAQmxErrChk (DAQmxSetWriteRegenMode(taskHandle,DAQmx_Val_DoNotAllowRegen));

/*********************************************/
/*/ DAQmx Write Code
/*********************************************/
DAQmxErrChk (DAQmxWriteAnalogF64(taskHandle,250000,0,-1,DAQmx_Val_GroupByScanNumber,data,&written,NULL));

/*********************************************/
/*/ DAQmx Start Code
/*********************************************/
DAQmxErrChk (DAQmxStartTask(taskHandle));

printf("Generating voltage continuously. Press any key to interrupt\n");

while(!_kbhit())
{

DAQmxErrChk (DAQmxGetWriteSpaceAvail(taskHandle, &writeBufferSpaceAvailable));
printf("writeBufferSpaceAvailable : %d\n",writeBufferSpaceAvailable);
if(writeBufferSpaceAvailable > 250000)
{
DAQmxErrChk (DAQmxWriteAnalogF64(taskHandle,250000,0,-1,DAQmx_Val_GroupByScanNumber,data,&written,NULL));
printf("data written : %d\n",written);
}
Sleep(100);
}
_getch();

Error:
if( DAQmxFailed(error) )
DAQmxGetExtendedErrorInfo(errBuff,2048);
if( taskHandle!=0 ) {
/*********************************************/
/*/ DAQmx Stop Code
/*********************************************/
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
}
if( DAQmxFailed(error) )
printf("DAQmx Error: %s\n",errBuff);
printf("End of program, press Enter key to quit\n");
getchar();
return 0;
}

Message Edited by Rolly on 08-13-2005 03:55 PM

0 Kudos
Message 7 of 17
(5,043 Views)
Hi,
 
In addition I changed the above example code to following for square wave generation:
 
// DAQmx_wfm_noregen.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <NIDAQmx.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define DAQmxErrChk(functionCall) { if( DAQmxFailed(error=(functionCall)) ) { goto Error; } }
int main(void)
{
int32 error=0;
TaskHandle taskHandle=0;
char errBuff[2048]={'\0'};
bool32 done=0;
int i=0;
int32 written;
float64 data[100];
for (i=0;i<50;i++)
 data[i]=-1;
for (i=50;i<100;i++)
 data[i]=1;

DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
DAQmxErrChk (DAQmxCreateAOVoltageChan(taskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL));
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,"",200000,DAQmx_Val_Rising,DAQmx_Val_ContSamps,1000));
DAQmxErrChk (DAQmxCfgOutputBuffer (taskHandle, 200000*5));
DAQmxErrChk (DAQmxSetWriteRegenMode(taskHandle,DAQmx_Val_DoNotAllowRegen));
DAQmxErrChk (DAQmxWriteAnalogF64(taskHandle,100000,0,-1,DAQmx_Val_GroupByChannel,data,&written,NULL));
DAQmxErrChk (DAQmxStartTask(taskHandle));
printf("Generating voltage continuously. Press any key to interrupt\n");
while(!_kbhit())
{
 for (i=0;i<50;i++)
 data[i]=-5;
 for (i=50;i<100;i++)
 data[i]=5;
 DAQmxErrChk (DAQmxWriteAnalogF64(taskHandle,100000,0,-1,DAQmx_Val_GroupByChannel,data,&written,NULL));
 Sleep(100);
}
_getch();
Error:
if( DAQmxFailed(error) )
DAQmxGetExtendedErrorInfo(errBuff,2048);
if( taskHandle!=0 )
{
    DAQmxStopTask(taskHandle);
 DAQmxClearTask(taskHandle);
}
if( DAQmxFailed(error) )
printf("DAQmx Error: %s\n",errBuff);
printf("End of program, press Enter key to quit\n");
getchar();
return 0;
}
 
But DAQmx refused to run and prompted?? Can you have a look at if I am doing correctly? Thanks very much! 🙂
 
0 Kudos
Message 8 of 17
(5,040 Views)
Hi Rolly,

I really need to know what error message you're getting from DAQmx, since you didn't specify it in your messages. In the mean time let me talk about the last code you sent.
You're configuring the task for 200KS/s, then attempting to write 100KS to the buffer, However, since your data array is only 100 points long, the write function is writing 100 points to the buffer and then 90900 * 2 bytes of corrupt data from your memory, because it's reading way past the end of the array. So I'd recommend you always creata an array as large as the maximum write you're planning to do, or you write multiple times (it's not possible to write more than once before start).
It's possible that you don't have 200,000 bytes of available ram after your 100 bytes array, and that would cause an exception in the operating system, which would crash your application. Please let me know if you're seeing this behavior.
I also recommend you calculate all of your data before you start running your task, so you have all the processor throughput you can get dedicated to interrupts.
I hope this helps, otherwise please post the error message you're getting.

Greetings

Daniel Domene
0 Kudos
Message 9 of 17
(5,022 Views)

HI Daniel,

Please take a look at the attached pictures, the error prompt for the 1st no-regeneration example code, and the square waveform output I want to achieve.

Thx,

Rolly

0 Kudos
Message 10 of 17
(5,001 Views)