My past few days have been spent attempting ESP8266 flashing and running blinky . Considering how I have a working firmware from my NodeMCU experiment, I considered this to be quick. I was mistaken, obviously.
Some of the important lessons learnt are shared below:
ESP8266 Power Source
The first consideration is that ESP8266 based boards operate on 3.3V with boot time current of around 300mA which settles down to a lower value of around 50mA (need to verify yet). This information led me to use one of the L78L33 IC (max continuous current 100mA) lying around my workstation. It heated up and burned away in a few minutes.
I had a few variable voltage regulator LM317 ICs handy as well, capable of supplying over 1.5A current. Unfortunately, the resistor combinations I had allowed me to configure LM317 for either 3.1V or 3.5V. I tried 3.5V and burnt the ESP8266EX in a few minutes 🙂 . With my lesson learnt, I ordered LD33CV 3.3 volt fixed voltage regulator ICs with current supply of 800mA. The new ESP8266EX and the voltage regulator have been alive for quite a few days now. Phew!
My first activity after setting up LD33CV with ESP8266EX was to measure the current: it was a constant 350mA! Turns out, due to firmware issues, the ESP8266 chip was rebooting again and again, drawing large amounts of current almost continuously.
Till you get a stable firmware ready, use an oversized voltage regulator (like LD1117V33 or LD33CV). ESP8266 in a reboot loop may draw around 350mA continuously!
Serial Console 74880 bps
Opening the serial console at baud rate of 74880 bps (the default ESP8266 bootloader baud rate), was pretty straightforward on Windows (I used RealTerm). On Ubuntu, however, after trying out all the famous serial consoles (GNU Screen, minicom and cu to name a few), I finally stumbled upon this link: http://sensornodeinfo.rockingdlabs.com/blog/2016/01/19/baud74880/. anybaud is not a neat solution, but I settled on it after hours of searching.
ESP8266 boot mode
Understanding boot modes of ESP8266 is very important to make sure the device functions as intended. I found the most complete description of the boot mode at this forum post: http://bbs.espressif.com/viewtopic.php?t=774 and https://zoetrope.io/tech-blog/esp8266-bootloader-modes-and-gpio-state-startup. The boot mode is determined by the 3 bit formed by BOOT_TYPE = [GPIO15, GPIO0, GPIO2].
- 001 – UART Download Mode (Programming)
- 011 – Flash Startup (Normal)
- 100 – SD-Card Boot
This essentially means that toggling between Programming mode and Normal mode requires toggling of GPIO0, given the GPIO15 is pulled down to ground and GPIO2 is at VCC (handled by internal pullups). These GPIO pins are connected to weak pullups by default. In the ESP8266EX baseboard I have, GPIO15 is pulled down to ground and not exposed. I have connected GPIO2 to VCC and connected a push button on GPIO0 leading to ground for easily controlling the booting mode manually.
These GPIO and booting mode specifications have a few other implications as well. It is recommended that these GPIO pins are not used for regular input/output and left for boot control, flashing and debugging messages (on GPIO2). However, my ESP8266EX module only exposes these two GPIOs. Looks like these modules are good for using ESP8266 as a Serial to WiFi convertor only… what a waste!
Following the NodeMCU design, I connected an LED to GPIO2 for a blinky program, and had flashing problems since. NodeMCU is taking care of a few other things to reliably connect a LED to GPIO2. I will look in to this later.
I found myself diving deeper into the abyss with every failed attempt to flash the ESP8266. I had used almost all the flashing tools available (esptool, NodeMCU flasher and flash download tool), with virtually all permutation of configurations when things started to go awry. Having explored this path, I have outlined a more systematic approach I followed later on.
The first step is to identify the flash chip onboard your device. For me, it is a Berj Micro 25Q80ASSIG. A quick glance at the datasheet reveals that it is a 1MB flash which operates at 80MHz SPI clock speed and allows both DIO and QIO modes. This information will be useful for configuration in later stages.
The tool of my choice turned out to be esptool. Primarily, because it has a command line interface and is extremely flexible. The flashing command used are:
esptool.py --port /dev/ttyUSB0 write_flash \ -fs 8m -ff 80m -fm dio \ <load_address_1> <binary_path_1> \ <load_address_2> <binary_path_2> \ ... <load_address_N> <binary_path_N>
A successful flash operation was prompted as follows:
esptool.py v1.2-dev Connecting... Running Cesanta flasher stub... Flash params set to 0x022f Writing 4096 @ 0x0... 4096 (100 %) Wrote 4096 bytes at 0x0 in 0.4 seconds (90.3 kbit/s)... Writing 4096 @ 0xfc000... 4096 (100 %) Wrote 4096 bytes at 0xfc000 in 0.4 seconds (90.3 kbit/s)... Writing 401408 @ 0x1000... 401408 (100 %) Wrote 401408 bytes at 0x1000 in 34.8 seconds (92.3 kbit/s)... Writing 401408 @ 0x81000... 401408 (100 %) Wrote 401408 bytes at 0x81000 in 34.8 seconds (92.3 kbit/s)... Writing 4096 @ 0x7e000... 4096 (100 %) Wrote 4096 bytes at 0x7e000 in 0.4 seconds (90.1 kbit/s)... Writing 4096 @ 0xfe000... 4096 (100 %) Wrote 4096 bytes at 0xfe000 in 0.4 seconds (90.2 kbit/s)... Leaving...
I believe I have damaged the flash or its controlling pins on my device. This allowed me to experiment and record different kinds of console outputs.
After successful flash of ESP8266 SDK prebuilt binaries, the device prints the following prompt on serial console:
ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 1856, room 16 tail 0 chksum 0x63 load 0x3ffe8000, len 776, room 8 tail 0 chksum 0x02 load 0x3ffe8310, len 552, room 8 tail 0 chksum 0x79 csum 0x79 2nd boot version : 1.5 SPI Speed : 80MHz SPI Mode : DIO SPI Flash Size & Map: 8Mbit(512KB+512KB) jump to run user1 @ 1000 ����
According to comments in esptool, we do not have access to erase the flash directly. This is worked around by making the ESP8266 execute one of the flash erase function provided by SDK and hope that it will succeed. From this logic, we must have at least some working bits of firmware in flash to be able to erase it. After running flash_erase, the following output was seen on reset. The ESP8266 is basically doing nothing at this point.
ets Jan 8 2013,rst cause:2, boot mode:(3,6) ets_main.c
WiFi Configuration Information
Blue LED on ESP8266 baseboard is lit whenever WiFi is initialized. After a successful flash erase, the light remained off. Flashing esp_init_data_default.bin fixes the problem and blue lights starts to blink on reset. It can be assumed that this binary holds configuration information related to WiFi.
Incorrect Firmware / Flashing Error
If flash has not been properly programmed, device is able to boot up. boot*.bin directs the device to boot one of the two binary images loaded to flash. In absence of proper boot*.bin, device prints the following prompt on serial:
ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 23988, room 16 tail 4 chksum 0x0f load 0x3ffe8000, len 2180, room 4 tail 0 chksum 0xc9 load 0x3ffe8884, len 8, room 8 tail 0 chksum 0x62 csum 0x62
In some instances, the devices may encounter a fatal error on boot (error message is printed on serial console) and ESP8266 reboots again and again. Problems like these are mostly caused by unsuccessful flashing or an incompatible firmware.
I have yet to finalize the design on breadboard for this setup. This activity has gave me some important pointers:
- Using ESP8266 as a standalone IoT makes sense when using a baseboard which exposes all the GPIO pins.
- Proper flashing setup (automatic entry to flash mode by serial to USB controller and scripts tuned for the hardware) is necessary for reliable and speedy development later on.
I have a few tasks related to this lined up for me now. Furthermore, I will be updating this post with more hardware setup findings.