diff tempctrl.c @ 57:adc9b1555f9d

Add the ability to log temperatures to SD card. Fix a few warnings while I am here.
author Daniel O'Connor <darius@dons.net.au>
date Mon, 08 Apr 2013 22:20:40 +0930
parents b4440f9f6d47
children bbdf5642a7b7
line wrap: on
line diff
--- a/tempctrl.c	Sun Apr 07 22:44:23 2013 +0930
+++ b/tempctrl.c	Mon Apr 08 22:20:40 2013 +0930
@@ -37,6 +37,7 @@
 #include "stm32f10x.h"
 
 #include "1wire.h"
+#include "ff.h"
 #include "flash.h"
 #include "tempctrl.h"
 
@@ -79,6 +80,8 @@
     int16_t	check_interval;
     int16_t	stale_factor;
 
+    char	logfilefmt[64];
+
     uint8_t	pad[1]; /* Pad to multiple of 4 bytes */
 } settings_t;
 
@@ -107,6 +110,7 @@
     .heatinv = 1,
     .check_interval = 10,
     .stale_factor = 3,
+    .logfilefmt = "/%Y%M%D.log"
 };
 
 /* Local variable declarations */
@@ -117,7 +121,7 @@
 static void		tempctrl_write_settings(void);
 static void		setstate(char state);
 static const char *	state2long(char s);
-static void		printtemp(const char *name, int tmp, const char *trailer);
+static int		fmttemp(char *buf, const char *name, int tmp, const char *trailer);
 static GPIO_TypeDef	*char2port(char port);
 
 /* 
@@ -162,9 +166,14 @@
     int			stale;
     time_t		t;
     struct tm		tm;
-    char		buf[23];
+    char		linebuf[90], *p;
+    FRESULT		fserr;
+    FIL			f;
+    char		fbuf[20];
     
     t = time(NULL);
+    stale = 0;
+    tempt = 0;
     
     /* Time to check temperatures? */
     if (t < checktime)
@@ -196,8 +205,6 @@
     /* Check for stale data */
     if (lastdata + (settings.check_interval * settings.stale_factor) < t)
 	stale = 1;
-    else
-	stale = 0;
 
     /* Default to remaining as we are */
     nextstate = '-';
@@ -282,29 +289,47 @@
     
     if (settings.mode != TC_MODE_NOTHING) {
 	localtime_r(&t, &tm);
-	assert(strftime(buf, sizeof(buf) - 1, "%Y/%m/%d %H:%M:%S: ", &tm) != 0);
-	fputs(buf, stdout);
-	printtemp("Tr", settings.target_temp, ", ");
-	printtemp("Fm", tempt, ", "); // Use actual value from sensor
-	printtemp("Fr", fridge_temp, ", ");
-	printtemp("Am", ambient_temp, ", ");
-	printf("St: %s, Fl: %s%s\r\n", state2long(currstate), 
-	       forced ? "F" : "", 
-	       stale ? "S" : "");
+	p = linebuf;
+	p += strftime(p, sizeof(linebuf) - 1, "%Y/%m/%d %H:%M:%S: ", &tm);
+	p += fmttemp(p, "Tr", settings.target_temp, ", ");
+	p += fmttemp(p, "Fm", tempt, ", ");
+	p += fmttemp(p, "Fr", fridge_temp, ", ");
+	p += fmttemp(p, "Am", ambient_temp, ", ");
+	sprintf(p, "St: %s, Fl: %s%s\r\n", state2long(currstate), 
+		forced ? "F" : "", 
+		stale ? "S" : "");
+	fputs(linebuf, stdout);
+	if (settings.logfilefmt[0] != '\0') {
+	    strftime(fbuf, sizeof(fbuf) - 1, settings.logfilefmt, &tm);
+	    
+	    if ((fserr = f_open(&f, fbuf, FA_WRITE | FA_OPEN_ALWAYS)) != FR_OK) {
+		printf("Failed to open file: %d\n", fserr);
+		goto openerr;
+	    }
+
+	    if ((fserr = f_lseek(&f, f_size(&f))) != FR_OK) {
+		printf("Failed to seek to end of file: %d\n", fserr);
+		goto openerr;
+	    }
+	
+	    f_puts(linebuf, &f);
+	    f_close(&f);
+	}
     }
 
+  openerr:
     setstate(currstate);
 }
 
 /*
- * Print out temperature (or short error code) with specified trailer
+ * Format a temperature (or short error code) with specified trailer
  */
-static void
-printtemp(const char *name, int tmp, const char *trailer) {
+static int
+fmttemp(char *buf, const char *name, int tmp, const char *trailer) {
     if (tmp > OW_TEMP_BADVAL)
-	printf("%s: %d.%02d%s", name, GETWHOLE(tmp), GETFRAC(tmp), trailer);
+	return sprintf(buf, "%s: %d.%02d%s", name, GETWHOLE(tmp), GETFRAC(tmp), trailer);
     else
-	printf("%s: %s%s", name, OWTempStatusStr(tmp, 1), trailer);
+	return sprintf(buf, "%s: %s%s", name, OWTempStatusStr(tmp, 1), trailer);
 }
 
 /* Read the settings from SPI flash
@@ -433,7 +458,8 @@
 	       "Min heat overshoot - %d, Min cool overshoot - %d\r\n"
 	       "Min cool on time - %d, Min cool off time - %d\r\n"
 	       "Min heat on time - %d, Min heat off time - %d\r\n"
-	       "Cool: Port %c Pin %d Inv %d, Heat: Port %c Pin %d Inv %d\r\n",
+	       "Cool: Port %c Pin %d Inv %d, Heat: Port %c Pin %d Inv %d\r\n"
+	       "Log format: %s\n",
 	       settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], 	
 	       settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], 	
 	       settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], 
@@ -445,7 +471,8 @@
 	       settings.mincoolontime, settings.minheatontime,
 	       settings.minheatontime, settings.minheatofftime,
 	       settings.coolport, settings.coolpin, settings.coolinv,
-	       settings.heatport, settings.heatpin, settings.heatinv
+	       settings.heatport, settings.heatpin, settings.heatinv,
+	       settings.logfilefmt[0] == '\0' ? "none" : settings.logfilefmt
 	    );
 	return;
     }
@@ -492,6 +519,17 @@
 	}
 	return;
     }
+    if (!strcasecmp(argv[0], "log")) {
+	if (argc == 1)
+	    bzero(settings.logfilefmt, sizeof(settings.logfilefmt));
+	else {
+	    if (strlen(argv[1]) > sizeof(settings.logfilefmt) - 1)
+		printf("New path too log (%d > %d)\n", strlen(argv[1]), sizeof(settings.logfilefmt));
+	    else
+		strcpy(settings.logfilefmt, argv[1]);
+	return;
+	}
+    }
     
     /* Handle setting the multitude of variables
      * It's last to simplify things */
@@ -570,6 +608,8 @@
 	    return GPIOD;
 	case 'E':
 	    return GPIOE;
+	default:
+	    assert(1 == 0); /* Silence GCC warning */
     }
 }