Arduino Forum

Using Arduino => Programming Questions => Topic started by: taurian on Mar 11, 2012, 07:30 pm

Title: Zero crossing detection
Post by: taurian on Mar 11, 2012, 07:30 pm
hello
I am through an electronic circuit to detect the I zero crossing it enters the pin enables the interruption arduino and to calculate the period of the input signal.

this and the code I'm using ....

Code: [Select]
int digitalPin=2;
float pulseHigh,stopTime,startTime,pulseLow,perio;


void setup(){

 Serial.begin(9600);
  pinMode(digitalPin, INPUT);
 
   attachInterrupt(0, periodo,FALLING);

}


void loop(){



}
void periodo(){
  detachInterrupt(0);
 if(digitalRead((2)==HIGH)){
 startTime=micros();
   pulseHigh=startTime-stopTime;
 }
 if(digitalRead((2)==LOW)){
     
     
   startTime=micros();
   pulseLow=stopTime-startTime;
 }
 perio=pulseHigh+pulseLow;
 Serial.println('Periodo');
 Serial.println(pulseHigh,BIN);

}


Thanks Gil


Moderator edit: [code] [/code] tags added.
Title: Re: Zero crossing detection
Post by: Grumpy_Mike on Mar 11, 2012, 07:33 pm
You can't use serial print from inside an interrupt routine.
Title: Re: Zero crossing detection
Post by: taurian on Mar 11, 2012, 07:36 pm
But as I do as a void function does not return?


Thanks Gil
Title: Re: Zero crossing detection
Post by: Grumpy_Mike on Mar 11, 2012, 07:39 pm
A void function is just a function that returns no values, this has nothing to do with your problem which is that you are using print statements inside an interrupt.
Title: Re: Zero crossing detection
Post by: taurian on Mar 11, 2012, 07:48 pm
yes you are right I have to do seriaprint outside the function.
Title: Re: Zero crossing detection
Post by: Techone on Mar 12, 2012, 04:28 am
Quote
I am through an electronic circuit to detect the I zero crossing it enters the pin enables the interruption arduino and to calculate the period of the input signal.


I am just curious. What is the schematic ? Can you post it ? And what is the expect frequency going into the interrupt pulse ?

I did a code to measure the time on and off of a AC voltage from the plug of a home.  I use pulseIn(). A little calculation there, and I show the frequency, duty cycle, time on and time off. No interrupt. The Ardiuno is fast enough to use pulseIn(). An interrupt will work, but it as to be very short, like for example :

Code: [Select]

void myinterrupt()
{
  state = HIGH;
}


And in your main code, you simply check that HIGH using a while() loop or if() or do { } while() loop.
Title: Re: Zero crossing detection
Post by: el_supremo on Mar 12, 2012, 04:39 am
You should not call detachInterrupt in the interrupt routine. When you do that it means that subsequent interrupts will not call periodo again.

Pete
Title: Re: Zero crossing detection
Post by: nickgammon on Mar 12, 2012, 07:45 am
Code: [Select]


    attachInterrupt(0, periodo,FALLING);

...

void periodo(){
   detachInterrupt(0);
  if(digitalRead((2)==HIGH)){    //  <---- well this will never happen


Title: Re: Zero crossing detection
Post by: taurian on Mar 12, 2012, 12:53 pm
Quote
I did a code to measure the time on and off of a AC voltage from the plug of a home.  I use pulseIn(). A little calculation there, and I show the frequency, duty cycle, time on and time off. No interrupt. The Ardiuno is fast enough to use pulseIn(). An interrupt will work, but it as to be very short, like for example :



Hello
I tried to do it your way whatever. I have the circuit in proteus I've put it here.

int pin = 7;
int pin1 = 6;
unsigned long duration, pulseHigh, pulseLow,fre;
void setup()
{
  Serial.begin(9600);
  pinMode(pin, INPUT);
  pinMode(pin1, INPUT);
}

void loop()
{
  //Serial.println('duration');
  pulseHigh = pulseIn(pin, HIGH);
  pulseLow = pulseIn(pin1,LOW);
  duration= pulseHigh+pulseLow;
  fre=1/duration;
  Serial.println(fre);
}


thank Gil
Title: Re: Zero crossing detection
Post by: taurian on Mar 12, 2012, 12:58 pm
Quote
attachInterrupt(0, periodo,FALLING);

...

void periodo(){
   detachInterrupt(0);
  if(digitalRead((2)==HIGH)){    //  <---- well this will never happen


I want to calculate a time period then I will release the microcontroller to do other operations, and only when done and recalculates the period.


thank Gil
Title: Re: Zero crossing detection
Post by: Grumpy_Mike on Mar 12, 2012, 01:02 pm
Quote
I have the circuit in proteus I've put it here.

Link??

Please use the # icon when posting code not the quote icon next to it.
Title: Re: Zero crossing detection
Post by: taurian on Mar 12, 2012, 01:06 pm
ok thanks for the info


Thanks Gil :)
Title: Re: Zero crossing detection
Post by: Techone on Mar 12, 2012, 05:32 pm
@taurian

What is the frequency of the pulse being measured ?

The example code being show by you will work. The trick is, to sample the pulse a few times, average it and than you display and do other things, and come back you take samples again.   The interrupt method is OK, but you have to activate the interrupt, sample the pulse, de-activate the interrupt, and calculate, display, whatever you have to do and repeat.

 
Title: Re: Zero crossing detection
Post by: taurian on Mar 12, 2012, 07:21 pm
Quote
What is the frequency of the pulse being measured ?

The example code being show by you will work. The trick is, to sample the pulse a few times, average it and than you display and do other things, and come back you take samples again.   The interrupt method is OK, but you have to activate the interrupt, sample the pulse, de-activate the interrupt, and calculate, display, whatever you have to do and repeat.


The frequency that will work will be 60Hz to 50Hz

with the interruption is in order so that detects a transition by zero I start taking samples, but I have a problem if the frequency changes. always had to read the frequency ..
I do not know how?

Thanks Gil
Title: Re: Zero crossing detection
Post by: raxz on Mar 12, 2012, 08:39 pm
Is Your zero crossing detection schematic working?
I got my dimmer working.
I'm using Arduino Mega 1280.
Here is my code, hope You understand:
Code: [Select]

volatile int counterValue;
int requestValue;

void setup() {
 attachInterrupt(0, resetCounter, CHANGE);
 cli();                      //Disable global interrupts
 TCCR3A = 0;                 //Set register to 0
 TCCR3B = 0;                 //Set register to 0
 OCR3A = 640;                //Compare match register to get desired timer count (50Hz mains)
 TCCR3B |= (1 << WGM12);     //Turn on CTC mode
 TIMSK3 |= (1 << OCIE3A);    //Enable timer compare interrupt
 TCCR3B |= (1 << CS10);      //Start timer
 sei();                      //Enable global interrupts
 pinMode(7, OUTPUT);
}

ISR(TIMER3_COMPA_vect) {
 counterValue++;
 counterValue &= 0xff;
 if (counterValue==requestValue) {
   digitalWrite(7, HIGH);
 } else {
   digitalWrite(7, LOW);
 }
}

void resetCounter()
{
 counterValue=0;
}

void loop(){
 requestValue=map(analogRead(0), 0, 1023, 0, 255);
}
Title: Re: Zero crossing detection
Post by: taurian on Mar 12, 2012, 11:36 pm
(http://)
Quote
Is Your zero crossing detection schematic working?
I got my dimmer working.
I'm using Arduino Mega 1280.
Here is my code, hope You understand:


Here is my circuit
I could send the complete program to compile.
I wanted to calculate the frequency of a signal and take samples in the same period when the frequency change in the middle of taking the samples have to cancel these samples ..

(http://file:///C:/kk.jpg)

Thanks Gil
Title: Re: Zero crossing detection
Post by: taurian on Mar 13, 2012, 12:36 am
I'm not able to place an image. how can I do?

Thanks Gil
Title: Re: Zero crossing detection
Post by: Techone on Mar 13, 2012, 03:39 am
@taurian

Thank for the explaination. Alright, my schematic amd my code will work for that purpose. My zero crossing circuit use the output of a wall wart <-- extract / harvest transformer - reduce the AC secondary voltage , use op-amp as a comparator, when it cross the zero volt line, the state change, and the pulse is convert to TTL level and goes to a transistor - switch on / off and into a digital pin.

Check this tread.  http://arduino.cc/forum/index.php/topic,93205.0.html (http://arduino.cc/forum/index.php/topic,93205.0.html)
Title: Re: Zero crossing detection
Post by: Techone on Mar 13, 2012, 03:51 am
@Ragnar

I also did a dimmer using the Arduino. I use the same schematic <-- the zero level , but I rectify in full mode to produce positive pulse only, not positive and cut for 1/2 of 60 Hz. It produce two positive pulse from the 60 Hz, a full wave rectifier. I use the comparator to cut close to the zero to produce a 120 Hz very short pulse, and it is going into an digital / interrupt pin. And from it, it produce a PWM pulse, depending of the reading of the potentiometer, and send a turn off into the opto coupler, and the rest a turn on, the other side , opto and traic take care of the AC wave being cut properly and time right.

Here the tread. http://arduino.cc/forum/index.php/topic,91274.15.html (http://arduino.cc/forum/index.php/topic,91274.15.html)

Title: Re: Zero crossing detection
Post by: raxz on Mar 13, 2012, 06:03 am
I use this schematic: 
(http://www.hoelscher-hi.de/hendrik/light/dmxdimmer/zc_sch.gif)
Only problem is that dimmer is working, if requestValue is somewhere between 1 and 216.
I checked with oscilloscope and it gave me from full wave to zero between those values.

I have 8 channels of dimmer and I'm going to dim house lights with returning light switches or impulse light switches or however you call it. Holding switch down dims up, after release it dims down. Short click turns full on or full of etc...
Title: Re: Zero crossing detection
Post by: nickgammon on Mar 13, 2012, 06:07 am

I'm not able to place an image. how can I do?

Thanks Gil


Expand "Additional Options". There is an option there to attach a file (eg. a PNG file).

However to imbed it in the middle, some of us just upload the images to wherever (our own server, or an image host) and put an "image" link to it in the body of the post (see the buttons above the text entry box).
Title: Re: Zero crossing detection
Post by: taurian on Mar 13, 2012, 05:02 pm
This is my electronic circuit in Proteus

thanks Gil
Title: Re: Zero crossing detection
Post by: taurian on Mar 13, 2012, 06:04 pm
I think I already know but the less as I do already have my detecter circuit to the zero crossing as you pass by my zero external interruption is activated and will activate a timer and so I'll take samples until a new interruption ..

thank Gil
Title: Re: Zero crossing detection
Post by: Techone on Mar 13, 2012, 06:12 pm
@taurian

Can you print out the schematic, scan it, and re-post it here. The problem is. I don't have Proteus, and I am not the only one.

@Ragnar

Hmm... Simple. But I don't feel comfy about connected 230 VAC into a opto-coupler. More protection is needed, in my opinion. The pulse output will be only 50 Hz, so I assume your code will take care of it, to sync with the AC main.  My design is safer, the sync is taking care of the circuit to give me a 120 Hz pulse <-- I live in North America, and my code will take care of it.

If your code and your circuit work just nice, than I salute you. It will be nice to share your schematics and code, so others may make the same thing or use as a example.  
Title: Re: Zero crossing detection
Post by: raxz on Mar 13, 2012, 09:03 pm
Well, I already posted my code at the end of previous page.
And on this page I posted ZC schematic I used.
230VAC is not doing any harm, if you are smart enough to use precaution. Of course it's safer to use transformer and then opto, but it doesn't matter as long as I don't touch it. :P
My system is in the middle of final assembly. It will be used to control and dim lights.
Picture of work in progress: http://www.upload.ee/image/2159720/IMAG0094.jpg
Board with blue terminals is for switches and there is schematic to take away any sparkling noise from switches. I press the button and it holds output high from 0 to 600ms. I set them to about 100ms. If you hold longer than 200ms, then you start dimming the lights.
The one on the right is relay board. There will be 8 random fire solid state relays and 16 normal relays.
Solid state relays need zero crossing detection and I use the code I posted before to drive them.
Title: Re: Zero crossing detection
Post by: taurian on Mar 13, 2012, 09:11 pm
This is my circuit for detecting zero crossing..


thank Gil
Title: Re: Zero crossing detection
Post by: taurian on Mar 13, 2012, 09:19 pm
Quote
I got my dimmer working.
I'm using Arduino Mega 1280.
Here is my code, hope You understand


I do not know much is still setting the timers. when it detects the interruption timer reset to zero right?


thank Gil
Title: Re: Zero crossing detection
Post by: raxz on Mar 13, 2012, 09:29 pm

Quote
I got my dimmer working.
I'm using Arduino Mega 1280.
Here is my code, hope You understand


I do not know much is still setting the timers. when it detects the interruption timer reset to zero right?


thank Gil

Yes, at every interrupt it sets counter to zero and starts again counting up from 0 to 255 (in reality it is 1 to 216 or smth near this number and 216 is full OFF and 1 is full ON).
If counter value is same as I requested with requestValue, it sets output high and triac holds itself up until the end of half period.
Title: Re: Zero crossing detection
Post by: taurian on Mar 13, 2012, 09:47 pm
Quote
Yes, at every interrupt it sets counter to zero and starts again counting up from 0 to 255 (in reality it is 1 to 216 or smth near this number and 216 is full OFF and 1 is full ON).
If counter value is same as I requested with requestValue, it sets output high and triac holds itself up until the end of half period


If I sign my period is 20ms as I set my timer to take a sample of 2 seconds in 2 seconds


thank Ragnar
Title: Re: Zero crossing detection
Post by: taurian on Mar 13, 2012, 11:38 pm



Where can I get the libraries to be able to run your code?

If you please.

thank Ragnar
Title: Re: Zero crossing detection
Post by: taurian on Mar 14, 2012, 12:59 am
Code: [Select]
#include <Timerthree.h>
#include <Timerone.h>

volatile int counterValue;
int requestValue;

void setup() {
  attachInterrupt(0, resetCounter, CHANGE);
  cli();                      //Disable global interrupts
  TCCR3A = 0;                 //Set register to 0
  TCCR3B = 0;                 //Set register to 0
  OCR3A = 640;                //Compare match register to get desired timer count (50Hz mains)
  TCCR3B |= (1 << WGM12);     //Turn on CTC mode
  TIMSK3 |= (1 << OCIE3A);    //Enable timer compare interrupt
  TCCR3B |= (1 << CS10);      //Start timer
  sei();                      //Enable global interrupts
  pinMode(7, OUTPUT);
}

ISR(TIMER3_COMPA_vect) {
  counterValue++;
  counterValue &= 0xff;
  if (counterValue==requestValue) {
    digitalWrite(7, HIGH);
  } else {
    digitalWrite(7, LOW);
  }
}

void resetCounter()
{
  counterValue=0;
}

void loop(){
  requestValue=map(analogRead(0), 0, 1023, 0, 255);
}


I already have the libraries when compiling the code but got an error says that the variables are not declared...
Example: sketch_mar13a: 11: error: 'OCR3A' was not declared in this scope
sketch_mar13a: 13: error: 'TIMSK3' was not declared in this scope
sketch_mar13a: 13: error: 'OCIE3A' was not declared in this scope


thank you
Title: Re: Zero crossing detection
Post by: Techone on Mar 14, 2012, 02:46 am
@taurian

Thank for the schematic. Did you connect the ground to the battery ?   Is like :  pos 9 neg   ---- GND --- pos 9 neg
The gnd is the middle of the battery connection. Did you connected it there ? That is the right place. The schematic look "fine", but I just wonder... 
Title: Re: Zero crossing detection
Post by: raxz on Mar 14, 2012, 06:15 am
I'm not using any libraries.
Following code compiles ok.
Binary sketch size: 3188 bytes (of a 126976 byte maximum)
Code: [Select]
volatile int counterValue;
int requestValue;

void setup() {
  attachInterrupt(0, resetCounter, CHANGE);
  cli();                      //Disable global interrupts
  TCCR3A = 0;                 //Set register to 0
  TCCR3B = 0;                 //Set register to 0
  OCR3A = 640;                //Compare match register to get desired timer count (50Hz mains)
  TCCR3B |= (1 << WGM12);     //Turn on CTC mode
  TIMSK3 |= (1 << OCIE3A);    //Enable timer compare interrupt
  TCCR3B |= (1 << CS10);      //Start timer
  sei();                      //Enable global interrupts
  pinMode(7, OUTPUT);
}

ISR(TIMER3_COMPA_vect) {
  counterValue++;
  counterValue &= 0xff;
  if (counterValue==requestValue) {
    digitalWrite(7, HIGH);
  } else {
    digitalWrite(7, LOW);
  }
}

void resetCounter()
{
  counterValue=0;
}

void loop(){
  requestValue=map(analogRead(0), 0, 1023, 0, 255);
}
Title: Re: Zero crossing detection
Post by: taurian on Mar 14, 2012, 01:22 pm
Quote
I'm not using any libraries.
Following code compiles ok.
Binary sketch size: 3188 bytes (of a 126976 byte maximum)


Thank you now I'm trying to adapt the code to my project after any doubt I'll give news

thank:)
Title: Re: Zero crossing detection
Post by: taurian on Mar 14, 2012, 01:28 pm
@techone

I have not connected to any battery my input signal going to pull the generator functions ..
but did not realize your question

thank
Title: Re: Zero crossing detection
Post by: Techone on Mar 14, 2012, 05:57 pm
Your circuit is using op-amps. It need a dual power line ( + line, - line ) and the gnd is the mid point of the batteries connection. And the gnd has to be connected with the gnd to work properly.

I hope you understand.
Title: Re: Zero crossing detection
Post by: taurian on Mar 14, 2012, 06:30 pm
The battery I used to say to this is to feed the polarization of the m-amp.
  The polarization and I'm using 5v and 0v and I use the v 5 the arduino.

Thank Techone
Title: Re: Zero crossing detection
Post by: taurian on Mar 15, 2012, 09:34 pm
This and my code to read an analog value but the result is not good.

thank

Code: [Select]

#include <TimerOne.h>

int ledPin =2;    // LED connected to digital pin 13
int analogPin=3;

float a;
void setup()   {               
  Serial.begin(9600);
  pinMode(ledPin,INPUT);
  pinMode(13, OUTPUT); 
  Timer1.initialize(131000);
  attachInterrupt(0,periodo,RISING);


}

// the loop() method runs over and over again,
// as long as the Arduino has power

void loop()                   
{
  a=analogRead(analogPin);
  Serial.println(a);
}

void periodo()
{
 
  digitalWrite( 13, digitalRead( 13 ) ^ 1 );

}

Title: Re: Zero crossing detection
Post by: raxz on Mar 15, 2012, 09:39 pm
What is not good? What You expect? What You get?
Title: Re: Zero crossing detection
Post by: taurian on Mar 15, 2012, 09:52 pm
I wanted to see the values ??vary depending on the analog input signal and this does not happen that the values ??are repeated.

thank