#include "isobuffer.h" #include "isodriver.h" #include "uartstyledecoder.h" isoBuffer::isoBuffer(QWidget *parent, int bufferLen, isoDriver *caller, unsigned char channel_value) : QWidget(parent) { buffer = (short *) calloc(bufferLen*2, sizeof(short)); bufferEnd = bufferLen-1; samplesPerSecond = (double) bufferLen/(double)21; samplesPerSecond = samplesPerSecond/375*VALID_DATA_PER_375; sampleRate_bit = samplesPerSecond * 8; virtualParent = caller; channel = channel_value; } void isoBuffer::openFile(QString newFile) { if (fptr != NULL){ fclose(fptr); } if (newFile.isEmpty()){ fptr = NULL; } else { QByteArray temp = newFile.toLatin1(); char *fileName = temp.data(); fptr = fopen(fileName, "w"); if (fptr == NULL) qFatal("Null fptr in isoBuffer::openFile"); qDebug() << "opening file" << fileName; qDebug() << "fptr = " << fptr; } } void isoBuffer::writeBuffer_char(char* data, int len) { double convertedSample; for (int i=0; iwrite(numStr); currentColumn++; if (currentColumn >= COLUMN_BREAK){ currentFile->write("\n"); currentColumn = 0; } //Reset the average and sample count for next data point fileIO_sampleCount = 0; average_sample_temp = 0; //Check to see if we've reached the max file size. if(fileIO_max_file_size != 0){ //value of 0 means "no limit" fileIO_numBytesWritten += 9; //7 chars for the number, 1 for the comma and 1 for the space = 9 bytes per sample. if(fileIO_numBytesWritten >= fileIO_max_file_size){ fileIOEnabled = false; //Just in case signalling fails. fileIOinternalDisable(); } } } } } return; } void isoBuffer::writeBuffer_short(short* data, int len) { //for (int i=(len-1);i>-1;i--){ for (int i=0; iwrite(numStr); currentColumn++; if (currentColumn >= COLUMN_BREAK){ currentFile->write("\n"); currentColumn = 0; } //Reset the average and sample count for next data point fileIO_sampleCount = 0; average_sample_temp = 0; //Check to see if we've reached the max file size. if(fileIO_max_file_size != 0){ //value of 0 means "no limit" fileIO_numBytesWritten += 9; //7 chars for the number, 1 for the comma and 1 for the space = 9 bytes per sample. if(fileIO_numBytesWritten >= fileIO_max_file_size){ fileIOEnabled = false; //Just in case signalling fails. fileIOinternalDisable(); } } } } } return; } short *isoBuffer::readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset) { //ignore singleBit for now double timeBetweenSamples = (double) sampleWindow * (double) samplesPerSecond / (double) numSamples; double accumulatedDelay = 0; int delaySamples = (int)((double)delayOffset * (double)samplesPerSecond); int front = back - 1 - delaySamples; if (front < 0) front = 0; int idx, subIdx; if(readData!=NULL) free(readData); readData = (short *) calloc(numSamples, sizeof(short)); if(singleBit){ for (int i=0; i (double) front){ accumulatedDelay -= (double) front; front = bufferEnd; } idx = (int) floor(((double) front - accumulatedDelay)); subIdx = (int) floor(8*(((double) front - accumulatedDelay) - floor(((double) front - accumulatedDelay)))); //qDebug() << "subIdx = " << subIdx; if (idx < 0){ accumulatedDelay--; accumulatedDelay -= (double) front; front = bufferEnd; idx = (int) round(((double) front - accumulatedDelay)); } readData[i] = buffer[idx] & (1 << subIdx); accumulatedDelay += timeBetweenSamples; } }else{ for (int i=0; i (double) front){ accumulatedDelay -= (double) front; front = bufferEnd; } idx = (int) round(((double) front - accumulatedDelay)); if (idx < 0){ accumulatedDelay--; accumulatedDelay -= (double) front; front = bufferEnd; idx = (int) round(((double) front - accumulatedDelay)); } readData[i] = buffer[idx]; accumulatedDelay += timeBetweenSamples; } } return readData; } void isoBuffer::clearBuffer() { for (int i=0; iopen(QIODevice::WriteOnly); currentFile = file; //Add the header char headerLine[256]; sprintf(headerLine, "EspoTek Labrador DAQ V1.0 Output File\nAveraging = %d\nMode = %d\n", samplesToAverage, virtualParent->driver->deviceMode); currentFile->write(headerLine); //Set up the isoBuffer for DAQ fileIO_maxIncrementedSampleValue = samplesToAverage; fileIO_max_file_size = max_file_size; fileIO_sampleCount = 0; fileIO_numBytesWritten = 0; average_sample_temp = 0; //Enable DAQ fileIOEnabled = true; qDebug("File IO enabled, averaging %d samples, max file size %uMB", samplesToAverage, max_file_size/1000000); qDebug() << max_file_size; return; } void isoBuffer::disableFileIO(){ fileIOEnabled = false; currentColumn = 0; currentFile->close(); return; } double isoBuffer::sampleConvert(short sample, int TOP, bool AC){ double scope_gain = (double)(virtualParent->driver->scopeGain); double voltageLevel; voltageLevel = (sample * (vcc/2)) / (frontendGain*scope_gain*TOP); if (virtualParent->driver->deviceMode != 7) voltageLevel += voltage_ref; #ifdef INVERT_MM if(virtualParent->driver->deviceMode == 7) voltageLevel *= -1; #endif if(AC){ voltageLevel -= virtualParent->currentVmean; //This is old (1 frame in past) value and might not be good for signals with large variations in DC level (although the cap should filter that anyway)?? } return voltageLevel; } short isoBuffer::inverseSampleConvert(double voltageLevel, int TOP, bool AC){ double scope_gain = (double)(virtualParent->driver->scopeGain); short sample; if(AC){ voltageLevel += virtualParent->currentVmean; //This is old (1 frame in past) value and might not be good for signals with large variations in DC level (although the cap should filter that anyway)?? } #ifdef INVERT_MM if(virtualParent->driver->deviceMode == 7) voltageLevel *= -1; #endif if (virtualParent->driver->deviceMode != 7) voltageLevel -= voltage_ref; //voltageLevel = (sample * (vcc/2)) / (frontendGain*scope_gain*TOP); sample = (voltageLevel * (frontendGain*scope_gain*TOP))/(vcc/2); return sample; } #define NUM_SAMPLES_SEEKING_CAP (20) #ifdef INVERT_MM #define X0_COMPARISON_CAP > #define X1_X2_COMPARISON_CAP < #else #define X0_COMPARISON_CAP < #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){ return -1; //too hard, not really important } short vbot_s = inverseSampleConvert(vbot, 2048, 0); qDebug() << "vbot_s (x0) = " << vbot_s; int num_found = 0; for(int i=samplesInPast; i; i--){ short currentSample = buffer[back - i]; if(currentSample X0_COMPARISON_CAP vbot_s){ num_found++; } else num_found--; if(num_found < 0){ num_found = 0; } if (num_found > NUM_SAMPLES_SEEKING_CAP){ return samplesInPast-i; } } return -1; } int isoBuffer::cap_x1fromLast(double seconds, int x0, double vbot){ int samplesInPast = seconds * samplesPerSecond; samplesInPast -= x0; if(back < samplesInPast){ return -1; //too hard, not really important } short vbot_s = inverseSampleConvert(vbot, 2048, 0); qDebug() << "vbot_s (x1) = " << vbot_s; int num_found = 0; for(int i=samplesInPast; i; i--){ short currentSample = buffer[back - i]; if(currentSample X1_X2_COMPARISON_CAP vbot_s){ num_found++; } else num_found--; if(num_found < 0){ num_found = 0; } if (num_found > NUM_SAMPLES_SEEKING_CAP){ return samplesInPast-i + x0; } } return -1; } int isoBuffer::cap_x2fromLast(double seconds, int x1, double vtop){ int samplesInPast = seconds * samplesPerSecond; samplesInPast -= x1; if(back < samplesInPast){ return -1; //too hard, not really important } short vtop_s = inverseSampleConvert(vtop, 2048, 0); qDebug() << "vtop_s (x2) = " << vtop_s; int num_found = 0; for(int i=samplesInPast; i; i--){ short currentSample = buffer[back - i]; if(currentSample X1_X2_COMPARISON_CAP vtop_s){ num_found++; } else num_found--; if(num_found < 0){ num_found = 0; } if (num_found > NUM_SAMPLES_SEEKING_CAP){ return samplesInPast-i + x1; } } return -1; } void isoBuffer::serialManage(double baudRate, int type){ //Types: // 0 - standard UART, no parity // 1 - standard UART, with parity bit // 100 - I2C if(decoder == NULL){ decoder = new uartStyleDecoder(this); connect(decoder, SIGNAL(wireDisconnected(int)), virtualParent, SLOT(serialNeedsDisabling(int))); } if(stopDecoding){ decoder->updateTimer->start(CONSOLE_UPDATE_TIMER_PERIOD); stopDecoding = false; } decoder->serialDecode(baudRate); }