In this post, we go into detail about programming the ESP8266. We will start with a programming guide for the ESP8266 in the Arduino environment, looking at the main functions and comparing them with their equivalents in a conventional Arduino.
In the previous post of the series about the ESP8266, we saw how to set up the Arduino environment to program the ESP8266. We already mentioned that, despite being very similar, there are differences between programming an Arduino and an ESP8266.
On the other hand, we have also seen the hardware details of the ESP8266, comparing them with Arduino’s. In this post, we will assume that the hardware differences are clear. In case of doubt, refer to the previous post.
Therefore, we begin with the programming guide for the ESP8266, the different functions of the ESP8266 and the similarities and differences with Arduino programming.
Time Functions
Millis and Delay
The time functions millis() and micros() work the same as in Arduino. The functions delay() and delayMicroseconds() also work, with the considerations about Yielding that we will see next.
Yielding
This is one of the most important differences compared to an Arduino. The ESP8266 executes many functions related to maintaining and managing the WiFI connection and the TCP/IP stack. If it does not execute these actions, we will have communication problems, lockups, and reboots.
For this reason, it is recommended to avoid blocking for more than 100-200ms in our code. In fact, if 3 seconds pass without calling these functions, the WatchDog will restart the ESP8266. And even with the WatchDog disabled, with a wait longer than 8 seconds, the ESP8266 will restart on its own.
The ESP8266 functions are executed at the end of each loop, when calling the delay() function, or with the function developed for the ESP8266 in Arduino yield(), which we could consider equivalent to delay(0).
In summary, if you have a process that requires more than 100-200ms, you must modify it to include a delay() or a yield().
On the other hand, the delaymicroseconds() function does not call yield(), so we should avoid using it for waits longer than about 20ms.
Connections and Hardware
Communication
Serial Port
Using the serial port on the ESP8266 is very similar to its use in Arduino and employs all the functions we are used to for sending and receiving data (read, write, print, println…)
The only peculiarities are related to additional functions available on the ESP8266, as the ESP8266 has 2 serial ports.
The first port (UART0) is connected to 2 pairs of pins. By default, TX0 GPIO1 and RX0 GPIO3 are used, but it can be changed to TX0 GPIO15 and RX0 GPIO13. If we want to switch between both possibilities, we use the function.
Serial.swap()
The second port (UART1) is associated with pins TX1 GPIO2 and RX2 GPIO8. But GPIO8 is used for the connection with external memory. Therefore, UART1 can only be used to send data. The functions are the same as the usual ones, but using Serial1 instead of Serial. For example, UART1 would be initialized like this:
Serial1.begin(baud)
I2C Bus
The use of I2C on the ESP8266 is similar to Arduino and uses the same functions. The difference is that the ESP8266 does not have hardware for I2C communication, so it simulates it via software.
This implies an additional processing load for the ESP8266 that Arduino does not have. But, as an advantage, we can use any two pins for communication.
By default, the pins used are SDA GPIO4 (D2) and SCL GPIO5 (D14). But we can change it with the function:
Wire.begin(SDA, SCL)
The maximum speed is about 450kHZ. Otherwise, the programming is identical to Arduino.
SPI Bus
The ESP8266 has a hardware SPI accessible to the user (sometimes designated HSPI). Again, its use is similar and employs the same functions as in a conventional Arduino. The default pins are MISO GPIO12 (D12), MOSI GPIO13 (D7), CLK GPIO14 (D13), and SS GPIO15 (D10).
Additionally, on the ESP8266 we can easily change the SPI frequency up to 1Mhz with the function:
SPI.setFrequency(frequency)
WiFi Communication
To access the WiFi functionalities of the ESP8266 we will use the ESP8266WiFI library, whose operation is similar to the Arduino WiFi library.
ESP8266WiFi Class
To include it in our project we use:
#include <ESP8266WiFi.h>
The WiFi functionality is one of the main points of interest of the ESP8266. We will see its use intensively in the upcoming tutorials of the ESP8266 series, so we are not going to delve into it for now.
Arduino Libraries
One of the most frequently asked questions when talking about programming the ESP8266 in Arduino is: will Arduino libraries work on the ESP8266? And the answer is, I’m sorry to say, that in general they will not be compatible.
But it’s not always the case. If the library only uses C++ code (for example, a calculation library), or uses environment functions to handle hardware, this library will work.
However, if it accesses internal elements of the architecture like timers, registers, or if it uses assembly code to speed up certain tasks, for example, the library will not work unless it has been specifically adapted for the ESP8266.
Fortunately, the popularity of the ESP8266 has led the community to develop or adapt most of the libraries available for Arduino. Although, among the many available, we will have to specifically search for those compatible with ESP8266.
As we can see, despite some differences, in general it is very similar to programming an Arduino. This is due to the great work of the community in developing compatibility between devices, and makes it very easy to use the ESP8266 with the Arduino environment.
In the next posts, we will see how to do something similar with the ESP32, and we will start seeing examples and projects with the ESP8266.

