Better Triac triggering.
[kokare.git] / kokare.c
CommitLineData
31415646
FT
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <inttypes.h>
4
5#define SEGA 128
6#define SEGB 64
7#define SEGC 4
8#define SEGD 16
9#define SEGE 32
10#define SEGF 2
11#define SEGG 1
12#define SEGP 8
13
14uint8_t font[16] = {
15 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF,
16 SEGB | SEGC,
17 SEGA | SEGB | SEGD | SEGE | SEGG,
18 SEGA | SEGB | SEGC | SEGD | SEGG,
19 SEGB | SEGC | SEGF | SEGG,
20 SEGA | SEGC | SEGD | SEGF | SEGG,
21 SEGA | SEGC | SEGD | SEGE | SEGF | SEGG,
22 SEGA | SEGB | SEGC,
23 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG,
24 SEGA | SEGB | SEGC | SEGD | SEGF | SEGG,
25 SEGA | SEGB | SEGC | SEGE | SEGF | SEGG,
26 SEGC | SEGD | SEGE | SEGF | SEGG,
27 SEGA | SEGD | SEGE | SEGF,
28 SEGB | SEGC | SEGD | SEGE | SEGG,
29 SEGA | SEGD | SEGE | SEGF | SEGG,
30 SEGA | SEGE | SEGF | SEGG,
31};
32/* LED */
33uint8_t dsp[2] = {0, 0};
34char leda = 0;
35char ledc = 0;
36/* Timer */
37char of = 0;
38int oticks = 0;
59d1e985 39unsigned long mnow;
31415646
FT
40/* Pulse counter */
41char pstate = 0;
42char pval = 0;
43/* Switch */
44char sstate = 0;
45int stime = 0;
46/* Temp sensor */
47char tstate = 0;
48char tlock = 0;
49unsigned long tstart;
50unsigned long ttime;
51unsigned long ttimea = 10000;
52/* Zero-cross detector*/
59d1e985
FT
53char zok = 0;
54unsigned long ztime;
31415646 55/* Triac */
59d1e985
FT
56char trstate = 0;
57char tron = 0;
495bea06 58unsigned long trtime;
59d1e985 59unsigned short trdelay = 0;
31415646
FT
60
61void init(void)
62{
63 /* Timer init */
64 TCCR1A = 0;
65 TCCR1B = 1;
66 TIMSK1 = 1;
67
68 /*
69 * B0..2 = Pulse sensor
70 * B3..5 = ISP
71 * B6..7 = CLK
72 */
59d1e985 73 DDRB = 0x30;
31415646
FT
74 PORTB = 0x07;
75 PCMSK0 = 0x07;
76 PCICR = 0x01;
77 /*
78 * C0..5 = LEDA0..5
79 * C6 = /RESET
80 * C7 = NC
81 */
82 DDRC = 0x3f;
83 PORTC = 0x00;
84 /*
85 * D0 = Triac
86 * D1 = NTC FET
87 * D2 = ZCD (INT0)
88 * D3 = NTC Op-amp (INT1)
89 * D4..5 = LEDA6..7
90 * D6..7 = LEDC0..1
91 */
92 DDRD = 0xf3;
93 PORTD = 0x00;
94 EICRA = 0x0d;
95 EIMSK = 0x03;
96}
97
98unsigned char bindisp(unsigned char num)
99{
100 unsigned char ret;
101
102 ret = 0;
103 if(num & 1)
104 ret |= SEGA;
105 if(num & 2)
106 ret |= SEGB;
107 if(num & 4)
108 ret |= SEGC;
109 if(num & 8)
110 ret |= SEGD;
111 if(num & 16)
112 ret |= SEGE;
113 if(num & 32)
114 ret |= SEGF;
115 if(num & 64)
116 ret |= SEGG;
117 if(num & 128)
118 ret |= SEGP;
119 return(ret);
120}
121
122void display(char num)
123{
124 dsp[0] = font[(num / 10) % 10];
125 dsp[1] = font[num % 10];
126}
127
128void disphex(unsigned char num)
129{
130 dsp[0] = font[(num & 0xf0) >> 4];
131 dsp[1] = font[num & 0x0f];
132}
133
134unsigned long getticks(void)
135{
136 return(TCNT1 + (((unsigned long)oticks) << 16));
137}
138
139void ledcycle(void)
140{
141 static uint16_t last = 0;
142 uint8_t c, d, v;
143
144 if(TCNT1 - last > 500) {
145 last = TCNT1;
146 if(++leda >= 8) {
147 leda = 0;
148 if(++ledc >= 2)
149 ledc = 0;
150 }
151 if(dsp[ledc] & (1 << leda)) {
152 if(leda < 6) {
153 c = 1 << leda;
154 d = 0;
155 } else {
156 c = 0;
157 d = 0x10 << (leda - 6);
158 }
159 d |= ledc?0x40:0x80;
160 } else {
161 c = d = 0;
162 }
163 PORTC = c;
164 PORTD = (PORTD & 0x0f) | d;
165 }
166}
167
168void tempcycle(void)
169{
31415646
FT
170 if(tstate == 0) {
171 if((PIND & 8) && (tlock == 0)) {
172 PORTD |= 2;
59d1e985 173 tstart = mnow;
31415646
FT
174 tstate = 1;
175 }
176 } else if(tstate == 1) {
59d1e985 177 if(mnow - tstart > 1000) {
31415646
FT
178 PORTD &= ~2;
179 tstate = 0;
59d1e985 180 tstart = mnow;
31415646
FT
181 }
182 }
183}
184
185void calcavg(void)
186{
187 if(tlock == 1) {
188 tlock = 2;
189 ttimea = ((ttimea * 15) + ttime) >> 4;
190 tlock = 0;
191 }
192}
193
59d1e985
FT
194void triaccycle(void)
195{
196 if(trstate == 0) {
197 if(tron && zok && (mnow > ztime + trdelay)) {
198 PORTD |= 1;
199 zok = 0;
200 trstate = 1;
495bea06 201 trtime = mnow;
59d1e985
FT
202 }
203 } else if(trstate == 1) {
495bea06
FT
204 if(mnow > trtime + 500) {
205 PORTD &= ~1;
206 trstate = 0;
207 }
59d1e985
FT
208 }
209}
210
31415646
FT
211int main(void)
212{
213 int cur;
214
215 cur = 0;
216 init();
217 sei();
218 display(0);
59d1e985 219
31415646 220 while(1) {
59d1e985 221 mnow = getticks();
31415646
FT
222 ledcycle();
223 tempcycle();
224 calcavg();
59d1e985 225 triaccycle();
31415646
FT
226
227 /*
228 dsp[0] = bindisp((ttimea & 0xff00) >> 8);
229 dsp[1] = bindisp(ttimea & 0x00ff);
230 */
231 /*
232 disphex((ttimea & 0xff000) >> 12);
233 */
495bea06 234#if 0
59d1e985
FT
235 /*
236 Temp display
237 */
31415646
FT
238 if(ttimea < 20000) {
239 display((ttimea / 100) % 100);
240 dsp[0] |= SEGP;
241 if(ttimea >= 10000)
242 dsp[1] |= SEGP;
243 } else {
244 display(ttimea / 1000);
245 }
59d1e985 246#endif
495bea06
FT
247#if 1
248 /*
249 Phony Triac control
250 */
251 if(pval != 0) {
252 cur += pval;
253 if(cur < 0)
254 cur = 0;
255 if(cur > 99)
256 cur = 99;
257 display(cur);
258 trdelay = 10000 - ((unsigned short)cur * 100);
259 pval = 0;
260 }
261 if(sstate == 2) {
262 tron = !tron;
263 sstate = 0;
264 }
265#endif
59d1e985 266#if 0
31415646 267 /*
59d1e985
FT
268 Pulse counter display
269 */
31415646
FT
270 cur += pval;
271 pval = 0;
272 if(sstate == 2) {
273 cur = stime;
274 sstate = 0;
275 }
276 if(cur > 99)
277 cur = 99;
278 if(cur < -99)
279 cur = -99;
280 if(cur < 0) {
281 display(-cur);
282 dsp[0] |= SEGP;
283 } else {
284 display(cur);
285 }
59d1e985 286#endif
31415646
FT
287 }
288}
289
290ISR(SIG_INTERRUPT0)
291{
59d1e985
FT
292 ztime = getticks();
293 zok = 1;
31415646
FT
294}
295
296ISR(SIG_INTERRUPT1)
297{
298 unsigned long now;
299
300 now = getticks();
301 if(tstate == 0) {
302 tstate = 1;
303 if(tlock != 2)
304 ttime = now - tstart;
305 tstart = now;
306 PORTD |= 2;
307 tlock = 1;
308 }
309}
310
311ISR(SIG_OVERFLOW1)
312{
313 of = 1;
314 oticks++;
315}
316
317ISR(SIG_PIN_CHANGE0)
318{
319 if((sstate == 0) & ((PINB & 1) == 0)) {
320 stime = oticks;
321 sstate = 1;
322 }
323 if((sstate == 1) & ((PINB & 1) == 1)) {
324 stime = oticks - stime;
325 sstate = 2;
326 }
327 if(pstate == 0) {
328 if((PINB & 2) == 0) {
329 pstate = 1;
330 } else if((PINB & 4) == 0) {
331 pstate = 2;
332 }
333 } else if(pstate == 1) {
334 if((PINB & 4) == 0) {
335 pval++;
336 pstate = 3;
337 } else {
338 pstate = 0;
339 }
340 } else if(pstate == 2) {
341 if((PINB & 2) == 0) {
342 pval--;
343 pstate = 3;
344 } else {
345 pstate = 0;
346 }
347 } else {
348 if((PINB & 2) && (PINB & 4))
349 pstate = 0;
350 }
351}