I have been trying to implement an open drain Serial output using a Arduino Nano. In the following example I have used 2 Arduino Nanos (both operating at 5V Vcc), using one Arduino as the transmitter and the other as the reciever.

The Transmitter is programmed to send the following series of bytes:

fe fe 68 60 39 12 11 81 16 68 c1 1 35 1a 16 fe fe

The receiver is obviously expected to receive the same. But instead this is what the receiver seems to be receiving:

0 0 9 2 63 3b 77 3f 3a 9 1f 7f 65 39 3a 0 0

The following is the circuit I am using to interface between the two Arduinos:

Interface Circuit

I apologize if the terminology I have used here isn't totally accurate, since I am only a beginner in the field. Am I missing something in the circuit? Is the N-Channel MOSFET I'm using here appropriate for this application? Any insight would be greatly appreciated, thanks in advance.

  • \$\begingroup\$ Notice that you can toggle a GPIO pin directly from input mode (= tristate) to output low and vice versa from software. Hence, if you implement a software serial interface, you don't even need an external transistor to create an equivalent to an open drain output. You basically just output your data to the DDRx instead of the PORTx register. \$\endgroup\$ – JimmyB Jun 19 '17 at 13:23

This is messed up a number of ways:

  1. You say the digital output is open drain, but you have provided nothing that will make the signal go high, ever.
  2. A 60 V 55 A MOSFET is gross overkill here. At least this one can be turned on usefully with only 5 V gate drive. So while silly, it should at least work.
  3. The transistor inverts. That means the transmitting and receiving UARTs have to be configured for opposite polarity. That is not possible with most microcontrollers. Such UARTs are generally fixed with the line idle level being high.
  4. You mentioned nothing about baud rate or hardware protocol, like 8-N-1. This is not something you can overlook.
  5. The baud rate has to be slow enough so that the passive pullup can pull the line high in a small fraction of the bit time.
  6. It's a real head scratcher why you didn't just connect the two pins together directly with a pullup. How is that not the obvious thing to do? There is no need for a hairbrain scheme here.
  • \$\begingroup\$ "you have provided nothing that will make the signal go high, ever"?! What about R2? \$\endgroup\$ – JimmyB Jun 20 '17 at 14:04
  • \$\begingroup\$ @Jim: R2 pulls up the output of the FET, not the open drain output of the processor driving TX1. \$\endgroup\$ – Olin Lathrop Jun 20 '17 at 15:10
  • 1
    \$\begingroup\$ As I understand it, the µC only has a push/pull TX output, and the OP is trying to convert it to an open drain via an external transistor (for multi-master maybe). \$\endgroup\$ – JimmyB Jun 20 '17 at 15:32
  • 2
    \$\begingroup\$ "trying to implement an open drain" was where I read the emphasis on implement. Also, IIRC the Arduino Nano does not have an open drain (hardware) serial output. \$\endgroup\$ – JimmyB Jun 30 '17 at 14:59
  • 1
    \$\begingroup\$ I don't think the digital output is open drain. The Arduino Nano is based on the ATmega328. As far as I know (after reading the datasheet), it only has open-drain output for the I²C interface (called "2-wire Serial Interface" (TWI)) for signals SDA and SCL (page 108), not the serial output. \$\endgroup\$ – Peter Mortensen Mar 30 '18 at 17:10

First of all: Why do you want to use the MOSFET there?

And what use shall R1 have?


Using one single MOSFET will invert the output of the IC so when the IC outputs high level on the Tx pin you'll get low level on the Rx pin and vice versa!

I was just checking the waveform of fe fe 68 and the waveform of 00 00 09. Assuming some timing parameters (time between two bytes) one of the two waveforms is exactly the inverse of the other waveform.

So when the Tx pin is high when sending fe fe 68 it will be low when sending 00 00 09 and when it is low for the first sequence it is high for the second sequence.

So this is the reason why you don't receive what you expect: The MOSFET acts as a NOT gate.


Note: I am assuming that your goal in the open-drain quest is to eventually have a plurality of Arduino transmitter nodes connected to a single receiver.

The usual serial class of the Arduino uses the hardware UART and idles high (and, of course, is a push-pull output). The expectation of the chip designer is that you will use an inverting RS232 driver and an inverting RS232 receiver.

So if you want to make an 'or' allowing two transmitters and one receiver you can either invert twice using a pair of PNP BJTs or p-channel MOSFETs at the transmitter (with a pull-down resistor), and an inverter at the receiver, or you can use diodes like the dual shown below, with a pull-up resistor:


simulate this circuit – Schematic created using CircuitLab

Keep in mind that RS232 drivers and receivers were designed with levels, impedances and protection for robust operation with long-ish cables and if you attempt that sort of thing with CMOS inputs/outputs you will open yourself up to all kinds of issues.

The preferred solution in this case, in my opinion, would be to use RS485 drivers and receivers with a properly terminated twisted pair (plus a common ground) and enable only the transmitter that is active. You would use an extra GPIO to enable the active transmitter.

enter image description here

Anyway, this would be the way to do it as you were thinking:


simulate this circuit

Finally, you might be able to modify the SoftwareSerial class to diddle the DDR bit rather than the output and simulate open drain using the AtMega output directly (requiring only a resistor and no transistors), however that's more work and has other disadvantages (such as lack of speed) over using the provided hardware on the chip.


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.