CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Need help with AC 60Hz Dimmer ( timer0 interrupt )

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
freesat



Joined: 08 Feb 2011
Posts: 32

View user's profile Send private message

Need help with AC 60Hz Dimmer ( timer0 interrupt )
PostPosted: Wed Sep 21, 2011 4:20 pm     Reply with quote

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

View user's profile Send private message

change the code... now its works better, but need adjusts.
PostPosted: Thu Sep 22, 2011 1:59 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Sep 22, 2011 1:44 pm     Reply with quote

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

View user's profile Send private message

Only triac fire on incorrect time on waveform
PostPosted: Thu Sep 22, 2011 5:29 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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