# Why use UART to communicate between Arduino and ESP Wi-Fi module?

I have been learning about the different communication protocols used between Arduino and other components/sensors, namely, SPI, UART and I2C. I want to add Wi-Fi to my Arduino UNO project using ESP8266 (for now, and maybe later upgrade to an ESP32 as it's more powerful).

But i am wondering why in all the schematics that i have seen in my online research, the Arduino is always connected to the ESP8266 module via UART? Why not use SPI or I2C? Why is UART (apparently) considered superior for ESP communication with the Arduino over the two other communication protocols?

Thanks in advance for the help.

• The common ESP8266 modules have only serial interface. – Eugene Sh. Apr 12 '19 at 16:49
• What do you mean by 'common'? I think all the ESP8266 modules share the same basic functionalities, unless i'm wrong? Actually, i have just found a guide where I2C communication was used between the Arduino and the ESP8266, so this makes everything even more confusing! medium.com/@krukmat/arduino-esp8266-through-i2c-49b78e697b7a – WiredMaker Apr 12 '19 at 17:11
• ESP-01 used on that link has only UART pins according to any documentation I could find around. I don't understand what is described there. I am guessing a bit-banging over the GPIO pins from the ESP side. So bit-banging is inherently worse solution than using a dedicated hardware peripheral. – Eugene Sh. Apr 12 '19 at 17:25
• Well, one thing is that between the three, UART is the only one where the interface is full duplex AND data going one direction can start and stop independently of of data on the other line which is useful if the ESP wants to send data to the MCU of its own accord. The main benefit of I2C is addressing and multi-master neither of which are needed here. – DKNguyen Apr 12 '19 at 18:13
• FWIW, github.com/esp8266/Arduino/pull/5226 ESP8266 can never be a compliant I2C slave; there is no hardware support, and a bit-by-bit software solution isn't going to be fast enough for the standard I2C speed of 100kHz because 1) the interrupt won't arrive fast thought and 2) the GPIO bus clock is slower than 100kHz. That's why this solution can handle 14kHz max, which is useless since most other devices run at 100kHz. Try ESP32, it has I2C hardware. – Unknown123 Apr 13 '19 at 0:21

## 1 Answer

UART offers two way communication with just 2 wires.

I2C is one way communication for 2 wires. It can be made two way by implementing a custom notify mechanism where slave sends a signal whenever it has some data to send using a GPIO connection. This requires another pin and hence 3 wires for two way communication as compared to two in UART. Another alternative is polling as pointed out in comments below. Personally I prefer interrupt driven flow over polling. However if you are OK with polling, 2 wires can indeed do the job.

SPI requires a minimum of 4 wires. (Maybe 3 wires in case of single slave as Elliot commented)

Given the limited number of pins available on esp modules, I guess community might have chosen to use UART as the primary data transfer mechanism. Plus UART is simpler to implement than other counterparts. (This line could be opinion based so please pardon me if you tend to disagree)

It's possible to use esp modules as a stand alone MCU for general projects. You can use port expanders in case more GPIOs are needed. I used a similar architecture in one of my projects. I used esp-arduino for developing the firmware inside arduino IDE itself.

• I2C is only two wires (SCL and SDA) but UART is much simpler to implement as you stated – selectstriker2 Apr 12 '19 at 18:11
• For a single slave you might be able to do SPI with three wires. – Elliot Alderson Apr 12 '19 at 18:19
• @select - I have edited my answer to explain the 3 wire requirement. Please take a look. – Whiskeyjack Apr 12 '19 at 18:45
• @Elliot - updated my answer. thanks for pointing it out. – Whiskeyjack Apr 12 '19 at 18:45
• Even if conventional I2C would require polling, it's worth keeping in mind that many simple firmwares can only act on incoming data at a particular point in their loop execution anyway. Given that the ESP8266 has quite a bit more RAM than an ATmega, there's actually a valid argument for having the ESP buffer the data until the ATmega is ready to ask for it. Of course that same difference in resources can point to running the whole application on the ESP. – Chris Stratton Apr 12 '19 at 18:49