1
\$\begingroup\$

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?

\$\endgroup\$
  • \$\begingroup\$ I cannot help you on this but I can say that showing the circuit diagram would be a useful addition to this question. Next would be adding an active link to the opto (for the lazy) then possibly reviewing the questions you've already asked and seeing if there is a possibility that you can accept some answers. \$\endgroup\$ – Andy aka Feb 3 '16 at 22:11
  • \$\begingroup\$ Please check, edited... \$\endgroup\$ – Vladimir Djukic Feb 3 '16 at 22:18
  • \$\begingroup\$ I hate those wires. The steel plug tends to detach from the (often badly soldered) copper wire, leading to an open circuit (that you cannot see thanks to the black rubbery plastic). I would test each and every one of those wires for continuity with a multimeter. EDIT: That code is fundamentally broken so I don't bother discussing it in comments. I'll post an answer. \$\endgroup\$ – jms Feb 3 '16 at 22:28
  • \$\begingroup\$ LOL zeroState != zeroState, like Dark = Light, or False = True. \$\endgroup\$ – Marko Buršič Feb 3 '16 at 23:11
  • \$\begingroup\$ Not my code, but anyway that part isn't importante, just this: digitalRead(zeroPin) \$\endgroup\$ – Vladimir Djukic Feb 3 '16 at 23:45
1
\$\begingroup\$

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 );
    }
}
\$\endgroup\$
  • \$\begingroup\$ zeroPin isn't high when digitalRead(zeroPin) == 0 My problem is no metter if I trun on or off main circuit I will always get digitalRead(zeroPin) == 1. \$\endgroup\$ – Vladimir Djukic Feb 3 '16 at 23:43
  • \$\begingroup\$ @VladimirDjukic I understand that, however your code would not have worked either. What happens if you disconnect the optoisolator from the input pin 2 (zeroPin), and toggle the state of that pin manually? Does the code work in that case? To test it, you need to add a pull down resistor from zeroPin to ground, and a pull up momentary switch (or just a length of wire) from zeroPin to +5V. Every button press should simulate one zero crossing. \$\endgroup\$ – jms Feb 3 '16 at 23:55
  • \$\begingroup\$ It works with button.... \$\endgroup\$ – Vladimir Djukic Feb 4 '16 at 0:01
  • \$\begingroup\$ This go in right direction, why it does't work with optoisolator? \$\endgroup\$ – Vladimir Djukic Feb 4 '16 at 12:19
  • \$\begingroup\$ What happens if you connect the opto to the arduino as usual but connect H11AA1 pin 1 to arduino ground and H11AA1 pin 2 to arduino 5V trough a 330 ohm resistor? It should count a "zero crossing" each time you disconnect the resistor from 5V. This is exactly what Marko Buršič said, but it's unclear to me if you tried it or not. \$\endgroup\$ – jms Feb 4 '16 at 13:02
2
\$\begingroup\$

Are you connecting a 10k between 5V and pin number 5? If not, you may have damaged the opto-isolator. The 10k is necessary to give a place for voltage to drop when the opto turns on. Also like jms said, you probably want to do something like zeroState = !zeroState;

If you think of the pins 4 & 5 of the opto as a switch, ideally if you through the switch it would conduct all the voltage from 5V to ground. Now, if 5V was an ideal supply, that means I = V/R , I = 5V/0 which is infinite. Now in reality what is happening is the switch closed and you probably exceeded the maximum power dissipation of the transistor in the opto, which in this case is 200mW. Might have broke it, might not. Just check it with a voltmeter that has diode mode, pin 5-4 should be about 0.7V forward and inf or open with the leads reversed and pin 5-6 is about 0.7V and inf of open when the leads are reversed.

\$\endgroup\$
  • \$\begingroup\$ +1 for catching that feeding an LED with no series resistor can blow the led (in this case, the led that's "invisibly" hidden inside the optoisolator), but please try to explain slightly more how/why it's needed to protect the LED from overcurrent above the diode's "knee" voltage, and add your comment about zerostate = !zerostate; into your answer using the "edit" button at the bottom of your answer post. \$\endgroup\$ – Robherc KV5ROB Feb 3 '16 at 23:19
  • \$\begingroup\$ I replaced opto and added 10k same result \$\endgroup\$ – Vladimir Djukic Feb 3 '16 at 23:44
1
\$\begingroup\$

To chek if the circuit works it is quite simple, simply don't connect AC, use a 5v of arduino and connect a series resitor like 330 ohm, then observe if something changes. There aren't seen 10k and those 33k resitors on the protoboard, have you connected them? Second the input resistors 33k + 33k = 66k might be to much: 230V * 1,41 = 325V peak, 325/66k = 4.9mA, don't know if the forward current is enough even at peak voltage to change the opto state.

\$\endgroup\$
  • \$\begingroup\$ That is the problem I get same result no metter if AC on or off. I tried also with 10K resistor but no result,, \$\endgroup\$ – Vladimir Djukic Feb 3 '16 at 23:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.