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 */
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;
TCCR1A = 0;
TCCR1B = 1;
TIMSK1 = 1;
+ OCR2A = 16;
+ TCCR2A = 2;
+ TCCR2B = 4;
+ TIMSK2 = 2;
/*
* B0..2 = Pulse sensor
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)
int main(void)
{
- int state, cur;
+ int state, cur, run;
unsigned long utime;
state = 0;
- cur = 99;
+ cur = 100;
+ run = 0;
init();
sei();
display(0);
while(1) {
mnow = getticks();
- ledcycle();
tempcycle();
calcavg();
convcycle();
dsp[0] = dsp[1] = SEGG;
}
}
- 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;
}
+ if(run)
+ dsp[1] |= SEGP;
+ else
+ dsp[1] &= ~SEGP;
} 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;
+ if(cur < 100)
+ display(cur);
+ else
+ dsp[0] = dsp[1] = SEGG;
utime = mnow;
}
- if(mnow - utime > 1000000) {
+ if(mnow - utime > 1000000)
state = 0;
- }
if(sstate == 2) {
- tron = !tron;
+ run = !run;
sstate = 0;
}
} else if(state == 2) {
+ /* Display raw temp time reading */
if(ttimea < 20000) {
display((ttimea / 100) % 100);
dsp[0] |= SEGP;
sstate = 0;
}
}
+ /*
+ * Set Triac to match temperature
+ */
+ if(run) {
+ if(tempk - 273 < cur) {
+ tron = 1;
+ if(cur - (tempk - 273) > 5) {
+ /* For some reason, the Triac currently doesn't
+ * trigger on one of the AC half-cycles below 0.7
+ * ms. */
+ trdelay = 7;
+ } else if(cur - (tempk - 273) >= 3) {
+ trdelay = 20;
+ } else if(cur - (tempk - 273) >= 2) {
+ trdelay = 40;
+ } else {
+ trdelay = 70;
+ }
+ } else {
+ tron = 0;
+ }
+ } else {
+ tron = 0;
+ }
#endif
/*
dsp[0] = bindisp((ttimea & 0xff00) >> 8);
}
}
+ISR(SIG_OUTPUT_COMPARE2A)
+{
+ ledcycle();
+}
+
ISR(SIG_OVERFLOW1)
{
- of = 1;
oticks++;
}