You're right, I had the resistors wrong.
Making the change brought it up to 4.6V.
But, having the zeners in there adds about 40uS to the zero-cross signal.
It takes 35uS without the zeners, and 75uS with them.
Add in the interrupt latency for PBP type interrupts, time to do math in the handler, the minimum pauseus of 24us, and taking into account that a half cycle of 60hz is 8,333uS ... I'm sure the first step was quite a bit dimmer.
But the biggest problem is delaying inside the interrupt handler.
When 90% of the time is spent in the handler, the pause 10000 in the main loop takes almost a minute.
So here's my next attempt.
It uses Timer1 for the delays, so the main program can keep running in the foreground.
The handlers have been changed to ASM type to minimize latencies.
And the math is done in a separate subroutine that only runs once when you change the brightness, instead of having to do the math on every zero-cross.
It should be pretty close to the MAX/MIN dimming, but you may need to adjust the MaxBright/MinBright constants a little.
If you adjust them too far, it will start flashing.
Hope that works better.Code:INCLUDE "DT_INTS-14.bas" ; Base Interrupt System INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts Include "modedefs.bas" @ __Config _XT_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BODEN & _CP & _CPD MaxBright CON 8250 ; maximum brightness MinBright CON 200 ; minimum dimming Brightness var word TriacDelay var Word AlwaysON var BIT AlwaysOFF var BIT OffPeriod var BIT ; used by timer1 periods Triac var PortA.1 ' Output to TRIAC gate ACLine var PortA.2 ' Input for the FullWave rectify AC line Buz var PortC.2 INTEDG VAR OPTION_REG.6 TMR1ON VAR T1CON.0 TMR1IF VAR PIR1.0 Timer1 VAR WORD EXT @Timer1 = TMR1L TRISA = %001100 TRISC = 0 CMCON = 7 ANSEL = 0 PORTA=0 PORTC=0 ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler INT_INT, _ACDetect, ASM, yes INT_Handler TMR1_INT, _T1Handler, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM @ INT_ENABLE INT_INT ; enable external (INT) interrupts @ INT_ENABLE TMR1_INT ; enable Timer1 interrupts Triac=0 ' disable Triac Gate brightness=0 ' Set delay to minimum gosub SetDelay while 1 pause 3000 high buz: pause 500 : low buz brightness=MaxBright : gosub SetDelay : pause 10000 :high buz: pause 50 : low buz brightness=MaxBright-2 : gosub SetDelay : pause 10000 :high buz: pause 50 : low buz brightness=4500 : gosub SetDelay : pause 10000 :high buz: pause 50 : low buz brightness=4000 : gosub SetDelay : pause 10000 :high buz: pause 50 : low buz brightness=3500 : gosub SetDelay : pause 10000 :high buz: pause 50 : low buz brightness=MinBright : gosub SetDelay : pause 10000 :high buz: pause 50 : low buz brightness=0 : gosub SetDelay : pause 7000 wend SetDelay: Brightness = Brightness min MaxBright ; limit maximum brightness AlwaysON = !(Brightness != MaxBright) ; MaxBright is always ON AlwaysOFF = !(Brightness != 0) ; 0 is always OFF if !AlwaysOFF then Brightness = Brightness max MinBright ; limit minimum dimming triacdelay = -(MaxBright - Brightness) ; calc delay time RETURN ;------------------------------------------ T1Handler: if OffPeriod then ; triac delay finished OffPeriod = 0 triac=1 ; turn on triac Timer1 = -50 ; load timer for 50uS else triac = 0 ; turn off triac after 50uS TMR1ON = 0 endif @ INT_RETURN ;------------------------------------------ ACDetect: if AlwaysON then triac=1 ' Activate TRIAC else if AlwaysOFF then triac = 0 else Timer1 = triacdelay ; load delay into timer TMR1IF = 0 ; clear the interrupt flag TMR1ON = 1 ; start the timer OffPeriod = 1 ; tell T1Handler this is the main delay endif endif INTEDG = !INTEDG ; toggle INTEDG to get both edges @ INT_RETURN




Bookmarks