05-26-2009 05:40 PM
Hi,
I am trying to store the data from my DAQ system in a TDMS file using the TDMS_AppendDataValues function. I have no problem getting it to stream a single set of results, but when I try to put it in a while loop to store new samples as they becomes available, it just keeps repeating the first set of data that it stored instead of appending the new sets. I've checked to make sure that my program is updating the data array as the samples become available, and it is, so I'm not sure why my write function keeps repeating itself. It's reading from an analog input using DAQmxReadAnalog64. Does anyone have advice for using TDMS with continuous data acquisition from a DAQ unit?
05-27-2009 11:34 AM
How are you checking to make sure that the data array you are passing to TDMS_AppendDataValues is updating? Is this data array being overwritten or is new data also being appended to it? If the later is the case check your numberOfValues parameters to make sure you are continually putting the first X values. Also, when you say it keeps repeating the first set of data is it appending the first set of data over and over again or is it actually writing over the first set of data and making a TDMS file that is the same size?
Regards,
Steven Zittrower
Applications Engineer
National Instruments
05-27-2009 05:48 PM
Hi,
I displayed the first value of the array to the screen and used a timer to refresh the value every second or so to check that it was changing. Also, I ran the program at slower speeds than I intend to and stored the data to a spreadsheet. The data array is being overwritten, not appended. The TDMS function is appending the first set of data over and over again.
05-28-2009 10:29 AM
Can you post the snippit of code to this forum where you initialize the array, update the array with DAQmxReadAnalog64, and then call TDMS_AppendDataValues?
Thanks,
Steven Zittrower
Applications Engineer
National Instruments
05-28-2009 12:27 PM
Gladly! Sorry if it's a bit hard to follow, trying to snip out relevant parts without posting the whole program. Not sure if you want to see the configuration stuff, it's just setting up a few analog input channels in the same task. Basically I want to be able to display the readings from the measurement devices on screen, then start recording data once we actually start the experiment.
float64 *data=NULL; //data array
//This is the callback for the toggle button to collect data
int CVICALLBACK SHOW_VALUES (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
GetCtrlVal(TabPanelHandle, MTAB_DISPLAY,&running); //Toggle switch to start collecting data
if (running ==1)
{
StartTasks(); //Calls the function to start the tasks
if( (data=malloc(AIavg*numChannels*sizeof(float64)))==NULL ) //Allocates memory to the data array
{
MessagePopup("Error","Not enough memory");
}
}
if (running ==0)
{
StopTasks(); //Calls the function to stop the tasks
}
while (running)
{
ReadData();
ProcessSystemEvents();
}
break;
}
return 0;
}
// Function to read data
void ReadData(void)
{
DAQmxReadAnalogF64(analoghandle,AIavg,10.0,DAQmx_Val_GroupByChannel,data,AIavg*numChannels,&numRead,NULL);
}
//Then there's another function to toggle whether or not the data is recorded
int CVICALLBACK RECORD_DATA (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
GetCtrlVal(TabPanelHandle, MTAB_DISPLAY,&recording);
if (recording ==1)
{
if (initial ==0) //I put this in so that it only does the TDMS configuration once
{
ConfigureData();
}
}
while (recording ==1 && initial==1) //Makes sure that streaming doesn't begin until after file configuration
{
gStop = FALSE;
WriteData();
Delay(AIavg/AIrate);
ProcessSystemEvents;
ProcessDrawEvents;
}
if (recording ==0)
{
TDMS_CloseFile (0);
initial=0;
}
break;
}
return 0;
}
//This does the TDMS file configuration
void ConfigureData(void)
{
channels = malloc (sizeof(TDMSChannelHandle) * numChannels);
TDMS_CreateFile (filename, TDMS_Streaming, FILE_NAME, FILE_DESC, "", "", &file);
TDMS_AddChannelGroup (file, GROUP_NAME, GROUP_DESC, &group);
for (chan = 0; chan < numChannels && !gStop; chan++)
{
sprintf (channelName, "channel%d", chan);
sprintf (channelDesc, "Data for channel %d", chan);
TDMS_AddChannel (group, TDMS_Double, channelName, channelDesc, 0, &channels[chan]);
}
initial =1;
return;
}
void WriteData (void)
{
TDMS_AppendDataValues (channels[0], data, 3*AIavg, 1);
}
05-29-2009 10:06 AM
A couple of things. I see all the callbacks that you attached but am having trouble seeing the flow of the program. Can you attach (preferably by file) the code so I can see the main and program flow. In addition, try removing DAQmx from the equation and just generate random values. If the TDMS_Append function is still not updating correctly then we know it's related to that function or your programming.
Regards,
Steven Zittrower
Applications Engineer
National Instruments
05-29-2009 10:36 AM
06-02-2009 01:07 PM
06-03-2009 11:35 AM
At first glance I am not seeing the error in your code. Just to verify your first questions I was able to make a program that could write random data to a TDMS file. In fact, you can do the same as well just open the shipping example tdmsWriteBenchmark and modify the program so it calls GenerateSimulatedData during the TDMS_AppendDataValues for loop.
If both TDMS_AppendDataValues and ArraytoFile are exhibiting the same behavior the error must be with your array. I think this is not being updated correctly or perhaps even misallocated. Try calling printf() on the array directly before the file functions to see if this is even changing. If you can create a very small program that reproduces the problem that I can run I don't mind spending a few minutes running through that with a debugger and see if I can't narrow this down any more if you still are stuck.
Regards,
Steven Zittrower
Applications Engineer
National Instruments
06-04-2009 01:28 PM
Yes, I have verified that the array is being updated correctly and changing. I was using a different function to average the values of the array and write them to a file, which worked fine when I tested it with the equipment. My problem now, I think, is that I want to write the whole array, not just an average, and I can't seem to do that. My data acquisition functions are based on this example:
http://zone.ni.com/devzone/cda/epd/p/id/583
How would you make that write the data it gets, the entire array, to a file?