optocoupler doesn't work using output pin

I'm trying to get an optocoupler to work and have ran into trouble. The optocoupler is a Sharp PC817. My goal is to have the Arduino simulate pressing a button on an RF remote for my roller shades (and later on an AC remote). I wired the transistor side to bypass a remote button and the LED side to an Arduino output pin and ground. I turn the pin on:

pinMode(12, OUTPUT);
digitalWrite(12, HIGH);

I see 3.18V between the pin and ground (my Arduino is 3.3V), but the remote button isn't triggered. I'm aware I should use a resistor, but at the moment I have only a single 47 ohm resistor (more are on the way). I tried with and without the resistor, still nothing. FWIW, I measure 0.94V across the optcoupler LED when the output pin is high but the remote button isn't triggered.

If I use the Arduino's 3.3V pin instead of an output pin, the optocoupler works as desired and the remote button is triggered. This makes me sure that my polarity and connections are correct. I also tried using 1 and 2 AAA batteries and the optocoupler also works with those. Why doesn't it work when using an output pin? :frowning: I feel like such a noob! :frowning:

I should mention I do see some strange behavior: The RF remote has an LCD screen and the first button press turns the screen on, but doesn't send any RF. The next button press sends RF (a red LED blinks when it is sending). If the screen is off and I activate the optocoupler using an output pin, the screen turns on. However, if I turn the pin off and back on (or unplug and replug a wire), the remote does not send any RF. I have no idea how the optocoupler could trigger the remote to turn on the screen, but not to send RF!

Another thing that might be relevant (however unlikely) is that I'm powering the remote using 3.3V from the Arduino. I did switch to batteries just to see if that helped, but it didn't.

Your measurements on the optical side sound perfectly normal. That 3.18V should be enough, the pin should be able to supply enough current (10-20 mA is needed). Do add the 47 Ohm resistor, it protects both your Arduino and the optocoupler.

Also measure the resistance on the other side of the optocoupler: it should be very low when the pin is high, and high when the pin is low. That way you know whether the pin is doing its job and the phototransistor of the optocoupler is actually reacting.

You should be wired like Fig 16 on the opto-coupler datasheet. The LED-side needs a current-limiting resistor and the output needs a pull-up resistor. But we don't know anything about the remote circuitry, if there's already a pull-up, or if an opto-coupler will even work (although you say it works when you drive the opto-oupler with a battery)..

Note that the opto-coupler will invert (depending on how the LED is wired). When the internal LED is on, the transistors turns-on, pulling-down the output. When the LED is off, the pull-up resistor pulls-up the output.

What voltage readings are you getting at the opto-coupler's output? (Measured with reference to the output-side ground, if the ground are isolated.)

Also measure the resistance on the other side of the optocoupler: it should be very low when the pin is high, and high when the pin is low.

That sounds like a good idea. My circuit on one side is power, optocoupler, 47 ohm resistor, ground and on the other side of the optocoupler is the DMM. I see:
OL when the optocoupler is off, of course.
With 1 AAA battery, 121 ohms.
With 2 AAA batteries, 38.6 ohms.
With the 3.3v pin, 39.3 ohms.
With an output pin, 36.4 k ohms. <- note the k!

Why is the output pin is so different?!

DVDdoug:
The LED-side needs a current-limiting resistor and the output needs a pull-up resistor.

I'll need to do more reading to understand how a pull-up resistor works. FWIW, it works as I want when using a battery or 3.3v pin.

Make a test circuit. Hookup the Arduino to the LED side of the Arduino, correctly with a resistor. On the control side, use a simple LED circuit with a separate power source.
See if the Arduino and opto complete the second circuit.
You may have already blown the opto by not using a resistor.

When you use the pin 12 HIGH, does it light up a normal LED?

n4te:
With an output pin, 36.4 k ohms. <- note the k!

That is most likely some miswiring, or a code problem where you don't have the pin set to OUTPUT and HIGH (assuming the other end of the optocoupler is GND and you have it wired the correct way around). The resistance you measure there, however, is less than the dark resistance which should be the MOhm range, so there appears to be at least some current running through the LED.

Please post your actual schematics and code.

INTP:
You may have already blown the opto by not using a resistor.

Or the port of the Arduino...
According to specs an Arduino can source about 20 mA, which by itself is not enough to blow an LED, however the LED without resistor effectively shorts the port to GND.

wvmarle:
Or the port of the Arduino...
According to specs an Arduino can source about 20 mA, which by itself is not enough to blow an LED, however the LED without resistor effectively shorts the port to GND.

No, that spec is how much it can safely source. If you short the pin, it will supply 40-50 mA until it fails. An LED is not quite as bad as a direct short due to the diode drop.

You're right. It's likely to provide more when shorted.
50 mA is the absolute maximum rating for the PC817 input (for short periods it can handle more; up to 1A peak for 100 us even) so I expect it's the Arduino that fails first.

I simplified the code, changed the pin, and tested the optocoupler resistance again. The code:

void setup () {
  Serial.begin(9600);
  Serial.println("Starting...");
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  Serial.println("Pin 8 is ON!");
}

void loop () {
  delay(250);
}

The circuit is (sorry if these is a better way to describe this):
pin 8 -> optocoupler (+)
optocoupler (-) -> 47 ohm resistor -> GND
On the other side of the optocoupler I have a DMM measuring ohms: I see 0.68 k ohms.

If I change the circuit:
3.3V pin -> optocoupler (+)
optocoupler (-) -> 47 ohm resistor -> GND
Then on the other side of the optocoupler I see 45 ohms.

INTP:
When you use the pin 12 HIGH, does it light up a normal LED?

I don't actually have a spare LED. This is embarrassing for a tinkerer, I'm sure! I will look around for something I can destroy for its LED. Maybe I can use the DMM instead?

n4te:
The circuit is (sorry if these is a better way to describe this):

Better to draw it out. Pen & paper + photo or install software such as KiCAD.

pin 8 -> optocoupler (+)

Same results for other pins?

Your multimeter can show voltage level at a pin, but can't readily show whether it can actually supply the current needed to light an LED. It just doesn't work the same.

Do get a handful of LEDs. They're dirt cheap nowadays, and come in handy in many more situations (including making your projects look pretty).

You can try using whatever pin controls the onboard LED, like pin 13 for Unos/Nanos/maybe yours.

And make sure you're actually uploading code and not just verifying it. Much time has been wasted on people who couldn't realize they weren't even uploading their code to the board.

Oh boy, the mystery is solved! I put away the DMM and stared at the stupid Arduino for a while. I took the DMM back out and repeated the test with pin 8 -- and I got 120 ohms! Hopeful, I connected the remote, but the button still didn't work. I connected the DMM, now I got 0.68 k ohms... what the hell! I nearly bit the damn thing in two. After some more staring, I swapped the leads on the DMM: 120 ohms. Sooo apparently the polarity for the optocoupler is important. /headdesk

I connected the remote, swapped the wires, and it worked. It must have been quite some bad luck that every time I connected the remote wires or DMM (which was many times!) I got them backward.

I feel like I should go read something as punishment for going into this without sufficient understanding. Any suggestions?

INTP:
And make sure you're actually uploading code and not just verifying it. Much time has been wasted on people who couldn't realize they weren't even uploading their code to the board.

Aye, I'm a software engineer so I've been there more than once! I verified the right code is running by changing the println.

I'll get some LEDs to help with future pains!

Thank you, everyone, for your help! <3

n4te:
Sooo apparently the polarity for the optocoupler is important. /headdesk

It is indeed. Both sides. On the output there's a photo transistor, not an LDR or so.

n4te:
I feel like I should go read something as punishment for going into this without sufficient understanding. Any suggestions?

Here's a good one to read: Using MOSFET as a switch

Or learn how to draw electrical schematics. The arrow on symbols like the diode symbol is quite important. Unfortunately I don't have a good link to one.

Thanks for the link!

Behold! :smiley:

Nice looking tidy prototype, but when you get it all working, lose the proto board, that will give endless problems in a few months or less!

If not a PCB, solder it up with stripboard or similar. You won't regret it.

That white thing is afaik normally called solderless breadboard, not protoboard. Protoboard aka perfboard is soldered, and indeed the logical next step.
Also better to go for an Arduino Nano, and maybe some PC847s and a PC827 instead of ten PC817s.