Go Down

Topic: Zero crossing detection (Read 17083 times) previous topic - next topic

taurian

Mar 11, 2012, 07:30 pm Last Edit: Mar 11, 2012, 07:31 pm by Coding Badly Reason: 1
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.

Grumpy_Mike

You can't use serial print from inside an interrupt routine.

taurian

But as I do as a void function does not return?


Thanks Gil

Grumpy_Mike

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.

taurian

yes you are right I have to do seriaprint outside the function.

Techone

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.

el_supremo

You should not call detachInterrupt in the interrupt routine. When you do that it means that subsequent interrupts will not call periodo again.

Pete
Don't send me technical questions via Private Message.

nickgammon

Code: [Select]


    attachInterrupt(0, periodo,FALLING);

...

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


Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

taurian

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

taurian

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

Grumpy_Mike

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.

taurian

ok thanks for the info


Thanks Gil :)

Techone

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

 

taurian

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

raxz

#14
Mar 12, 2012, 08:39 pm Last Edit: Mar 12, 2012, 08:40 pm by Ragnar Reason: 1
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);
}

Go Up