Dimmable AC Light Box
From versions 0.5 to 0.7 of the code I went through assembly hell as I kept updating the code trying to get UART to work. As one could imagine, the process of removing the IC every few minutes to test code became tedious, and I started bending pins. I knew what I had to do. I had to implement ICSP so I wouldn’t have to worry about removing the IC from the board. It was also around this time I felt confident enough to make a logic board, so I did.
I ended up assigning version 0.6 to code that would not even execute as a way to save what changes I had been making before making other changes.
The problem I had was configuring the half dozen registers needed to get UART to function correctly, and actually….Reading-TFM. I wasn’t configuring the SPBRG register, and it is required to time the UART speed. The SPBRG register also needs to be calibrated differently based on the clock speed, which I hastily obtained the wrong value for. I also ended up using 3 interrupts. One for the hardware Zero Crossing detection on INT-0, another for the UART Receive, and the last for a timer for the Zero-Crossing offset. Configuring the registers to allow these interrupts, along with configuring and understanding the concepts like the “pre-scaler” took MANY hours of skimming through data sheets.
Also, my friend, the Interrupt Vector. 😀
8-Bit PICs only have one. So what is an Interrupt Vector, you may ask? It’s a memory location where execution jumps to whenever an interrupt is triggered. As all three Interrupts jumped to the same address, I was forced to compare registers to see which Interrupt called execution to jump there.
ALSO, the registers being worked on when interrupted DO NOT automatically become saved. First thing I would do in the Interrupt routine is SAVE all work registers to temp addresses. I used Microchips’ own example to do this. Upon completion of the Interrupt routine, I would then restore the register values.
org 0x0004 ; memory location h004
; ***************************************************************************
; Interupt Service Routine MUST RUN FROM HERE ONLY !
;
; First run the Context Save Registers – you need to create the _temp filesisr_CS
movwf W_ISR_TEMP ; copy W to temp
swapf STATUS,W ; swap status to be saved into W
clrf STATUS ; bank 0
movwf STATUS_ISR_TEMP ; save status in bank O
movf PCLATH,W ; save pclath
movwf PCLATH_ISR_TEMP
clrf PCLATH ; clear to page 0 for ISR
movf FSR,W ; save FSR
movwf FSR_ISR_TEMP; User Code – MUST STAY WITHING ISR BOUNDARIES – DO NOT USE GOTOs OUT OF THE ISR – USE NO CALLS
; CONTEXT RESTORE REGISTERS
isr_END
movf FSR_ISR_TEMP,W
movwf FSR
movf PCLATH_ISR_TEMP,W
movwf PCLATH
swapf STATUS_ISR_TEMP,W ; swap status temp to w to set org bank
movwf STATUS ; movW to status
swapf W_ISR_TEMP,F ; restore W
swapf W_ISR_TEMP,W
retfie ; return from isr; End of ISR
;****************************************************************************
I built out the box around this time over the course of a few weeks. I took my time, and collected the hardware I needed from Skycraft, Radioshack, Mouser, and Home Depot. As safety was excessively on my mind, I used high grade electrical wire to feed power to the box, and grounded both the top, and the bottom of the box.
I chose to house the Triacs on a perfboard, with an electrical power bus soldered to the bottom of the board (Which I unfortunately do not have a picture of.)
I used 10 fuses.
- A 10-amp fuse for the Triac board that drove all the outputs.
- An individual fuse per each of the 8 channel.
- Another for for the transformer that drives the zero crossing detection, and 5v rail.
——————————————–
The triacs are by STMicroelectronics, Model BTA16-600B, and they are being driven by Fairchild MOC3021 opto-isolators. After reading through lots of example circuits, I decided to go with the minimalistic, resistive only load circuit found in the datasheet for the MOC3021M.
I started mounting the components, and although not visible from the top of this PCB, a striped 16 gauge, stranded electrical wire runs the horizontal length of it, soldered on with a 100 watt soldering gun. I used this as a power bus. I then soldered bare 18 gauge, stranded wire that runs from this bus to each Triac, and then to the output screw terminals. The screw terminals at the front of the board are digital I/O inputs for each channel, and for power and ground.
To drive the opto-isolators, I used NPN transistors to switch their ground pins, and drove the transistors from the PIC Micro.
Below is the box with power and zero crossing detection board on left wall, logic board on back wall, and triac board coming off the base of the box.
Different angle with transformer in upper right.
With the box safely assembled, and without AC mains cable hanging everywhere, I concentrated on optimizing the assembly code….
Pingback: Dimming AC lights the hard way - Hack a Day
Hi.
Does the transformer induce some phase (delay) to the zero cross detection?
Juan, I’d imagine the Sine Wave looks the same after being stepped down, only with less power, so I don’t think a delay is being caused here, or the wave is being pushed out of phase.
The wave becomes rectified and drives a Transistor that in turn inverts the signal into a a square wave. i.e. when voltage is 0, the transistor passes no power, and a pull up drives the interrupt high. What I believe is happening is once the wave hits a low threshold, say 4v, for example, the transistor no longer functions, and the interrupt is triggered. I’d like to find a solution to this.
Hope that helps.
I know this has been idle for a few months but just to give a possible solution.
You have a processor, which allows you more flexibility that a transistor circuit monitoring a full wave rectifier.
If you use a single separate diode as a half wave rectifier,with some resistors you’ll get a square wave at the line frequency, that you could read with logic input.
Now if life were perfect,you’d be set, because all you would have to do is monitor that input for an edge. Rising or falling. That would be a zero crossing. It may even work just that simple. But possibly there is line noise on the AC that would give you several as the signal is near Vinputhigh. There is also a symmetry issue, where voltage crossing would be different on one phase from the other. Its the kind of thing you’d use a Schmidt trigger to read if you were using pure logic.
This is where the processor comes in. You can calculate how deep into the wave form the input crosses Vih, and when it will crass back again on the way down. From there you can calculate where the real zero crossing is.
With further elaboration you should be able to use that data make a phase locked loop in software that locks into the 60 Hz signal of the AC line. Using that as a time base, then you can determine your triac firing times.
On additional thought, you can really factor out the asymmetrical aspect of the half wave detector. Whatever Vih is, the peak of the AC powerline waveform is going to be half way between the rising edge and the falling edge. Likewise the nadir of the low part of the cycle will be half way between the falling edge and the next rising edge.
This PIC has a timer. So if (after deglitching) you take the times of the rising and falling edges, you should be able to calculate where the peaks are, and thereby the zero crossings.
I’d probably set it up so that a timer caused an interrupt when it rolled over, intending that to be a zero crossing. Reloading the timer count should take into account the error based on the the expected peak times. If the peak is not at 1/4 of a cycle, and the low at 3/4 of a cycle, calculate the error, and add that in when setting the timer count back 1/2 a cycle in the interrupt service routine.
You can even use an initialization process at the start of day to figure out how many timer ticks a cycle is, and not worry about an absolute scaled time base. just get an average for a few cycles.
Therefore with a bitof deglitching, you should be able to know
You can use another optocoupler on the transformer line in place of the transistor circuit instead. Look up the 4N26. The internal diode will half rectify the wave and the transistor will cause a more precise square wave you can base your timing from.
You must be Psychic. The last comment here was over a month ago, and I JUST had gotten done purchasing it’s sister chip, the H11AA1 when you commented. I was researching this earlier. The Renard PIC controller uses it, and I think I’ll adapt it also.