Closed ufcolemanlab closed 9 years ago
Getting close! This is plotting real data, but it's looking garbled for some reason. I gotta mess around with the sampling rates and memory buffers.
Looks like the issue is ADData not being filled with the memory buffer data. Working on fixing this now...
*EDIT: So ADData is being filled with data but it does not look right... the values are in the way too huge considering the voltage and gain... I'll be looking into this over the weekend.
I seem to remember something about needing to convert ADData information to a different format... maybe that's the problem? Still looking...
Yea, looks like we'll have to use one of mccdaq's functions to convert the ADData value to volts using the cbToEngUnits() function.
I've not managed to get this working, but I'll try it out tomorrow.
To do the conversion you would have to add the following two lines:
float *EngUnits; // this should be put outside of the working loop cbToEngUnits(BoardNum, Gain, ADData[CurIndex], EngUnits); // this should be put inside of the working loop
Now you just have to dereference EngUnits to get the value.
Note: the cbToEngUnits() function cannot convert the values stored in ADData32[](contains values of type DWORD). However, after testing our program, it seems to only utilize ADData[](contains values of type WORD), so this should not be a problem.
Alright, so we are plotting voltage values now. The next issue that was solved was that ADData is filling up independent of our query for data. This means that sometimes when I asked for the current index and the datapoint it was more than +1 from my previous call which was displaying garbled data.
I fixed this with the following code:
void SamplingThread::sample( double elapsed )
{
long CurCount;
long CurIndex;
short Status;
int BoardNum = 0;
float v;
int ULStat = cbGetStatus (BoardNum, &Status, &CurCount, &CurIndex,AIFUNCTION);
if ((Status == RUNNING) && CurCount > 0 )
{
if (CurIndex==StoredLocation)
{
//do nothing
}
else if (CurIndex=(StoredLocation+1))
{
int ENG = cbToEngUnits(BoardNum,BIP5VOLTS,ADData[CurIndex],&v);
double v_double=static_cast<double>(v);
//if (v_double != 0)
//{
//printf (" Value: %d ",CurIndex);
//}
const QPointF s( elapsed, v_double );
SignalData::instance().append( s );
StoredLocation=CurIndex;
}
else
{
int difference=CurIndex-StoredLocation;
int start_temp=StoredLocation+1;
for (int temp_index; temp_index <= difference; temp_index++)
{
int ENG = cbToEngUnits(BoardNum,BIP5VOLTS,ADData[start_temp],&v);
double v_double=static_cast<double>(v);
//if (v_double != 0)
//{
//printf (" Value: %d ",start_temp);
//}
const QPointF s( elapsed, v_double );
SignalData::instance().append( s );
start_temp++;
}
StoredLocation=start_temp-1;
}
}
}
Basically i'm storing the last location that was plotted and checking this versus changes in ADData. When there is more than +1 difference I use the for loop to catch up. This means that our plot will always be behind our actual hardware collection but since or importance is placed on the quality of the data collection (not the quality of the plot) this is acceptable for now.
I called MCCDAQ and they did not know the frequency of the generated analog signal via their InstaCal software so it's hard to know for sure what our sampling rate should be to test the software. I think we're at the point though where we can hook up a DAQ and start recording our own generated signals.
After I confirm we're recording a signal on a single channel (working on now), the next step is to implement multiple channels which should be fairly simple. The DAQ stores multiple channel data in the ADData variable as... (example using 3 channels): 123123123123123123123123123... In the sampling thread I plan to make a new variable called currentChannel which will keep track of which channel to send the collected datapoint to. Hopefully this will work as expected and not be too difficult. We'll have to create new curvedatas for the plot... I'll update again when I have the multi channel plot working.
Also, we have some problems when the data set becomes very large (stops plotting) so I think there may be a problem with the variable used to store the plot information when it gets beyond a certain size... I'll look into that. I have a feeling we'll have to throw out old data during the plot for now to fix this.
I ended up narrowing down the size problem to the cbToEngUnits function. If I enable this part of the code at 1ms sample rate I get to around 15 seconds before it crashes... If I remove this function the program does not crash and continues to record just fine. I'm calling MCCDAQ to ask about this now.
After talking with MCCDAQ I narrowed it down to one of the function inputs ADData[curIndex]. I'm looking into this now.
Victory. I got it working. We can record voltage data in a circular buffer and plot it in real time from one channel.
I'm now switching back to the multi channel problem.
Got all 8 analog channels plotting on the same line... looks messy obviously, but I'm able to pull in all 8 channels instead of just 1 now. I'm now working on sending that data into new plot objects (last step).
Hopefully all I'll have to do is to turn the data structure into a matrix array (it's a vector array atm) and call the specific row that I want for each new curve object. We'll see...
Oh grep... you are my friend.
I got the plotting and sample thread timer synchronized with the data collection timer by moving the data inside the start button code in mainwindow.cpp:
the new main.cpp code is:
I'll push my version onto github later tonight after I get some more changes in.