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

A question about Triac triggering
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Jul 01, 2013 4:28 pm     Reply with quote

For the MOC3020 - i would use 10 us LED drive to insure repeatable firing , especially for good "late in the cycle" operation.

The MOC3020 is a very low cost device with a SLOW response for guaranteed activation.

For really FAST triggering - i would consider a ferrite transformer coupled circuit, and a comparator form of Z cross detector.

Let me guess: this is a hobbyist/student endeavor?
shams



Joined: 30 Jun 2013
Posts: 11

View user's profile Send private message

PostPosted: Tue Jul 02, 2013 12:17 am     Reply with quote

Ttelmah wrote:
Because you want to adjust how long _after_ the zero cross, you fire the TRIAC.....
...

So is it that...I can fire the triac through Timer INT without firing in while loop?
Sorry, I'm asking so many questions.
Code:
  while (1) {
     if (ZC)
     {
        output_high(PIN_C0);
       ...
     }
  }


Can it be used in this way...:
Code:

#include <16F886.h>

#fuses HS
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin NOT enabled
#FUSES BROWNOUT //Reset when brownout detected

#use delay(clock=20M)

#define DIM_LEVEL 65535
int1 ZC=FALSE;


#INT_EXT                         //External Interrupt
void  EXT_isr(void)
{
   output_low(PIN_C0);             //make sure gate is OFF

   set_timer0(DIM_LEVEL);          //preload_time into Timer0
   enable_interrupts(INT_TIMER0);  //start Timer0

   ZC = TRUE;

}

#int_TIMER0
void  TIMER0_isr(void)
{
     if (ZC)   //execute if zero crossing occures
     {
        set_timer0(0);        //stop Timer0
        output_high(PIN_C0);  //turn the gate ON
        delay_uS(100);
        output_low(PIN_C0);  //turn the gate OFF
        clear_interrupt(INT_TIMER0);  //clear Timer0
        ZC = FALSE;
     }
}

void main( void ) {

   //drive all pins low, except B0, set as input
   output_b(0);
   output_c(0);
   output_float(PIN_B0);

   setup_timer_0( T0_INTERNAL | T0_DIV_1 );

   //ext_int_edge(H_TO_L); //set the falling edge to trigger on the ZC signal
   ext_int_edge(L_TO_H);   //set the rising edge to trigger on the ZC signal

   clear_interrupt(INT_EXT);

   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

  while (1) {

  }
}


Last edited by shams on Wed Jul 03, 2013 1:26 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19620

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 12:44 am     Reply with quote

You are still 'missing the point' about TRIAC firing. The duration of the pulse has nothing whatsoever to do with how long the TRIAC is on.

It is 'when' the pulse is relative to the zero crossing point that controls the 'on' duration.

You need to display the following in a fixed pitch font:

Code:

|-------------------|-------------------|------  zero crossing points

-|-------------------|-------------------|-----  firing pulse for 'full on'

-------------------|-------------------|-------  firing pulse for 'minimum'

----------|-------------------|----------------  firing pulse for '50%'


Now, the firing pulse is just a pulse. For your rather slow TRIAC, 10uSec ideal. Fast TRIAC's, have nSec pulse widths required.
Once fired, the TRIAC itself, remains on, for the rest of the mains half cycle.
You can't fire the TRIAC, till it has a little voltage across it, so you cannot fire it 'at' the zero crossing point.
For 50Hz mains, a 'half cycle', is 10mSec.
So fire it 1mSec after the zero point, and it'll be on 90% of the time.
Fire it 9mSec after the zero point, and it'll be on just 10% of the time.
Fire it 5mSec after the zero point, and it'll be on 50% of the time.

So (logic only):
Code:

Detect zero - start timer - set the time to time-out, based upon the power you want. Longer time - up to10mSec = lower power.

Detect timer time-out, - fire the pulse. Go back to waiting for the zero detection.


You have to get away from thinking of the actual 'pulse' having any relationship to how long the TRIAC is 'on'. It is _when_ the pulse happens, that determines this, nothing else.

Best Wishes
shams



Joined: 30 Jun 2013
Posts: 11

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 1:33 am     Reply with quote

Thank you, Ttelmah. I changed the code as per your suggestion.
Kindly see above your post. Do you think the concept is right?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 2:33 am     Reply with quote

You're the with the hardware in front of you.

Tell us, does it do what you expect or not?

You've got this line, so I'm assumng that you really have a 20MHz clock.
Code:
#use delay(clock=20M)

That's 5M instruction cycles per second.

You've then set up a timer0 delay to count down with these lines.
Code:
#define DIM_LEVEL 65535
.........
set_timer0(DIM_LEVEL);          //preload_time into Timer0

How long do you think the delay might be?

Mike

PS You are also expecting us to remember what your old code was after you've editted an old post.
I've slept since then and suggest you simply post your new code, leaving the original post intact.

EDIT
At your level you'ld be better off using the CCS delay functions throughout.
That way you could write very short simple code 'til you've learnt the basics.
shams



Joined: 30 Jun 2013
Posts: 11

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 2:53 am     Reply with quote

Mike Walne wrote:
...
I've slept since then and suggest you simply post your new code, leaving the original post intact.
...

Thanks Mike. I'll follow that next time.

I'm expecting that Triac will be fired after the "waiting time" set in Timer0. But it's not working in my expected way. I really need to understand the timer math.
Do you mind to share the calculation for timer0 delay?

EDIT:
This is the math I discovered.
((1/(MainsFreq*2)) / 256) / (1/(Crystal Freq/4)) = TimerCount

For 50Hz Mains @ 20Mhz Clock
1/(50Hz*2) = 10ms
10ms/256 = 39us
1/(20MHz/4) = 0.2us
39us/0.2us = 195

So if I got the math right then my max delay will be 256-195=61...is it?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 3:41 am     Reply with quote

It would help if you told us what your code:-

1) Should do.
2) Does do.
3) Does not do.

There are just too many things you don't understand.

I'm suggesting you do soemthing REALLY simple, as a learning exercise.

I'm assuming that you're hardware is OK, and you can do a simple 1Hz LED flasher at the correct speed.

THEN

Do a forever loop:-

1) Wait for zero cross.
2) Wait 5ms (i.e. delay_ms(5).
3) Fire Triac.
4) Loop back to (1)

Work on the KISS principal.
Do not use interrupts etc.
The code for the entire loop should be no more than 6 or 7 lines!
Should fire Triac with 50% duty.

Get to the stage where something works as expected, learn and make progress.

Mike
shams



Joined: 30 Jun 2013
Posts: 11

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 4:27 am     Reply with quote

Thanks once again.

Actually my HW and code both works without the Timer INT. But I would like to implemen Timer INT since I'll be using an ADC to change the delay.

Working code (without Timer INT):
Code:

#include <16F886.h>

#fuses XT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin NOT enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT

#use delay(int=4000000)

int1 ZC=FALSE;


#INT_EXT                         //External Interrupt
void  EXT_isr(void)
{
   if(!ZC){     //check if gate is really OFF
     output_low(PIN_C0);
   }
   ZC = TRUE;

}


void main( void ) {

   //drive all pins low, except B0, set as input
   //output_a(0);
   output_b(0);
   output_c(0);
   output_float(PIN_B0);

   ext_int_edge(L_TO_H);   //set the rising edge to trigger on the ZC signal

   clear_interrupt(INT_EXT);

   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

  while (1) {
     if (ZC)
     {
        delay_ms(6);    //set the luminosity 50%
        output_high(PIN_C0);
        delay_uS(100);
        output_low(PIN_C0);
        ZC = FALSE;
     }

  }
}
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 7:06 am     Reply with quote

I was anticipating you might work entirely without any interrupts.

However:-

1) Are you now saying that your latest code gives you the brightness you expect?
2) Can you change the brightness by varying the value in the delay_ms(xx) statement?

Yes. I understand what it is you are trying to do, but you need to work in SMALL manageable steps.
Get one section working properly, then move on.

Mike
shams



Joined: 30 Jun 2013
Posts: 11

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 8:48 am     Reply with quote

Hi Mike, answer of your questions:

1. Yes, I get the expected brightness
2. Yes, brightness is varying by the value of delay_ms (0-10ms).

However, adding ADC option changes the whole thing...i.e lamp starts blinking...

I read a lot about Timer INT and the help from you guys, seems I'm close to the concept. But one thing I still couldn't discover, it is the timer prescaller thing.
Code:

setup_timer_0( T0_INTERNAL | T0_DIV_1 );
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
..etc.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 9:40 am     Reply with quote

Good, you're making progress
Quote:
Hi Mike, answer of your questions:

1. Yes, I get the expected brightness
2. Yes, brightness is varying by the value of delay_ms (0-10ms).

BUT:-
Quote:
However, adding ADC option changes the whole thing...i.e lamp starts blinking...

a) How many new things are you trying to introduce at once?
b) Are you trying to use the timers?
c) Are you certain that your ADC values are stable?

I'm asking these questions in response to
Quote:
I read a lot about Timer INT and the help from you guys, seems I'm close to the concept. But one thing I still couldn't discover, it is the timer prescaller thing.
Code:

setup_timer_0( T0_INTERNAL | T0_DIV_1 );
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
..etc.


Mike
shams



Joined: 30 Jun 2013
Posts: 11

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 10:19 am     Reply with quote

Thanks buddy. Laughing

I'm not trying ADC at the moment and my concentration is timer thing. I think I need the Tick approx 60* per second. I need your help to understand the calculation.
Code:
setup_timer_0(T0_INTERNAL|T0_8_BIT|T0_DIV_64);
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jul 03, 2013 11:04 am     Reply with quote

Sorry for being so pedestrian, but you keep trying to run before you can crawl, let alone walk.

What do you actually want the timer_0 to do for you?
I need to know before I can offer guidance.

Mike
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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