#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
+#include <math.h>
-#define SEGA 128
-#define SEGB 64
-#define SEGC 4
-#define SEGD 16
-#define SEGE 32
-#define SEGF 2
-#define SEGG 1
-#define SEGP 8
+#define SEGA 4
+#define SEGB 2
+#define SEGC 1
+#define SEGD 32
+#define SEGE 64
+#define SEGF 16
+#define SEGG 8
+#define SEGP 128
uint8_t font[16] = {
SEGA | SEGB | SEGC | SEGD | SEGE | SEGF,
SEGA | SEGE | SEGF | SEGG,
};
/* LED */
+#define LCDELAY 1000
uint8_t dsp[2] = {0, 0};
char leda = 0;
char ledc = 0;
/* Timer */
-char of = 0;
-int oticks = 0;
+volatile char of = 0;
+volatile int oticks = 0;
unsigned long mnow;
/* Pulse counter */
-char pstate = 0;
+volatile char pstate = 0;
char pval = 0;
/* Switch */
-char sstate = 0;
+volatile char sstate = 0;
int stime = 0;
/* Temp sensor */
-char tstate = 0;
-char tlock = 0;
+volatile char tstate = 0;
+volatile char tlock = 0;
unsigned long tstart;
unsigned long ttime;
unsigned long ttimea = 10000;
char tavgok = 0;
+/* Conversion loop */
+int tempk;
+volatile ktok = 0;
/* Zero-cross detector*/
-char zok = 0;
+volatile char zok = 0;
unsigned long ztime;
/* Triac */
char trstate = 0;
static uint16_t last = 0;
uint8_t c, d, v;
- if(TCNT1 - last > 500) {
+ if(TCNT1 - last > LCDELAY) {
last = TCNT1;
if(++leda >= 8) {
leda = 0;
}
}
+void convcycle(void)
+{
+ static char state = 0;
+ static unsigned long last = 0;
+ static float a, ra, l, t;
+
+ /*
+ * 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:
+ * a = ttimea as float
+ * C = 1e6 / (A * C * ln(2))
+ * ra = a * C
+ * l = ln(ra)
+ * t = B / l
+ * Note, temperature is in Kelvin
+ */
+#define C 9.792934
+#define B 4020.0
+ if(state == 0) {
+ if((mnow - last > 200000) && tavgok) {
+ a = (float)ttimea;
+ state = 1;
+ tavgok = 0;
+ }
+ } else if(state == 1) {
+ ra = a * C;
+ state = 2;
+ } else if(state == 2) {
+ l = log(ra);
+ state = 3;
+ } else if(state == 3) {
+ t = B / l;
+ state = 4;
+ } else if(state == 4) {
+ tempk = (int)t;
+ ktok = 1;
+ state = 0;
+ }
+}
+
void triaccycle(void)
{
if(trstate == 0) {
ledcycle();
tempcycle();
calcavg();
+ convcycle();
triaccycle();
#if 1
*/
if(state == 0) {
/* Display temperature */
- if(tavgok) {
- tavgok = 0;
- if(ttimea < 20000) {
- display((ttimea / 100) % 100);
- dsp[0] |= SEGP;
- if(ttimea >= 10000)
- dsp[1] |= SEGP;
+ if(ktok) {
+ ktok = 0;
+ if((tempk >= 273) && (tempk <= 372)) {
+ display(tempk - 273);
} else {
- display(ttimea / 1000);
+ dsp[0] = dsp[1] = SEGG;
}
}
if(pval != 0) {
state = 1;
utime = mnow;
}
+ if(sstate == 2) {
+ sstate = 0;
+ if(stime > 10) {
+ state = 2;
+ } else {
+ tron = !tron;
+ }
+ }
} else if(state == 1) {
/* Triac control */
if(pval != 0) {
if(mnow - utime > 1000000) {
state = 0;
}
- }
- if(sstate == 2) {
- tron = !tron;
- sstate = 0;
+ if(sstate == 2) {
+ tron = !tron;
+ sstate = 0;
+ }
+ } else if(state == 2) {
+ if(ttimea < 20000) {
+ display((ttimea / 100) % 100);
+ dsp[0] |= SEGP;
+ if(ttimea >= 10000)
+ dsp[1] |= SEGP;
+ } else {
+ display(ttimea / 1000);
+ }
+ if(sstate == 2) {
+ state = 0;
+ sstate = 0;
+ }
}
#endif
/*
display(ttimea / 1000);
}
#endif
-#if 1
+#if 0
/*
* ZVD debug
*/
tron = !tron;
sstate = 0;
}
+ if(tron)
+ dsp[1] |= SEGP;
+ else
+ dsp[1] &= ~SEGP;
#endif
#if 0
/*
} else {
display(cur);
}
+ if(PINB & 4)
+ dsp[1] |= SEGP;
#endif
}
}
ISR(SIG_PIN_CHANGE0)
{
- if((sstate == 0) & ((PINB & 1) == 0)) {
+ if((sstate == 0) && !(PINB & 4)) {
stime = oticks;
sstate = 1;
}
- if((sstate == 1) & ((PINB & 1) == 1)) {
+ if((sstate == 1) && (PINB & 4)) {
stime = oticks - stime;
sstate = 2;
}
if(pstate == 0) {
if((PINB & 2) == 0) {
pstate = 1;
- } else if((PINB & 4) == 0) {
+ } else if((PINB & 1) == 0) {
pstate = 2;
}
} else if(pstate == 1) {
- if((PINB & 4) == 0) {
+ if((PINB & 1) == 0) {
pval++;
pstate = 3;
} else {
pstate = 0;
}
} else {
- if((PINB & 2) && (PINB & 4))
+ if((PINB & 2) && (PINB & 1))
pstate = 0;
}
}