# HG changeset patch # User Daniel O'Connor # Date 1365425440 -34200 # Node ID adc9b1555f9d786c642507cd254ef1eb1b51189a # Parent f0563086040d20b03e6f9829e792ada82690f74a Add the ability to log temperatures to SD card. Fix a few warnings while I am here. diff -r f0563086040d -r adc9b1555f9d main.c --- a/main.c Sun Apr 07 22:44:23 2013 +0930 +++ b/main.c Mon Apr 08 22:20:40 2013 +0930 @@ -94,7 +94,7 @@ if (!isprint(c)) continue; - cmd.buf[cmd.state] = tolower(c); + cmd.buf[cmd.state] = c; /* Echo back to the user */ comm_put(cmd.buf[cmd.state]); diff -r f0563086040d -r adc9b1555f9d tempctrl.c --- 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 */ } }