|
|
View previous topic :: View next topic |
Author |
Message |
freesat
Joined: 08 Feb 2011 Posts: 32
|
Need help with AC 60Hz Dimmer ( timer0 interrupt ) |
Posted: Wed Sep 21, 2011 4:20 pm |
|
|
Hi guys...
I want some help with ac 60hz dimmer, my goal is to build a custom dmx smoke machine with temperature control (also I will build incandescent lamp dimmer array too ), is almost done! but i have trouble with ac dimmer.
steps...
Processor:
PIC12F628 running at 4Mhz internal, using zero cross detector on ext_int pin.
dmx512:
Done (works fine without use delay on ext_int! Especial thanks to "Mark" for sample receive routine).
Temperature control: Done (works and need improve delays with scope, but delay freezes rda interrupt causing data lost).
Wind control:
Done (Works fine! dc pwm with mosfet)
Motor control:
Done (works fine! solid state relay with mosfet)
I think the problem is delay to fire triac on ext_int is too high and no left cycles to process rda_int, and if i right, use a timer0 and wait right moment to fire triac.
Any suggestions? I will appreciate any help.
best regards
Sebastiao Rocha
my sample code...
Code: |
#define triac PIN_B3
#define channel_temperature 0
#define channel_fan 1
#define channel_motor 2
int8 dmx_channel[3]; /* Smooke machine with 3 channels ( temperature, fan, motor ) */
#int_EXT
void EXT_isr(void) {
int16 wait_dutty_time;
output_low( triac );
/* Calculated delay time ( us / max_dutty * dutty ) */
wait_dutty_time = (int16) (16575/255) * ( dmx_channel[channel_temperature] ^ 255 );
delay_us( wait_dutty_time );
/* dont fire triac if dutty is zero, remember... dutty is inverted "xor with 255" */
if ( wait_dutty_time < 16510 ) { output_high( triac ); }
}
void main( void ) {
dmx_channel[channel_temperature] = 127 /* set dutty to 50%, for test only */
enable_interrupts( INT_EXT );
ext_int_edge( H_TO_L );
enable_interrupts(GLOBAL);
while ( 1 ) {}
}
|
I think code using timer0 like this will work... this im need help.
Code: |
enable_interrupts(INT_TIMER0);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1 | RTCC_8_BIT );
set_timer0(?);
int16 wait_dutty_time = 16510;
#int_EXT
void EXT_isr(void) {
output_low( triac );
/* Calculated delay time ( us / max_dutty * dutty ) */
wait_dutty_time = (int16) (16575/255) * ( dmx_channel[channel_temperature] ^ 255 );
}
#int_TIMER0
void TIMER0_isr(void) {
if ( wait_dutty_time >0 ) { wait_dutty_time--; }
/* time to fire triac */
if ( wait_dutty_time == 0 ) { output_high( triac ); }
/* time to disable triac */
if ( wait_dutty_time == 16510 ) { output_low( triac ); }
} |
|
|
|
freesat
Joined: 08 Feb 2011 Posts: 32
|
change the code... now its works better, but need adjusts. |
Posted: Thu Sep 22, 2011 1:59 am |
|
|
I rebuild the code and it is more stable, but have some noise and is not 100% adjusted with waveform, need more adjusts, any help will be appreciated.
Note: I changed to 12F675 only for tests with ac.
Code: |
#include <12F675.h>
#fuses INTRC, NOMCLR
#use delay(clock=4M, oscilator=4M, int=4M )
#zero_ram
int8 triac_dutty = 0;
#int_EXT
void EXT_isr( void ) {
set_timer0( triac_dutty );
if ( triac_dutty < 255 ) { output_low( PIN_A5 ); }
}
#int_TIMER0
void TIMER0_isr( void ) {
set_timer0( 0 );
delay_us(100);
if ( triac_dutty >0 ) { output_high( PIN_A5 ); }
}
void main( void ) {
setup_timer_0( T0_INTERNAL| T0_DIV_64 | T0_8_BIT );
ext_int_edge(H_TO_L);
enable_interrupts( INT_EXT );
set_timer0( 0 );
enable_interrupts( INT_TIMER0 );
enable_interrupts( GLOBAL );
while ( 1 ) {
set_adc_channel(2);
delay_us(10);
triac_dutty = read_adc();
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 22, 2011 1:44 pm |
|
|
This is not real code. It doesn't compile. The compiler gives these errors:
Quote: |
*** Error 100 "pcm_test.c" Line 4(5,45): USE parameter value is out of range Unknown option: OSCILATOR
*** Error 12 "pcm_test.c" Line 19(11,12): Undefined identifier -- delay_us
*** Error 12 "pcm_test.c" Line 37(13,14): Undefined identifier -- delay_us |
You have misspelled "oscillator" (for CCS), which makes the compiler
not accept the #use delay() statement, so it won't allow delay_us().
You don't need to have all 3 parameters in the #use delay() statement.
Since you have INTRC, that tells the compiler you want the internal
oscillator. In this case, you only need to put in a "clock=4M" parameter.
Also, if you want to use the oscillator pins for i/o, you should specify
the INTRC_IO fuse. Example:
Code: |
#include <12F675.h>
#fuses INTRC_IO, NOMCLR
#use delay(clock=4M )
|
Also you never call the setup_adc_ports() function. You're trying to use
AN2 as an analog pin, but it's still in digital mode. That's not correct.
Add this line near the start of main():
Code: |
setup_adc_ports(sAN2);
|
|
|
|
freesat
Joined: 08 Feb 2011 Posts: 32
|
Only triac fire on incorrect time on waveform |
Posted: Thu Sep 22, 2011 5:29 pm |
|
|
Hi PCM Programer, thanks for reply...
in fact i dont put full code, but it compile and run ok, all interrupts are working as spected and also adc read too, triac fire on incorrect time on waveform, i dont have a scope to check this.
i put this line Code: | #use delay(clock=4M, oscilator=4M, int=4M ) | because i have some calculations like this and only putting int=4M doenst work. is not misspell and with me works fine ( i build on old version, 4.114, but i will downlaod and install an update )
Code: | SPBRG=(((getenv("CLOCK")/250000)/16)-1); |
will be nice, if getenv can get values from ( oscilator and int ) too. i use getenv a lot, because code is more smart and i can switch PIC Model at any time without modify code.
this is all code im trying now. ( note: Serial routines removed, because this PIC doenst have USART )
Code: |
#include <12F675.h>
#device adc=8;
#fuses INTRC_IO, NOMCLR, NOPROTECT, BROWNOUT, NOPUT
#use delay( clock=4M, oscilator=4M, int=4M )
#use fast_io(A)
#zero_ram
#define PORT_zero PIN_A2
#define PORT_adc PIN_A4
#define PORT_triac PIN_A5
int8 triac_dutty = 0;
#int_EXT
void EXT_isr( void ) {
set_timer0( triac_dutty );
if ( triac_dutty < 255 ) { output_low( PORT_triac ); }
}
#int_TIMER0
void TIMER0_isr( void ) {
set_timer0( 0 );
delay_us(600);
if ( triac_dutty >0 ) { output_high( PORT_triac ); }
}
void main( void ) {
int8 tmp;
set_tris_a( 0b011111 );
setup_comparator(NC_NC_NC_NC);
setup_adc_ports(sAN3);
setup_adc(ADC_CLOCK_INTERNAL );
setup_timer_0( T0_INTERNAL| T0_DIV_64 | T0_8_BIT );
ext_int_edge(H_TO_L);
enable_interrupts( INT_EXT );
set_timer0( 0 );
enable_interrupts( INT_TIMER0 );
enable_interrupts( GLOBAL );
while ( 1 ) {
set_adc_channel(3);
delay_us(15);
tmp = read_adc();
if ( tmp != triac_dutty ) { triac_dutty = tmp; }
}
} |
edit: correcting type error. |
|
|
|
|
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
|
Powered by phpBB © 2001, 2005 phpBB Group
|