Zero Cross Error detect [SOLVED]

HI All,

Trying to detect of if a zc signal is present at a pin and switch on an LED if not zc is not detected. The below code is used to simulate zc by connecting pin9 to pin2

here, where do i set the LED to go high when ZC is is not detected or when a zc signal is not present in pin2 ?

thanks

How will you know that ZC is not detected?

How will you know that ZC is not detected?

when no signal is present at pin2.

the idea is to turn the LED ON when there is no signal at PIN2, obviously when the optocoupler H11AA1 is faulty at the collector.

You can add a time out to the while loop and provide notification of error. You can halt the sketch on the timeout.

Perhaps something like this demonstration, where it sends 10 simulated zero crossing pulses and then stops the timer so as to reach the timeout. I light the led on pin 13 on timeout.

#include <TimerOne.h>

boolean zeroCrossingFlag = false;
unsigned long timeout = 1000;
volatile int count = 0;//for demo sketch to set zeroCrossingFlag

void setup() {
  Serial.begin(115200);
  Serial.println("starting while loop timeout demo");
  
  //set up timer 1 to simulate zero cross pulse from H11aa1
  //10 micro seccond pulse every 10 milli seconds simulate
  //two crossings per period at 50Hz
  pinMode(9, OUTPUT);//jumper pin 9 to pin 2 for INT0
  pinMode(13, OUTPUT);//internal led on pin 13
  Timer1.initialize(10000);//fire pulse every 10ms 50Hz
  Timer1.attachInterrupt(ZCpulse);//timer interrupt called

  pinMode(2, INPUT_PULLUP);//zero cross interrupt pin
  attachInterrupt(0, setFlag, FALLING);//zero cross detect
}

void loop() {

  unsigned long startTime = millis();
  while (!zeroCrossingFlag && (millis() - startTime < timeout))
  {
    //hang in while loop until either zeroCrossFlag or timeout occurs
    //both conditions need to be met to stay in while loop
  }

  if (zeroCrossingFlag)//exit while loop due to flag set
  {
    Serial.println("exit while loop with zero cross detected");
    zeroCrossingFlag = false;
  }
  else  //exit while loop due to time out error
  {
    Serial.println("zero cross time out error");
    digitalWrite(13, HIGH);
    while (1); // halt sketch on timeout
  }

 
}

void ZCpulse()
{
  digitalWrite(9, HIGH);
  delayMicroseconds(10);//10 us every 10 milliseconds
  digitalWrite(9, LOW);
}

void setFlag() //demonstration to fire 10 pulses and disable interrupt
{
  zeroCrossingFlag = true;//interrupt sets flag true
  count++;
  if (count == 10)
  Timer1.stop();
}

Appreciate your effort here @cattledog but i am looking for something simpler. Just check on the initial startup only. Not worried if the error occurs during operation. Even if that happens it would be notified on the next startup. So lets say the zc does not work during operation, the user would normally cycle the power hoping it would work on restart and here the LED would turn ON as there is not signal at pin2.

if (digitalRead(zCd) == LOW)
    {
      digitalWrite(LED, HIGH)
    }
else
   {
     digitalWrite(LED, LOW);
    }
}

Wait at the end of setup(), until a zero crossing must have occured, then check the zeroCrossingFlag.

Trying to detect of if a zc signal is present at a pin and switch on an LED if not zc is not detected

Just check on the initial startup only. Not worried if the error occurs during operation.

You presently start with zeroCrossingFlag = false. After you attach the interrupt the flag should be set to true if things are working correctly.

You could do something like this in setup().

//set up code prior to attachInterrupt and test
attachInterrupt(0, setFlag, FALLING);//zero cross detect
zeroCrossingFlag =false; //make sure interrupt has not been triggered by attachInterrupt 
delay (500)//wait to get an interrupt triggered
if(!zeroCrossingFlag) //zeroCrossing Flag has not been set true by the interrupt during the delay period
{
  digitalWrite(LedPin, HIGH);
  //either halt code with while(1) or present error message
}

You presently start with zeroCrossingFlag = false. After you attach the interrupt the flag should be set to true if things are working correctly.

That was just something to start, did not know where to start at, hence added that line.
not sure if i've got what you meant but here is how i got it

attachInterrupt(0, setFlag, FALLING);//zero cross detect
zeroCrossingFlag =false; //make sure interrupt has not been triggered by attachInterrupt
delay (500);//wait to get an interrupt triggered
if(!zeroCrossingFlag) //zeroCrossing Flag has not been set true by the interrupt during the delay period
{
  digitalWrite(led, HIGH);
  digitalWrite(rst, HIGH);
}

during compilation, an error was returned "Arduino: 1.6.11 (Windows 8.1), Board: "Arduino/Genuino Uno"

zce_detect:6: error: expected constructor, destructor, or type conversion before '(' token

attachInterrupt(0, setFlag, FALLING);//zero cross detect

^

zce_detect:7: error: 'zeroCrossingFlag' does not name a type

zeroCrossingFlag =false; //make sure interrupt has not been triggered by attachInterrupt

^

zce_detect:8: error: expected constructor, destructor, or type conversion before '(' token

delay (500);//wait to get an interrupt triggered

^

zce_detect:9: error: expected unqualified-id before 'if'

if(!zeroCrossingFlag) //zeroCrossing Flag has not been set true by the interrupt during the delay period

^

exit status 1
expected constructor, destructor, or type conversion before '(' token"

attachInterrupt(0, setFlag, FALLING);//zero cross detect
zeroCrossingFlag =false; //make sure interrupt has not been triggered by attachInterrupt
delay (500);//wait to get an interrupt triggered
if(!zeroCrossingFlag) //zeroCrossing Flag has not been set true by the interrupt during the delay period
{
  digitalWrite(led, HIGH);
  digitalWrite(rst, HIGH);
}

Please post complete code which can be compiled and checked. You have enough posts to know that its impossible to figure out what error messages mean on "snippets" of incomplete code.

When I define rst, (which is not in the sketch originally posted) the following sketch compiles without error. I have no clue what you did wrong.

#include <TimerOne.h>//used for simulation trigger of zero crossing interrupt
int led = 9;
int rst = 5;//I have no idea what rst in your snippet is
volatile boolean zeroCrossingFlag = false;//set in zero crossing interrupt

//button variables push button on pin 4
byte prevVal4 = LOW;
byte val4 = LOW;

void setup() {

  Serial.begin(9600);
  Serial.println("Push Button to Weld");

  //set up timer 1 to simulate zero cross pulse from H11aa1
  //10 micro seccond pulse every 10 milli seconds simulate
  //two crossings per period at 50Hz
  pinMode(9, OUTPUT);//jumper pin 9 to pin 2 for INT0
  pinMode(10, OUTPUT);
  Timer1.initialize(10000);//fire pulse every 10ms 50Hz
  Timer1.attachInterrupt(ZCpulse);//timer interrupt called

  pinMode(4, INPUT_PULLUP);//button pin

  pinMode(2, INPUT_PULLUP);//zero cross interrupt pin
  attachInterrupt(0, setFlag, FALLING);//zero cross detect

  zeroCrossingFlag = false; //make sure interrupt has not been triggered by attachInterrupt
  delay (500);//wait to get an interrupt triggered
  if (!zeroCrossingFlag) //zeroCrossing Flag has not been set true by the interrupt during the delay period
  {
    digitalWrite(led, HIGH);
    digitalWrite(rst, HIGH);
  }

}

void loop() {

  val4 = digitalRead(4);//poll button every loop

  //button press to trigger weld cycle
  if (val4 == LOW && prevVal4 == HIGH) //if state change
  {
    delay(10);//blocking debounce
    val4 = digitalRead(4);//read again

    if (val4 == LOW && prevVal4 == HIGH)//steady reading?
    {
      zeroCrossingFlag = false;//set flag false and wait for next
      while (!zeroCrossingFlag) {};
      Serial.print("pre weld triggered  ");
      delay(5);//delay to trigger on sine wave peak
      Serial.println(millis());//digitalwrite output pin ON here
      delay(50);//preweld time
      Serial.println(millis());//digitalwrite output pin OFF here
      zeroCrossingFlag = false;//set flag false and wait for next
      while (!zeroCrossingFlag) {};
      delay(5);//delay to trigger on sine wave peak
      Serial.println("main weld triggered");//digitalwrite output pin ON here
      Serial.println(millis());
      delay(450);//weld step
      Serial.println(millis());//digitalwrite output pin OFF here
      Serial.println("");
    }
  }
  prevVal4 = val4;

}

void ZCpulse()
{
  digitalWrite(9, HIGH);
  delayMicroseconds(10);//10 us every 10 milliseconds
  digitalWrite(9, LOW);
}

void setFlag()
{
  zeroCrossingFlag = true;//interrupt sets flag true
}

Sorry thought we knew what the matter was that we talking about. The you have mentioned above is that for the pre-weld and weld. The when i disconnect the pin9 from pin2(pin9 being the pulse) the LED on pin10 should be on. But that did not happen. That was the whole idea. No Pulse on pin2 and the LED goes ON.

after a few trial and error found, sharing just in case some one needs it

zeroCrossingFlag = false;//set flag false and wait for next
      while (!zeroCrossingFlag) 
             {
                digitalWrite(zce, LOW);
             }
      digitalWrite(zce, HIGH);

So here when the zero cross is detected the LED would light up and if not the LED would be OFF. Tested it by disconnecting the anode on the optocoupler and it worked. :slight_smile: