Monday, October 13, 2014

Getting started with development on ESP8266

Enterprising tinkerers on the esp8266 message boards have added the Xtensa Call0 ABI support to gcc, allowing a fairly clean way to compile the code and run it on the device.

I'm going try to try to put the steps together here, mainly for my own benefit since I'll probably forgot otherwise. :-)

To get the toolchain up and running, follow the instructions given here:
$ git clone -b lx106 git://
$ cd crosstool-NG
$ ./bootstrap && ./configure --prefix=`pwd` && make && make install
$ ./ct-ng xtensa-lx106-elf
$ ./ct-ng build
This will compile the toolchain targeted at xtensa lx106 into the builds/ directory and will take a while.  You may be required to install some missing dependencies.  Meanwhile, we need to download the SDK and few other odds and ends.

From this post, download the file which contains the "esptool" package which will parse the elf generated by gcc compiler above, extract the relevant sections, and repack it into a binary format ready to be flashed.  While you're there, also download the Makefiles which we'll modify to work with the toolchain above.

From this post, download the esp8266 sdk package.  Extract the SDK package, extract the inside the SDK (as the Makefile looks for SDK_DIR/esptool/esptool executable) and build the esptool executable
$ unzip
$ cp esp8266_sdk_v0.9.1
$ cd esp8266_sdk_v0.9.1
$ unzip
$ cd esptool
$ vim Makefile  # edit target from WINDOWS to LINUX
$ make
To build the "AT" firmware, I had to copy the new updated makefile from Makefile_AT_0.9.1 into the SDK_DIR/examples/at directory and make couple of changes to the Makefile by setting the SDK_BASE, setting EXTRA_INCDIR to add include/ and /usr/include/ fields, and pointing to the toolchain built above for CC/AR/LD calls.
$ cp esp8266_sdk_v0.9.1/examples/at
$ cd esp8266_sdk_v0.9.1/examples/at
$ unzip
$ vim Makefile # Update SDK_BASE, EXTRA_INCDIR, CC, AR, LD
$ make
It would've been lovely if it all had just worked...  but some more tweaks and missing dependencies are required.  First, we need to put the libc.a and libhal.a from extra_libs.tgz from this post and put it in the SDK_DIR/lib directory.  I also had to comment out int32_t in SDK_DIR/include/c_types.h.  After that, though, simple "$ make" and we get the two firmware files, 0x00000.bin and 0x40000.bin!

To download the firmware to the ESP8266, you need to boot the board with GPIO0 tied to ground to have it come up in programming mode.  Once in programming mode, I was able to use the download script to program the new code
python --port COM3 write_flash 0x00000 0x00000.bin
python --port COM3 write_flash 0x40000 0x40000.bin
I got some error messages after erasing and programming had completed, but everything seems to work OK even with the error message.

ESP8266 Communicating
The module uses AT command set, and I was able to test the basic functionality by doing the following:
COM3> AT+CIFSR # Get IP address
# Server mode enabled, test with nc IP_ADDRESS 5000

# Client mode, test with nc -l 6000
COM3> AT+CIPSEND=<length>
What I'm interested in doing doing, though, is mode where the device wakes up by itself, automatically connects to a known Wifi station, and either automatically starts sending data or starts up a server so that data can be pulled out.  This seems closer to the SDK's "IoT_demo" code base.  I'm able to build and flash the resulting image, but I'm not quite sure what it is that the demo does yet.  I suppose if I can't figure it out, I can just write something from scratch instead. :-)

Saturday, October 4, 2014

Wireless Power Consumption and ESP8266

I've been in touch with the folks at Bogart Engineering, who makes the "Trimetric" battery monitor used to monitor the 48V lead acid battery pack at the house.  I've been able to successfully read the streaming data out of the device, and have been trying to figure out an easy way to gather and store that data.

Trimetric Battery Monitor
The battery monitor is powered directly by the 48V and is down-converted to 5V.  The conversion is done with a linear regulator, so the main limit is the heat dissipation.  Unfortunately, this means available current at the 5V rail is low tens of mA, which basically rules out running anything that communicates over Wifi, including the ESP8266 module.  I knew there was about a magnitude difference in power consumption between Bluetooth and Wifi, but it really didn't hit me until I was reading through the different datasheet to figure out what would actually work in this case.

Given the power budget, I'm back to looking at Bluetooth serial dongles, and probably get a low end NUC running Linux which will give me more flexibility in case I wanted to add something like a weather station or run a server in the house.

The ESP8266 board finally arrived, and I've turned it on to make sure that it works - and it does seem to really work! :-)  I've also found a fairly active forum with people trying to do exactly what I'm trying to accomplish.  I've been lurking due to lack of time, but it seems like the main issue is that the IoT development kit's precompiled bits are compiled in Tensilica's proprietary compiler in an ABI that's quite different from the one supported in gcc.  Apparently there's a VirtualBox machine image floating around with all the required bits installed, but a lot of people's focus seems to be on trying to figure out how to compile and run code on fully open development stack.  At least on the firmware download side, it doesn't seem like flash chip twiddling is required - someone reverse engineered the flashing tool and created a documented open version of it!

ESP8266 Board
Some random notes about the ESP8266 board that I have - it's running firmware version 00160910 and communicates at 115200 baud instead of 57600 baud reported elsewhere.  The board layout also requires the chip enable to be held high on top of connecting the tx/rx pins and power and ground.

Even though my intended use for this part is gone due to power consumption (seems to be 200~300mA), I'm hoping I can at least help out in the effort to get open stack toolchain working.  Even with the different ABI, it might be possible to create a glue layer that would allow gcc complied code to talk to the precompiled binaries.  Should be an interesting puzzle to try to figure out.