WiFi MQTT Display with the ESP8266

ESP8266 MQTT OLED Display
ESP8266 MQTT OLED Display

Like many people I have been playing with the Espressif ESP8266 WiFi modules over the last few months. I’ve had a couple of modules running for a while now, one connected to an Arduino pro mini clone with a 2×16 OLED display and one running directly on the ESP8266 using the NodeMcu Lua interpreter controlling a relay over an HTTP REST-like API.

One thing I was really hoping for was a native MQTT implementation as it is the protocol I use for my home automation and sensor network. Luckily tuanpm on the esp8266.com forums gave us a boxing day present in the form of a native MQTT client. MQTT on the ESP8266 means it will be easy to integrate input and output nodes in to my existing home automation and sensor network.

For a first test I just changed the MQTT and WiFi settings in user_config.h, tweaked the Makefile for my environment and compiled with the esp-open-sdk toolchain (currently with the 0.9.3 Espressif SDK, I need to update) and it compiled fine, I flashed it to the ESP8266 and gave it a test run on a busy MQTT topic (all my environmental sensors) for a day or so and it handled it without a problem.

esp8266_modulesThe following day I hooked up a spare 0.96″ I2C OLED display and soon had it showing data from my sensors.
This demo is using the common ESP-01 variant of the ESP8266 board, available on eBay from Chinese sellers for around £2 each or a bit over double that from UK sellers. The downside of this module is that it only has two GPIO pins and we need both of those for the I2C and GPIO0 also to be grounded when we want to get into programming mode, a minor inconvenience but I also have some ESP-03 boards that I am working on a PCB for, as well as an ESP-12 and some ESP-WROOM modules that I got as a freebie from Espressif, all these have a lot more available GPIO pins.

The demo C code is available here, it’s hardcoded to my setup but it should get you going if you want to give it a try.

This code combines Tuan PM’s port of the MQTT client library for ESP8266 (itself ported from the library for Contiki), zarya’s ESP8266 I2C driver and the OLED driver found here.

It subscribes to three MQTT topics and displays them on the OLED (two temperature feeds and an info message on the bottom of the screen), the display I am using is this 0.96″ 128×64 White OLED but similar displays are widely available (plenty on eBay).

Configuration

I2C address for the OLED is in include/driver/i2c_oled.h
MQTT broker and WiFi settings are in include/user_config.h
GPIO pins to use for I2C are in driver/i2c.h
MQTT topics to subscribe to are in the MQTT_Start() function in user/mqtt.c
What to do with the incoming messages is defined in deliver_publish() in user/mqtt.c

If you want to add more than 3 topics you will need to change MQTT_SUB_TOPIC_NUM in user_config.h and the mqtt_topic variable declaration near the top of mqtt.c

I use Linux so I haven’t tested the Windows Makefile, it is as it comes with the MQTT demo but should work provided the SDK & tool paths are correct for your build environment.

Hardware wise it is just 3v3 to VCC and CH_PD on the ESP8266 and VCC on the OLED, ground on both and SDA on the OLED to GPIO2 and SCK to GPIO0.

This is just a quick demo for now but I’ve got a few ideas where it could be useful, I might do a custom PCB using the ESP-03 plus a regulator and maybe a DS18B20 sensor and a button or two.


 

Update 31/12/14: I was asked to add some more info on how to get this onto the ESP8266 for someone new to it so here is the complete process from installing the toolchain/SDK through to compiling and flashing to the ESP8266. I’ve done this from memory but I don’t think I’ve missed anything.

Make sure you have all the prerequisites installed, on Ubuntu 14.04 this can be done with:

sudo apt-get install make unrar autoconf automake libtool gcc g++ gperf flex bison texinfo gawk ncurses-dev libexpat-dev python sed

Grab the esp-open-sdk from the Github, either with git:

git clone https://github.com/pfalcon/esp-open-sdk

or download and unpack the zip

cd to the esp-open-sdk directory and do:

make STANDALONE=n

This will download all the necessary toolchain and SDK files and compile them.

Install the other esptool – There are two different tools called esptool and with the current Makefile you need both. esptool.py is a python tool that is used to flash the .bin files to the ESP8266 and is installed with the esp-open-sdk process above.
With the current Makefile you will also need the binary esptool from here, this one creates the firmware .bin files (esptool.py can create .bin files too, it just needs some changes to the Makefile).

Now back in the esp_mqtt_oled directory find the following lines in the Makefile to make sure they point to the location of the files you just installed:

XTENSA_TOOLS_ROOT ?= ../esp-open-sdk/xtensa-lx106-elf/bin
SDK_BASE ?= ../esp-open-sdk/sdk/
ESPTOOL ?= esptool.py
FW_TOOL ?= ../esptool/esptool

Also make sure the ESPPORT is pointing to the location of your serial adapter, eg:
ESPPORT ?= /dev/ttyUSB2

Connect the ESP8266 to your 3.3v serial adapter, RX on the ESP8266 to TXD of the adapter and TX to RXD
You need 3.3v to the VCC and CH_PD pins on the ESP8266 and ground to GND.
you also need to connect GPIO0 to GND during power on to get it into programming mode.
You will probably find that your serial adapter cannot supply enough power for the ESP8266, in that case you will need to power it from an external 3.3v source, disconnect the 3.3v from the serial adapter but make sure the ground from the power source and the serial adapter are both connected.

Now from esp_mqtt_oled directory do:

make

This will compile and build the firmware, you should get no errors but the Warning messages are normal (actually just info). You should now have a firmware directory with two files: 0x00000.bin 0x40000.bin

Then to flash these firmware files to the ESP8266 do:

make flash

Now disconnect GPIO from ground and back to SCL on the OLED and restart the ESP8266 (power off/on). Hopefully you should see some startup messages on the OLED now: “ESP8266 MQTT OLED” then “WiFi connected” then “MQTT connected” and finally data from the MQTT topics you defined in mqtt.c should start to appear.

You can also do “make test” to connect to the serial output with screen or use another serial app at 115200 baud, eg. minicom with “minicom -b 115200 -D /dev/ttyUSB2

If you want to change anything and reflash it is just a case of doing:

make clean
make
make flash

Hopefully that will save anyone new to this some time.

21 thoughts on “WiFi MQTT Display with the ESP8266

  1. Thanks for documenting this, it will be very useful to me.
    I’m using Node-Red with Ciseco XRF radios (measuring temperature, contacts and 2 relays) and a TADO heating controller all publishing to MQTT. The aim is to build a customised heating/water controller to replace the TADO eventually (just for fun).
    One observation, would it be better to have the topics for MQTT hardcoded to oled2\line1 oled2\line2 etc which could allow greater flexibility because you can then publish the MQTT\temp data to the topic oled2\line1. If you change your mind you wont need to reflash the esp8266 🙂 ….
    Also, could I get 3 x GPIO (2x to drive relays and 1x pushbutton) and an oled working on one module?.

  2. Hi, this is great, thanks for writing it up.
    I’m having problems though… I can change any of the status strings like ‘STATION IDLE’ and see the effect when I recompile and re-flash the ESP8266. However, no matter what I change the MQTT_HOST variable to, it insists on trying to connect to 192.168.1.21 – even though I grep the firmware files and see that I’ve changes the value to my local IP ranges. Any ideas???? I’ve tried about 20 times, and nothing fixes it. But I can happily change status strings and see the effect with grep and when it’s running!

  3. solved… turns out I have to flash the 512K nodemcu image between each attempt… don’t know why, but it fixes it… maybe an erase problem?

  4. With all the experience you have had, how would you feel about an ESP8266 standalone reporting a temperature reading back back to a waiting arduino over wifi? Do you think it would be a fairly low power situation assuming its not constantly transmitting?

  5. I just spotted this – it is worth noting that Minh has now changed his coding slightly, there is no longer a setting in the config file for how many message the software subscribes to – also as of 2 days ago it works (there was an issue with simultaneous subscriptions coming in). For those looking in on Windows, don’t dispair this is no longer just for Linux people – compilation and flashing can now all be done in Eclipse in Windows – most of that is described somewhere on my blog at htttp://scargill.wordpress.com.

    Personally I’m happy this works on the ESP-01 as they are the cheapest boards so far and so making good use of the two IO pins is great. Another way of course to handle displays is to use a serial display such as the Sparfun MicroView – as that uses serial you don’t have the hassle with GPIO-0. Still – lots of possibilities with I2c !!

  6. Yes, I spotted that, some great work Minh has been doing on both the native and Lua MQTT stuff. I hadn’t hit the bug with messages arriving simultaneously as the data from my sensors comes in via one of my Tiny328 RFM12B nodes that is connected to my server over serial so only one can come in at a time. I then use Node-RED to forward them to various MQTT topics.

    Have also got a couple of the Microviews here which will probably end up connected to an ESP8266, I think they will make a nice combination.

  7. I also changed CFG_HOLDER in include/user_config.h from 0x00FF55A1 to 0x00FF56A1 but no wifi AP from ESP module. Not sure if STA is joining my wifi AP.
    I also tried it on ESP-01 but same result. Thank you.

  8. Please ignore previous two post but I just got ESP-12 to work but not sure why ESP-01 is not working…. Not sure but using a fresh ESP-12 was the key…..Erasing problem? Thank you!

  9. Thank you again for your great work!
    Took me a while to figure out that you also have to update include/driver/i2c.h to change the GPIO pins for I2C.
    Not sure but looks like driver/i2c.h is where you define parameters and include/driver/i2c.h is where pin assignment really takes place. Parameters must match up on both files. Are names predefined somewhere? (such as PERISH_IO_UX_MTMS_U) Thanks!

  10. Hi all, I’m really excited by this project. Sadly my experience of building under Ubuntu is limited and I can’t get the original to compile. It ends like this from “make STANDALONE -d”.
    Any help would be really appreciated.

    Considering target file `firmware/0x00000.bin’.
    File `firmware/0x00000.bin’ does not exist.
    Pruning file `build/app.out’.
    Finished prerequisites of target file `firmware/0x00000.bin’.
    Must remake target `firmware/0x00000.bin’.
    Putting child 0x09bce990 (firmware/0x00000.bin) PID 7502 on the chain.
    Live child 0x09bce990 (firmware/0x00000.bin) PID 7502
    Reaping winning child 0x09bce990 PID 7502
    ../esptool/esptool -eo build/app.out -bo firmware/0x00000.bin -bs .text -bs .data -bs .rodata -bc -ec
    Live child 0x09bce990 (firmware/0x00000.bin) PID 7503
    ../esptool/esptool: 1: ../esptool/esptool: Syntax error: “(” unexpected
    Reaping losing child 0x09bce990 PID 7503
    make: *** [firmware/0x00000.bin] Error 2
    Removing child 0x09bce990 PID 7503 from chain.
    peter@peter-MM061:~/esp_mqtt_oled$

  11. Hi Peter, where and how did you download the esptool?

    Michael, sorry I am only familiar with Ubuntu and OS X setup.
    Good luck.

    I found out that only one of the three OLED screen types are working on my implementation.
    SainSmart OLEDS (blue light) works well. White light version doesn’t work unless you use 3.3v. False advertisement – 5v doesn’t work. Even with 3.3v some doesn’t work (bought 5). SainSmart has no support. I also bought more on Ebay (red PCB version) but they all didn’t work.

  12. it’s the Eclipse IDE environment, I just haven’t learned how to take project files such as yours and incorporate them into an Eclipse project. There are a few ESP firmware projects where it is just a matter of importing the project files into Eclipse, but that doesn’t seem to be working for me.

  13. I would also love to know if it is possible to import this into the Eclipse IDE environment,
    http://www.esp8266.com/viewtopic.php?f=9&t=820

    I added it there, fixed the build command, and then get stuck when building with:

    15:00:01 **** Build of configuration Default for project esp_mqtt_oled ****
    mingw32-make.exe -f C:/Users/ilan/git/esp_mqtt_oled/Makefile all
    AR build/app_app.a
    LD build/app.out
    c:/Espressif/ESP8266_SDK/lib\libmain.a(app_main.o): In function `wdt_init’:
    (.irom0.text+0x3a8): undefined reference to `user_init’
    c:/Espressif/ESP8266_SDK/lib\libmain.a(app_main.o): In function `wdt_init’:
    (.irom0.text+0x527): undefined reference to `user_init’
    collect2.exe: error: ld returned 1 exit status
    C:/Users/ilan/git/esp_mqtt_oled/Makefile:116: recipe for target ‘build/app.out’ failed
    mingw32-make.exe: *** [build/app.out] Error 1

    15:00:02 Build Finished (took 1s.408ms)

  14. Hello, the “binary esptool” as refered to above, which entry in the esp_mqtt_oled Make file does this refer to?

    ESPTOOL ?= esptool.py
    FW_TOOL ?= ../esptool/esptool

    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.