X-Git-Url: http://dolda2000.com/gitweb/?p=kokare.git;a=blobdiff_plain;f=kokare.c;h=f7033d8d29b16e6067445fa70ca1436a5dce9089;hp=35e5a0107026c18432e2dee8413f50300a6f8941;hb=HEAD;hpb=c77327664d2a8fd272e91c2c99b8803ad123beb3 diff --git a/kokare.c b/kokare.c index 35e5a01..f7033d8 100644 --- a/kokare.c +++ b/kokare.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -31,12 +32,10 @@ uint8_t font[16] = { SEGA | SEGE | SEGF | SEGG, }; /* LED */ -#define LCDELAY 1000 uint8_t dsp[2] = {0, 0}; char leda = 0; char ledc = 0; /* Timer */ -volatile char of = 0; volatile int oticks = 0; unsigned long mnow; /* Pulse counter */ @@ -67,8 +66,9 @@ volatile char trdelay = 0; void init(void) { /* Timer init - * Timer 0 cycles timing sensitive subsystems + * Timer 0 cycles the Triac * Timer 1 is used for global timing + * Timer 2 cycles the LED display */ OCR0A = 100; TCCR0A = 2; @@ -77,6 +77,10 @@ void init(void) TCCR1A = 0; TCCR1B = 1; TIMSK1 = 1; + OCR2A = 16; + TCCR2A = 2; + TCCR2B = 4; + TIMSK2 = 2; /* * B0..2 = Pulse sensor @@ -132,10 +136,10 @@ unsigned char bindisp(unsigned char num) return(ret); } -void display(char num) +void display(char num, char d0, char d1) { - dsp[0] = font[(num / 10) % 10]; - dsp[1] = font[num % 10]; + dsp[0] = font[(num / 10) % 10] | (d0?SEGP:0); + dsp[1] = font[num % 10] | (d1?SEGP:0); } void disphex(unsigned char num) @@ -146,38 +150,41 @@ void disphex(unsigned char num) unsigned long getticks(void) { - return(TCNT1 + (((unsigned long)oticks) << 16)); + uint16_t v; + unsigned long r; + + cli(); + v = TCNT1; + r = v + (((unsigned long)oticks) << 16); + if((TIFR1 & 0x01) && !(v & 0x8000)) + r += 0x10000; + sei(); + return(r); } void ledcycle(void) { - static uint16_t last = 0; uint8_t c, d, v; - if(TCNT1 - last > LCDELAY) { - last = TCNT1; - if(++leda >= 8) { - leda = 0; - if(++ledc >= 2) - ledc = 0; - } - if(dsp[ledc] & (1 << leda)) { - if(leda < 6) { - c = 1 << leda; - d = 0; - } else { - c = 0; - d = 0x10 << (leda - 6); - } - d |= ledc?0x40:0x80; + if(++leda >= 8) { + leda = 0; + if(++ledc >= 2) + ledc = 0; + } + if(dsp[ledc] & (1 << leda)) { + if(leda < 6) { + c = 1 << leda; + d = 0; } else { - c = d = 0; + c = 0; + d = 0x10 << (leda - 6); } - cli(); - PORTC = c; - PORTD = (PORTD & 0x0f) | d; - sei(); + d |= ledc?0x40:0x80; + } else { + c = d = 0; } + PORTC = c; + PORTD = (PORTD & 0x0f) | d; } void tempcycle(void) @@ -221,16 +228,23 @@ void convcycle(void) * Theoretically: * t = RC * ln(2) => R = t / (C * ln(2)) * R = A * exp(B / T) => T = B / ln(R / A) - * T = B / ln(R / (A * C * ln(2))) - * In the following: + * T = B / ln(t / (A * C * ln(2))) + * Where: + * t = The measured time (s) + * R = The resistance of the thermistor (Ohm) + * C = The capacitance of the capacitor (F) + * T = The temperature (K) + * A, B are the thermistor-specific constants + * + * In the following code: * a = ttimea as float - * C = 1e6 / (A * C * ln(2)) + * C = 1e-6 / (A * C * ln(2)) * ra = a * C * l = ln(ra) * t = B / l * Note, temperature is in Kelvin */ -#define C 9.792934 +#define C 10.819112 /* A is 0.1333469 */ #define B 4020.0 if(state == 0) { if((mnow - last > 200000) && tavgok) { @@ -257,18 +271,27 @@ void convcycle(void) int main(void) { - int state, cur; + int state, cur, run, rstate, delta; unsigned long utime; - state = 0; - cur = 99; + state = 1; + cur = eeprom_read_byte(0); + if(cur < 0) + cur = 0; + if(cur > 100) + cur = 100; + run = 0; + rstate = 0; + utime = getticks(); init(); sei(); - display(0); + if(cur < 100) + display(cur, 0, 0); + else + dsp[0] = dsp[1] = SEGG; while(1) { mnow = getticks(); - ledcycle(); tempcycle(); calcavg(); convcycle(); @@ -282,57 +305,86 @@ int main(void) if(ktok) { ktok = 0; if((tempk >= 273) && (tempk <= 372)) { - display(tempk - 273); + display(tempk - 273, 0, run); } else { - dsp[0] = dsp[1] = SEGG; + dsp[0] = SEGG; + dsp[1] = SEGG | (run?SEGP:0); } } - if(pval != 0) { + if(pval != 0) state = 1; - utime = mnow; - } if(sstate == 2) { sstate = 0; - if(stime > 10) { + if(stime > 10) state = 2; - } else { - tron = !tron; - } + else + run = !run; } } else if(state == 1) { - /* Triac control */ + /* Temp setting */ if(pval != 0) { cur += pval; pval = 0; if(cur < 0) cur = 0; - if(cur > 99) - cur = 99; - display(cur); - trdelay = 99 - cur; + if(cur > 100) + cur = 100; utime = mnow; } - if(mnow - utime > 1000000) { + if(mnow - utime > 2000000) { state = 0; + eeprom_write_byte(0, cur); } if(sstate == 2) { - tron = !tron; + run = !run; sstate = 0; } + if(cur < 100) { + display(cur, 0, run); + } else { + dsp[0] = SEGG; + dsp[1] = SEGG | (run?SEGP:0); + } } else if(state == 2) { + /* Display raw temp time reading */ if(ttimea < 20000) { - display((ttimea / 100) % 100); - dsp[0] |= SEGP; - if(ttimea >= 10000) - dsp[1] |= SEGP; + display((ttimea / 100) % 100, 1, ttimea >= 10000); } else { - display(ttimea / 1000); + display(ttimea / 1000, 0, 0); } if(sstate == 2) { state = 0; sstate = 0; } } + /* + * Set Triac to match temperature + */ + if(run) { + delta = cur - (tempk - 273); + if(rstate == 0) { + if(delta > 0) { + tron = 1; + if(delta > 8) { + /* For some reason, the Triac currently doesn't + * trigger on one of the AC half-cycles below 0.7 + * ms. */ + trdelay = 7; + } else { + trdelay = 75 - (delta * 5); + } + } else { + tron = 0; + rstate = 1; + } + } else if(rstate == 1) { + tron = 0; + if(delta >= 2) + rstate = 0; + } + } else { + tron = 0; + } #endif /* dsp[0] = bindisp((ttimea & 0xff00) >> 8); @@ -453,9 +505,13 @@ ISR(SIG_OUTPUT_COMPARE0A) } } +ISR(SIG_OUTPUT_COMPARE2A) +{ + ledcycle(); +} + ISR(SIG_OVERFLOW1) { - of = 1; oticks++; }