'************************************************* '************************************************* '** ** '** Simple Triac Dimmer DEMO ** '** ** '** Using Zero Crossing Detection ** '** ** '** by Mike Crean C/O autlec@optusnet.com.au ** '** Perth Western Australia ** '** ** '** 8515, 8535 & other AVR Micros. ** '** ** '** This Demo is set up for a 50Hz mains ** '** supply. There are comments in the ** '** program for changes to 60Hz. ** '** The micro was set for an 8meg. clock. ** '** May need some mod's if lower speeds ** '** are used. ** '** ** '** For stable operation use the 2nd zero ** '** crossing circuit (4069) in AN125 ** '** (mcselec.com). ** '** ** '** WITH MAINS DISCONNECTED FROM TRIAC or LOAD ** '** ** '** Connect a Dual Trace CRO to PortB.2 Triac ** '** drive & PortD.2 Zero Crossing input. ** '** ** '** The relation between zero crossing & the ** '** Triac drive will be seen. Can be used to ** '** set program values for other mains ** '** frequencies (Hz). The values must be set & ** '** checked so Triac trigger is after zero ** '** crossing & before next zero crossing. If ** '** incorrect the Triac & or load may draw ** '** high current & cause other serious faults. ** '** ** '** NOTE|- Uses a NON zero crossing MOC Triac ** '** driver connected from PortB.2 via a 330R ** '** resistor to neg. DC micro supply ** '** ** '** The following program defaults to auto ** '** repeat dimming. If an RS232 interface is ** '** connected it can be changed to one shot ** '** auto dimming or variable dimming if a POT. ** '** is connected to AD0 (5k, wiper to AD0 & ** '** one end to neg. (-) and other to 5V+ ** '** ** '** For hardware refer to Triac/MOC ** '** manufacturers application notes. ** '** Uses a sensitive gate Triac. ** '** ** '** DANGER - WARNING ** '** ---------------- ** '** High voltages are present when equipment ** '** is connected to a mains supply. ** '** ** '** Some Authorities may only allow suitably ** '** qualified & licensed persons to connect ** '** any such equipment to a high voltage ** '** supply. ** '** ** '** Take CAUTION. Avoid electric SHOCK ** '** ** '** E&OE ** '** ** '************************************************* '************************************************* '$sim $regfile = "8535def.dat" $crystal = 8000000 $baud = 9600 Config Adc = Single , Prescaler = Auto Config Timer0 = Timer , Prescale = 1 '** Sets T0 / rate '** Values (1,8,64,256 & Config Int0 = Falling '** Interrupt 0 (Int0) Config Portd = Input '** Set Portd to Inputs Config Portb = Output '** Set Portb to Outputs '** Config variables Dim Rx As Byte , Channel As Byte , Afdm As Byte , Onesh As Byte Dim Reprate As Byte , Afdmchk As Byte , Afchk As Byte Dim Count As Integer , Td As Integer Dim Dstuff As Single Dim W As Word , Stuff As Word Afdm = 0 '** Set to auto dim (default) Afchk = 0 Afdmchk = 0 Onesh = 0 Reprate = 5 '** Will repeat every 5 Secs. On Urxc Rec_isr '** Call Recv. Interrupt service routine Enable Urxc '** Enable ISR calls On Timer0 Tim0_isr '** Call Timer0 ISR Enable Timer0 '** Enable Timer0 ISR calls Enable Int0 '** Enable Int0 ISR calls On Int0 Int0_isr '** Call Int0 ISR Enable Interrupts '** Enable all interrupts Stop Timer0 '** Stop the Timer Start Adc '** Start the Adc '** Have used PortB.2 as MOC - Triac driver as you may use PortA as ADCs Portb.2 = 0 '** Pull PortB.2 Low (Triac OFF) '***** MAIN PROGRAM LOOP ***** Do nop Loop '** Get the Zero Crossing Point from Hardware on PortD.2 ** '** This signal is normaly HIGH and goes low on falling + half cycle ** '** Zero Crossing is detected on the falling edge of Int0 ** '** For Hardware see AN125 at mcselec.com ** Int0_isr: '** Interrupt0 Interrupt Service Routine Start Timer0 '** Start Timer 0 Gosub Getadc '** Get the ADC values '** The ADC conversion & other '** calculations are in this section '** because they take the most time. Return '** Return to MAIN Program Loop '** If a Pot. is used as a dimmer then use PortA.0 for input as 0 - 5V ** Getadc: '** Read the ADC channels (10 bit ADC) = (0 to 1023 count) '** ADC vref has to be 5V+ (use a fillter - 330R & 100nf) ** For Channel = 0 To 7 W = Getadc(channel) '** Loop to read 8 ADCs If Channel = 0 Then Stuff = W '** Put ADC0 into Stuff (from Pot.) Next Channel If Afdm = 0 Then '** Set to Auto Dim Mode If Afdmchk = 0 Then Td = 1 : Afdmchk = 1 End If If Td < 231 Then '** Change 231 value for 60Hz Td = Td + 1 End If If Td > 230 Then '** Change 230 value for 60Hz If Afchk = 0 Then Portb.2 = 0 Afchk = 1 Count = 0 End If End If If Onesh = 0 Then '** Set Auto Repeat mode ON If Afchk = 1 Then Count = 0 : Afchk = 0 : Afdmchk = 0 Wait 4 '** Wait 4 Sec. before Auto Repeat End If End If End If If Afdm = 1 Then '** Set in Dimmer Mode Dstuff = Stuff / 4.55 '** Put Stuff (word) into Td (Integer) Td = Dstuff '** Change 4.55 value for 60Hz End If If Td < 1 Then '** If Td < 0 crossing point Td = 1 '** set Td > 0 crossing point End If If Td > 235 Then '** If Td is > next 0 crossing point Td = 235 '** set Td < next 0 crossing point End If '** Change 235 values for 60Hz Return Tim0_isr: 'Timer0 ISR, called if T0 overflows If Afchk = 1 Then '** Jump this lot if in Auto Dim Mode nop Goto Skiptriac End If Count = Count + 1 '** Start counter (No. of interrupts) '** counts each time T0 overflows If Count > Td Then '** If the count > AD0 / 3 then send Count = 0 '** pulses & set count to 0 Stop Timer0 '** Stop Timer 0 '** Send 3 pulses to the Triac Set Portb.2 '** Turn Portb.2 on (high), PIN 3 Waitus 100 '** Wait 100 u/s Reset Portb.2 '** Turn Portb.2 off (low), PIN 3 Waitus 100 '** Wait 100 u/s Set Portb.2 '** Repeat for 3 pulses Waitus 100 Reset Portb.2 Waitus 100 Set Portb.2 Waitus 100 Reset Portb.2 Waitus 100 End If Skiptriac: Return '** Return to MAIN Program Loop Rec_isr: '** Recv. buffer ISR Rx = Inkey() '** Get Char (ASCII) from Recv. buffer If Rx = 63 Then '** 63 = chr ? Print : Print " Dimmer Test" '** Send to Tx buffer Print " -----------------------------" Print : Print " ? - Help" Print " | - Send Ad0 to buffer" Print " ! - Set to auto fade (default)" Print " @ - Set to dimmer mode (Pot.)" Print " # - Set auto fade to repeat (default)" Print " $ - Set auto fade to one shot" End If If Rx = 124 Then '** 124 = chr | Print : Print " Ad0 = " ; Stuff '** Send Ad0 to Tx buffer Print " Td = " ; Td Print " Afdm = " ; Afdm Print " Afdmchk = " ; Afdmchk End If If Rx = 33 Then '** 33 = chr ! Afdm = 0 : Afchk = 0 '** Set to Auto Fade (default) End If If Rx = 64 Then '** 64 = chr @ Afdm = 1 : Afchk = 0 '** Set to Dimmer mode End If If Rx = 35 Then '** 35 chr # Onesh = 0 : Afdm = 0 '** Auto Fade Repeats every 5Secs. End If If Rx = 36 Then '** 36 chr $ Onesh = 1 : Afdm = 0 '** Auto fade is one shot End If Rx = 0 Return '** Return to MAIN Program Loop End '** End of program and code space '***** E&OE *****