DAQ Playback tested and working

This commit is contained in:
Chris Esposito 2017-12-28 13:23:33 +11:00
parent 1bd7af8b48
commit 025df96ea6
9 changed files with 260 additions and 15 deletions

View File

@ -39,7 +39,8 @@ SOURCES += main.cpp\
isobufferbuffer.cpp \
uartstyledecoder.cpp \
daqform.cpp \
daqloadprompt.cpp
daqloadprompt.cpp \
isobuffer_file.cpp
HEADERS += mainwindow.h \
functiongencontrol.h \
@ -54,7 +55,8 @@ HEADERS += mainwindow.h \
unified_debug_structure.h \
uartstyledecoder.h \
daqform.h \
daqloadprompt.h
daqloadprompt.h \
isobuffer_file.h
android:{
FORMS += ui_files_mobile/mainwindow.ui \

View File

@ -1,6 +1,7 @@
#include "daqloadprompt.h"
#include "ui_daqloadprompt.h"
#include <QDebug>
#include "siprint.h"
daqLoadPrompt::daqLoadPrompt(QWidget *parent, double minTime, double maxTime) :
QDialog(parent),
@ -13,11 +14,14 @@ daqLoadPrompt::daqLoadPrompt(QWidget *parent, double minTime, double maxTime) :
ui->endTimeDoubleSpinBox->setMinimum(minTime);
ui->startTimeDoubleSpinBox->setMaximum(maxTime);
ui->endTimeDoubleSpinBox->setMaximum(maxTime);
ui->startTimeDoubleSpinBox->setValue(minTime);
ui->endTimeDoubleSpinBox->setValue(maxTime);
//Internal signals
connect(ui->startTimeDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(valueChange()));
connect(ui->endTimeDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(valueChange()));
valueChange();
}
daqLoadPrompt::~daqLoadPrompt()
@ -31,4 +35,11 @@ void daqLoadPrompt::valueChange(){
startTime(ui->startTimeDoubleSpinBox->value());
endTime(ui->endTimeDoubleSpinBox->value());
double contig_ram_required = ((ui->endTimeDoubleSpinBox->value() - ui->startTimeDoubleSpinBox->value()) / min_interval) * 4 + 512; //4 bytes per sample (float), each sample is stored only once. 512 is just a bullshit value to represent the overhead required to store the other variables in the buffer object
siprint cotig_print("B",contig_ram_required);
ui->contigRamLabel_Value->setText(cotig_print.printVal());
}

View File

@ -300,7 +300,7 @@ short isoBuffer::inverseSampleConvert(double voltageLevel, int TOP, bool AC){
#define X1_X2_COMPARISON_CAP >
#endif
//For capacitance measurement. x0, x1 and x2 are all various time points used to find the RC coefficient.
int isoBuffer::cap_x0fromLast(double seconds, double vbot){
int samplesInPast = seconds * samplesPerSecond;
if(back < samplesInPast){

View File

@ -0,0 +1,82 @@
#include "isobuffer_file.h"
#include "math.h"
#include <QDebug>
isoBuffer_file::isoBuffer_file(QWidget *parent, int bufferlen, double sampleRate_Hz) : QWidget(parent)
{
buffer = (float *) calloc(bufferlen, sizeof(float));
bufferEnd = bufferlen-1;
samplesPerSecond = sampleRate_Hz;
}
void isoBuffer_file::writeBuffer_float(float* data, int len)
{
for (int i=0; i<len;i++){
buffer[back] = (float) data[i];
if (back == bufferEnd){
back = 0;
}
else back++;
}
return;
}
float *isoBuffer_file::readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset)
{
//ignore singleBit for now
double timeBetweenSamples = (double) sampleWindow * samplesPerSecond / (double) numSamples;
double accumulatedDelay = 0;
int delaySamples = (int)((double)delayOffset * samplesPerSecond);
int front = back - 1 - delaySamples;
if (front < 0) front = 0;
/*
qDebug() << "sampleWindow" << sampleWindow;
qDebug() << "numSamples" << numSamples;
qDebug() << "delayOffset" << delayOffset;
qDebug() << "samplesPerSecond" << samplesPerSecond;
qDebug() << "timeBetweenSamples" << timeBetweenSamples;
qDebug() << "delaySamples" << delaySamples;
qDebug() << "back" << back;
qDebug() << "front" << front;
*/
int idx, subIdx;
if(readData!=NULL) free(readData);
readData = (float *) calloc(numSamples, sizeof(float));
if(singleBit){
return readData; //Garbage. Not supported.
}else{
for (int i=0; i<numSamples;i++){
if (timeBetweenSamples > (double) front){
qDebug() << "Wrap!";
accumulatedDelay -= (double) front;
front = bufferEnd;
}
idx = (int) round(((double) front - accumulatedDelay));
if (idx < 0){
qDebug() << "Wrap";
accumulatedDelay--;
accumulatedDelay -= (double) front;
front = bufferEnd;
idx = (int) round(((double) front - accumulatedDelay));
}
readData[i] = buffer[idx];
accumulatedDelay += timeBetweenSamples;
}
}
return readData;
}
void isoBuffer_file::clearBuffer()
{
for (int i=0; i<bufferEnd;i++){
buffer[i] = 0;
}
back = 0;
}

View File

@ -0,0 +1,25 @@
#ifndef ISOBUFFER_FILE_H
#define ISOBUFFER_FILE_H
#include <QWidget>
#include "xmega.h"
class isoBuffer_file : public QWidget
{
Q_OBJECT
public:
explicit isoBuffer_file(QWidget *parent, int bufferlen, double sampleRate_Hz);
//Required Functions
void writeBuffer_float(float* data, int len);
float *readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset);
void clearBuffer();
double samplesPerSecond;
int bufferEnd, back = 0;
float *buffer, *readData = NULL;
signals:
public slots:
};
#endif // ISOBUFFER_FILE_H

View File

@ -1,5 +1,6 @@
#include "isodriver.h"
#include "isobuffer.h"
#include "isobuffer_file.h"
#include "platformspecific.h"
#include <math.h>
#include "daqloadprompt.h"
@ -61,6 +62,11 @@ void isoDriver::timerTick(void){
//qDebug() << length << "read in!!";
total_read += length;
if(fileModeEnabled){
qDebug() << "File mode is active. Abort live refresh";
return;
}
if (length==0){
//Zero length packet means something's gone wrong. Probably a disconnect.
qDebug() << "Zero length iso packet!";
@ -170,6 +176,14 @@ void isoDriver::digitalConvert(short *shortPtr, QVector<double> *doublePtr){
//cool_waveform = cool_waveform - AC_offset;
}
void isoDriver::fileStreamConvert(float *floatPtr, QVector<double> *doublePtr){
double *data = doublePtr->data();
for (int i=0;i<GRAPH_SAMPLES;i++){
data[i] = floatPtr[i];
}
}
void isoDriver::startTimer(){
/*if (isoTimer!=NULL){
@ -194,7 +208,7 @@ void isoDriver::setVisible_CH2(bool visible){
}
void isoDriver::setVoltageRange(QWheelEvent *event){
if(doNotTouchGraph == true) return;
if(doNotTouchGraph && !fileModeEnabled) return;
if (!(event->modifiers() == Qt::ControlModifier)){
double c = (topRange - botRange) / (double)400;
@ -243,8 +257,10 @@ void isoDriver::setVoltageRange(QWheelEvent *event){
delay -= c* ((double)100 - (double)pixPct) * pixPct/100;
}
if (window > (double)MAX_WINDOW_SIZE) window = (double)MAX_WINDOW_SIZE;
if ((window + delay) > MAX_WINDOW_SIZE) delay -= window + delay - (double)MAX_WINDOW_SIZE;
double mws = fileModeEnabled ? daq_maxWindowSize : ((double)MAX_WINDOW_SIZE);
if (window > mws) window = mws;
if ((window + delay) > mws) delay -= window + delay - mws;
if (delay < 0) delay = 0;
qDebug() << window << delay;
} else {
@ -273,8 +289,10 @@ void isoDriver::setVoltageRange(QWheelEvent *event){
delay -= c* ((double)100 - (double)pixPct) * pixPct/100;
}
if (window > (double)MAX_WINDOW_SIZE) window = (double)MAX_WINDOW_SIZE;
if ((window + delay) > MAX_WINDOW_SIZE) delay -= window + delay - (double)MAX_WINDOW_SIZE;
double mws = fileModeEnabled ? daq_maxWindowSize : ((double)MAX_WINDOW_SIZE);
if (window > mws) window = mws;
if ((window + delay) > mws) delay -= window + delay - mws;
if (delay < 0) delay = 0;
windowAtPause = window;
qDebug() << window << delay;
@ -633,7 +651,7 @@ void isoDriver::setTriggerMode(int newMode){
triggerType = (triggerType_enum)newMode;
}
void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) //0 for off, 1 for ana, 2 for dig, -1 for ana750
void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) //0 for off, 1 for ana, 2 for dig, -1 for ana750, -2 for file
{
//qDebug() << "made it to frameActionGeneric";
if(!paused_CH1 && CH1_mode == - 1){
@ -702,7 +720,7 @@ void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) //0 for off, 1
readData375_CH1 = internalBuffer375_CH1->readBuffer(window,GRAPH_SAMPLES,CH1_mode==2, delay + ((triggerEnabled&&!paused_CH1) ? triggerDelay + window/2 : 0));
if(CH2_mode) readData375_CH2 = internalBuffer375_CH2->readBuffer(window,GRAPH_SAMPLES,CH2_mode==2, delay + (triggerEnabled ? triggerDelay + window/2 : 0));
if(CH1_mode == -1) readData750 = internalBuffer750->readBuffer(window,GRAPH_SAMPLES,false, delay + (triggerEnabled ? triggerDelay + window/2 : 0));
if(CH1_mode == -2) readDataFile = internalBufferFile->readBuffer(window,GRAPH_SAMPLES,false, delay);
//qDebug() << "Trigger Delay =" << triggerDelay;
@ -732,6 +750,11 @@ void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) //0 for off, 1
broadcastStats(0);
}
if(CH1_mode == -2) {
fileStreamConvert(readDataFile, &CH1);
}
for (double i=0; i<GRAPH_SAMPLES; i++){
x[i] = -(window*i)/((double)(GRAPH_SAMPLES-1)) - delay;
if (x[i]>0) {
@ -1301,6 +1324,7 @@ void isoDriver::loadFileBuffer(QFile *fileToLoad){
}
qDebug("There are %d elements!", numel);
//Prompt user for start and end times
double defaultSampleRate = 375000;
if(mode == 6){
@ -1313,8 +1337,61 @@ void isoDriver::loadFileBuffer(QFile *fileToLoad){
daqLoadPrompt dlp(this, minTime, maxTime);
connect(&dlp, SIGNAL(startTime(double)), this, SLOT(daqLoad_startChanged(double)));
connect(&dlp, SIGNAL(endTime(double)), this, SLOT(daqLoad_endChanged(double)));
//Defaults
daqLoad_startTime = minTime;
daqLoad_endTime = maxTime;
dlp.exec();
//Copy the data into the isoBuffer
//Initialise the (modified) isoBuffer.
int bufferLen = (int)(((daqLoad_endTime - daqLoad_startTime)/minTime) * 1.1) + 1; //Add a bit on to account for rounding error. Int conversion rounds down, so we add 1.
qDebug() << "daqLoad_endTime" << daqLoad_endTime;
qDebug() << "daqLoad_startTime" << daqLoad_startTime;
qDebug() << "minTime" << minTime;
qDebug() << "bufferLen" << bufferLen;
double sampleRate_Hz = defaultSampleRate/averages;
internalBufferFile = new isoBuffer_file(this, bufferLen, sampleRate_Hz);
//Go to start of data section
fileToLoad->seek(0);//Return to start
currentLine = fileToLoad->readLine(); //Chew up header
qDebug() << currentLine;
currentLine = fileToLoad->readLine(); //Chew up averages line
qDebug() << currentLine;
currentLine = fileToLoad->readLine(); //Chew up mode line
qDebug() << currentLine;
tempList.clear();
//Copy the data into the (modified) isoBuffer
float tempArray[COLUMN_BREAK + 1]; //751 elements per row with the old files; this just avoids a possible crash;
int temp_len;
qDebug() << "Loading data into isoBuffer_file";
while (!fileToLoad->atEnd()) {
currentLine = fileToLoad->readLine();
tempList.append(currentLine.split(','));
tempList.removeLast(); //Last element is a "\n", not a number.
temp_len = tempList.count();
for (int i=0; i<temp_len; i++){
tempArray[i] = tempList.at(i).toFloat();
}
internalBufferFile->writeBuffer_float(tempArray, temp_len);
tempList.clear();
}
qDebug() << "Initialising timer";
//Initialise the file timer.
if (fileTimer != NULL){
delete fileTimer;
}
fileTimer = new QTimer();
fileTimer->setTimerType(Qt::PreciseTimer);
fileTimer->start(TIMER_PERIOD);
connect(fileTimer, SIGNAL(timeout()), this, SLOT(fileTimerTick()));
qDebug() << "File Buffer loaded!";
enableFileMode();
qDebug() << "File Mode Enabled";
}
void isoDriver::daqLoad_startChanged(double newStart){
@ -1327,5 +1404,19 @@ void isoDriver::daqLoad_endChanged(double newEnd){
daqLoad_endTime = newEnd;
}
void isoDriver::fileTimerTick(){
//qDebug() << "isoDriver::fileTimerTick()";
frameActionGeneric(-2,0);
}
void isoDriver::enableFileMode(){
fileModeEnabled = true;
daq_maxWindowSize = daqLoad_endTime - daqLoad_startTime;
}
void isoDriver::disableFileMode(){
fileModeEnabled = false;
}

View File

@ -11,6 +11,7 @@
#include "siprint.h"
class isoBuffer;
class isoBuffer_file;
//isoDriver is a huge class. It handles everything related to the isochronous IN stream - and perhaps that constraint was applied a bit too loosely (spot the C programmer...).
//Too much stuff is handled in this class, and it's too heavily entangled with the (generic/win/unix)UsbDriver classes.
@ -22,7 +23,8 @@ class isoDriver : public QLabel
public:
explicit isoDriver(QWidget *parent = 0);
//Generic Vars
isoBuffer *internalBuffer375_CH1, *internalBuffer375_CH2, *internalBuffer750, *internalBufferFile = NULL;
isoBuffer *internalBuffer375_CH1, *internalBuffer375_CH2, *internalBuffer750;
isoBuffer_file *internalBufferFile = NULL;
#if QCP_VER == 1
QCPItemText *cursorTextPtr;
#endif
@ -44,6 +46,9 @@ public:
void setAxes(QCustomPlot *newAxes);
double meanVoltageLast(double seconds, unsigned char channel, int TOP);
void loadFileBuffer(QFile *fileToLoad);
//DAQ
bool fileModeEnabled = false;
double daq_maxWindowSize;
private:
//Those bloody bools that just Enable/Disable a single property
bool paused_CH1 = false, paused_CH2 = false, paused_multimeter = false;
@ -75,6 +80,7 @@ private:
//Generic Functions
void analogConvert(short *shortPtr, QVector<double> *doublePtr, int TOP, bool AC, int channel);
void digitalConvert(short *shortPtr, QVector<double> *doublePtr);
void fileStreamConvert(float *floatPtr, QVector<double> *doublePtr);
bool properlyPaused();
void autoGain(void);
void udateCursors(void);
@ -86,6 +92,7 @@ private:
//Variables that are just pointers to other classes/vars
QCustomPlot *axes;
short *readData375_CH1, *readData375_CH2, *readData750;
float *readDataFile;
char *isoTemp = NULL;
short *isoTemp_short = NULL;
siprint *v0, *v1, *dv, *t0, *t1, *dt, *f;
@ -106,11 +113,12 @@ private:
double seriesResistance = 0;
//Generic Vars
double windowAtPause = 0.01;
QTimer* isoTimer = NULL, *slowTimer = NULL;
QTimer* isoTimer = NULL, *slowTimer = NULL, *fileTimer = NULL;
long total_read = 0;
unsigned int length;
QFile *snapshotFile_CH1;
QFile *snapshotFile_CH2;
//DAQ
double daqLoad_startTime, daqLoad_endTime;
signals:
@ -193,6 +201,9 @@ public slots:
void serialNeedsDisabling(int channel);
void daqLoad_startChanged(double newStart);
void daqLoad_endChanged(double newEnd);
void fileTimerTick();
void enableFileMode();
void disableFileMode();
};
#endif // ISODRIVER_H

View File

@ -966,8 +966,9 @@ void MainWindow::cycleDelayRight(){
void MainWindow::cycleDelayLeft(){
qDebug() << "LEFT";
double mws = ui->controller_iso->fileModeEnabled ? ui->controller_iso->daq_maxWindowSize : ((double)MAX_WINDOW_SIZE);
ui->controller_iso->delay += ui->controller_iso->window/10;
if(ui->controller_iso->delay > (MAX_WINDOW_SIZE - ui->controller_iso->window)) ui->controller_iso->delay = (MAX_WINDOW_SIZE - ui->controller_iso->window);
if(ui->controller_iso->delay > (mws - ui->controller_iso->window)) ui->controller_iso->delay = (mws - ui->controller_iso->window);
}
void MainWindow::cycleDelayRight_large(){
@ -978,8 +979,9 @@ void MainWindow::cycleDelayRight_large(){
void MainWindow::cycleDelayLeft_large(){
qDebug() << "LEFT";
double mws = ui->controller_iso->fileModeEnabled ? ui->controller_iso->daq_maxWindowSize : ((double)MAX_WINDOW_SIZE);
ui->controller_iso->delay += ui->controller_iso->window/2;
if(ui->controller_iso->delay > (MAX_WINDOW_SIZE - ui->controller_iso->window)) ui->controller_iso->delay = (MAX_WINDOW_SIZE - ui->controller_iso->window);
if(ui->controller_iso->delay > (mws - ui->controller_iso->window)) ui->controller_iso->delay = (mws - ui->controller_iso->window);
}
void MainWindow::enableLabradorDebugging(){

View File

@ -50,6 +50,27 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="contigRamLabel">
<property name="text">
<string>Contiguous RAM required:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="contigRamLabel_Value">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">