Getting
Started with ESP 01 Programming: How to use an Arduino Uno to program an ESP01. Although there are 4 GIPOs at the
connector, find out the ONLY One you can Use Easily! Why is the 8
pin connector badly designed?
ESP 01 Programming is made a little tricky, in that unlike all
other Arduino boards, there is no built-in USB to Serial converter and
there is no on-board power regulator
chip.
This
is done to save space, and the idea is that you use an external serial programmer to program the ESP01.
The image above shows a ESP01S (left) - You can identify it as it has a single white box to the right and
below the antenna - this is the blue LED (it's off), and ESP01 (right) - has four components in the same place.
A common error you will get during programming is:=
"A fatal esptool.py error occurred: Failed to connect to ESP8266: Timed out waiting for packet header"
TIP: Find out the reason and (partial) solution to why you get that error (and how to get round it) - on this page.
ESP01 Programming
Warning: Actually Programming this board is ultra tricky!
You need to be able to see the data sent from the ESP01 (to
check, that while you're sitting there twiddling your thumbs, the
ESP01 actually got the message to start doing something!).
You can do
this with the Uno RX and TX LEDs or use an oscilloscope.
Getting this to program is a real pain! But information on this page should help!
Alternatively use an ESP8266 with built in Serial chip and reset circuit.
Programming hardware
For programmingy ou can do one of the following:
Use an external FTDI
serial adaptor (but adjust for 3V3),
Use a separate programming board,
Use an Uno as a programmer (easy 3V3 operation)!
The interesting method used here is to use a Arduino Uno as a
programmer for your ESP01. You could use any Arduino board as the
programmer as it is used as a serial
adaptor i.e. only the serial connections from the on-board USB interface connect to the target (ESP-01).
Warning: This device must only be operated at 3V3.
Do not use 5V with the ESP01 -you will blow it up!
In this tutorial, we will cover the basics of ESP 01 programming
through a simple example using the Arduino IDE and an Arduino Uno board.
By the end, you'll understand the key concepts needed to begin
developing your own interactive and connected ESP 01-based creations.
ESP01 pinout
What is the ESP 01?
Because it has no extras on board (with minimal pinout), the ESP 01 is highly affordable. It is actually
the cheapest way to make a WiFi connected unit.
The only down side is that you do not get a voltage regulator so
powering them is difficult - in a design you will want either an block
adaptor and voltage regulator, or a 3V3 switcher from mains.
The ESP 01 is a the smallest WiFi board you can get, based around the
ESP8266 chip. It lets you easily connect projects to WiFi networks but
only provides 2GPIO pins for use. In many cases this is more than enough
especially for simple on/off control.
Note: With careful design you can use two more GPIO (see below).
Despite its small size, the ESP 01
module is still powerful because it uses the ESP8266 chip with built-in
TCP/IP networking capabilities and 32-bit RISC CPU. It runs on 3.3V and
communicates over UART (serial) interface, making it compatible with
common microcontrollers like the Arduino.
Note: There are two types of ESP01 (ESP01 and ESP01S). Find out the differences between them (and chips fitted) in that link.
How many Usable pins?
There is really only one easy to use pin: GPIO2 and a slightly more difficult to use GPIO0.
How many pins can you use on the ESP01?
In fact there are 4 usable I/O pins but there are constraints on
three of them. Three of the GPIO pins are required during programming. The only usable GPIO pin that has no constraints is GPIO2.
Here is a list of constraints on the GPIO pins
GPIO
Constraint
GPIO2
Free for user use - No constraints.
GPIO0
Must be held low for programming - in all circuits -(this is a dedicated input that indicates Flash Mode when held low). Must be held high during boot (or reset) in your circuit.
GPIO1
Used as serial RX pin during ESP 01 programming.
If you unplug the ESP01 then and insert it into your circuit then you
can use it as a normal I/O
GPIO3
Used as serial TX pin during ESP 01 programming.
If you unplug the ESP01 then and insert it into your circuit then you
can use it as a normal I/O
These constraints apply during ESP 01 programming so you either use
circuitry that does not interfere with the signal levels during
programming or - the easier way - remove the board from your circuit
after programming and plug it into your target system!
Control GPIO0
The more tricky one is GPIO0 - that must be held high during boot,
since it is a dedicated input that indicates "Enter Flash Mode". If
it is held low during power up the chip will enter Flash Programming Mode.
So add a pull-up resistor in your circuit (or use ESP01S) and ensure the external circuit does not pull
it low until after boot. The easy way - make it an output (which is
active after boot - it will be an input during boot by default and a pull-up - attached on the ESP01S, but not the ESP01 - will ensure it does not enter programming mode).
Note: ESP01 has a 12k pull-up on GPIO0 whereas ESP01 does not.
What is the CH_PD pin?
The pin CH_PD stands for CHip Power Down. Some people also call it the Chip Enable pin (chip is on when at 3V3 and off when at 0V),
Holding it high allows normal operation whereas when it is low the chip
is set to low power mode. Add your own pull-up in your circuit or use an
ESP01S.
For the ESP01S a 12k pull-up holds this high for you. For the ESP01 (older) you have to add your own pull-up.
Note: ESP01 has a 12k pull-up on CH_PD whereas ESP01 does not.
What is the RST pin?
This is the chip ReSeT pin. You pull it low
(then high) to reset the chip. If you want to program the chip hold
GPIO1 low and the reset the chip. Add your own pull-up in your circuit
or use an ESP01S.
On the ESP01S a 12k pull-up holds this high for you. For the ESP01 (older) you have to add your own pull-up.
Note: ESP01 has a 12k pull-up on RST whereas ESP01 does not.
Details of the Uno Rx Tx circuit
While developing the circuit I noticed that even when the Uno is held
in reset the voltage at the RX pin was 5V. We really don't want 5V
applied to the ESP01.
The Rx, Tx part of the schematic is shown below. On the left is the
USB chip and on the right is the ATmega328p. To the far right is the Uno
connector.
So between USB chip (left side) and the 328pins is one single 1k resistor each for Rx and Tx
paths. The Arduino Uno pin connections directly attach to the
ATmega328p. The 1k resistors protect the USB chip so that if the USB
chip output high, and you pull the pin low, limited current can flow.
The following diagrams show reset for UBS and Uno:
Reset for the USB chip is entirely separate and only goes to an ICSP connector.
Uno reset circuit showing DTR signal through C5 to reset pin of the 328p chip (see this "Arduino ISP" page for how it operates), and to the connectors:
It means holding the reset line for the 328p low, resets the 328p but the
USB chip still outputs 5V to the Rx pin as it is not reset.
You can't reset the USB chip anyway as it must operate the serial lines -
the problem is that when not active it drives 5V on the Arduino Rx line
(pin 0). The TXD1 signal from the USB chip drives the RX line into the
328p.
Solving the Rx Tx problem.
The problem is one of nomenclature.
When thinking about the Uno the Uno RXD input (Arduino pin 0) receives data from the
USB chip (USBTX pin name TXD1, signal name M8RXD), and when you use the Uno Rx, it is an input at Arduino pin 0.
When thinking about the USB chip to program an external ESP 01, the
signal connected to the UNO Rx is an output from the USB chip (USBTX pin
is TXD1, signal name M8RXD).
In fact for ESP 01 programming:
UnoRX is USBTX,
Uno TX is USBRX.
The solution is therefore to non-intuatively Not swap Uno Rx and Uno Tx when
programming the ESP01; connect Rx to Rx, and Tx to Tx. This because we need the "USB chip operation" not the
Uno centric operation!
Note: This was only
discovered after connecting the circuit - and shows how useful it is to
check everything before you plug in your target board.
Note: This is true for any Arduino module that has on board serial chip.
Solving the next TX problem
I did notice this before - the voltage at Arduino pin 0 was a bit low
(with external voltage drop divide -1k, 2k) but pushed on anyway.
With the output from the TXD1 line (labelled M8RXD) - it has an
in-series 1k resistor. With the original circuit that drops the voltage
to get from 5V to 3V3, I originally had at the output at the Arduino pin going to a 1k and 2k
divider.
This would work if that other serial resistor (RN4B) was not there! However
we can use the existing 1k and lose the 1k in the external circuit. This will
give the correct drop down voltage, giving the desired voltage
divider, using 1k (RN4B), 2k(external) . The external 2k will form a voltage divider with RN4B above to
give max 3V3 at Arduino pin 0.
Warning: This 1k resistor may not be present on other types of Arduino board - in that case use an external 1k, 2k voltage divider at the output.
Programming the ESP 01
To program the ESP 01, you need to hold GPIO0 low and do a reset.
This is why external boards use a toggle switch and a push button: so
you can hold GPIO0 low and then blip the reset to enter Flash
programming mode.
The key point for the schematics below is that programming of the
Arduino Uno is bypassed; all it is really doing is using the other chip
on the Uno board that handles the serial USB to Serial RS232 interface
(Tx and Rx). This is why the ATMega328p is held in reset (so that its
pins are set as inputs for non interference of Rx and Tx pins).
The other point about the ESP01 is that it must only use 3V3 and that
is the reason for the drop down potential divider (R1 (now the on board 1k RN4B), R2). It also shows use of
the internal 3V3 regulator from the Uno to power the ESP01.
Note: The available power will only be sufficient for programming. In
use the ESP01 can use 100's of mA. If you use WiFi it may work for
testing but could be unreliable. Use a higher current source 3V3 supply
for reliable operation.
ESP 01 programming schematic
The following circuit shows the three pull-up resistors that are not included on the ESP 01 board so you have to add them externally as shown here:
Note: Observe the RESET connection on the Uno.
Observe that RX and TX are Not swapped intentionally (here's why).
Warning: For the Uno you must use RX and TX signals as shown above.
The above circuit diagram will work with both ESP-01 and ESP-01S but
the following one is a bit easier as it uses less components.
ESP 01S programming schematic
The following circuit shows the easier circuit for ESP 01S
programming. You don't need the three pull-ups as they are already on
the ESP01S board:
Note: Observe the RESET connection on the Uno.
Observe that RX and TX are Not swapped intentionally (here's why).
Warning: For the Uno you must use RX and TX signals as shown above.
How to enter flash programming mode
Hold GPIO1 low (toggle switch SW1).
Blip RST low (push button, then release) - or cycle the power.
Using a DIP adaptor
The problem with the 8 pin IDC connector is that it is not breadboard
friendly so you could either use flying dupont wires or create/buy an
adaptor. I bought one. Now, the next problem is that the IDC is not
polarised - meaning you can get the connections completely wrong (by 180
degrees = magic smoke)!
Warning: Connect the ESP01 the right way round or get smoke!
IDC adaptor engineering lesson
Actually there is a very good design lesson here. If you observe the
connector and then rotate it 180 degrees. Yep, you really do get magic
smoke - you will destroy the ESP01 because ESP01 VCC is connected to
GND, and ESP GND is connected to VCC - exactly what you don't want!
For a real "engineered" design the VCC and GND connections should
never be placed so that they can be symmetrically opposite. Basically
put Tx on pin2, Vcc on pin8 (Rx is pin1) - GND is on pin7. That way when the connector is rotated
wrongly you get power applied to signal wires and not the power supply
of the ESP8266 i.e. it would not blow up.
Warning: Don't put the ESP01 the wrong way round.
Lets say you swapped connections for VCC and Tx (as above) - for all new ESP01
board designs, then if you accidentally rotate 180 degrees you would be
applying VCC to Rx, and GND to Tx = no effect.
Note This is not a problem just for the adaptor, it is a problem that
can happen for any ESP01 that you plug into any board designed to hold the
ESP01!
The other solution is to use proper IDC connectors and not just pins -
you can get IDC plug and adaptor sockets with a notch/and matching tab,
so you could not physically insert them the wrong way round.
Get the orientation right
You have to be able to get the pins matched up so, here's the back
and front images of the adaptor. If unsure, buzz out where GND and TXD
are located and fit accordingly - your board may be different!
TXD is bottom left:
This is the correct way to insert the ESP 01 for programming.
Warning: Don't put the ESP01 the wrong way round.
Once you have setup the circuit to match the schematic check the
voltages are what you expect at the connector before plugging in the ESP
01 to program it.
Programming the ESP01 using An Uno
Steps for programming the ESP01 using an Arduino Uno:
Install the ESP8266 board package in the Arduino IDE. This adds ESP8266 board support to the IDE.
Select the correct ESP8266 board in the Tools > Board menu. Search for and use "Generic ESP8266".
Connect the ESP-01 to the Arduino Uno as outlined above. The Uno will communicate with the ESP-01 over serial to upload code.
Open/write your ESP8266 sketch/code in the Arduino IDE. Make sure to include WiFi and ESP8266 libraries as needed.
Select the correct serial port that the Uno is using in Tools > Port.
Blip the reset button in your circuit.
Click the upload button to program the ESP-01. The Arduino Uno acts as a serial-to-USB converter and programmer in this process.
The ESP-01 will reset and run your uploaded code. You can monitor serial output on the Arduino IDE serial monitor.
So in summary, the Arduino Uno provides the programming interface
between the ESP-01 module and computer/Arduino IDE through its serial
port functionality.
Troubleshoot IDE and the Uno
A message you might get is this:
Compilation error: ESP8266WiFi.h: No such file or directory
You might get this message even though you have installed the library - the library is not the problem!
When you use the Uno for ESP 01 programming, the IDE does not really operate
as you want; it interrogates the board and thinks it is the Uno (it is, but you are bypassing it).
The key point here is to first
select the port that the Arduino Uno is located at, and then switch to
the real target board you want to program (since the Uno is used as a
serial driver only - you are not using the Uno as the target board!).
The Arduino IDE will forget this between sessions so follow along
with the screen shots below to get the Uno and ESP8266 working as you
need:
1. Select the Arduino Uno and port
2. Use Board Selector
Now click "Select other board and port..." (see image above).
You can see that the correct port is selected. Now type in "generic" in the "Search Board" box.
3. Switch to Generic ESP8266
Select Generic ESP8266 Module and keep the original port selection. Click OK.
4.Check that you are setup for the ESP8266
At the top of the IDE you should see this; meaning that the Uno is
now bypassed and you can successfully program the ESP8266 without a
library warning!
Simple Sketch Examples
WiFi connection example
The following sketch is a simple one that connects to WiFi and reports the IP address assigned if successful.
Now open the Arduino IDE and select the board as "Generic ESP8266
Module" and the correct serial port. If you are between sessions the IDE
can forget so use the trouble shooting checklist above to setup the Uno
for ESP8266 programming. Now
continue programming.
We will use an example sketch from
the ESP8266 WiFi library to connect the ESP 01 to a WiFi network and
print its IP address. Copy and paste the code below, add your own WiFi
SSID and password fields, then upload it.
#include<ESP8266WiFi.h>
constchar* ssid = "YOUR_WIFI_SSID";
constchar* password = "YOUR_WIFI_PASSWORD";
voidsetup(){
Serial.begin(74880); // This allows you to see ESP01 start data.
Serial.println("\nESP 01 Starting WiFi test...");
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
}
voidloop(){}
TIP: Using a serial
baud rate of 74880 lets you see ESP8266 serial messages (from the
bootloader) as well as your own - it's useful to see what's going on.
If uploading is successful, the ESP 01 will connect to
WiFi and print its IP address back over the serial monitor. This
demonstrates how easily the powerful ESP8266 chip inside can be
programmed to connect to wireless networks using the Arduino IDE
environment.
Working with GPIO
The ESP 01 provides 2 GPIO (if you have the ESP01S) then GPIO2 is connected to an on board blue LED, if not add an external LED and limit resistor (1k).
There are two programmable pins on the ESP01 &
ESP01S that you can configure as either digital inputs or outputs to
interface with sensors, actuators, and other hardware. The two available
GPIOs that are attached to the connector are GPIO0 and GPIO2. However
GPIO0 must be held high during boot so it's easier to use GPIO2.
Here is an example of how to control and write to pin GPIO2:
#defineLED_PIN2
voidsetup(){
pinMode(LED_PIN, OUTPUT);
}
voidloop(){
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay(1000);
}
Combined Web And GPIO example
Although you can use the above code standalone, here's an example of
combining both Web and GPIO operations. In addition an extra LED is
controlled from GPIO0. Note also the non blocking timing which allows asynchronous LED flashing.
#include<ESP8266WiFi.h>
#defineLEDPIN2
#defineLEDPIN_0
constchar* ssid = "YOUR_WIFI_SSID";
constchar* password = "YOUR_WIFI_PASSWORD";
voidsetup(){
Serial.begin(74880); // This allows you to see ESP01 start data.
During programming TX is an output from the ESP01 and RX is an input to the ESP01, but after that they are fair game.
The key is to attach circuits that do not interfere with
the RX and TX signals, if you keep the programmer attached, and the easiest way to do that is to make your
circuit be inputs. That means do not attach circuits that generate
signals but only ones that receive signals.
For instance you could make RX and TX, I2C signals (it
is unlikely that the correct signals sequence would make the attached
I2C device react. Or you could attach LEDs (as long as the load is not
too great).
Alternatively, if you unplug the ESP01 from the
programmer and put it into your own circuit you can use the TX and RX
pins as normal I/O. The only requirement is that GPIO0 is held high
initially (so that the ESP01 does not enter boot mode).
Troubleshooting ESP 01 programming
Both of the chips I have would often fail to program ESP01 and EPS01S.
Occasionally I
got it to program the Flash, but more often than not it returned the
boot error codes (see below).
By observing the reset problem and (partial solution below) it now
seems that the device will program more reliably - not every time but
far better than before - Note this is for both ESP01 and ESP01S - they
have the same problem.
Looking around the web there a
quite a few instances of ESP 01 programming failure for no particular
reason. You could see this sort of error message in the Arduino IDE:
A fatal esptool.py error occurred: Failed to connect to ESP8266: Timed out waiting for packet header
It could be flying wires etc. However I looked on an oscilloscope at
the signals and they seemed very good. Sometimes the ESP01 would output
data on request at the header reading stage and then would program
correctly but mainly it did not. I tried solder lead inspection, using a
high current power source, adding more caps (10uF) externally to the
board, resoldering with iron, then hot air gun - all that did not work.
But, after using the reset technique below - it became easier to program reliably.
The reset problem
It is probably best just to get another ESP01 chip!
However I now think this:
I am not convinced the following messages accurately reflect what is
going on in the circuit because if you time your reset signal to about
25% before the end of Arduino IDE compilation completion then the
chances of programming the board greatly increase.
It feels as though the reset timing is the most important factor. If
you reset too early, it seems as though the ESP01 times out. If you reset
to late, it does not have time to react - no output on oscilloscope from
ESP01 to Arduino pin. The sweet spot is near the end of compilation!
The interesting thing is that the signals do look clean.
Another observation is that it is useful to view the response from
the ESP01. Initially I used an oscilloscope to view Rx and Tx but you
only really need to look at the Tx and Rx LEDs on the Arduino Uno.
While the sequence of initial programming is running during this serial output text (shown in the programming window):
Connecting........_____....._____..
You should see both Rx and Tx LEDs go on at the same time, and then a
long period of both LEDs off. If you only see one LED (Rx) it means the
ESP01 is not responding; blipping the reset can sometimes get the
programming sequence going again - or programming drops out and you have
to have another go!
Once the headers have been exchanged (this can take many ....._____
sequences) programming will start; you'll get lots of Rx LED (USB chip
to ESP01)
with a few Tx LED blips - the acknowledge from the ESP01. You can also
see the percentage Flash programming completed in the output window.
In the end you will get the ESP01 to flash but it's going to take some patience and probably watch those LEDs (to detect activity on TX pin of ESP01).
Another useful observation is that using the ESP8266, on a board
with built in serial that uses automatic reset, I never get these
problems.
The automatic reset circuit recommended by Espressif uses CTR and DTR
to control the reset pin and CH_EN pins is probably what is needed to
get reliable ESP 01 programming (but you'll need to find the DTR and CTR
signals from the serial output chip on the Uno to do it!):
Source of schematic link (Search for: 'As an example of auto-reset circuitry implementation'):
Boot messages on ESP 01 programming
ets Jan 8 2013,rst cause:2, boot mode:(1,6) - these are typical reset messages.
ets Jan 8 2013,rst cause:2, boot mode:(1,7) - these are typical reset messages.
Boot Message Explanation
Do not take these messages as accurate indications of your circuit
setup as I said above, I think it is more to do with reset timing.
The message "ets Jan 8 2013,rst cause:2, boot mode:(1,7)" indicates
that the device has experienced a hardware reset due to an insufficient
power supply. This error typically occurs when the device is not
receiving enough power to operate properly.
The message "ets Jan 8 2013,rst cause:2, boot mode:(1,6)" indicates
that the device has experienced a hardware reset due to an improper
power supply. This error typically occurs when the device is not
receiving enough power to operate properly or when there is a voltage
fluctuation.
Here's a breakdown of the message:
ets Jan 8 2013: This is the timestamp of the reset event, indicating that it occurred on January 8, 2013.
rst cause:2: It indicates that the module was last reset due to an external reset.
boot mode:(1,7)
The second number (7) indicates that the GPIO pins are not being used and GPIO0 is low, GPIO2 is high.
boot mode:(1,6):
The second number (6) indicates that the GPIO pins are set to input mode and GPIO0=low, GPIO2=low during reset.
The first number is the GPIO0 status while the second is for GPIO2.
IF you enter normal mode you get the output : boot mode:(3,6).
Conclusions
Be prepared for a length programming session - if you have patience you can get these things to program but it's may not be
easy!!!
The reset technique discussed here should let you program the chip
without getting that annoying error message; but you will sometimes
still get it!
The method discussed here greatly increases the reliability of ESP 01 programming.
Written by John Main who has a degree in Electronic Engineering.
Note: Parts of this page were written using poe as a research assistant.
A PIR sensor lets your Arduino sense movement without contact. This tutorial covers PIR sensor basics, connecting one to an Arduino board and coding a motion detector.
Arduino Hall Effect Sensor: Add magnetic sensing superpowers to your Arduino projects with an easy-to-use hall effect sensor. With full code and layout...
Get started with an Arduino humidity sensor using the DHT11, which reports both humidity and temperature. Complete guide with full code for using this sensor
Comments
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.