Mercurial > ~darius > hgwebdir.cgi > stm32temp
comparison 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 |
comparison
equal
deleted
inserted
replaced
56:f0563086040d | 57:adc9b1555f9d |
---|---|
35 #include <sys/time.h> | 35 #include <sys/time.h> |
36 #include <time.h> | 36 #include <time.h> |
37 #include "stm32f10x.h" | 37 #include "stm32f10x.h" |
38 | 38 |
39 #include "1wire.h" | 39 #include "1wire.h" |
40 #include "ff.h" | |
40 #include "flash.h" | 41 #include "flash.h" |
41 #include "tempctrl.h" | 42 #include "tempctrl.h" |
42 | 43 |
43 /* Holds all the settings needed */ | 44 /* Holds all the settings needed */ |
44 typedef struct { | 45 typedef struct { |
76 uint8_t heatinv; | 77 uint8_t heatinv; |
77 | 78 |
78 /* Check/stale times */ | 79 /* Check/stale times */ |
79 int16_t check_interval; | 80 int16_t check_interval; |
80 int16_t stale_factor; | 81 int16_t stale_factor; |
82 | |
83 char logfilefmt[64]; | |
81 | 84 |
82 uint8_t pad[1]; /* Pad to multiple of 4 bytes */ | 85 uint8_t pad[1]; /* Pad to multiple of 4 bytes */ |
83 } settings_t; | 86 } settings_t; |
84 | 87 |
85 /* Current settings in RAM */ | 88 /* Current settings in RAM */ |
105 .heatport = 'E', | 108 .heatport = 'E', |
106 .heatpin = 5, | 109 .heatpin = 5, |
107 .heatinv = 1, | 110 .heatinv = 1, |
108 .check_interval = 10, | 111 .check_interval = 10, |
109 .stale_factor = 3, | 112 .stale_factor = 3, |
113 .logfilefmt = "/%Y%M%D.log" | |
110 }; | 114 }; |
111 | 115 |
112 /* Local variable declarations */ | 116 /* Local variable declarations */ |
113 | 117 |
114 /* Local function prototypes */ | 118 /* Local function prototypes */ |
115 static void tempctrl_load_or_init_settings(void); | 119 static void tempctrl_load_or_init_settings(void); |
116 static void tempctrl_default_settings(void); | 120 static void tempctrl_default_settings(void); |
117 static void tempctrl_write_settings(void); | 121 static void tempctrl_write_settings(void); |
118 static void setstate(char state); | 122 static void setstate(char state); |
119 static const char * state2long(char s); | 123 static const char * state2long(char s); |
120 static void printtemp(const char *name, int tmp, const char *trailer); | 124 static int fmttemp(char *buf, const char *name, int tmp, const char *trailer); |
121 static GPIO_TypeDef *char2port(char port); | 125 static GPIO_TypeDef *char2port(char port); |
122 | 126 |
123 /* | 127 /* |
124 * tempctrl_init | 128 * tempctrl_init |
125 * | 129 * |
160 char nextstate; | 164 char nextstate; |
161 int forced; | 165 int forced; |
162 int stale; | 166 int stale; |
163 time_t t; | 167 time_t t; |
164 struct tm tm; | 168 struct tm tm; |
165 char buf[23]; | 169 char linebuf[90], *p; |
170 FRESULT fserr; | |
171 FIL f; | |
172 char fbuf[20]; | |
166 | 173 |
167 t = time(NULL); | 174 t = time(NULL); |
175 stale = 0; | |
176 tempt = 0; | |
168 | 177 |
169 /* Time to check temperatures? */ | 178 /* Time to check temperatures? */ |
170 if (t < checktime) | 179 if (t < checktime) |
171 return; | 180 return; |
172 | 181 |
194 } | 203 } |
195 | 204 |
196 /* Check for stale data */ | 205 /* Check for stale data */ |
197 if (lastdata + (settings.check_interval * settings.stale_factor) < t) | 206 if (lastdata + (settings.check_interval * settings.stale_factor) < t) |
198 stale = 1; | 207 stale = 1; |
199 else | |
200 stale = 0; | |
201 | 208 |
202 /* Default to remaining as we are */ | 209 /* Default to remaining as we are */ |
203 nextstate = '-'; | 210 nextstate = '-'; |
204 | 211 |
205 /* Temperature diff, -ve => too cold, +ve => too warm */ | 212 /* Temperature diff, -ve => too cold, +ve => too warm */ |
280 currstate = nextstate; | 287 currstate = nextstate; |
281 | 288 |
282 | 289 |
283 if (settings.mode != TC_MODE_NOTHING) { | 290 if (settings.mode != TC_MODE_NOTHING) { |
284 localtime_r(&t, &tm); | 291 localtime_r(&t, &tm); |
285 assert(strftime(buf, sizeof(buf) - 1, "%Y/%m/%d %H:%M:%S: ", &tm) != 0); | 292 p = linebuf; |
286 fputs(buf, stdout); | 293 p += strftime(p, sizeof(linebuf) - 1, "%Y/%m/%d %H:%M:%S: ", &tm); |
287 printtemp("Tr", settings.target_temp, ", "); | 294 p += fmttemp(p, "Tr", settings.target_temp, ", "); |
288 printtemp("Fm", tempt, ", "); // Use actual value from sensor | 295 p += fmttemp(p, "Fm", tempt, ", "); |
289 printtemp("Fr", fridge_temp, ", "); | 296 p += fmttemp(p, "Fr", fridge_temp, ", "); |
290 printtemp("Am", ambient_temp, ", "); | 297 p += fmttemp(p, "Am", ambient_temp, ", "); |
291 printf("St: %s, Fl: %s%s\r\n", state2long(currstate), | 298 sprintf(p, "St: %s, Fl: %s%s\r\n", state2long(currstate), |
292 forced ? "F" : "", | 299 forced ? "F" : "", |
293 stale ? "S" : ""); | 300 stale ? "S" : ""); |
294 } | 301 fputs(linebuf, stdout); |
295 | 302 if (settings.logfilefmt[0] != '\0') { |
303 strftime(fbuf, sizeof(fbuf) - 1, settings.logfilefmt, &tm); | |
304 | |
305 if ((fserr = f_open(&f, fbuf, FA_WRITE | FA_OPEN_ALWAYS)) != FR_OK) { | |
306 printf("Failed to open file: %d\n", fserr); | |
307 goto openerr; | |
308 } | |
309 | |
310 if ((fserr = f_lseek(&f, f_size(&f))) != FR_OK) { | |
311 printf("Failed to seek to end of file: %d\n", fserr); | |
312 goto openerr; | |
313 } | |
314 | |
315 f_puts(linebuf, &f); | |
316 f_close(&f); | |
317 } | |
318 } | |
319 | |
320 openerr: | |
296 setstate(currstate); | 321 setstate(currstate); |
297 } | 322 } |
298 | 323 |
299 /* | 324 /* |
300 * Print out temperature (or short error code) with specified trailer | 325 * Format a temperature (or short error code) with specified trailer |
301 */ | 326 */ |
302 static void | 327 static int |
303 printtemp(const char *name, int tmp, const char *trailer) { | 328 fmttemp(char *buf, const char *name, int tmp, const char *trailer) { |
304 if (tmp > OW_TEMP_BADVAL) | 329 if (tmp > OW_TEMP_BADVAL) |
305 printf("%s: %d.%02d%s", name, GETWHOLE(tmp), GETFRAC(tmp), trailer); | 330 return sprintf(buf, "%s: %d.%02d%s", name, GETWHOLE(tmp), GETFRAC(tmp), trailer); |
306 else | 331 else |
307 printf("%s: %s%s", name, OWTempStatusStr(tmp, 1), trailer); | 332 return sprintf(buf, "%s: %s%s", name, OWTempStatusStr(tmp, 1), trailer); |
308 } | 333 } |
309 | 334 |
310 /* Read the settings from SPI flash | 335 /* Read the settings from SPI flash |
311 * If the CRC fails then reload from onboard flash | 336 * If the CRC fails then reload from onboard flash |
312 */ | 337 */ |
431 "Ambient ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" | 456 "Ambient ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" |
432 "Mode - %c, Target - %d, Hystersis - %d\r\n" | 457 "Mode - %c, Target - %d, Hystersis - %d\r\n" |
433 "Min heat overshoot - %d, Min cool overshoot - %d\r\n" | 458 "Min heat overshoot - %d, Min cool overshoot - %d\r\n" |
434 "Min cool on time - %d, Min cool off time - %d\r\n" | 459 "Min cool on time - %d, Min cool off time - %d\r\n" |
435 "Min heat on time - %d, Min heat off time - %d\r\n" | 460 "Min heat on time - %d, Min heat off time - %d\r\n" |
436 "Cool: Port %c Pin %d Inv %d, Heat: Port %c Pin %d Inv %d\r\n", | 461 "Cool: Port %c Pin %d Inv %d, Heat: Port %c Pin %d Inv %d\r\n" |
462 "Log format: %s\n", | |
437 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], | 463 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], |
438 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], | 464 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], |
439 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], | 465 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], |
440 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], | 466 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], |
441 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], | 467 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], |
443 settings.mode, settings.target_temp, settings.hysteresis, | 469 settings.mode, settings.target_temp, settings.hysteresis, |
444 settings.minheatovershoot, settings.mincoolovershoot, | 470 settings.minheatovershoot, settings.mincoolovershoot, |
445 settings.mincoolontime, settings.minheatontime, | 471 settings.mincoolontime, settings.minheatontime, |
446 settings.minheatontime, settings.minheatofftime, | 472 settings.minheatontime, settings.minheatofftime, |
447 settings.coolport, settings.coolpin, settings.coolinv, | 473 settings.coolport, settings.coolpin, settings.coolinv, |
448 settings.heatport, settings.heatpin, settings.heatinv | 474 settings.heatport, settings.heatpin, settings.heatinv, |
475 settings.logfilefmt[0] == '\0' ? "none" : settings.logfilefmt | |
449 ); | 476 ); |
450 return; | 477 return; |
451 } | 478 } |
452 if (!strcasecmp(argv[0], "mode")) { | 479 if (!strcasecmp(argv[0], "mode")) { |
453 if (argc < 2) { | 480 if (argc < 2) { |
490 if (!strcasecmp(argv[0], "amb")) | 517 if (!strcasecmp(argv[0], "amb")) |
491 memcpy(&settings.ambient_ROM, ROM, sizeof(ROM)); | 518 memcpy(&settings.ambient_ROM, ROM, sizeof(ROM)); |
492 } | 519 } |
493 return; | 520 return; |
494 } | 521 } |
522 if (!strcasecmp(argv[0], "log")) { | |
523 if (argc == 1) | |
524 bzero(settings.logfilefmt, sizeof(settings.logfilefmt)); | |
525 else { | |
526 if (strlen(argv[1]) > sizeof(settings.logfilefmt) - 1) | |
527 printf("New path too log (%d > %d)\n", strlen(argv[1]), sizeof(settings.logfilefmt)); | |
528 else | |
529 strcpy(settings.logfilefmt, argv[1]); | |
530 return; | |
531 } | |
532 } | |
495 | 533 |
496 /* Handle setting the multitude of variables | 534 /* Handle setting the multitude of variables |
497 * It's last to simplify things */ | 535 * It's last to simplify things */ |
498 if (argc < 3) { | 536 if (argc < 3) { |
499 fputs("Incorrect number of arguments for variable/value\r\n", stdout); | 537 fputs("Incorrect number of arguments for variable/value\r\n", stdout); |
568 return GPIOC; | 606 return GPIOC; |
569 case 'D': | 607 case 'D': |
570 return GPIOD; | 608 return GPIOD; |
571 case 'E': | 609 case 'E': |
572 return GPIOE; | 610 return GPIOE; |
573 } | 611 default: |
574 } | 612 assert(1 == 0); /* Silence GCC warning */ |
575 | 613 } |
614 } | |
615 |