changeset 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 0950d4b3a45c
children c9e4f63c2033
files FXAnalyse.c FXAnalyse.h FXAnalyse.uir fake-data-provider.c file-data-provider.c
diffstat 5 files changed, 339 insertions(+), 248 deletions(-) [+]
line wrap: on
line diff
--- a/FXAnalyse.c	Thu Mar 21 12:08:27 2013 +0100
+++ b/FXAnalyse.c	Thu Mar 21 18:24:45 2013 +0100
@@ -14,8 +14,6 @@
 #include "DDS_Fox.h" 
 #include "muParserDLL.h"
 
-#define FXLINELENGTH 123
-#define LOGFILEPATH "C:\\Femto\\Software\\FXQE80"
 #define DATAFOLDER "Z:\\Measures-2013"
 
 #define DEDRIFT_DDS_FREQUENCY 70000000
@@ -26,10 +24,22 @@
 static int EstimateN3Panel;
 static int LoggingPanel;
 
-char LogFileName[MAX_PATHNAME_LEN];
+// data acquisition status
+int acquiring;
+// data queue
+CmtTSQHandle dataQueue;
+// data provider thread
+CmtThreadFunctionID dataProviderThread;
 
-double utc = 0;
+// data providers
+int CVICALLBACK FakeDataProvider (void *functionData);
+int CVICALLBACK FileDataProvider (void *functionData);
 
+// select which data provider to use
+#define DataProvider FileDataProvider
+
+
+double utc;
 double Ch1, Ch2, Ch3, Ch4;
 double Math1, Math2, Math3, Math4, Math5;
 double N1, N2, N3, N4;
@@ -44,9 +54,8 @@
 
 muParserHandle_t MathParser1, MathParser2, MathParser3, MathParser4, MathParser5;
 
-int Acquiring = FALSE;
 
-long OldLogFilePtr = 0;
+
 double Ndiv = 8.0;
 
 int settling = 0;
@@ -233,7 +242,8 @@
 }
 
 
-void writeData(char *folder, char *name, char *id, char *date, char *time, double utc, double value)
+void writeData(const char *folder, const char *name, const char *id, 
+		const char *timestr, double utc, double value)
 {
 	char line[1024];
 	char filename[FILENAME_MAX];
@@ -242,12 +252,20 @@
 	snprintf(filename, sizeof(filename), "%s\\%s-%s.txt", folder, id, name);
 	
 	int fd = OpenFile(filename, VAL_WRITE_ONLY, VAL_APPEND, VAL_ASCII);
-	Fmt(line, "%s\t%s\t%f[p3]\t%f[p3]", date, time, utc, value);
+	Fmt(line, "%s\t%f[p3]\t%f[p3]", timestr, utc, value);
 	WriteLine(fd, line, -1);
 	CloseFile(fd);
 }
 
 
+#define NCHAN 4
+#define DATA_EVENT_SIZE (NCHAN + 1)
+#define DATA_QUEUE_SIZE (128 * DATA_EVENT_SIZE)
+
+void CVICALLBACK DataAvailableCB (CmtTSQHandle queueHandle, unsigned int event,
+		int value, void *callbackData);
+
+
 int main (int argc, char *argv[])
 {
 	double frequency;
@@ -265,8 +283,6 @@
 	if ((LoggingPanel = LoadPanel (0, "FXAnalyse.uir", LOGGING)) < 0)
 		return -1;
 	
-	DisplayPanel (MainPanel);
-	
 	// initialize 4x AD9959 DDS box
 	DDS4xAD9912_Reset(&DDS4xAD9912);
 	GetCtrlVal(MainPanel, PANEL_DDS1, &frequency);
@@ -318,6 +334,15 @@
 	mupDefineVar(MathParser5, "Math4", &Math4);
 	GetCtrlVal(MainPanel, PANEL_MATHSTRING5, expr);
 	mupSetExpr(MathParser5, expr);
+
+	// data queue
+	CmtNewTSQ(DATA_QUEUE_SIZE, sizeof(double), 0, &dataQueue);
+
+	// register callback to execute when data will be in the data queue
+	CmtInstallTSQCallback(dataQueue, EVENT_TSQ_ITEMS_IN_QUEUE, DATA_EVENT_SIZE,
+		DataAvailableCB, NULL, CmtGetCurrentThreadID(), NULL);
+	
+	DisplayPanel(MainPanel);
 	
 	RunUserInterface();
 	
@@ -469,50 +494,23 @@
 }
 
 
-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);
-}
-
-
 int CVICALLBACK CB_OnStart (int panel, int control, int event,
 		void *callbackData, int eventData1, int eventData2)
 {
 	switch (event)
 	{
 		case EVENT_COMMIT:
-			if (Acquiring) {
-				PlotCh1.IndexPoint = 0;
-				PlotCh2.IndexPoint = 0;
-				PlotCh3.IndexPoint = 0;
-				PlotCh4.IndexPoint = 0;
-				PlotMath1.IndexPoint = 0;
-				PlotMath2.IndexPoint = 0; 
-				PlotMath3.IndexPoint = 0; 
-				PlotMath4.IndexPoint = 0; 
-				PlotMath5.IndexPoint = 0;
-				Allan_Reset(&AllanCh1);
-				Allan_Reset(&AllanCh2);
-				Allan_Reset(&AllanCh3);
-				Allan_Reset(&AllanCh4);
-				Allan_Reset(&AllanMath1);
-				Allan_Reset(&AllanMath2);
-				Allan_Reset(&AllanMath3);
-				Allan_Reset(&AllanMath4);
-				Allan_Reset(&AllanMath5);
-			}
-			Acquiring = TRUE;
-			SetCtrlAttribute(MainPanel, PANEL_STARTBUTTON, ATTR_LABEL_TEXT, "__RESET"); 
-			
-			CurrentFileName(LogFileName);
-			GetFileInfo(LogFileName, &OldLogFilePtr);
-			OldLogFilePtr -= OldLogFilePtr%FXLINELENGTH + FXLINELENGTH - 2;
+			if (acquiring)
+				break;
 			
 			logmsg("Start");
+			acquiring = 1;
 			
+			// start data provider thread
+			CmtScheduleThreadPoolFunctionAdv(
+				DEFAULT_THREAD_POOL_HANDLE, DataProvider, NULL,
+				THREAD_PRIORITY_HIGHEST, NULL, 0, NULL, 0, &dataProviderThread);
+
 			break;
 	}
 	return 0;
@@ -523,99 +521,49 @@
 {
 	switch (event) {
 		case EVENT_COMMIT:
-			Acquiring = FALSE ;
-			SetCtrlAttribute(MainPanel, PANEL_STARTBUTTON, ATTR_LABEL_TEXT, "__START");
+			if (! acquiring)
+				break;
+			
+			logmsg("Stop");
+			acquiring = 0;
+			
+			// wait for data provider thread to terminate
+			CmtWaitForThreadPoolFunctionCompletion(
+				DEFAULT_THREAD_POOL_HANDLE, dataProviderThread,
+				OPT_TP_PROCESS_EVENTS_WHILE_WAITING);
+			CmtReleaseThreadPoolFunctionID(
+				DEFAULT_THREAD_POOL_HANDLE, dataProviderThread);
+			
 			break;
 	}
 	return 0;
 }
 
-int CVICALLBACK CB_OnTimer (int panel, int control, int event,
-		void *callbackData, int eventData1, int eventData2)
+
+void CVICALLBACK DataAvailableCB (CmtTSQHandle queueHandle, unsigned int event,
+		int value, void *callbackData)
 {
-	int LogFile;
-	long LogFileSize;
-	char LineBuffer[FXLINELENGTH+10] = "\r\n_1 ";
-	
-	char TimeTag[] = "100103 000000.000";   // K+K time tag meaning here 2010 january the 3rd at 00:00:00.000
-	char Date[] = "03/01/2010" ;
-	char Time[] = "00:00:00.000" ;
-	char Year[] = "2010";
-	char ShortYear[] = "10";  // the last 2 digits of calendar year only
-	char Month[] = "01";
-	char Day[] = "03";
-	char Hour[] = "00";
-	char Min[] = "00" ;
-	char Sec[] = "00.000";
-	struct tm LocalTime ;
-	time_t utcTime;
-
-	int BoxChecked = FALSE; 
+	double data[DATA_EVENT_SIZE];
+	int BoxChecked = FALSE;
+	int read;
 	
 	switch (event) {
-		case EVENT_TIMER_TICK:
-			if (! Acquiring)
-				break;
-			
-			GetFileInfo(LogFileName, &LogFileSize);
-					
-			if (LogFileSize > OldLogFilePtr+2*FXLINELENGTH-2) {  // if a complete newline has been written
-						
-				SuspendTimerCallbacks();
-				
-				// 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(Date,0,TimeTag,4,2);
-				CopyBytes(Date,3,TimeTag,2,2);   
-				CopyBytes(Date,8,TimeTag,0,2);
-				CopyBytes(Time,0,TimeTag,7,2);
-				CopyBytes(Time,3,TimeTag,9,2);
-				CopyBytes(Time,6,TimeTag,11,6);
-				SetCtrlVal(MainPanel, PANEL_DATE, Date);
-				SetCtrlVal(MainPanel, PANEL_TIME, Time); 
+		case EVENT_TSQ_ITEMS_IN_QUEUE:
+			/* read data from the data queue */
+			while (value >= DATA_EVENT_SIZE) {
 				
-				CopyBytes(Year,2,TimeTag,0,2); // first 2 bytes of year string remains "20"
-				CopyBytes(ShortYear,0,TimeTag,0,2);
-				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);
-				utc = (double) utcTime + strtod(Sec,NULL);
+				read = CmtReadTSQData(queueHandle, data, DATA_EVENT_SIZE, TSQ_INFINITE_TIMEOUT, 0);
+				if (read != DATA_EVENT_SIZE)
+					logmsg("Error!");
+				value = value - read;
+				
+				utc = data[0];
+				Ch1 = data[1];
+				Ch2 = data[2];
+				Ch3 = data[3];
+				Ch4 = data[4];
+				
 				SetCtrlVal(MainPanel, PANEL_UTC, utc);
-				
-				// scan the line for counters's channels information
-				
-				ReadLine(LogFile, LineBuffer, FXLINELENGTH+9);
-				CloseFile(LogFile);
-				
-				Scan(LineBuffer, "%f%f%f%f", &Ch1, &Ch2, &Ch3, &Ch4);
-				Ch1 = 1000*Ch1;
-				Ch2 = 1000*Ch2;
-				Ch3 = 1000*Ch3;
-				Ch4 = 1000*Ch4;
-						
 				SetCtrlVal(MainPanel, PANEL_FREQ1, Ch1);
 				SetCtrlVal(MainPanel, PANEL_FREQ2, Ch2);
 				SetCtrlVal(MainPanel, PANEL_FREQ3, Ch3);  
@@ -1327,47 +1275,38 @@
 				}
 				
 				int save;
+				
 				// run id derived from current date in the form YYMMDD
 				char id[7];
-				snprintf(id, sizeof(id), "%2s%2s%2s", ShortYear, Month, Day);
+				FormatDateTimeString(utc, "%y%m%d", id, sizeof(id));
+				
+				// time
+				char timestr[24];
+				FormatDateTimeString(utc, "%d/%m/%Y %H:%M:%S.%3f", timestr, sizeof(timestr));
+				SetCtrlVal(MainPanel, PANEL_TIME, timestr);
 				
 				// write LO frequency (Math2) to disk
 				GetCtrlVal(MainPanel, PANEL_CHECKBOX_MATH2SAVE, &save);
 				if (save) {
-					writeData(DATAFOLDER, "Lo", id, Date, Time, utc, Math2);
-					writeData("C:\\Femto\\Results", "OptCavity", id, Date, Time, utc, Math2);
+					writeData(DATAFOLDER, "Lo", id, timestr, utc, Math2);
+					writeData("C:\\Femto\\Results", "OptCavity", id, timestr, utc, Math2);
 				}
 				
 				// write Hg frequency (Math3) to disk
 				GetCtrlVal(MainPanel, PANEL_CHECKBOX_MATH3SAVE, &save);
 				if (save) {
-					writeData(DATAFOLDER, "Hg", id, Date, Time, utc, Math3);
-					writeData("C:\\Femto\\Results", "HgCavity", id, Date, Time, utc, Math3);
+					writeData(DATAFOLDER, "Hg", id, timestr, utc, Math3);
+					writeData("C:\\Femto\\Results", "HgCavity", id, timestr, utc, Math3);
 				}
 				
 				// write ExtraMath (Math5) to disk
 				GetCtrlVal(MainPanel, PANEL_CHECKBOX_MATH5SAVE, &save);
 				if (save) {
-					writeData(DATAFOLDER, "Ex", id, Date, Time, utc, Math5);
+					writeData(DATAFOLDER, "Ex", id, timestr, utc, Math5);
 				}
-				
-				// Special case to handle change of day at next second
-				if ( LocalTime.tm_hour==23 && LocalTime.tm_min==59 && strtod(Sec,NULL)>=58 ) { 
-					Acquiring = FALSE;
-					do {
-						Delay(5.1);
-						CurrentFileName(LogFileName);
-					} while (!GetFileInfo(LogFileName, &OldLogFilePtr));
-					Acquiring = TRUE;
-					OldLogFilePtr = 2;
-				}
-				
-				ResumeTimerCallbacks(); 
-				
 			}		
 			break;
 	}
-	return 0;
 }
 
 
--- a/FXAnalyse.h	Thu Mar 21 12:08:27 2013 +0100
+++ b/FXAnalyse.h	Thu Mar 21 18:24:45 2013 +0100
@@ -54,104 +54,101 @@
 #define  PANEL_CHECKBOX_FREQ2PLOT         17      /* control type: radioButton, callback function: CB_OnFreqPlot */
 #define  PANEL_CHECKBOX_MATH1PLOT         18      /* control type: radioButton, callback function: CB_OnFreqPlot */
 #define  PANEL_CHECKBOX_FREQ1PLOT         19      /* control type: radioButton, callback function: CB_OnFreqPlot */
-#define  PANEL_TIMER                      20      /* control type: timer, callback function: CB_OnTimer */
-#define  PANEL_DDS2                       21      /* control type: numeric, callback function: CB_ChangeDDSOut */
-#define  PANEL_TEXTMSG                    22      /* control type: textMsg, callback function: (none) */
-#define  PANEL_TEXTMSG_2                  23      /* control type: textMsg, callback function: (none) */
-#define  PANEL_SLOPETIME                  24      /* control type: numeric, callback function: CB_ChangeSlopeTime */
-#define  PANEL_DDS1                       25      /* control type: numeric, callback function: CB_ChangeDDSOut */
-#define  PANEL_SPLITTER                   26      /* control type: splitter, callback function: (none) */
-#define  PANEL_CHANGENDIV                 27      /* control type: numeric, callback function: CB_OnChangeNdiv */
-#define  PANEL_N3CHOICE                   28      /* control type: numeric, callback function: CB_ChangeN */
-#define  PANEL_N3CALCULUS                 29      /* control type: command, callback function: CB_OnNCalculus */
-#define  PANEL_N1CHOICE                   30      /* control type: numeric, callback function: CB_ChangeN */
-#define  PANEL_N2CHOICE                   31      /* control type: numeric, callback function: CB_ChangeN */
-#define  PANEL_N2CALCULUS                 32      /* control type: command, callback function: CB_OnNCalculus */
-#define  PANEL_DDS4STEP                   33      /* control type: ring, callback function: CB_ChangeDDSStep */
-#define  PANEL_DDS3STEP                   34      /* control type: ring, callback function: CB_ChangeDDSStep */
-#define  PANEL_DDS2STEP                   35      /* control type: ring, callback function: CB_ChangeDDSStep */
-#define  PANEL_CENTERFREQUENCY            36      /* control type: numeric, callback function: (none) */
-#define  PANEL_SLOPE_APPLIED              37      /* control type: numeric, callback function: CB_SetSlope */
-#define  PANEL_MATH4                      38      /* control type: numeric, callback function: (none) */
-#define  PANEL_MATH5                      39      /* control type: numeric, callback function: (none) */
-#define  PANEL_MATH3                      40      /* control type: numeric, callback function: (none) */
-#define  PANEL_CHECKBOX_MATH5PLOT         41      /* control type: radioButton, callback function: CB_OnFreqPlot */
-#define  PANEL_CHECKBOX_MATH4PLOT         42      /* control type: radioButton, callback function: CB_OnFreqPlot */
-#define  PANEL_CHECKBOX_MATH4ALLAN        43      /* control type: radioButton, callback function: CB_OnAllanPlot */
-#define  PANEL_DDS1STEP                   44      /* control type: ring, callback function: CB_ChangeDDSStep */
-#define  PANEL_TEXTMSG_15                 45      /* control type: textMsg, callback function: (none) */
-#define  PANEL_CHECKBOX_MATH5ALLAN        46      /* control type: radioButton, callback function: CB_OnAllanPlot */
-#define  PANEL_CHECKBOX_MATH3PLOT         47      /* control type: radioButton, callback function: CB_OnFreqPlot */
-#define  PANEL_CHECKBOX_MATH5SAVE         48      /* control type: radioButton, callback function: (none) */
-#define  PANEL_CHECKBOX_MATH4SAVE         49      /* control type: radioButton, callback function: (none) */
-#define  PANEL_CHECKBOX_MATH3ALLAN        50      /* control type: radioButton, callback function: CB_OnAllanPlot */
-#define  PANEL_MATHSTRING4                51      /* control type: string, callback function: CB_ChangeMath */
-#define  PANEL_TEXTMSG_17                 52      /* control type: textMsg, callback function: (none) */
-#define  PANEL_MATH2                      53      /* control type: numeric, callback function: (none) */
-#define  PANEL_SPLITTER_15                54      /* control type: splitter, callback function: (none) */
-#define  PANEL_SPLITTER_12                55      /* control type: splitter, callback function: (none) */
-#define  PANEL_CHECKBOX_MATH2PLOT         56      /* control type: radioButton, callback function: CB_OnFreqPlot */
-#define  PANEL_CHECKBOX_MATH3SAVE         57      /* control type: radioButton, callback function: (none) */
-#define  PANEL_CHECKBOX_MATH2SAVE         58      /* control type: radioButton, callback function: (none) */
-#define  PANEL_CHECKBOX_MATH2ALLAN        59      /* control type: radioButton, callback function: CB_OnAllanPlot */
-#define  PANEL_TEXTMSG_7                  60      /* control type: textMsg, callback function: (none) */
-#define  PANEL_MATHSTRING3                61      /* control type: string, callback function: CB_ChangeMath */
-#define  PANEL_MATH1                      62      /* control type: numeric, callback function: (none) */
-#define  PANEL_SPLITTER_6                 63      /* control type: splitter, callback function: (none) */
-#define  PANEL_TEXTMSG_18                 64      /* control type: textMsg, callback function: (none) */
-#define  PANEL_TEXTMSG_6                  65      /* control type: textMsg, callback function: (none) */
-#define  PANEL_TEXTMSG_8                  66      /* control type: textMsg, callback function: (none) */
-#define  PANEL_TEXTMSG_19                 67      /* control type: textMsg, callback function: (none) */
-#define  PANEL_MATHSTRING1                68      /* control type: string, callback function: CB_ChangeMath */
-#define  PANEL_TEXTMSG_9                  69      /* control type: textMsg, callback function: (none) */
-#define  PANEL_TEXTMSG_10                 70      /* control type: textMsg, callback function: (none) */
-#define  PANEL_MATHSTRING2                71      /* control type: string, callback function: CB_ChangeMath */
-#define  PANEL_TEXTMSG_16                 72      /* control type: textMsg, callback function: (none) */
-#define  PANEL_SPLITTER_11                73      /* control type: splitter, callback function: (none) */
-#define  PANEL_SPLITTER_16                74      /* control type: splitter, callback function: (none) */
-#define  PANEL_SPLITTER_9                 75      /* control type: splitter, callback function: (none) */
-#define  PANEL_SPLITTER_3                 76      /* control type: splitter, callback function: (none) */
-#define  PANEL_MINUS10KDDS1               77      /* control type: command, callback function: CB_OnMinus10k */
-#define  PANEL_MINUS10KDDS4               78      /* control type: command, callback function: CB_OnMinus10k */
-#define  PANEL_MINUS10KDDS3               79      /* control type: command, callback function: CB_OnMinus10k */
-#define  PANEL_MINUS10KDDS2               80      /* control type: command, callback function: CB_OnMinus10k */
-#define  PANEL_PLUS10KDDS4                81      /* control type: command, callback function: CB_OnPlus10k */
-#define  PANEL_PLUS10KDDS3                82      /* control type: command, callback function: CB_OnPlus10k */
-#define  PANEL_PLUS10KDDS1                83      /* control type: command, callback function: CB_OnPlus10k */
-#define  PANEL_PLUS10KDDS2                84      /* control type: command, callback function: CB_OnPlus10k */
-#define  PANEL_TEXTMSG_11                 85      /* control type: textMsg, callback function: (none) */
-#define  PANEL_MATHSTRING5                86      /* control type: textBox, callback function: CB_ChangeMath */
-#define  PANEL_SPLITTER_8                 87      /* control type: splitter, callback function: (none) */
-#define  PANEL_MJD                        88      /* control type: numeric, callback function: (none) */
-#define  PANEL_UTC                        89      /* control type: numeric, callback function: (none) */
-#define  PANEL_TIME                       90      /* control type: string, callback function: (none) */
-#define  PANEL_DATE                       91      /* control type: string, callback function: (none) */
-#define  PANEL_SPLITTER_14                92      /* control type: splitter, callback function: (none) */
-#define  PANEL_SPLITTER_13                93      /* control type: splitter, callback function: (none) */
-#define  PANEL_DDS4                       94      /* control type: numeric, callback function: CB_ChangeDDSOut */
-#define  PANEL_SPLITTER_2                 95      /* control type: splitter, callback function: (none) */
-#define  PANEL_DDS3                       96      /* control type: numeric, callback function: CB_ChangeDDSOut */
-#define  PANEL_N1CALCULUS                 97      /* control type: command, callback function: CB_OnNCalculus */
-#define  PANEL_FINDSIGN3                  98      /* control type: command, callback function: CB_OnFindSign */
-#define  PANEL_SIGN3                      99      /* control type: numeric, callback function: (none) */
-#define  PANEL_FINDSIGN2                  100     /* control type: command, callback function: CB_OnFindSign */
-#define  PANEL_SIGN2                      101     /* control type: numeric, callback function: (none) */
-#define  PANEL_FINDSIGN1                  102     /* control type: command, callback function: CB_OnFindSign */
-#define  PANEL_SIGN1                      103     /* control type: numeric, callback function: (none) */
-#define  PANEL_FIND10K3                   104     /* control type: command, callback function: CB_OnFind275K */
-#define  PANEL_FIND275K2                  105     /* control type: command, callback function: CB_OnFind275K */
-#define  PANEL_RESETSLOPE                 106     /* control type: command, callback function: CB_OnResetSlope */
-#define  PANEL_CHECKBOX_STOPIFAUTODE      107     /* control type: radioButton, callback function: CB_OnStopSlopeCancellingOnUnlocked */
-#define  PANEL_CHECKBOX_RECENTER          108     /* control type: radioButton, callback function: CB_OnReCentering */
-#define  PANEL_CHECKBOX_KEEPSLOPE         109     /* control type: radioButton, callback function: CB_OnCROX */
-#define  PANEL_CHECKBOX_KEEP              110     /* control type: radioButton, callback function: CB_OnCROX */
-#define  PANEL_SLOPE_REFERENCE            111     /* control type: ring, callback function: CB_OnSlopeReference */
-#define  PANEL_ESTIMATE_N3                112     /* control type: command, callback function: CB_OnEstimateN */
-#define  PANEL_INVERT_SLOPE_SIGN          113     /* control type: radioButton, callback function: CB_InvertSlopeSign */
-#define  PANEL_MEASURE_SLOPE              114     /* control type: LED, callback function: CB_MeasureSlope */
-#define  PANEL_SLOPE_MEASURED             115     /* control type: numeric, callback function: (none) */
-#define  PANEL_RESET_DEDRIFT_DDS          116     /* control type: command, callback function: CB_ResetDedriftDDS */
-#define  PANEL_SHOWLOG                    117     /* control type: command, callback function: CB_ShowLog */
+#define  PANEL_DDS2                       20      /* control type: numeric, callback function: CB_ChangeDDSOut */
+#define  PANEL_TEXTMSG                    21      /* control type: textMsg, callback function: (none) */
+#define  PANEL_TEXTMSG_2                  22      /* control type: textMsg, callback function: (none) */
+#define  PANEL_SLOPETIME                  23      /* control type: numeric, callback function: CB_ChangeSlopeTime */
+#define  PANEL_DDS1                       24      /* control type: numeric, callback function: CB_ChangeDDSOut */
+#define  PANEL_SPLITTER                   25      /* control type: splitter, callback function: (none) */
+#define  PANEL_CHANGENDIV                 26      /* control type: numeric, callback function: CB_OnChangeNdiv */
+#define  PANEL_N3CHOICE                   27      /* control type: numeric, callback function: CB_ChangeN */
+#define  PANEL_N3CALCULUS                 28      /* control type: command, callback function: CB_OnNCalculus */
+#define  PANEL_N1CHOICE                   29      /* control type: numeric, callback function: CB_ChangeN */
+#define  PANEL_N2CHOICE                   30      /* control type: numeric, callback function: CB_ChangeN */
+#define  PANEL_N2CALCULUS                 31      /* control type: command, callback function: CB_OnNCalculus */
+#define  PANEL_DDS4STEP                   32      /* control type: ring, callback function: CB_ChangeDDSStep */
+#define  PANEL_DDS3STEP                   33      /* control type: ring, callback function: CB_ChangeDDSStep */
+#define  PANEL_DDS2STEP                   34      /* control type: ring, callback function: CB_ChangeDDSStep */
+#define  PANEL_CENTERFREQUENCY            35      /* control type: numeric, callback function: (none) */
+#define  PANEL_SLOPE_APPLIED              36      /* control type: numeric, callback function: CB_SetSlope */
+#define  PANEL_MATH4                      37      /* control type: numeric, callback function: (none) */
+#define  PANEL_MATH5                      38      /* control type: numeric, callback function: (none) */
+#define  PANEL_MATH3                      39      /* control type: numeric, callback function: (none) */
+#define  PANEL_CHECKBOX_MATH5PLOT         40      /* control type: radioButton, callback function: CB_OnFreqPlot */
+#define  PANEL_CHECKBOX_MATH4PLOT         41      /* control type: radioButton, callback function: CB_OnFreqPlot */
+#define  PANEL_CHECKBOX_MATH4ALLAN        42      /* control type: radioButton, callback function: CB_OnAllanPlot */
+#define  PANEL_DDS1STEP                   43      /* control type: ring, callback function: CB_ChangeDDSStep */
+#define  PANEL_TEXTMSG_15                 44      /* control type: textMsg, callback function: (none) */
+#define  PANEL_CHECKBOX_MATH5ALLAN        45      /* control type: radioButton, callback function: CB_OnAllanPlot */
+#define  PANEL_CHECKBOX_MATH3PLOT         46      /* control type: radioButton, callback function: CB_OnFreqPlot */
+#define  PANEL_CHECKBOX_MATH5SAVE         47      /* control type: radioButton, callback function: (none) */
+#define  PANEL_CHECKBOX_MATH4SAVE         48      /* control type: radioButton, callback function: (none) */
+#define  PANEL_CHECKBOX_MATH3ALLAN        49      /* control type: radioButton, callback function: CB_OnAllanPlot */
+#define  PANEL_MATHSTRING4                50      /* control type: string, callback function: CB_ChangeMath */
+#define  PANEL_TEXTMSG_17                 51      /* control type: textMsg, callback function: (none) */
+#define  PANEL_MATH2                      52      /* control type: numeric, callback function: (none) */
+#define  PANEL_SPLITTER_15                53      /* control type: splitter, callback function: (none) */
+#define  PANEL_SPLITTER_12                54      /* control type: splitter, callback function: (none) */
+#define  PANEL_CHECKBOX_MATH2PLOT         55      /* control type: radioButton, callback function: CB_OnFreqPlot */
+#define  PANEL_CHECKBOX_MATH3SAVE         56      /* control type: radioButton, callback function: (none) */
+#define  PANEL_CHECKBOX_MATH2SAVE         57      /* control type: radioButton, callback function: (none) */
+#define  PANEL_CHECKBOX_MATH2ALLAN        58      /* control type: radioButton, callback function: CB_OnAllanPlot */
+#define  PANEL_TEXTMSG_7                  59      /* control type: textMsg, callback function: (none) */
+#define  PANEL_MATHSTRING3                60      /* control type: string, callback function: CB_ChangeMath */
+#define  PANEL_MATH1                      61      /* control type: numeric, callback function: (none) */
+#define  PANEL_SPLITTER_6                 62      /* control type: splitter, callback function: (none) */
+#define  PANEL_TEXTMSG_18                 63      /* control type: textMsg, callback function: (none) */
+#define  PANEL_TEXTMSG_6                  64      /* control type: textMsg, callback function: (none) */
+#define  PANEL_TEXTMSG_8                  65      /* control type: textMsg, callback function: (none) */
+#define  PANEL_TEXTMSG_19                 66      /* control type: textMsg, callback function: (none) */
+#define  PANEL_MATHSTRING1                67      /* control type: string, callback function: CB_ChangeMath */
+#define  PANEL_TEXTMSG_9                  68      /* control type: textMsg, callback function: (none) */
+#define  PANEL_TEXTMSG_10                 69      /* control type: textMsg, callback function: (none) */
+#define  PANEL_MATHSTRING2                70      /* control type: string, callback function: CB_ChangeMath */
+#define  PANEL_TEXTMSG_16                 71      /* control type: textMsg, callback function: (none) */
+#define  PANEL_SPLITTER_11                72      /* control type: splitter, callback function: (none) */
+#define  PANEL_SPLITTER_16                73      /* control type: splitter, callback function: (none) */
+#define  PANEL_SPLITTER_9                 74      /* control type: splitter, callback function: (none) */
+#define  PANEL_SPLITTER_3                 75      /* control type: splitter, callback function: (none) */
+#define  PANEL_MINUS10KDDS1               76      /* control type: command, callback function: CB_OnMinus10k */
+#define  PANEL_MINUS10KDDS4               77      /* control type: command, callback function: CB_OnMinus10k */
+#define  PANEL_MINUS10KDDS3               78      /* control type: command, callback function: CB_OnMinus10k */
+#define  PANEL_MINUS10KDDS2               79      /* control type: command, callback function: CB_OnMinus10k */
+#define  PANEL_PLUS10KDDS4                80      /* control type: command, callback function: CB_OnPlus10k */
+#define  PANEL_PLUS10KDDS3                81      /* control type: command, callback function: CB_OnPlus10k */
+#define  PANEL_PLUS10KDDS1                82      /* control type: command, callback function: CB_OnPlus10k */
+#define  PANEL_PLUS10KDDS2                83      /* control type: command, callback function: CB_OnPlus10k */
+#define  PANEL_TEXTMSG_11                 84      /* control type: textMsg, callback function: (none) */
+#define  PANEL_MATHSTRING5                85      /* control type: textBox, callback function: CB_ChangeMath */
+#define  PANEL_SPLITTER_8                 86      /* control type: splitter, callback function: (none) */
+#define  PANEL_UTC                        87      /* control type: numeric, callback function: (none) */
+#define  PANEL_TIME                       88      /* control type: string, callback function: (none) */
+#define  PANEL_SPLITTER_14                89      /* control type: splitter, callback function: (none) */
+#define  PANEL_SPLITTER_13                90      /* control type: splitter, callback function: (none) */
+#define  PANEL_DDS4                       91      /* control type: numeric, callback function: CB_ChangeDDSOut */
+#define  PANEL_SPLITTER_2                 92      /* control type: splitter, callback function: (none) */
+#define  PANEL_DDS3                       93      /* control type: numeric, callback function: CB_ChangeDDSOut */
+#define  PANEL_N1CALCULUS                 94      /* control type: command, callback function: CB_OnNCalculus */
+#define  PANEL_FINDSIGN3                  95      /* control type: command, callback function: CB_OnFindSign */
+#define  PANEL_SIGN3                      96      /* control type: numeric, callback function: (none) */
+#define  PANEL_FINDSIGN2                  97      /* control type: command, callback function: CB_OnFindSign */
+#define  PANEL_SIGN2                      98      /* control type: numeric, callback function: (none) */
+#define  PANEL_FINDSIGN1                  99      /* control type: command, callback function: CB_OnFindSign */
+#define  PANEL_SIGN1                      100     /* control type: numeric, callback function: (none) */
+#define  PANEL_FIND10K3                   101     /* control type: command, callback function: CB_OnFind275K */
+#define  PANEL_FIND275K2                  102     /* control type: command, callback function: CB_OnFind275K */
+#define  PANEL_RESETSLOPE                 103     /* control type: command, callback function: CB_OnResetSlope */
+#define  PANEL_CHECKBOX_STOPIFAUTODE      104     /* control type: radioButton, callback function: CB_OnStopSlopeCancellingOnUnlocked */
+#define  PANEL_CHECKBOX_RECENTER          105     /* control type: radioButton, callback function: CB_OnReCentering */
+#define  PANEL_CHECKBOX_KEEPSLOPE         106     /* control type: radioButton, callback function: CB_OnCROX */
+#define  PANEL_CHECKBOX_KEEP              107     /* control type: radioButton, callback function: CB_OnCROX */
+#define  PANEL_SLOPE_REFERENCE            108     /* control type: ring, callback function: CB_OnSlopeReference */
+#define  PANEL_ESTIMATE_N3                109     /* control type: command, callback function: CB_OnEstimateN */
+#define  PANEL_INVERT_SLOPE_SIGN          110     /* control type: radioButton, callback function: CB_InvertSlopeSign */
+#define  PANEL_MEASURE_SLOPE              111     /* control type: LED, callback function: CB_MeasureSlope */
+#define  PANEL_SLOPE_MEASURED             112     /* control type: numeric, callback function: (none) */
+#define  PANEL_RESET_DEDRIFT_DDS          113     /* control type: command, callback function: CB_ResetDedriftDDS */
+#define  PANEL_SHOWLOG                    114     /* control type: command, callback function: CB_ShowLog */
 
 
      /* Menu Bars, Menus, and Menu Items: */
@@ -192,7 +189,6 @@
 int  CVICALLBACK CB_OnStartNCalculus(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
 int  CVICALLBACK CB_OnStop(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
 int  CVICALLBACK CB_OnStopSlopeCancellingOnUnlocked(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
-int  CVICALLBACK CB_OnTimer(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
 int  CVICALLBACK CB_ResetDedriftDDS(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
 int  CVICALLBACK CB_SetSlope(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
 int  CVICALLBACK CB_ShowLog(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
Binary file FXAnalyse.uir has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fake-data-provider.c	Thu Mar 21 18:24:45 2013 +0100
@@ -0,0 +1,35 @@
+/* FXAnalise fake data provider */
+
+#include <userint.h>
+#include <utility.h>
+
+/* data acquisition flag */
+extern int acquiring;
+/* data queue */
+extern CmtTSQHandle dataQueue;
+
+int CVICALLBACK FakeDataProvider (void *functionData)
+{
+	int mainThreadId;
+	double mark;
+	double data[5] = {0.0, 10000.0, 2.0, 3.0, 4.0};
+	
+	/* get main thread id to post messages to it */
+	mainThreadId = CmtGetMainThreadID();
+	
+	while (acquiring) {
+   		mark = Timer();
+		
+		/* update data */
+		GetCurrentDateTime(&data[0]);
+		data[1] = data[1] + 0.1;
+		
+		/* push data into the data queue */
+		CmtWriteTSQData(dataQueue, data, 5, TSQ_INFINITE_TIMEOUT, 0);
+		
+		/* wait till next second */
+   		SyncWait(mark, 1.00);
+	}
+	
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/file-data-provider.c	Thu Mar 21 18:24:45 2013 +0100
@@ -0,0 +1,121 @@
+/* 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;
+}