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 urgent help with Zero crossing detector.

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



Joined: 21 Sep 2023
Posts: 5

View user's profile Send private message

Need urgent help with Zero crossing detector.
PostPosted: Thu Sep 21, 2023 9:39 pm     Reply with quote

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: 19504

View user's profile Send private message

PostPosted: Sat Sep 23, 2023 2:54 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Sep 26, 2023 4:10 pm     Reply with quote

Thank you!
How can I have a timeout for no change. Please help!
_________________
Nayeem
temtronic



Joined: 01 Jul 2010
Posts: 9224
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 27, 2023 5:34 am     Reply with quote

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: 19504

View user's profile Send private message

PostPosted: Wed Sep 27, 2023 6:23 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 27, 2023 3:55 pm     Reply with quote

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: 9224
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 27, 2023 4:55 pm     Reply with quote

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: 19504

View user's profile Send private message

PostPosted: Fri Sep 29, 2023 4:33 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Oct 08, 2023 4:08 pm     Reply with quote

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: 19504

View user's profile Send private message

PostPosted: Mon Oct 09, 2023 2:26 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 09, 2023 5:31 pm     Reply with quote

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
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