View previous topic :: View next topic |
Author |
Message |
prafulla.prolific
Joined: 05 Jun 2013 Posts: 10 Location: Mumbai
|
Help For Zero Detect & Phase Angle Control |
Posted: Tue Jun 11, 2013 5:50 am |
|
|
I am using 16F873A Controller for Phase Control & Zero Detect. Using Optocoupler EL817D, I have read Zero detect and output Pulse given to MOC3023 which connect between TRIAC Gate & Microcontroller. I have written Sample Program for low Phase Level.my code as
Pin Used for functioning as
Pin 26-RB5- Zero Cross Detect.
Pin 4-RA2- Phase Drive _Pulses to MOC3023.
Code: |
//------------------------------------------------------------------------------
#define MINIMUM_FIRING_ENGLE 115
#define MAXIMUM_FIRING_ENGLE 245
//------------------------------------------------------------------------------
void initialize_ports(void);
void initialize_variables(void);
unsigned int8 fire_on_delay;
unsigned int8 firing_angle;
unsigned int1 TRAIC_GATE;
//------------------------------------------------------------------------------
#int_RB
void RB_isr(void) // Zero Cross Detect _ to Pin RB5
{
TRAIC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
}
//------------------------------------------------------------------------------
#int_TIMER0
void TIMER0_isr(void)
{
disable_interrupts(INT_TIMER0); //disable timer0 interrupt
if(TRAIC_GATE)
{
output_low(PIN_A2);
TRAIC_GATE=0;
set_timer0(fire_on_delay);
enable_interrupts(INT_TIMER0);
}
else if(!TRAIC_GATE)
{
output_high(PIN_A2);
TRAIC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0);
}
}
//------------------------------------------------------------------------------
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
// setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
setup_timer_1(T1_DISABLED);
enable_interrupts(INT_RB);
// setup_timer_2(T2_DIV_BY_16,255,1);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
initialize_ports();
initialize_variables();
// enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(TRUE)
{
firing_angle = 142.61;
fire_on_delay= 238.39;
}
// TODO: USER CODE!!
}
//------------------------------------------------------------------------------
void initialize_ports(void)
{
output_low(PIN_A0);
output_low(PIN_A1);
output_high(PIN_A2); \\Output to TRIAC Gate_ Through MOC3023
output_float(PIN_A3);
output_float(PIN_A4);
output_float(PIN_A5);
output_float(PIN_B5);
}
//------------------------------------------------------------------------------
void initialize_variables(void)
{
TRAIC_GATE=0;
firing_angle = 142.61;
fire_on_delay= 238.39;
}
//----------------------------------------------------------------------------- |
Previously i had written code for 16F684. It is working but using same logic it can't work. Can anyone help me? What's wrong in my logic or in program? _________________ I m Working as PIC Programmer Fresher |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Jun 11, 2013 5:58 am |
|
|
1-care to post the schematic of your circuit?
2- what were you expecting by trying to set timers to FLOAT values ?
3- what you posted is horribly INCOMPLETE - and nearly impossible to analyze. for instance : what PIC - ? what CLOCK/use_delay??
4- POST A PROGRAM that COMPILES , and is complete and shows your issue !!!
then we have this:
Code: |
fire_on_delay= 238.39; // odd assignment for an INT8 !!
firing_angle = 142.61;
// and in the isr
set_timer0(fire_on_delay);
set_timer0(firing_angle);
|
also
you never change your params for the above either ??
and
it is not useful to disable and re-enable ints INSIDE your ISR.
you have quite the mess and it is hard to know where to start really |
|
|
prafulla.prolific
Joined: 05 Jun 2013 Posts: 10 Location: Mumbai
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 11, 2013 1:34 pm |
|
|
Quote: | Previously i had written code for 16F684
It is working |
There is no way this code worked before.
That's because this #int_rb code is wrong. The #int_rb interrupt occurs
when an i/o pin changes state. The "changed state" condition is latched.
As long as the latch (inside the PIC) is set, the #int_rb interrupt will
continuously occur. To clear the latch, you have to read PortB. However
if you use the input_b() function to read the port, it will normally change
all of PortB into an input port. If some pins on PortB are used for outputs,
this setup will be changed, and those output pin won't work. So it's better
to read PortB directly.
Code: | #int_RB
void RB_isr(void) // Zero Cross Detect _ to Pin RB5
{
TRAIC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
} |
The code below shows how to read PortB without changing the TRIS,
to clear the "change condition" for #int_rb:
Code: |
#int_RB
void RB_isr(void) // Zero Cross Detect _ to Pin RB5
{
#byte PortB = getenv("SFR:PortB")
int8 temp;
temp = PortB;
TRAIC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
}
|
Also, another little minor thing. The device is called a "Triac". You spelled
it wrong in "TRAIC_GATE". Why is this important ? It's because C
programming and electronics requires attention to detail. Every little
detail is or can be important. If you miss something so simple as spelling,
how can you do a complex program with hundreds of details that must all
be correct ?
This line below is from the CCS Wizard. It's not correct. It's bug in the
wizard. Delete that line. It's not needed. SPI is disabled on power-up.
Quote: | setup_spi(SPI_SS_DISABLED); |
The code below shows that you have not learned the C language.
You are putting a floating number into a "unsigned 8 bit integer".
An 'int8' can only hold numbers from 0 to 255. How can it possibly
hold 142.61 ? I will be very clear. When an experienced programmer
sees this type of mistake, he groans. You must learn basic C
programming before you write a complicated program.
Quote: | unsigned int8 fire_on_delay;
unsigned int8 firing_angle;
firing_angle = 142.61;
fire_on_delay= 238.39; |
|
|
|
prafulla.prolific
Joined: 05 Jun 2013 Posts: 10 Location: Mumbai
|
|
Posted: Wed Jun 12, 2013 12:57 am |
|
|
Dear PCM Programmer I have change interrupt PORTB Change as given by your code
Code: | #int_RB
void RB_isr(void) // Zero Cross Detect _ to Pin RB5
{
#byte PortB = getenv("SFR:PortB")
int8 temp;
temp = PortB;
TRAIC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
} |
But not effect i had check zero detect pulse on CRO it shows 7ms ON & 3ms OFF pulses of 100Hzs, But on Outputside it shows 25us pulses also not stable. i am so confuse.
I am also posting previous code for 16F684 as
Code: |
#include <16F684.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PROTECT //Code protected from reads
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOCPD //No EE protection
#FUSES NOPUT //No Power Up Timer
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#use delay(clock=8000000)
//------------------------------------------------------------------------------
#define MINIMUM_FIRING_ENGLE 115
#define MAXIMUM_FIRING_ENGLE 245
#BYTE PORTA = 0x05
#BYTE PORTC = 0x07
//------------------------------------------------------------------------------
void initialize_ports(void);
void initialize_variables(void);
void read_pot_position(void);
void shift_buff(void);
void shift_adc_buff(void);
unsigned int8 buff[50]={};
unsigned int8 fire_on_delay;
unsigned int8 firing_angle;
unsigned int1 TRAIC_GATE;
unsigned int8 temp_port_a;
//------------------------------------------------------------------------------
#int_RA
void RA_isr(void)
{
TRAIC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
temp_port_a = PORTA;
}
//------------------------------------------------------------------------------
#int_TIMER0
void TIMER0_isr(void)
{
disable_interrupts(INT_TIMER0); //disable timer0 interrupt
if(TRAIC_GATE)
{
output_low(PIN_C2);
TRAIC_GATE=0;
set_timer0(fire_on_delay);
enable_interrupts(INT_TIMER0);
}
else if(!TRAIC_GATE)
{
output_high(PIN_C2);
TRAIC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0);
}
}
//------------------------------------------------------------------------------
void main()
{
setup_adc_ports(sAN5|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_64);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
enable_interrupts(INT_RA);
setup_oscillator(OSC_8MHZ);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
initialize_ports();
initialize_variables();
// enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(TRUE)
{
read_pot_position();
}
}
//------------------------------------------------------------------------------
void initialize_ports(void)
{
output_float(PIN_A0);
output_float(PIN_A1);
output_float(PIN_A2);
output_float(PIN_A3);
output_float(PIN_A4);
output_float(PIN_A5);
output_high(PIN_C0);
output_float(PIN_C1);
output_high(PIN_C2);
output_float(PIN_C3);
output_float(PIN_C4);
output_float(PIN_C5);
}
//------------------------------------------------------------------------------
void initialize_variables(void)
{
unsigned int8 i;
firing_angle = MINIMUM_FIRING_ENGLE;
TRAIC_GATE=0;
for(i=0;i<50;i++)
{
buff[i]=firing_angle;
}
}
//------------------------------------------------------------------------------
void read_pot_position(void)
{
unsigned int32 adc_output_data;
unsigned int16 i;
unsigned int8 temp_data;
unsigned int8 fire_data;
// unsigned int16 read_data;
set_adc_channel(5);
adc_output_data = 0;
for(i = 0; i <100; i++)
{
adc_output_data += read_adc(ADC_START_AND_READ);
}
temp_data=(unsigned int8)(adc_output_data/927.2);
if(temp_data > 11)
{
fire_on_delay=(unsigned int8)(266 - temp_data);
}
else
{
fire_on_delay=255;
}
fire_data = MINIMUM_FIRING_ENGLE + temp_data;
firing_angle =buff[0];
if(temp_data <=1)
{
firing_angle =0;
}
shift_buff();
buff[49]=fire_data;
}
//-----------------------------------------------------------------------------
void shift_buff(void)
{
unsigned int8 j;
for(j=0;j<49;j++)
{
buff[j]=buff[j+1];
}
}
//------------------------------------------------------------------------------
| its working with same hardware but PIC IC Change.I am Confuse please give any hint i will also try.
[img]http://postimg.org/image/yjr4nsi1r/[/img] _________________ I m Working as PIC Programmer Fresher |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Jun 12, 2013 9:54 am |
|
|
i lack confidence in the zero cross detector to actually show you the true
zero without, ongoing, varying ERROR.
1:
for true random firing angle - C8 may be too large for "low angle" , reliable firing. i would even OMIT it....
2:
using an OPTO coupler is dramatically less reliable than transformer coupling,
in my own design experience of such matters.
this is not to say i am SURE OPTO's can't work -
merely that on casual inspection, the circuit you show is susceptible to several kinds of error and drift, -
that a transformer + comparator circuit - would be more immune to . |
|
|
prafulla.prolific
Joined: 05 Jun 2013 Posts: 10 Location: Mumbai
|
|
Posted: Mon Jun 24, 2013 1:55 am |
|
|
ya now i modify my code and after zero detect interrupt occur start timer0 for delay for phase angle and give pulse (High) to MOC3021 and after 7ms from zero detect again pulse going to LOW to MOC3021 it work properly. Timer0 Delay increase from 1ms to 7ms then light intensity varies. _________________ I m Working as PIC Programmer Fresher |
|
|
|