view file-data-provider.c @ 88:9b7588cd4013

Move data acquisition into separate thread The data acquisition thread transfers data to the main thread trough a Thread Safe Queue. This separation allows for making the data acquisition system pluggable. The old file based communication to the KK counter is implemented along with a very simple fake data provider.
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Thu, 21 Mar 2013 18:24:45 +0100
parents
children c9aec93005a4
line wrap: on
line source

/* FXAnalise data provider reading data from KK data file on disc */

#include <ansi_c.h>
#include <utility.h>
#include <formatio.h>

//#define LOGFILEPATH "C:\\Femto\\Software\\FXQE80"
#define LOGFILEPATH "C:\\temp"

/* data acquisition flag */
extern int acquiring;
/* data queue */
extern CmtTSQHandle dataQueue;

void CurrentFileName(char *fname)
{
	char day[3], month[3], year[3];
	char *date = DateStr();
	Scan(date, "%s>%s[w2]-%s[w2]-20%s[w2]", month, day, year);
	Fmt(fname, "%s<%s\\%s%s%s_Frequ.txt", LOGFILEPATH, year, month, day);
}

#define FXLINELENGTH 123 

int CVICALLBACK FileDataProvider (void *functionData)
{
	int mainThreadId;
	
	/* get main thread id to post messages to it */
	mainThreadId = CmtGetMainThreadID();
	
	int LogFile;
	long LogFileSize;
	char LogFileName[MAX_PATHNAME_LEN];
	long OldLogFilePtr = 0;
	char LineBuffer[FXLINELENGTH + 10];
	
	char TimeTag[] = "100103 000000.000";   // K+K time tag meaning here 2010 january the 3rd at 00:00:00.000
	char Year[] = "2010";
	char Month[] = "01";
	char Day[] = "03";
	char Hour[] = "00";
	char Min[] = "00" ;
	char Sec[] = "00.000";
	struct tm LocalTime ;
	time_t utcTime;
	
	double data[5];
	
	CurrentFileName(LogFileName);
	GetFileInfo(LogFileName, &OldLogFilePtr);
	OldLogFilePtr -= OldLogFilePtr%FXLINELENGTH + FXLINELENGTH - 2;
	
	while (acquiring) {
			
		GetFileInfo(LogFileName, &LogFileSize);
		if (LogFileSize > OldLogFilePtr+2*FXLINELENGTH-2) {  // if a complete newline has been written
						
			// Open Log file and get to the beginning of newly completed line
			LogFile = OpenFile(LogFileName, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
			OldLogFilePtr += FXLINELENGTH;
			SetFilePtr(LogFile, OldLogFilePtr, 0);
				
			// return the last complete string from the log file and scan it for date and time information 
				
			// first, the time tag, and store it in various formats
			ReadFile(LogFile, TimeTag, 17);
				
			CopyBytes(Year,2,TimeTag,0,2); // first 2 bytes of year string remains "20"
			CopyBytes(Month,0,TimeTag,2,2);
			CopyBytes(Day,0,TimeTag,4,2);
			CopyBytes(Hour,0,TimeTag,7,2);
			CopyBytes(Min,0,TimeTag,9,2);
			CopyBytes(Sec,0,TimeTag,11,6);
			
			Fmt(&LocalTime.tm_year, "%d<%s", Year);
			Fmt(&LocalTime.tm_mon,  "%d<%s", Month);
			Fmt(&LocalTime.tm_mday, "%d<%s", Day);
			Fmt(&LocalTime.tm_hour, "%d<%s", Hour);
			Fmt(&LocalTime.tm_min,  "%d<%s", Min);
			Fmt(&LocalTime.tm_sec,  "%d<%s", "00");    // special case to handle non integer number of UTC seconds
			
			LocalTime.tm_hour += 0;
			LocalTime.tm_min  -= 0;  
			LocalTime.tm_sec  -= 0;  
			LocalTime.tm_mon  -= 1;  	// january is month 0 for tm struct
			LocalTime.tm_year -= 1900; // year is number of years since 1900 for tm struct
			LocalTime.tm_isdst = -1;  // daylight saving flag MUST be set to -1 (unallocated is bugging and +1 is making 1 hour error in summer)
			
			utcTime = mktime (&LocalTime);
			data[0] = (double) utcTime + strtod(Sec,NULL);
			
			// scan the line for counters's channels information
				
			ReadLine(LogFile, LineBuffer, FXLINELENGTH+9);
			CloseFile(LogFile);
				
			Scan(LineBuffer, "%f%f%f%f", &data[1], &data[2], &data[3], &data[4]);
			
			/* convert from kHz to Hz */
			data[1] = data[1] * 1000.0;
			data[2] = data[2] * 1000.0;
			data[3] = data[3] * 1000.0;
			data[4] = data[4] * 1000.0;
			
			/* push data into the data queue */
			CmtWriteTSQData(dataQueue, data, 5, TSQ_INFINITE_TIMEOUT, 0);
			
			// Special case to handle change of day at next second
			if ( LocalTime.tm_hour==23 && LocalTime.tm_min==59 && strtod(Sec,NULL)>=58 ) {
				do {
					Delay(5.1);
					CurrentFileName(LogFileName);
				} while (!GetFileInfo(LogFileName, &OldLogFilePtr));
				OldLogFilePtr = 2;
			}
		}
		Delay(0.05);
	}
	return 0;
}