4
\$\begingroup\$

I'm trying to read a NFC reader's output with an Arduino Nano ESP32 through Wiegand protocol.

Basically, the Wiegand protocol transmit the binary code with two pins: D0 (for the zeroes digits) and D1 (for the 1 digits). Both normally stays high (+5v), and when a digit is transmitted the signal drops to GND.

Here the graphical explenation:

Wiegand graph

Here is a physical test on the oscilloscope:

Wiegand on scope

I tried to read this signal with an Arduino Nano ESP32 using this circuit:

(Here the D0 signal only, D1 will be the same. I don't care that the signal shape is mirrored.) Optocoupler and level-shifter circuit

The issue is that Arduino cannot read it properly, some bits get lost.

Here is the scope of the PC817's output [Arduino's D9 pin] (Blue) compared with the NFC reader's output (Yellow):

Optocouplers output

List of components:

  • Optocoupler PC817;
  • MOSFET 2N7000;
  • Resistors;
  • Wiegand NFC reader.

I'm going to replace the 2N7000 with a MOSFET Depletion-mode DN2530

How can I have a better output from the optocoupler?

\$\endgroup\$
7
  • 1
    \$\begingroup\$ What purpose does the optocoupler even serve, why it is put into schematics? Also you have a scope, have you debugged where the waveform distorts on the signal path, instead of just what goes into FET and what goes into ESP? Also you have some setup issue, your scope claims 12V going into ESP and 20+ V coming from Wiegand reader. \$\endgroup\$
    – Justme
    Commented Jul 20 at 7:31
  • \$\begingroup\$ Optocoupler is an extra to isolate the Arduino. Sure, the signal is distorted on the optocoupler; the signal at the output of the mosfet is perfect. The thing is that I'm not sure if I'm sizing the resistors bad, or the PB817 is just slow. \$\endgroup\$
    – PaoloRos
    Commented Jul 20 at 7:33
  • 1
    \$\begingroup\$ Just reduce the value of R12 (10k -> 1k). Perhaps also a little R13. \$\endgroup\$
    – Antonio51
    Commented Jul 20 at 7:35
  • \$\begingroup\$ @Antonio51 is correct. The 10k pull-up at R12 is much too weak so the signal going to the GPIO rises too slowly when the LED in the optocoupler is no longer driven. Reduce it to a (much) smaller value and you will see sharper rising edges and less distortion. \$\endgroup\$
    – StarCat
    Commented Jul 20 at 7:40
  • 2
    \$\begingroup\$ Take out the opto. The Arduino community seem to have this bizarre religious attachment to optos which isn't based in engineering. If your 12V side could be shorted to mains, fair enough. If you're simply trying to go from 12V to 5V logic, you're wasting time, money and board space. Pull-up resistor on the 5V side, NPN to pull it low on the 12V side, job done. And now all your timing problems go away. \$\endgroup\$
    – Graham
    Commented Jul 21 at 1:46

3 Answers 3

3
\$\begingroup\$

At least the 10k pull-up makes it slow. try 1k or maybe less.

But the opto has rise time of max 18 us with 100 ohm.

Instead of using the FET to drive the LED, it could just drive the IO pin pulled to 3V3 - assuming grounds are tied together. You appear to have them separate, so the opto is not useless, but if you can tie the grounds together the opto can be removed.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you !! I'll add another question: Which value of capacitor can I put at the output of the opto to remove the noise? (I'm referring to the scope's blue line) \$\endgroup\$
    – PaoloRos
    Commented Jul 20 at 7:47
  • \$\begingroup\$ @PaoloRos The blue trace does not look noisy and any capacitance you put there will only slow the signal more. You can calculate that you have 3.3V supply and some resistor R like 1 kohm for 3.3mA pull-up current, and the signal pulse is only 45 us. You want a fast rising pulse. I'd say max 1nF. For 300ns rise time and 3mA, around 200pF. You really don't want to have any capacitor at all. \$\endgroup\$
    – Justme
    Commented Jul 20 at 7:59
  • \$\begingroup\$ Don't add any capacitance because this will again slow down the fall and rise times. The signal does not look particularly noisy to me. Remember this is a digital signal and it can tolerate a lot more noise than you're seeing now. \$\endgroup\$
    – StarCat
    Commented Jul 20 at 8:59
2
\$\begingroup\$

The PC817 optocoupler is known for its relatively slow propagation delays. If you manage to make it work, be aware that the output will exhibit substantially different low-to-high and high-to-low propagation delays, potentially causing a distorted bit width. For faster performance, consider alternatives like the 6N137 high-speed optocoupler or the ADUM1200 digital isolator. The ADUM1200ARZ can operate at up to 2 Mbps (BRZ and CRZ versions can handle up to 10 Mbps and 25 Mbps, respectively).

If you don’t need to isolate the NFC reader from your circuit, you can use the inexpensive TXB0108 or TXS0108 for voltage translation. Alternatively, consider using a bi-directional logic level converter for voltage translation, which you can build yourself using BSS138 (or 2N7000) NMOS transistors and a couple of resistors. Below is the logic level converter and its input (5V) and output (3.3V) waveforms. I made the assumption that R2 is output impedance of the NFC reader and C1 is the total loading capacitance of the MCU pin and the trace.
enter image description here

Here is the close-up view of the waveforms, which shows the output (top) is as fast as the input (bottom). enter image description here

\$\endgroup\$
9
  • \$\begingroup\$ The PC817 has a bandwidth of 80 kHz and a 45 us pulse being delayed by 20 us and/or shortened to 10 us is a non-issue for Wiegand pulses as long as they are there. Anything like 6N137 or any digital isolator going between 1 Mbps to 25 Mbps is just not needed. The bidirectional TXB and TXS level shifters are good for only up to 5V and wiegand is generally not 5V or bidirectional, and the impedances and capacitances and slew rates of Wiegand wiring are unlikely within range of proper operation for those level shifters and likely they fail to work properly. \$\endgroup\$
    – Justme
    Commented Jul 20 at 10:01
  • \$\begingroup\$ The custom BSS138 solution may work, but bidirectionality is not needed. I don't see any of these as good options compared to the existing solution that simply needs to change a single resistor per channel. \$\endgroup\$
    – Justme
    Commented Jul 20 at 10:03
  • \$\begingroup\$ @Justme Well happy trying PC817 if you ever work with one. The BSS138 solution I suggested is intended for voltage translation, not for bi-direction data transmission. \$\endgroup\$
    – kaosad
    Commented Jul 20 at 15:24
  • \$\begingroup\$ @Justme "The custom BSS138 solution may work, but bidirectionality is not needed. I don't see any of these as good options compared to the existing solution that simply needs to change a single resistor per channel." Using the custom BSS138 solution, you just reuse the 2 resistors and the NMOS; keep the PC817 for other project. \$\endgroup\$
    – kaosad
    Commented Jul 20 at 15:40
  • 1
    \$\begingroup\$ The PC817 looks like any other similar general purpose phototransistor optocoupler. They are slow but so are transistors. The only thing missing is the base connection for improving the turn off time. Perfectly good for simple Wiegand pulses, they are slow too. It just needs to be used correctly to work, like any component. The question is also about how to get better output from that opto, not about ditching it for better opto or other solution. \$\endgroup\$
    – Justme
    Commented Jul 20 at 19:52
0
\$\begingroup\$

At the end I decided to drop the optocoupler and keep the 2n7000 only.

enter image description here

and it works really nice: enter image description here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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