2 #include <avr/interrupt.h>
3 #include <avr/eeprom.h>
17 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF,
19 SEGA | SEGB | SEGD | SEGE | SEGG,
20 SEGA | SEGB | SEGC | SEGD | SEGG,
21 SEGB | SEGC | SEGF | SEGG,
22 SEGA | SEGC | SEGD | SEGF | SEGG,
23 SEGA | SEGC | SEGD | SEGE | SEGF | SEGG,
25 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG,
26 SEGA | SEGB | SEGC | SEGD | SEGF | SEGG,
27 SEGA | SEGB | SEGC | SEGE | SEGF | SEGG,
28 SEGC | SEGD | SEGE | SEGF | SEGG,
29 SEGA | SEGD | SEGE | SEGF,
30 SEGB | SEGC | SEGD | SEGE | SEGG,
31 SEGA | SEGD | SEGE | SEGF | SEGG,
32 SEGA | SEGE | SEGF | SEGG,
35 uint8_t dsp[2] = {0, 0};
39 volatile int oticks = 0;
42 volatile char pstate = 0;
45 volatile char sstate = 0;
48 volatile char tstate = 0;
49 volatile char tlock = 0;
52 unsigned long ttimea = 10000;
57 /* Zero-cross detector*/
58 volatile char zok = 0;
59 volatile char ztime = 0;
64 volatile char trdelay = 0;
69 * Timer 0 cycles the Triac
70 * Timer 1 is used for global timing
71 * Timer 2 cycles the LED display
86 * B0..2 = Pulse sensor
105 * D3 = NTC Op-amp (INT1)
115 unsigned char bindisp(unsigned char num)
139 void display(char num, char d0, char d1)
141 dsp[0] = font[(num / 10) % 10] | (d0?SEGP:0);
142 dsp[1] = font[num % 10] | (d1?SEGP:0);
145 void disphex(unsigned char num)
147 dsp[0] = font[(num & 0xf0) >> 4];
148 dsp[1] = font[num & 0x0f];
151 unsigned long getticks(void)
158 r = v + (((unsigned long)oticks) << 16);
159 if((TIFR1 & 0x01) && !(v & 0x8000))
174 if(dsp[ledc] & (1 << leda)) {
180 d = 0x10 << (leda - 6);
187 PORTD = (PORTD & 0x0f) | d;
193 if((PIND & 8) && (tlock == 0)) {
200 } else if(tstate == 1) {
201 if(mnow - tstart > 1000) {
215 ttimea = ((ttimea * 15) + ttime) >> 4;
223 static char state = 0;
224 static unsigned long last = 0;
225 static float a, ra, l, t;
229 * t = RC * ln(2) => R = t / (C * ln(2))
230 * R = A * exp(B / T) => T = B / ln(R / A)
231 * T = B / ln(t / (A * C * ln(2)))
233 * t = The measured time (s)
234 * R = The resistance of the thermistor (Ohm)
235 * C = The capacitance of the capacitor (F)
236 * T = The temperature (K)
237 * A, B are the thermistor-specific constants
239 * In the following code:
240 * a = ttimea as float
241 * C = 1e-6 / (A * C * ln(2))
245 * Note, temperature is in Kelvin
250 if((mnow - last > 200000) && tavgok) {
256 } else if(state == 1) {
259 } else if(state == 2) {
262 } else if(state == 3) {
265 } else if(state == 4) {
274 int state, cur, run, rstate, delta;
278 cur = eeprom_read_byte(0);
291 dsp[0] = dsp[1] = SEGG;
304 /* Display temperature */
307 if((tempk >= 273) && (tempk <= 372)) {
308 display(tempk - 273, 0, run);
311 dsp[1] = SEGG | (run?SEGP:0);
323 } else if(state == 1) {
334 if(mnow - utime > 2000000) {
336 eeprom_write_byte(0, cur);
343 display(cur, 0, run);
346 dsp[1] = SEGG | (run?SEGP:0);
348 } else if(state == 2) {
349 /* Display raw temp time reading */
351 display((ttimea / 100) % 100, 1, ttimea >= 10000);
353 display(ttimea / 1000, 0, 0);
361 * Set Triac to match temperature
364 delta = cur - (tempk - 273);
369 /* For some reason, the Triac currently doesn't
370 * trigger on one of the AC half-cycles below 0.7
374 trdelay = 75 - (delta * 5);
380 } else if(rstate == 1) {
390 dsp[0] = bindisp((ttimea & 0xff00) >> 8);
391 dsp[1] = bindisp(ttimea & 0x00ff);
394 disphex((ttimea & 0xff000) >> 12);
401 display((ttimea / 100) % 100);
406 display(ttimea / 1000);
445 Pulse counter display
483 ttime = now - tstart;
490 ISR(SIG_OUTPUT_COMPARE0A)
494 if(tron && (ztime >= trdelay)) {
499 } else if(trstate == 1) {
508 ISR(SIG_OUTPUT_COMPARE2A)
520 if((sstate == 0) && !(PINB & 4)) {
524 if((sstate == 1) && (PINB & 4)) {
525 stime = oticks - stime;
529 if((PINB & 2) == 0) {
531 } else if((PINB & 1) == 0) {
534 } else if(pstate == 1) {
535 if((PINB & 1) == 0) {
541 } else if(pstate == 2) {
542 if((PINB & 2) == 0) {
549 if((PINB & 2) && (PINB & 1))