Electronic – arduino – Optoisolator, did I connected it right? (Arduino Uno)

arduinoopto-isolatorzero crossing

Here is my connection for optoisolator,
enter image description here
2 wires, yellow and red are for AC current.
Other 3 in my arduino, orange pin 2, blue ground and red 5V power.

And diagram.
enter image description here

Datasheet for optoisolator:
http://www.vishay.com/docs/83608/h11aa1.pdf

I am using h11aa1 optoisolator.

Here is my code:

const uint8_t ledPin = 13;                          // Digital output pin that has the on board LED
const uint8_t zeroPin = 2;                          // Digital input pin to which the zero crossing detector is connected

uint8_t zeroCounter = 0;
bool zeroState = 0;
bool ledState = 0;

void setup() {
  Serial.begin(9600);
  pinMode( ledPin , OUTPUT );                       // Enable output driver for LED pin
  pinMode( zeroPin , INPUT );
}

void loop() {

 Serial.println(digitalRead(zeroPin));
  while ( digitalRead(zeroPin) == zeroState ) { // Wait for the state of the zero crossing detector to change
  zeroState != zeroState;
  zeroCounter++;
  if ( zeroCounter == 50 ) {         // Every 50 zero crossings change the LED state
  Serial.println(zeroState);
    digitalWrite( ledPin , ledState );
    zeroCounter = 0;
  }
  };
}

I get always 1 for digitalRead(zeroPin) and because of it Serial.println(zeroState) will never run…

Anyone can help me make this work?

Best Answer

Well written question: As much information is provided as possible, thank you for your effort.

This portion of your code is absolutely fine.

const uint8_t ledPin = 13;                          // Digital output pin that has the on board LED
const uint8_t zeroPin = 2;                          // Digital input pin to which the zero crossing detector is connected

uint8_t zeroCounter = 0;
bool zeroState = 0;
bool ledState = 0;

void setup() {
    Serial.begin(9600);
    pinMode( ledPin , OUTPUT );                       // Enable output driver for LED pin
    pinMode( zeroPin , INPUT );
}

This not so much.

void loop() {
    Serial.println(digitalRead(zeroPin));
    while ( digitalRead(zeroPin) == zeroState ) { // Wait for the state of the zero crossing detector to change
        zeroState != zeroState;
        zeroCounter++;
        if ( zeroCounter == 50 ) {         // Every 50 zero crossings change the LED state
            Serial.println(zeroState);
            ledState != ledState;
            digitalWrite( ledPin , ledState );
            zeroCounter = 0;
        }
    };
}  

I cleaned up the formatting so that the control flow is more apparent.

  • Serial.println(digitalRead(zeroPin)); just outputs the state of the zero crossing detector every time the main loop begins again. I don't know why you do this, but fine enough.
  • The while ( digitalRead(zeroPin) == zeroState ) {... block loops as long as the zero crossing pin is read as equal in value to the variable zeroState. As zeroState is set to 0 at the start of the program and then never modified again, this is equivalent to while ( digitalRead(zeroPin) == 0 ) {... which is probably not your intent. If digitalRead(zeroPin) always returns 1 anything within the while loop is actually never executed.
  • zeroState != zeroState; does nothing useful. != is a relational operator, not an "invert and assign" operator. If you want to invert the value of zeroState from 0 to 1 and vice versa, you would want to write zeroState = !zeroState;.
  • The led toggling code is fine, again with the exception of zeroState != zeroState; which is nonsensical. You probably want zeroState = !zeroState;
  • Finally the semicolon in }; is superfluous, it is the ending of the while ( digitalRead(zeroPin) == zeroState ) { block. While loops only need them if you omit the body of the loop, e.g. while(condition);

What are you trying to achieve with the zeroState variable in general? Are you attempting to only count every other zero crossing?

My take on the code:

const uint8_t ledPin = 13;                          // Digital output pin that has the on board LED
const uint8_t zeroPin = 2;                          // Digital input pin to which the zero crossing detector is connected

uint8_t zeroCounter = 0;
bool ledState = 0;

void setup() {
    Serial.begin(9600);
    pinMode( ledPin , OUTPUT );                       // Enable output driver for LED pin
    pinMode( zeroPin , INPUT );
}

void loop() {
    while ( digitalRead(zeroPin) != 0 ); //wait until zeroPin is low, to make sure that the same zero crossing isn't detected multiple times.
    while ( digitalRead(zeroPin) == 0 ); //wait until zeroPin is high, that's when a zero crossing occurs.
    zeroCounter++;
    if ( zeroCounter >= 50 ) {         // Every 50 zero crossings change the LED state
        zeroCounter = 0;
        Serial.println("50 zero crossings have occurred and 500ms have passed.");
        ledState = !ledState;
        digitalWrite( ledPin , ledState );
    }
}