From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Recording a continuous stream of data to a txt file?

Solved!
Go to solution

Hi, everyone! I'm fairly new to CVI, and was wondering if I could get some help on something. I'm trying to modify a sample file that continuously reads a voltage from a daq board. I'd like to record that data to a text file, but I'm fairly new to the C programming language (I'm a java person), and can't distinguish where the data is. Once I know where the data is, I think I can write the data using some sort of loop and the fprintf function. Any help would be greatly appreciated. This is the code for the StartCallBack method of the "Cont Acq-Int Clk"sample file I'm using: 

 

 

int CVICALLBACK StartCallback(int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
int32 error=0;
char chan[256];
uInt32 sampsPerChan;
float64 min,max,rate;
int log;
char errBuff[2048]={'\0'};

if( event==EVENT_COMMIT ) {
GetCtrlVal(panel,PANEL_CHANNEL,chan);
GetCtrlVal(panel,PANEL_MINVAL,&min);
GetCtrlVal(panel,PANEL_MAXVAL,&max);
GetCtrlVal(panel,PANEL_RATE,&rate);
GetCtrlVal(panel,PANEL_SAMPSPERCHAN,&sampsPerChan);
SetCtrlAttribute(panel,PANEL_STRIPCHART,ATTR_XAXIS_GAIN,1.0/rate);
log = (int)log10(rate);
SetCtrlAttribute(panel,PANEL_STRIPCHART,ATTR_XPRECISION,log);
SetCtrlAttribute(panel,PANEL_STRIPCHART,ATTR_POINTS_PER_SCREEN,sampsPerChan);

/*********************************************/
// DAQmx Configure Code
/*********************************************/
SetWaitCursor(1);
DAQmxErrChk (DAQmxCreateTask("",&gTaskHandle));
DAQmxErrChk (DAQmxCreateAIVoltageChan(gTaskHandle,chan,"",DAQmx_Val_Cfg_Default,min,max,DAQmx_Val_Volts,NULL));
DAQmxErrChk (DAQmxCfgSampClkTiming(gTaskHandle,"",rate,DAQmx_Val_Rising,DAQmx_Val_ContSamps,sampsPerChan));
DAQmxErrChk (DAQmxGetTaskAttribute(gTaskHandle,DAQmx_Task_NumChans,&gNumChannels));

if( (gData=(float64*)malloc(sampsPerChan*gNumChannels*sizeof(float64)))==NULL ) {
MessagePopup("Error","Not enough memory");
goto Error;
}

DAQmxErrChk (DAQmxRegisterEveryNSamplesEvent(gTaskHandle,DAQmx_Val_Acquired_Into_Buffer,sampsPerChan,0,EveryNCallback,NULL));
DAQmxErrChk (DAQmxRegisterDoneEvent(gTaskHandle,0,DoneCallback,NULL));

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

SetCtrlAttribute(panel,PANEL_STRIPCHART,ATTR_NUM_TRACES,gNumChannels);
SetCtrlAttribute(panel,PANEL_START,ATTR_DIMMED,1);
}

Error:
SetWaitCursor(0);
if( DAQmxFailed(error) ) {
DAQmxGetExtendedErrorInfo(errBuff,2048);
if( gTaskHandle!=0 ) {
/*********************************************/
// DAQmx Stop Code
/*********************************************/
DAQmxStopTask(gTaskHandle);
DAQmxClearTask(gTaskHandle);
gTaskHandle = 0;
if( gData ) {
free(gData);
gData = NULL;
}
SetCtrlAttribute(panel,PANEL_START,ATTR_DIMMED,0);
}
MessagePopup("DAQmx Error",errBuff);
}
return 0;
}

 

0 Kudos
Message 1 of 3
(2,916 Views)
Solution
Accepted by topic author supercharizard

Hello supercharizard,

this is the relevant line in the code you posted that can drive you to "where the data is" Smiley Wink

 

DAQmxErrChk (DAQmxRegisterEveryNSamplesEvent(gTaskHandle,DAQmx_Val_Acquired_Into_Buffer,sampsPerChan,0,EveryNCallback,NULL));

DAQmxRegisterEveryNSamplesEvent function establishes a callback function as a routine to be called when at least a predefined amount of data is acquired. The highlighted part in the line is the callback issued on this event, that you may want to study and modify adding data streaming.

This KnowledgeBase entry gives a brief explanation of available events. There are many other resources on DAQmx functions both in the online help and on this site that you should carefully study to better understand data acquisition.

 

With reference to disk output, there are several ways to do this: here are two examples that produce a binary file (faster, but you will need to write code to read data back) or append to an ASCII file aligned in columns (slower but readable with a text editor, i.e. no code needed to read data back). Another alternative is to make use of TDM library to stream data to disk: this last resource is notably more complicated so I suggest you to approach it after some more practice on the fundamentals.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 2 of 3
(2,908 Views)

Thank you so much, Roberto! That definitley helped a bunch! I've actually learned a bit more about TDMS, so luckily I can utilize that tool as well. 

 

0 Kudos
Message 3 of 3
(2,886 Views)