Electronic – arduino – Best way to connect 5V to GND from ESP (3.3V) – transistor or optocoupler

3.3v5varduinoesp8266transistors

First of all: I read through some of the suggested topics (i.e. connecting a 5V relay to an ESP), but to my (limited) understanding, this seems not to be the problem I'm trying to solve. If it is, please accept my apologies.

What I'm trying to do: I want to emulate an Atari-style joystick (which runs on 5V) with an ESP32 (3.3V). To do that, the direction pins of the joystick port need to be connected to the GND pin.

First I was thinking of using optocouplers because they provide galvanic isolation. However, since the ESP will be powered by the joystick port's 5V pin eventually, this might not be really necessary. So I thought about using transistors and supply the base of the transistor with the current from one of the ESP's GPIO. Collector and emitter would then be connected to GND and the respective direction pin of the joystick port.

Would that work as well and as reliable/fast as an optocoupler? I read about leakage current that can occur on transistors even if the GPIO connected to the transistor's base is off?
And could I use BC547 (NPN) transistors for that purpose, as I have lots of them laying around here? Or would a different type be better? And last question: In some of the examples using a transistor as a switch, I saw that GND would be connected to the collector and the load to the emitter. I thought that current flows from the collector to the emitter via the base, so I would have expected GND to be connected to the collector?

Thanks in advance for any suggestions/explanations!

Best Answer

You only need a single transistor on each output, and it doesn't need (or want) a pullup. Like this:-

schematic

simulate this circuit – Schematic created using CircuitLab

If you are reading the joystick switches directly then the signal will have to be inverted, but that is easily done in software. A small signal switching transistor like the BC547 or 2N3904 has negligible leakage current and is much faster than an optocoupler, as well as requiring a lot less drive current.

If the problem you are trying to solve is what I think it is, you will need to synchronize joystick movements to the game running on the computer. Most games only read the joystick port once during each vertical blank (or close to it), so if you latch the joystick input before this time, then update and hold the output until after the computer has read the port, you should be able to achieve perfect 'playback' of movements (provided the game's timing is consistent).

At 50 or 60Hz frame rate the switching speed isn't critical, so long as you are producing a stable output during the time that the joystick is being being read by the computer. If the game is running at a lower update rate (eg. 25Hz) you still need to provide a new output on every frame because you don't know which frames are 'active'.

To summarize:- detect the vertical blanking pulse and wait for some time afterwards (after the game has finished reading the joystick port), then sample the joystick state and transfer it to the output, latching the output until the next sample time.

Related Topic