Mercurial > ~darius > hgwebdir.cgi > tempctrl
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"))) { |