|
|
View previous topic :: View next topic |
Author |
Message |
nayeemcron
Joined: 21 Sep 2023 Posts: 5
|
Need urgent help with Zero crossing detector. |
Posted: Thu Sep 21, 2023 9:39 pm |
|
|
Can any one help me? I want to create a program to detect zero crossing. So, I am using PIN_A6 as my ZC pin which is just a digital input. It will be connected through a 1M resistor to be able to detect zero crossing. A PWM signal will be generated on CCP1 which is the ONPIN PIN_B3 in this case. This is to provide a input for a MOSFET Gate driver circuit. The code works for me and is able to detect zero crossing, however I want to add the following function:
*Detect true zero crossing by checking whether the state change is steady for 0.3ms.
*Exit out of the while loop if no zero crossing is detected for 11ms.
I am providing 230VAC 50hz.
Need urgent help, I am new to embedded systems programming.
Code: |
/************************************************************************
*****************************Header Files*******************************
************************************************************************/
#include <16F1826.h>
/************************************************************************
*****************************Configuration Bits*************************
************************************************************************/
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOCPD,NOMCLR //config bits
#use delay(clock = 32MHz) //define system clock
#use timer(timer=1, tick = 1us, bits = 16, noisr)
/************************************************************************
*****************************Pin Defination*****************************
************************************************************************/
#define ZCPin PIN_A6
#define ONPin PIN_B3
#define OFFPin PIN_A1
#define LEDPin PIN_A0
/************************************************************************
*****************************Global Valiables***************************
************************************************************************/
unsigned int GONFlag = 0;
unsigned int zCurrentState = 4;
unsigned int zPrevState = 4;
unsigned long time = 0;
/************************************************************************
*****************************Functions**********************************
************************************************************************/
void GateON();
/************************************************************************
*****************************Main Block*********************************
************************************************************************/
void main() {
delay_ms(5000);
GONFlag = 0;
set_tris_a(0x40); //PORT A defination
set_tris_b(0x00); //PORT B defination
output_low(PIN_A0);
while(1)
{
unsigned int zReading = input(ZCPin);
unsigned int currentZC;
unsigned int lastZC;
unsigned long timerTime;
if(zReading != zPrevState)
{
timerTime = get_ticks();
}
if(zReading != zPrevState && get_ticks() > timerTime-300)
{
if(zReading != zCurrentState)
{
zCurrentState = zReading;
if(zCurrentState == 1 && zPrevState ==0)
{
currentZC = 1;
}
else if(zCurrentState == 0 && zPrevState ==1)
{
currentZC = 1;
}
}
}
else
{
currentZC = 0;
}
zPrevState = zCurrentState;
if(GONFlag == 0 && currentZC == 1)
{
GONFlag = 1;
GateON();
}
// if(currentZC == lastZC && get_ticks() > 11000)
// {
// output_high(PIN_A0);
// break;
// }
// set_ticks(64535);
}
return;
}
void GateON()
{
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_4, 255, 1); // Set PWM frequency
set_pwm1_duty(127);
output_low(PIN_A7);
}
|
_________________ Nayeem |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19463
|
|
Posted: Sat Sep 23, 2023 2:54 am |
|
|
First, learn to use the code buttons. I have edited your post to use these.
Then, the circuit you describe is terribly dangerous, and will not detect
zero crossing properly, though it will probably sort of work, the levels
will be different on the negative half cycle than the positive half cycle.
Look at the circuits posted here:
[url]
https://circuitdigest.com/electronic-circuits/zero-crossing-detector-circuit-diagram
[/url]
Using an opto, or a transformer. These are the safer ways of doing this.
Be aware though that the opto circuit needs a transformer, or perhaps
a 2M2 resistor, not a 2K2 as shown.....
Look at using a timer. Very simple to have one counting, reset it on
the first detection and then when it reaches a particular count do your
test for still being steady, another can simply be used for the timeout
if no change. |
|
|
nayeemcron
Joined: 21 Sep 2023 Posts: 5
|
|
Posted: Tue Sep 26, 2023 4:10 pm |
|
|
Thank you!
How can I have a timeout for no change. Please help! _________________ Nayeem |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9205 Location: Greensville,Ontario
|
|
Posted: Wed Sep 27, 2023 5:34 am |
|
|
If I understand what you want, have a look in the CCS manual, 'common Q*A' section, 'How do I get getc() to timeout after a specified time?'
Copy the function, rename it,then...change to read at the ZCD pin and edit the time for 300ms.
This 'might' work for you.
As Mr. T says ISOLATE the 'mains' from both PIC and YOU !!!!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19463
|
|
Posted: Wed Sep 27, 2023 6:23 am |
|
|
He is not using getc. Just waiting on an external signal change.
However the answer CCS give in their FAQ (dating from before they
added the internal timeout ability), shows exactly how to do this:
[url]
https://www.ccsinfo.com/faq.php?page=getc_timeout
[/url]
Personally I'd use a timer rather than the count, to give an accurate time.
This is basic programming, and he needs to do this himself. |
|
|
nayeemcron
Joined: 21 Sep 2023 Posts: 5
|
|
Posted: Wed Sep 27, 2023 3:55 pm |
|
|
Sorry guys, I am a beginner in programming, which is why I was asking for help. And for Isolation, its not required in this application, as I do not need a bridge rectifier in my circuit for the power circuitry. Its a very low current application, and I am building regulators using zeners. [/code] _________________ Nayeem |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9205 Location: Greensville,Ontario
|
|
Posted: Wed Sep 27, 2023 4:55 pm |
|
|
You NEED isolation to keep the 230 VAC from destroying the PIC as well as not electrocuting YOU.
It is very easy to forget there's 230 on that PCB, get distracted ( phone rings, cat wants treats....) and you touch 240 volts. While the shock may not kill you, the lightning fast recoil of your arm into the filing cabinet drawer CAN break your wrist and send you to hospital.
PICs are cheap but a trip to the hospital will cost you a LOT of money !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19463
|
|
Posted: Fri Sep 29, 2023 4:33 am |
|
|
It is also very important to understand that a main supply will often have
momentary spikes way above the rated voltage. A single resistor, even if it is
rated to stand 250v, may well go short circuit if exposed to such a spike.
This is why circuitry that uses resistors to feed mains into something, will
normally have two resistors in series each of half the used value. This way
if one fails short circuit, the current is still kept to a potentially safe level.
Designing circuits to actually be 'safe' when working with mains voltage
needs a lot of learning. |
|
|
nayeemcron
Joined: 21 Sep 2023 Posts: 5
|
|
Posted: Sun Oct 08, 2023 4:08 pm |
|
|
I understand the concerns but this is already an existing PCB design which needs to be updated. I will use an optocoupler with a builtin bridge rectifier to do this but for now I need to prototype using existing PCB which has only a 1M2 reistor connected to the ZCD input pin. Also for prototyping I am using isloation transformer to connect to the mains and I am able to control the amount of short circuit current. Since I am new to programming, I was seeking for code advice. _________________ Nayeem |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19463
|
|
Posted: Mon Oct 09, 2023 2:26 am |
|
|
Seriously,
take that circuit and throw it away. If this is commercial, threaten the
company that you will report it to the electrical authorities in your country.
Single resistor droppers are illegal in most countries. |
|
|
nayeemcron
Joined: 21 Sep 2023 Posts: 5
|
|
Posted: Mon Oct 09, 2023 5:31 pm |
|
|
Yes. I am working with an update now in which I will use Opto with bultin bridge to do the zc detection.
In the Mean time, I am just writing code with existing hardware to validate it. Below is my code.
[/************************************************************************
*****************************Header Files*******************************
************************************************************************/
#include <16F1826.h>
/************************************************************************
*****************************Configuration Bits*************************
************************************************************************/
#fuses INTRC_IO,WDT_SW,NOPUT,NOPROTECT,NOCPD,NOMCLR,NOFCMEN,NOCLKOUT,NOIESO //config bits
#fuses NOSTVREN,BORV25,NODEBUG,LVP
#use delay(clock = 16MHz) //define system clock
#use timer(TIMER=0,TICK=1ms,BITS=8,NOISR)
/************************************************************************
*****************************Pin Defination*****************************
************************************************************************/
#define ZCPin PIN_A6
#define ONPin PIN_B3
#define OFFPin PIN_B4
#define RLY_Spin PIN_B5
#define RLY_Rpin PIN_B6
#define LEDpin PIN_A4
/************************************************************************
*****************************Global Valiables***************************
************************************************************************/
unsigned int RLYFlag;
unsigned int GONFlag;
unsigned int zCurrentState;
unsigned int zPrevState;
volatile unsigned int ZC;
unsigned int ZCP;
unsigned long time;
/************************************************************************
*****************************Function Prototypes************************
************************************************************************/
void RLYON();
void RLYOFF();
void GateON();
void GateOFF();
/************************************************************************
*****************************Main Block*********************************
************************************************************************/
void main() {
setup_oscillator(OSC_16MHZ);
RLYFlag = 0;
GONFlag = 0;
output_a(0x00);
output_b(0x00);
set_tris_a((1<<6)|(0<<3)|(0<<4));
set_tris_b((0<<4)|(0<<5)|(0<<6));
output_a(0x00);
output_b(0x00);
//setup_wdt(WDT_32MS);
delay_ms(1000);
setup_timer_0(T0_INTERNAL | T0_DIV_256);
enable_interrupts(INT_TIMER2); // Enable Timer1 interrupt
enable_interrupts(GLOBAL); // Enable global interrupts
setup_timer_2(T0_INTERNAL | T2_DIV_BY_16, 50, 1);
while(1)
{
if(RLYFlag == 0 && ZC == 1)
{
clear_interrupt(INT_TIMER2);
disable_interrupts(INT_TIMER2);
RLYON();
RLYFlag = 1;
enable_interrupts(INT_TIMER2);
}
else if(ZC==1)
{
clear_interrupt(INT_TIMER2);
disable_interrupts(INT_TIMER2);
GateON();
if(GONFlag == 0)
{
clear_interrupt(INT_TIMER2);
output_high(ONPin);
delay_ms(1000);
RLYOFF();
GONFlag = 1;
}
GateOFF();
enable_interrupts(INT_TIMER2);
}
if(ZC == 0 && get_ticks() > 50)
{
GateOFF();
break;
}
}
return;
}
/************************************************************************
*****************************TIMER 2 ISR********************************
************************************************************************/
#INT_TIMER2
void timer2_isr()
{
clear_interrupt(INT_TIMER2);
disable_interrupts(INT_TIMER2);
zCurrentState = input(ZCPin);
if(zCurrentState != zPrevState)
{
if(zCurrentState == 1 && zPrevState == 0)
{
set_ticks(0);
ZC = 1;
}
else if(zCurrentState == 0 && zPrevState == 1)
{
set_ticks(0);
ZC = 1;
}
}
else
{
ZC = 0;
}
zPrevState = zCurrentState;
enable_interrupts(INT_TIMER2);
}
/************************************************************************
*****************************Function Definations***********************
************************************************************************/
void RLYON()
{
output_high(RLY_Spin);
delay_ms(12);
output_low(RLY_Spin);
}
void RLYOFF()
{
output_high(RLY_Rpin);
delay_ms(12);
output_low(RLY_Rpin);
}
void GateON()
{
delay_ms(1);
output_high(ONPin);
delay_ms(7);
output_low(ONPin);
delay_ms(1);
}
void GateOFF()
{
output_low(ONPin);
output_high(OFFPin);
}][/code] _________________ Nayeem |
|
|
|
|
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
|