2017-10-21 06:11:49 +01:00
# include "isobuffer.h"
# include "isodriver.h"
2017-11-28 00:17:11 +00:00
# include "uartstyledecoder.h"
2017-10-21 06:11:49 +01:00
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 ; i < len ; i + + ) {
//qDebug() << "i = " << i;
buffer [ back ] = ( short ) data [ i ] ;
if ( back = = bufferEnd ) {
back = 0 ;
firstTime = false ;
}
else back + + ;
//Output to CSV
if ( fileIOEnabled ) {
2017-12-27 01:44:49 +00:00
//Current sample
convertedSample = sampleConvert ( data [ i ] , 128 , channel = = 1 ? virtualParent - > AC_CH1 : virtualParent - > AC_CH2 ) ;
//Accumulate
average_sample_temp + = convertedSample ;
fileIO_sampleCount + + ;
//Check to see if we can write a new sample to file
2017-12-24 03:08:27 +00:00
if ( fileIO_sampleCount = = fileIO_maxIncrementedSampleValue ) {
char numStr [ 32 ] ;
2017-12-27 01:44:49 +00:00
sprintf ( numStr , " %7.5f, " , average_sample_temp / ( ( double ) fileIO_maxIncrementedSampleValue ) ) ;
2017-12-24 03:08:27 +00:00
currentFile - > write ( numStr ) ;
currentColumn + + ;
2017-12-27 23:17:32 +00:00
if ( currentColumn > = COLUMN_BREAK ) {
2017-12-24 03:08:27 +00:00
currentFile - > write ( " \n " ) ;
currentColumn = 0 ;
}
2017-12-27 01:44:49 +00:00
//Reset the average and sample count for next data point
2017-12-24 03:08:27 +00:00
fileIO_sampleCount = 0 ;
2017-12-27 01:44:49 +00:00
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 ( ) ;
}
2017-12-24 03:08:27 +00:00
}
2017-10-21 06:11:49 +01:00
}
}
}
return ;
}
void isoBuffer : : writeBuffer_short ( short * data , int len )
{
//for (int i=(len-1);i>-1;i--){
for ( int i = 0 ; i < len ; i + + ) {
//qDebug() << "i = " << i;
buffer [ back ] = ( short ) data [ i ] > > 4 ; //Because it's a left adjust value!
if ( back = = bufferEnd ) {
back = 0 ;
firstTime = false ;
}
else back + + ;
2017-12-27 03:38:16 +00:00
double convertedSample ;
//Output to CSV
if ( fileIOEnabled ) {
//Current sample
convertedSample = sampleConvert ( ( data [ i ] > > 4 ) , 2048 , channel = = 1 ? virtualParent - > AC_CH1 : virtualParent - > AC_CH2 ) ;
//Accumulate
average_sample_temp + = convertedSample ;
fileIO_sampleCount + + ;
//Check to see if we can write a new sample to file
if ( fileIO_sampleCount = = fileIO_maxIncrementedSampleValue ) {
char numStr [ 32 ] ;
sprintf ( numStr , " %7.5f, " , average_sample_temp / ( ( double ) fileIO_maxIncrementedSampleValue ) ) ;
currentFile - > write ( numStr ) ;
currentColumn + + ;
2017-12-27 23:17:32 +00:00
if ( currentColumn > = COLUMN_BREAK ) {
2017-12-27 03:38:16 +00:00
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 ( ) ;
}
}
}
}
2017-10-21 06:11:49 +01:00
}
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 < numSamples ; i + + ) {
if ( timeBetweenSamples > ( 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 ) ) ;
}
2018-11-04 00:31:48 +00:00
readData [ i ] = buffer [ idx ] & ( 1 < < subIdx ) ;
2017-10-21 06:11:49 +01:00
accumulatedDelay + = timeBetweenSamples ;
}
} else {
for ( int i = 0 ; i < numSamples ; i + + ) {
if ( timeBetweenSamples > ( 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 ; i < bufferEnd ; i + + ) {
buffer [ i ] = 0 ;
}
back = 0 ;
firstTime = true ;
}
void isoBuffer : : gainBuffer ( int gain_log )
{
qDebug ( ) < < " Buffer shifted by " < < gain_log ;
for ( int i = 0 ; i < bufferEnd ; i + + ) {
if ( gain_log = = - 1 ) buffer [ i ] * = 2 ;
else buffer [ i ] / = 2 ;
}
}
void isoBuffer : : glitchInsert ( short type )
{
}
2017-12-27 01:44:49 +00:00
void isoBuffer : : enableFileIO ( QFile * file , int samplesToAverage , qulonglong max_file_size ) {
//Open the file
2017-10-21 06:11:49 +01:00
file - > open ( QIODevice : : WriteOnly ) ;
currentFile = file ;
2017-12-24 03:08:27 +00:00
2017-12-27 01:44:49 +00:00
//Add the header
char headerLine [ 256 ] ;
2017-12-27 03:39:56 +00:00
sprintf ( headerLine , " EspoTek Labrador DAQ V1.0 Output File \n Averaging = %d \n Mode = %d \n " , samplesToAverage , virtualParent - > driver - > deviceMode ) ;
2017-12-27 01:44:49 +00:00
currentFile - > write ( headerLine ) ;
//Set up the isoBuffer for DAQ
fileIO_maxIncrementedSampleValue = samplesToAverage ;
2017-12-24 03:08:27 +00:00
fileIO_max_file_size = max_file_size ;
fileIO_sampleCount = 0 ;
fileIO_numBytesWritten = 0 ;
2017-12-27 01:44:49 +00:00
average_sample_temp = 0 ;
//Enable DAQ
fileIOEnabled = true ;
2017-12-24 03:08:27 +00:00
2017-12-27 01:44:49 +00:00
qDebug ( " File IO enabled, averaging %d samples, max file size %uMB " , samplesToAverage , max_file_size / 1000000 ) ;
2017-12-24 03:08:27 +00:00
qDebug ( ) < < max_file_size ;
2017-10-21 06:11:49 +01:00
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
2017-12-28 02:23:33 +00:00
//For capacitance measurement. x0, x1 and x2 are all various time points used to find the RC coefficient.
2017-10-21 06:11:49 +01:00
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 ;
}
2017-11-28 00:17:11 +00:00
void isoBuffer : : serialManage ( double baudRate , int type ) {
2017-12-01 04:31:21 +00:00
//Types:
// 0 - standard UART, no parity
// 1 - standard UART, with parity bit
// 100 - I2C
2017-11-28 00:17:11 +00:00
if ( decoder = = NULL ) {
decoder = new uartStyleDecoder ( this ) ;
2017-11-28 02:09:52 +00:00
connect ( decoder , SIGNAL ( wireDisconnected ( int ) ) , virtualParent , SLOT ( serialNeedsDisabling ( int ) ) ) ;
}
if ( stopDecoding ) {
decoder - > updateTimer - > start ( CONSOLE_UPDATE_TIMER_PERIOD ) ;
stopDecoding = false ;
2017-11-28 00:17:11 +00:00
}
decoder - > serialDecode ( baudRate ) ;
}
2017-10-21 06:11:49 +01:00