comparison tempctrl.c @ 54:58f1ec46bff6

Add a beeper when the data is stale (only when USB is disabled as they share a pin) Move the time of day timer to OCR2 so we can use PB3/OC0 for PWM.
author darius@Inchoate
date Wed, 29 Oct 2008 17:41:04 +1030
parents cb184206344d
children 6b1057409d9a
comparison
equal deleted inserted replaced
53:98b5a43fc748 54:58f1ec46bff6
50 uint8_t fermenter_ROM[8]; 50 uint8_t fermenter_ROM[8];
51 uint8_t fridge_ROM[8]; 51 uint8_t fridge_ROM[8];
52 uint8_t ambient_ROM[8]; 52 uint8_t ambient_ROM[8];
53 int16_t target_temp; 53 int16_t target_temp;
54 uint16_t hysteresis; 54 uint16_t hysteresis;
55
56 /* How much to under/overshoot on heating/cooling */ 55 /* How much to under/overshoot on heating/cooling */
57 int16_t minheatovershoot; 56 int16_t minheatovershoot;
58 int16_t mincoolovershoot; 57 int16_t mincoolovershoot;
59 58
60 /* Minimum time the cooler can be on/off */ 59 /* Minimum time the cooler can be on/off */
78 uint8_t idlebits; 77 uint8_t idlebits;
79 78
80 /* Check/stale times */ 79 /* Check/stale times */
81 int16_t check_interval; 80 int16_t check_interval;
82 int16_t stale_factor; 81 int16_t stale_factor;
82
83 /* Beep if stale */
84 int8_t dobeep;
83 } __attribute__((packed)) settings_t; 85 } __attribute__((packed)) settings_t;
84 86
85 /* Current settings in RAM */ 87 /* Current settings in RAM */
86 static settings_t settings; 88 static settings_t settings;
87 89
107 .mode = TC_MODE_IDLE, 109 .mode = TC_MODE_IDLE,
108 .coolbits = _BV(6), 110 .coolbits = _BV(6),
109 .heatbits = _BV(7), 111 .heatbits = _BV(7),
110 .idlebits = 0x00, 112 .idlebits = 0x00,
111 .check_interval = 10, 113 .check_interval = 10,
112 .stale_factor = 3 114 .stale_factor = 3,
115 .dobeep = 1
113 }; 116 };
114 117
115 /* Local variable declarations */ 118 /* Local variable declarations */
116 volatile static time_t now; 119 volatile static time_t now;
120 #ifndef WITHUSB
121 volatile static uint8_t beeping = 0;
122 volatile static uint8_t lasttoggle = 0;
123 #endif
117 124
118 /* Local function prototypes */ 125 /* Local function prototypes */
119 static void tempctrl_load_or_init_settings(void); 126 static void tempctrl_load_or_init_settings(void);
120 static void tempctrl_default_settings(void); 127 static void tempctrl_default_settings(void);
121 static void tempctrl_write_settings(void); 128 static void tempctrl_write_settings(void);
133 tempctrl_init(void) { 140 tempctrl_init(void) {
134 /* Setup timer */ 141 /* Setup timer */
135 /* 16Mhz / 1024 = 15625 Hz / 125 = 125 Hz = IRQ every 8 ms */ 142 /* 16Mhz / 1024 = 15625 Hz / 125 = 125 Hz = IRQ every 8 ms */
136 143
137 /* CTC mode, no output on pin, Divide clock by 1024 */ 144 /* CTC mode, no output on pin, Divide clock by 1024 */
138 TCCR0 = _BV(WGM01)| _BV(CS02) | _BV(CS00); 145 TCCR2 = _BV(WGM21)| _BV(CS22) | _BV(CS21) | _BV(CS20);
139 146
140 /* Compare with ... */ 147 /* Compare with ... */
141 OCR0 = 125; 148 OCR2 = 125;
142 149
143 /* Enable interrupt for match on A */ 150 /* Enable interrupt for match on A */
144 TIMSK = _BV(OCIE0); 151 TIMSK = _BV(OCIE2);
145 152
146 now.sec = 0; 153 now.sec = 0;
147 now.usec = 0; 154 now.usec = 0;
148 155
149 tempctrl_load_or_init_settings(); 156 tempctrl_load_or_init_settings();
150 } 157 }
151 158
152 /* 159 /*
153 * Timer 0 Compare IRQ 160 * Timer 2 Compare IRQ
154 * 161 *
155 * Update time counter 162 * Update time counter
156 */ 163 */
157 164
158 ISR(TIMER0_COMP_vect) { 165 ISR(TIMER2_COMP_vect) {
159 wdt_reset(); 166 wdt_reset();
160 167
161 now.usec += 8000; /* 1000000 * 1 / F_CPU / 1024 / 125 */ 168 now.usec += 8000; /* 1000000 * 1 / F_CPU / 1024 / 125 */
162 while (now.usec > 1000000) { 169 while (now.usec > 1000000) {
163 now.usec -= 1000000; 170 now.usec -= 1000000;
164 now.sec++; 171 now.sec++;
165 } 172 }
173
174 #ifndef WITHUSB
175 if (beeping) {
176 lasttoggle++;
177 // 63 * 8ms = ~0.5s
178 if (lasttoggle > 63) {
179 DDRB ^= _BV(PB3);
180 lasttoggle = 0;
181 }
182 } else {
183 DDRB &= ~_BV(PB3);
184 lasttoggle = 0;
185 }
186 #endif
166 } 187 }
167 188
168 /* 189 /*
169 * tempctrl_update 190 * tempctrl_update
170 * 191 *
263 284
264 /* Override if we have stale data */ 285 /* Override if we have stale data */
265 if (stale) 286 if (stale)
266 nextstate = 'i'; 287 nextstate = 'i';
267 288
289 /* Handle beeping */
290 if (settings.dobeep && stale)
291 beeping = 1;
292 else
293 beeping = 0;
294
268 /* Handle state forcing */ 295 /* Handle state forcing */
269 if (settings.mode != TC_MODE_AUTO) 296 if (settings.mode != TC_MODE_AUTO)
270 forced = 1; 297 forced = 1;
271 else 298 else
272 forced = 0; 299 forced = 0;
437 " a Auto\r\n" 464 " a Auto\r\n"
438 " c Always cool\r\n" 465 " c Always cool\r\n"
439 " h Always heat\r\n" 466 " h Always heat\r\n"
440 " i Always idle\r\n" 467 " i Always idle\r\n"
441 " n Like idle but don't log anything\r\n" 468 " n Like idle but don't log anything\r\n"
469 #ifndef WITHUSB
470 "tc beep [01] Enable/disable beeping when data is stale\r\n"
471 #endif
442 "tc X Y Set X to Y where X is one of\r\n" 472 "tc X Y Set X to Y where X is one of\r\n"
443 " targ Target temperature\r\n" 473 " targ Target temperature\r\n"
444 " hys Hysteresis range\r\n" 474 " hys Hysteresis range\r\n"
445 " mhov Minimum heat overshoot\r\n" 475 " mhov Minimum heat overshoot\r\n"
446 " mcov Minimum cool overshoot\r\n" 476 " mcov Minimum cool overshoot\r\n"
475 "Fridge ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" 505 "Fridge ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
476 "Ambient ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" 506 "Ambient ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
477 "Mode - %c, Target - %d, Hystersis - %d\r\n" 507 "Mode - %c, Target - %d, Hystersis - %d\r\n"
478 "Min heat overshoot - %d, Min cool overshoot - %d\r\n" 508 "Min heat overshoot - %d, Min cool overshoot - %d\r\n"
479 "Min cool on time - %d, Min cool off time - %d\r\n" 509 "Min cool on time - %d, Min cool off time - %d\r\n"
480 "Min heat on time - %d, Min heat off time - %d\r\n"), 510 "Min heat on time - %d, Min heat off time - %d\r\n"
511 "Beep on stale - %S\r\n"),
481 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], 512 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3],
482 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], 513 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7],
483 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], 514 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3],
484 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], 515 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7],
485 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], 516 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3],
486 settings.ambient_ROM[4], settings.ambient_ROM[5], settings.ambient_ROM[6], settings.ambient_ROM[7], 517 settings.ambient_ROM[4], settings.ambient_ROM[5], settings.ambient_ROM[6], settings.ambient_ROM[7],
487 settings.mode, settings.target_temp, settings.hysteresis, 518 settings.mode, settings.target_temp, settings.hysteresis,
488 settings.minheatovershoot, settings.mincoolovershoot, 519 settings.minheatovershoot, settings.mincoolovershoot,
489 settings.mincoolontime, settings.minheatontime, 520 settings.mincoolontime, settings.minheatontime,
490 settings.minheatontime, settings.minheatofftime); 521 settings.minheatontime, settings.minheatofftime,
522 settings.dobeep ? PSTR("yes") : PSTR("no"));
491 return; 523 return;
492 } 524 }
493 if (!strcasecmp_P(cmd, PSTR("mode"))) { 525 if (!strcasecmp_P(cmd, PSTR("mode"))) {
494 switch (buf[8]) { 526 switch (buf[8]) {
495 case TC_MODE_AUTO: 527 case TC_MODE_AUTO:
502 534
503 default: 535 default:
504 printf_P(PSTR("Unknown mode character '%c'\r\n"), buf[8]); 536 printf_P(PSTR("Unknown mode character '%c'\r\n"), buf[8]);
505 break; 537 break;
506 } 538 }
539 return;
540 }
541 if (!strcasecmp_P(cmd, PSTR("beep"))) {
542 if (buf[8] == '1')
543 settings.dobeep = 1;
544 else if (buf[8] == '0')
545 settings.dobeep = 0;
546 else
547 printf_P(PSTR("Expected a 0 or 1\r\n"));
507 return; 548 return;
508 } 549 }
509 if (!strcasecmp_P(cmd, PSTR("ferm")) || 550 if (!strcasecmp_P(cmd, PSTR("ferm")) ||
510 !strcasecmp_P(cmd, PSTR("frg")) || 551 !strcasecmp_P(cmd, PSTR("frg")) ||
511 !strcasecmp_P(cmd, PSTR("amb"))) { 552 !strcasecmp_P(cmd, PSTR("amb"))) {