View previous topic :: View next topic |
Author |
Message |
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Fri Aug 07, 2009 1:40 am Post subject: Question for dimmable lighting controller. |
|
|
Has anyone had success with controlling ac lighting such as those used in Christmas displays? I've seen many DIY varieties on the web but most all of them are controlled with PIC controllers. I have searched the forum and have seen a few examples but I must admit, I have trouble following the code. I want to be able to have the ability to turn on/off or fade in/out multiple channels of light. I assume it is possible after all, the PIC crowd is doing it .
The code I adopted from the forum was this:
Code: |
$crystal = 8000000
$regfile = "m8def.dat"
Dim Chan1 As Byte '"working" dimmer level
Dim Chan2 As Byte
Dim Level1 As Byte 'commanded dimmer level
Dim Level2 As Byte
Dim Tt As Word 'use for time delay
Config Portb = Output
Config Pind.2 = Input
Config Int0 = Rising 'detect falling edge of trig pulse
On Int0 Zero_cross 'Initialise the INT0 Interrupt
Rem Use Nosave Option when you dont want the internal registers saved/restored
'Configure the timer to use the clock divided by 1, 8, 16 64
Config Timer0 = Timer , Prescale = 1 'Set up Timer0
On Timer0 Tim0_isr 'Define the ISR handler
Enable Timer0 'Start Timer
Enable Int0 'Enable External interrupts
Enable Interrupts 'Global interrupt enable
'******* Main loop does crossfade forever *************
'Main: 'main program loop
Do
'Up Light1
For Level1 = 1 To 244 'increase level 1 notch each loop
Waitus 250 'wait here 250 microseconds
Next
'Down Light1
For Level1 = 244 To 1 Step -1 'decrease level 1 notch each loop
Waitus 250 'wait here 250 microseconds
Next
'Up Light2
For Level2 = 1 To 244 'increase level 1 notch each loop
Waitus 250 'wait here 250 microseconds
Next
'Down Light2
For Level2 = 244 To 1 Step -1 'decrease level 1 notch each loop
Waitus 250 'wait here 250 microseconds
Next
Loop
End
'******************** Timer 0 interrupt service routine ****************
'DIM TIMER the following code is executed when the timer rolls over
'only does 2 channels
Tim0_isr:
C1:
Decr Chan1 'count down level
If Chan1 > 1 Then Goto C2
Set Portb.0 'If Chan1 > 1 Then Goto C2'Portb, bit 0 = high
C2: 'Assembly example
Decr Chan2 'count down level, set pin when equal
If Chan2 > 1 Then Goto Dim_done 'If Chan2 > 1 Then Goto dimdone
Set Portb.1 'Portb = Portb & 2
Dim_done:
Tcnt0 = 220 '$062 = 128 levels 8mhz = 220 6mhz = 225 'prescale timer
Bitwait Portd.2 , Reset 'scope trig
Return 'return from interrupt
'************** External interrupt - Zero Cross *************
'This code is executed when the external zero cross circuit triggers an interrupt'
Zero_cross:
Chan1 = Level1 'reset current dim level
Chan2 = Level2
Portb = 0 'turn off all triacs
Return
'******************************************
|
I changed the controller from a 2313 to a mega 8, and changed the frequency from 6mhz to 8mhz. I have created a zero cross circuit and am feeding the output of that into the INT0 port of the mega8. I only have one SSR right now (MOC3023/BTA12) and when I load and run the program, I do get some erratic dimming. My main problem is with the timer running and a secondary trigger interrupt, I can't follow the program logic to understand what it is doing. I'd love to get at least 4 and preferably 8 dimmable channels out of the mega8. Is this doable??
Thanks for any help,
Rick |
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Sat Aug 08, 2009 3:28 am Post subject: |
|
|
In case it would help anyone, the original post for this sample was http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=1062&highlight=triac+dimmer
The original question was posted by cordless and the sample I am trying to understand came from DToolan.
I consider myself pretty good at following most programs I come across. I'm really struggling trying to follow this one. When I use the program to drive my triac, I get a regular sequence (not erratic like I originally thought). The Light is dim, then bright, then fades from bright to dim then fades back to bright. This repeats continuously. I know my zero pulse generator is functional as I have hooked it up to a scope and can see the pulses.
Please, any help on how to follow this program would be GREATLY appreciated. The comments (while they may have been of help to the original author) don't even make sense to me in places. If cordless or DToolan are around maybe they could enlighten me... Please??
Thanks again,
Rick |
|
Back to top |
|
|
mako444
Joined: 02 Jul 2009 Posts: 90 Location: Rio de Janeiro
|
Posted: Sat Aug 08, 2009 9:09 pm Post subject: |
|
|
Dear friend, first: the main loop you are not doing anything, second: you can not use bitwait the routine of interruption because the zero crossing occurs every 16 milliseconds while the interruption of timer0 occurs in 28 micro seconds with the values you placed.
another problem: you get to activate the TRIAC must wait at least 1ms after zerocrossing otherwise not have sufficient voltage to activate it and think you do not need to use interrupt this program, you should setar doors in main loop
ex:
DO
'Up Light1
For Level1 = 1 To 244 'increase level 1 notch each loop
set portb,0
Waitus 250 'wait here 250 microseconds
Next
'Down Light1
For Level1 = 244 To 1 STEP -1 'decrease level 1 notch each loop
reset portb,0
Waitus 250 'wait here 250 microseconds
Next
'Up Light2
For Level2 = 1 To 244 'increase level 1 notch each loop
set portb,1
Waitus 250 'wait here 250 microseconds
Next
'Down Light2
For Level2 = 244 To 1 STEP -1 'decrease level 1 notch each loop
reset portb,2
Waitus 250 'wait here 250 microseconds
Next
LOOP |
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Sun Aug 09, 2009 12:52 am Post subject: |
|
|
Thank you mako444,
I thought the program was seriously flawed in its logic. I thought it may have just been my inability to follow it due to the interrupts and timers (of which I am admittedly weak) I now know otherwise. Now I just have to figure this all out.
Can you point me to any simple fade in / fade out bascom dimmer program. I have a zero cross (opto coupled) feeding into Int0. I've been searching for several days here in the forum and google but have had no luck thus far. I just want something simple I can build off of and learn from.
Thanks again,
I really do appreciate the help.
Rick |
|
Back to top |
|
|
press9761
Joined: 20 Jun 2006 Posts: 108
|
Posted: Sun Aug 09, 2009 2:06 am Post subject: |
|
|
Hay Rick.
Yeah, I have code that does what your looking for.
I use it to control inductive loads (like a pump).
As far as the hardware goes,...that's a hole other ball of wax.
The MOC3023 is a good start.
There are many ways of doing it.
I wrote this a while ago, and it works perfectly. So, I have no incentive to tighten it up.
In the code:
Pulseout Portd , 6 , Phaze
This is used only to kill time.
The triac is controlled by the pin "Pump"
I'm sure you will have a question or two.
Feel free to ask.
Jordan
Code: |
$regfile = M8def.dat
$crystal = 8000000
'$sim
Reset Portd.4
Wait 4
'_______________________________________________________________________________
Config Portd.4 = Output 'PUMP
Pump Alias Portd.4
'_______________________________________________________________________________
Config Pind.3 = Input 'INT1
'_______________________________________________________________________________
Config Pinc.2 = Input
Ben Alias Pinc.2 'button enable
'_______________________________________________________________________________
Config Pinb.6 = Input 'button's
Config Pinb.7 = Input
Up_button Alias Pinb.6
Down_button Alias Pinb.7
'_______________________________________________________________________________
Config Portd.6 = Input ' this is the pulsout pin,it is used as a timer only, conect to nothing
'_______________________________________________________________________________
Config Pinc.0 = Input
On_signal_pump Alias Pinc.0 'engage phazing system
'_______________________________________________________________________________
Config Pinc.1 = Input
Soft_start_off Alias Pinc.1 'soft start off
'_______________________________________________________________________________
'Vareable location
'###############################################################################
Dim T As Word
Dim Phaze As Word
Dim Black_out_protection As Byte
'_______________________________________________________________________________
Standby:
'###############################################################################
Disable Int1 'When the system is off the ISR is disabled
Reset Pump
Do
nop
Loop Until On_signal_pump = 1
'_______________________________________________________________________________
Soft_start_pump:
'###############################################################################
Config Int1 = Falling 'enable int1
On Int1 Int1_isr
Enable Interrupts
T = 0
Enable Int1
'_______________________________________________________________________________
If Soft_start_off = 1 Then
Phaze = 5500
Goto Blackout
End If
'_______________________________________________________________________________
Do
Set Pump
Phaze = 11000
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 360
Do
Set Pump
Phaze = 10500
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 480
Do
Set Pump
Phaze = 10000
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 600
Do
Set Pump
Phaze = 9500
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 625
Do
Set Pump
Phaze = 9000
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 650
Do
Set Pump
Phaze = 8500
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 675
Do
Set Pump
Phaze = 7000
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 700
Do
Set Pump
Phaze = 6500
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 725
Do
Set Pump
Phaze = 6000
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 750
Do
Set Pump
Phaze = 5800
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 775
Do
Set Pump
Phaze = 5500
If On_signal_pump = 0 Then Goto Pump_off
Loop Until T => 800
Goto Blackout:
'_______________________________________________________________________________
Int1_isr:
'*******************************************************************************
Reset Pump
Incr T
Pulseout Portd , 6 , Phaze
Set Pump
Return
'*******************************************************************************
Blackout:
'###############################################################################
Readeeprom Black_out_protection , 10 '^^EEPROM LOCATION 10^^
If Black_out_protection = 1 Then
Readeeprom Phaze , 20 '^^EEPROM LOCATION 20^^
End If
Goto Main
Main:
'###############################################################################
Do
If Ben = 1 Then Goto Wait_4_button_press 'here we wait for BEN to go high, when this happens the system now activates the button capability
Loop Until On_signal_pump = 0 'if pump is turnd off on_signal_pump=0 and system go's into an off mode
Goto Pump_off
'_______________________________________________________________________________
Wait_4_button_press:
'###############################################################################
'_______________________________________________________________________________
Do
If Ben = 0 Then Goto Button_press_done 'here we wait for BEN to low, then we save the info in eeprom
Debounce Up_button , 1 , Faster_select_pump 'these buttons are used change the phaze time
Debounce Down_button , 1 , Slower_select_pump
Loop Until On_signal_pump = 0 'if pump is turnd off on_signal_pump=0 and system go's into an off mode
Goto Pump_off
'_______________________________________________________________________________
Slower_select_pump:
'###############################################################################
If Phaze = 15500 Then '1% power
Black_out_protection = 1
Goto Wait_4_button_press
End If
'_______________________________________________________________________________
Phaze = Phaze + 100
Black_out_protection = 1
Goto Wait_4_button_press
'_______________________________________________________________________________
Faster_select_pump:
'###############################################################################
If Phaze = 5500 Then '100% power
Black_out_protection = 0
Goto Wait_4_button_press
End If
'_______________________________________________________________________________
Phaze = Phaze - 100
Black_out_protection = 1
Goto Wait_4_button_press
'_______________________________________________________________________________
Button_press_done:
'###############################################################################
Writeeeprom Phaze , 20 '**EEPROM LOCATION 20**
Writeeeprom Black_out_protection , 10 '**EEPROM LOCATION 10**
Goto Main
'###############################################################################
Pump_off:
'###############################################################################
Black_out_protection = 0
Writeeeprom Black_out_protection , 10 '**EEPROM LOCATION 10**
Goto Standby
'_______________________________________________________________________________
|
|
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Sun Aug 09, 2009 1:04 pm Post subject: |
|
|
Thanks Jordan,
I think I can actually follow what you are doing here...
Let me see if I got this right.
In your Int1_isr: you turn off the triac then use the pulseout (to nothing) to create the delay after the zero cross. The delay is the number of pulses in your variable "Phaze" which would be .5uS pulses at 8mhz (right??).
Code: |
Int1_isr:
'*******************************************************************************
Reset Pump
Incr T
Pulseout Portd , 6 , Phaze
Set Pump
Return
'*******************************************************************************
|
In the first part of your program you are ramping up the pump speed by gradually decreasing the delay from 11000 (5.5mS) pulses to 5500 (2.75mS).
You then read the last stored values from the eeprom for your "Black_out_protection" which will always be zero on power up because you set it that way at Pump_off.
Code: |
Blackout:
'###############################################################################
Readeeprom Black_out_protection , 10 '^^EEPROM LOCATION 10^^
If Black_out_protection = 1 Then
Readeeprom Phaze , 20 '^^EEPROM LOCATION 20^^
End If
Goto Main
|
Then you go to a main loop that checks if the button enable (BEN) is on , if so allows for change in phaze, etc...
I am guessing that the reading of the blackout protection is just for each run of the pump. That way if something interrupted the program, the phaze variable would be set to the last setting.
What happens to variable T... won't it overflow if the pump is run for a while? It is incremented each time in your isr but after the initial startup, I don't see it used. Or am I missing something?
How'd I do??
My circuit consists of a transformer dropping voltage to 6.3 ac 60hz. I feed both sides through 1k resistors into a PC814 ac input optocoupler giving me a 120hz pulse which is fed into Int0. (I'd have to change it to Int1 for your program I assume)
On the output side, I am simply driving a MOC3023 triac optocoupler into a BTA12 switching 120vac 60hz.
Without drawing up a schematic that's pretty much the (test) circuit I have created to play with. The output side definitely will switch the line on/off. The Zerocross seems to work fine creating clean pulses when viewed on a scope. I'm going to drop button press and eeprom portions and see if just by continuously increasing / decreasing the variable phaze I can get an effect of fade in / out.
Thanks again for the great example. I learn so much from what other people have done!! |
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Sun Aug 09, 2009 3:55 pm Post subject: |
|
|
This is the ac input to the PC814 VS the output.
Does this look normal??
I'm not very fluent with the scope (I borrowed it from a friend).
The Sinusoidal wave is the AC input to the PC814 and the pulses are the output being fed to the mega8.
Rick |
|
Back to top |
|
|
press9761
Joined: 20 Jun 2006 Posts: 108
|
Posted: Sun Aug 09, 2009 5:50 pm Post subject: |
|
|
Rick!!
I got to hand it to you, your dead on! 100% accurate code interpretation
and your circuit is also 100% perfect. You even are using a snuberless triac. VERY NICE!!
So, the variable T, it is only used in my soft start protocol. After that, its abandoned. So, it just keeps rolling over. Honestly, I'm not happy with that however,..it works just fine.
The "soft start" section ramps the power up slowly. Just keep in mind that I made that protocol for an inductive load. If you put a light bulb on your line and watch it start up,..it won't look like a gradual start up. You have to fiddle with the numbers to get it working right for you application.
Oh, one more thing. I see you are using a 12 amp triac. REMEMBER THIS!
Triac's under heavy load get hot!!
If you were to connect it to you vacuum,..
When they reach a certain temperature they will latch open!
If you cut the power to the AVR, the triac will still run!!
You vacuum will still be on.
It becomes very obvious when this "latching" happens. The vacuum will start to sputter.
This event can happen fast. It takes about 40 seconds for a 9 amp inductive load to latch a triac.
PUT A HEAT SINK AND A FAN ON IT.
Then,....you have no problem at all.
As far as the O- scope. It looks good.
Your going to need one....
I use the OWON PDS5022S. Cheep and effective,..actual, I have two of them. Find it on ebay.
Let me know how things go..
Jordan |
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Sun Aug 09, 2009 9:15 pm Post subject: |
|
|
I got a good deal on the triac that's the only reason for the 12A part. I don't intend to run more than 2 - 3 amps max thru it when all is said and done. I do have a heatsink for it though even though with good ventilation, it may be ok without one at that load. Thanks for the positive remarks. Your code was much more straightforward than the other code I got off the forum. I think I'm beginning to understand a little more about how to make these things respond the way I want to.
I've got a little work to do.
I'm assuming the goal in the 1st example I found was to use a timer to delay the firing of the triac rather than using the pulseout as a delay like you did.
Thanks again for your help,
I'll keep this posted with my progress in case anyone is interested.
Rick |
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Sun Aug 09, 2009 10:37 pm Post subject: |
|
|
Ok,
Using your ideas, Jordan, this code works as a simple fade from off to full on, then back off again. I learned one thing, and this may be the reason for the use of the timer for the delay instead of the pulseout. As the number of pulses increase, the overall delay also increases. I'm not sure exactly why because the pulseout should always fall within the 8.33us per trigger. (at 8mhz 16000 pulses should be 8us) Anyway, here is the stripped down code which does work as described.
Code: |
$regfile = "M8def.dat"
$crystal = 8000000
'$sim
Reset Portb.1
Wait 4
'_______________________________________________________________________________
Config Portb.1 = Output 'PUMP
Pump Alias Portb.1
'_______________________________________________________________________________
Config Pind.3 = Input 'INT1
'_______________________________________________________________________________
Config Portd.6 = Input ' this is the pulsout pin,it is used as a timer only, conect to nothing
'_______________________________________________________________________________
Dim T As Word
Dim Phaze As Word
'_______________________________________________________________________________
Config Int1 = Rising 'enable int1
On Int1 Int1_isr
Enable Interrupts
T = 0
Enable Int1
'Main loop
Do
For Phaze = 16000 To 100 Step -10
Waitus 100
Next
Wait 4
For Phaze = 100 To 16000 Step 10
Waitus 100
Next
Waitms 125
Loop
Int1_isr:
'****************************************************************************
Reset Pump
Pulseout Portd , 6 , Phaze
Set Pump
Return
|
Next I may try my hand with timers to see what else I can do!!
This is becoming fun again |
|
Back to top |
|
|
mako444
Joined: 02 Jul 2009 Posts: 90 Location: Rio de Janeiro
|
Posted: Sun Aug 09, 2009 11:54 pm Post subject: |
|
|
Looks at the simple and cheap zero crossing circuit.
this program generate a base time 1 second for demo how can you obtains a base time of the AC LINE, and you can use it for your project.
future I will post the second part of the program that I developed to control 4 triacs.
'-----------------------------------------------------------------------------------------
'name : dimmer.bas
'copyright : Luiz Natal Mendes dos Santos
'purpose : DIMMER
'micro : ATMEGA8
'suited for demo : yes
'commercial addon needed : no
'-----------------------------------------------------------------------------------------
' use a LED on PORTB.0 (pin 14)
' zero cross input for PORTD.2 (INT0 - pin4)
' you can use the circuit of pic addeded
$regfile = "m8def.dat" ' specify the used micro
$crystal = 8000000 ' used crystal frequency
$baud = 9600 ' use baud rate
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
'define variables -----------------------
Dim F As Byte
Dim Flag_zero As Bit
Dim C As Byte ' count how many times has passed for ISR (Zero_cross)
'end of dvariables ----------------------
Config Portb.0 = Output
Config Portb.1 = Output
Config Portd.2 = Input ' portd.2 INT0
Triac1 Alias Portb.0
Config Int0 = Rising 'detect change of state of port
On Int0 Zero_cross Nosave 'Initialise the INT0 Interrupt
Enable Interrupts 'Global interrupt enable
Enable Int0 'Enable External interrupts
Flag_zero = 0
'----------------------- main loop ---------------------------------
Do
If Flag_zero = 1 Then Gosub Fire_triacs
Loop
'-------------------- end of main loop -----------------------------
'************** External interrupt - Zero Cross *************
'This code is executed when the external zero cross circuit triggers an interrupt'
Zero_cross:
Flag_zero = 1
Return
'************************************************************
'------------------------- fire triacs -----------------------------
' 8mS = 8000uS time base max to triac
Fire_triacs:
C = C + 1 ' I use the base time of AC line to counter the time.
If C = 60 Then
C = 0
If Triac1 = 0 Then
Triac1 = 1
Else
Triac1 = 0
End If
End If
Flag_zero = 0
Return
End |
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
Posted: Mon Aug 10, 2009 11:33 pm Post subject: |
|
|
Mako444, I don't follow what you are doing quite as well. Looking at the program you posted, it looks as if the triac would only be turned on 500ms then off 500ms repeating.
Wouldn't your C variable increment by 1 every time you have a zero cross until it reaches 60 (1/2 a second would have elapsed) then the triac gets toggled C-gets reset to zero and the process begins again. This would continue cycling between on/off. Maybe I'm missing something obvious or was that what you were doing?
The zero cross circuit you included is nice. I've seen quite a few variations. I opted for an optoisolator to keep the ac 100% separate from my microcontroller. I get a good pulse as you can see in my scope photo above.
Could you explain to me how your program works? I'm sure I'm just missing something.
Rick |
|
Back to top |
|
|
mako444
Joined: 02 Jul 2009 Posts: 90 Location: Rio de Janeiro
|
Posted: Wed Aug 12, 2009 4:53 am Post subject: |
|
|
Sorry about the delay, you are sure the first part was just to demonstrate the zero cross circuit, try this second program of putting in place and led the moc3011 TRIAC.
TRY THIS CODE:
Dim A As Byte
Dim B As Byte
Dim C As Integer
Dim T As Byte
Dim Hertz As Byte
Dim X As Integer
Dim Triac1 As Bit
Config Portd.2 = Input
Config Portb.2 = Output
Config Int0 = Rising
Triac1 Alias Portb.2
On Int0 Int0_int 'Initialise the INT0 Interrupt
Enable Interrupts
Enable Int0 'enable the interrupt
A = 2
B = 54
C = 1
Do
For X = A To B Step C
Waitms 50
Next X
If A = 2 Then
A = 54
B = 2
C = -1
Else
A = 2
B = 54
C = 1
End If
Loop
End
Int0_int:
T = X / 2
Waitms T
Set Triac1
Waitms 1
Reset Triac1
Return |
|
Back to top |
|
|
Rick-S
Joined: 08 Jan 2009 Posts: 50
|
|
Back to top |
|
|
press9761
Joined: 20 Jun 2006 Posts: 108
|
Posted: Fri Aug 14, 2009 8:09 pm Post subject: |
|
|
Nice work Rick!
Glad to have helped.
Jordan |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|