0

I wish to connect an Arduino ( any of 328P family ) which its 5v, with ESP8266 (ESP-01, or even NodeMCU or Wemos D1 mini ) which is 3v3 logic. My goal is that ESP8266 will be in-charge of MQTT messages and other remote abilities, while Arduino board will be in charge of UP/Off/Down rocker switch and 2 relays ( For reliability I rather have this setup ). Both MCU's code is written by me using Arduino

I Know of 2 main ways: voltage divider and level shifter ( and 3rd will be to use a 3v3 logic as pro-mini - but let's leave for now ).

My questions are:

A) Does Rx Tx need a voltage to be the same ( some on-line tutorial ignore this at all )? if so, is it needed both ways ?

B) Some Tutorial mention that using a voltage divider create some communication interference. It is true and/ relevant for use as explained ?

C) Does SofwareSerial library is recommended (again - reliability ).

2 Answers 2

1

A) Does Rx Tx need a voltage to be the same ( some on-line tutorial ignore this at all )? if so, is it needed both ways ?

The point is, that often 3.3V MCUs cannot tolerate voltages significantly above that. So connecting 5V can hurt it. I've seen quite a bit of discussion online, if ESP boards are 5V tolerant or not, but I haven't seen a real investigation in this. Often you can very well get away with connecting them directly, but nobody will give you any guarantees about this. If you want to be safe, you need to add some kind of voltage transition from Arduino TX to ESP RX. The other line (ESP TX to arduino RX) is driven by the ESP with 3.3V, which is ok for the Arduino (3.3V is enough for the Arduino to see it as HIGH), so you don't need anything on this line.

B) Some Tutorial mention that using a voltage divider create some communication interference. It is true and/ relevant for use as explained ?

Since a voltage divider is passive, you get extra effects (parasitic capacitance and inductance), which limits the baudrate. Though I still got communication without errors with baudrates up to 115200 (I did not do a thorough investigation, this is just subjective experience). Electronically better would be proper level shifting (which uses transistors), but in most cases a voltage divider also works well. So I would say unless you want to use really high baudrates you are good with a voltage divider. Others can of course also provide their experience on this site.

Does SofwareSerial library is recommended (again - reliability ).

Generally a Hardware Serial interface is always better, since the communication protocol is completely handled in hardware. The code just needs to read and write the individual bytes from/to hardware registers. SoftwareSerial is used, when there is no free to use Hardware Serial interface. And it imposes some extra limits: You can only listen to one SoftwareSerial interface at any give time and you cannot use high baudrates with it (I think 115200 is already too high for it, depending on the used Arduino). Also it depends on the rest of your code (depends on your use of ISRs). So, if you have an unused hardware Serial interface on your Arduino board, you should use that. Otherwise you can use SoftwareSerial.

2

Just adding a little flesh to @chrisl's excellent answer with some added technical detail:

B) Some Tutorial mention that using a voltage divider create some communication interference. It is true and/ relevant for use as explained ?

The problem here is that the resistors and the input pin's capacitance form a low-pass filter. Too high a resistance and you deform the nice clean square wave of the serial data. This limits the baud rate you can reliably use. Reduce the resistor values and you increase the frequency of the filtering, thus allowing higher baud rates, but at the cost of increased current draw from the TX pin.

Does SofwareSerial library is recommended (again - reliability ).

The problem of SoftwareSerial is twofold: it's very much a "blocking" system, whereby the MCU can't be doing anything else when a byte is being either received or transmitted, and it's very picky about timing, partly because of that blocking. There are two factors that affect the maximum speed you can use: how fast the MCU can process the incoming signal to work out what it is, and how fast the MCU can process that decoded signal to get it stored in the buffer.

While it's possible to receive reliably a byte at 115200 baud the problem comes when receiving multiple bytes rapidly. The Arduino is not always able to take that received byte and store it in the RX ringbuffer fast enough before the start bit of the next byte arrives, so it misses it. This causes corruption in the data stream.

For this reason I never recommend more than 9600 baud (or maybe 38400 at a pinch) to give the Arduino more time to process the bytes as they arrive. However that then means that more time is spent doing the sending or receiving, which blocks the rest of your program during that time for longer.

Also SoftwareSerial is strictly half duplex: when you're receiving you can't send, and when you're sending you can't receive. It's only really of any use in a "call-response" style protocol where switching between sending and receiving is predictable.

2
  • Thank you. Setting speed as 9600 is good enough for me, since esp sends AUX numeric commands to Arduino, in form of 2 digit, and acknowledged message back. So I do not expect nothing fancy.
    – guyd
    Apr 15, 2021 at 12:23
  • Regarding softwareSerial, as I said- reliability at top
    – guyd
    Apr 15, 2021 at 12:25

Your Answer

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

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