Introduction: ESP32/ESP8266 WIFI Display Using MQTT Protocol
The idea came about because I wanted away to display sensor data from a robot remotely. Having a screen on a robot is very useful, but only if you are near that robot.
v1.0, to v2.0 are some of my first attempts at this goal. They do not use MQTT. They worked for what I wanted, but have some serious problems. Most of which I just don't want to fix after I added MQTT.
One week at the Automation Technology Club I did a MQTT demo, and all of a sudden it hit me. Use MQTT to display my robot data remotely. (Later, it hit me that I could use this for a lot of other things....yeah sometimes I'm a little slow.)
Hardware is really simple. Usage is pretty simple, and the results are good!
There are two base versions of code included in the github repository. One version creates it's own website and displays messages on either a TFT or OLED. The other version is the MQTT version, and was only written to use a OLED. (I recommend using the MQTT version, I will go over the original version briefly for historical reasons.)
Step 1: Hardware.
There are two versions of code included in the github repository,
To make v1.0 and v1.1 you need a NodeMcu board and a ILI9341 TFT screen. (Not recommend, this version creates a website, and doesn't use MQTT or have any type of screen formatting)
(I couldn't find a link to the TFT screen I used. Honestly I bought the screen about 4 or 5 years ago, couldn't get it to work, but it up, found it 6 months ago, hooked a 3.3v microcontroller to it, and it worked. I hooked it back up to a 5v Arduino and it didn't work....conclusion.... it's a 3v only display. (including the I/O pins))
It's a SPI TFT screen, 3.3v display it has a ILI9341 driver. This is similar to what I have but it's not the same screen.
To make v2.0 you simply need a ESP32 board with a OLED screen on board. (This version is a little better than v1.x, but I still would not recommend it. It still creates a website, doesn't use MQTT. It does have some limited screen formatting however)
To make the recommended (MQTT) version 1.3 MQTT you need any of the following.
1) A NodeMCU board and a I2C 0.96" OLED screen
or
2) A ESP32 board with a OLED screen on board.
or
3) A ESP8266 board with a OLED screen on board.
or
4) A Wemos D1 Mini with Mini OLED (I also use a battery shield and a dual base shield, but these aren't required)
Optionally any ESP32/ESP8266 and OLED screen should work, but you may need to make some changes in the software.
*** AS a note here, the ESP32 and ESP8266 boards that have a on board OLED don't require anything else. That is all the hardware you need. They do come with no PINs in the header, but you don't need to use the GPIO (Other than the I2C and it's already connected to the screen) for this project. ***
The D1 Mini needs to have it's pins solder to it, but once done, it would be the next easiest only requiring the D1 Mini and the mini OLED screen.
The NodeMCU board with a OLED screen would be the next simplest only needing 2 wires for data, and 2 wires for power.
And finally, the NodeMCU with the SPI color screen needing 8 wires total.
Also note none of these boards are truly breadboard friendly, the D1 mini is probably the closest. With just enough room to plug in wires on each side of it.
*** I used a breadboard with the NODEMCU but it was hanging over on one side of the board.
Step 2: Hooking It Up....
NodeMCU with SPI TFT Screen. This requires at least 8 wires.
SCREEN: NODEMCU PIN: VCC 3.3v GND GND CS D1 RESET 3.3v DC D4 MOSI D7 SCK D5 LED 3.3v
The only thing I can say is be careful, My TFT screen has the PIN names on the bottom of the screen meaning when you turn it over the pins are opposite. IE: VCC GND CS REST DC MOSI SCK LED would look like this when it's plugged in to the breadboard LED SCK MOSI DC REST CS GND VCC.
NodeMCU with I2C OLED Screen. This requires 4 wires total.
SCREEN: NODEMCU PIN: VCC 3.3v GND GND SDA D2 SCL D1
For the D1 MINI and the Mini OLED - simply solder the pin headers on and plug the screen into the D1 Mini.
if you also bought the dual base, and battery shield, solder the pin headers and plug them in. I am using a small quad copter battery - it doesn't have the right connector on it, but it does work (just watch your positives and negatives)
THE ESP32/ESP8266 with on board OLED will work the way they are. Personally I'm not planning on soldering the pin headers to these because I want to make a small case and turn them into name tags. (Another project for later).
Step 3: Libraries Needed (MQTT Version)
First you need to make sure you have the boards installed into your Arduino IDE.
ESP32 - follow the instructions for installing the boards to the IDE. https://github.com/espressif/arduino-esp32
ESP8266 (NodeMCU/D1 Mini) - follow the instructions for installing the boards to the IDE. https://github.com/esp8266/Arduino
You will need two other libraries:
PubSubClient.h https://github.com/knolleary/pubsubclient
SSD1306.h https://github.com/squix78/esp8266-oled-ssd1306
I am fairly sure I found PubSubClient in the library manager, so installing was simple.
The other, I downloaded the zip, unzipped it, renamed the new directory (removing the -master from the end), and moved the directory to my libraries folder. A restart of the IDE maybe required.
* Depending on your OS will depend on where the library directory is located. Typically, for Windows it's in the document folder, under the Arduino folder. Linux it's in typically in your home folder, under the Arduino folder.
If this is your first new library, the library directory may not exist and may need to be created.
Step 4: Using the MQTT Sketches....(A Little History Too)
MQTT is a publish/subscribe (MQ Telemetry Transport). extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. It is because of this that it has become a go to protocol for the IoT world of things.
Developed by IBM for the oil industry in 1999. (it's been around for a while).
MQTT uses brokers and topics. This is a very simplified understanding of what happens.
1) Device needs to "send" information - it connects to a MQTT broker and publishes a Message to a topic.
mean while in some part of the world a 2nd device
2) A 2nd device connects to the same MQTT broker, and subscribes to the same topic. When a message is posted to that topic this device reads it.
Even more simplified: Publish means Talk, Subscribe means listen.
A broker is pretty much a special type of server, and topic is sort of like a thread (no not really....forget that).
The Code can be found here: https://github.com/kd8bxp/Wifi_Display_Badge
So what does this mean for the sketches. Both the ESP8266 and the ESP32 sketches work for the most part the same, there really are just a few changes between the two and those changes are really more because of the devices themselves and not MQTT.
For us the broker I've chosen to use is 'test.mosquito.org' with no security, the topic the display subscribes too is 'display1' - If I turn all 4 of my devices on (as seen in the video), and I publish on test.mosquito.com to topic 'display1' all 4 devices will display the same message. And they will all display within milliseconds of each other.
Another thing is the device name, and that name needs to be unique on the broker - If two devices have the same name weird things happen. So, I've made attempts to create unique devices in the sketches using the MAC addresses of the devices. So far this seems to be working, but I have a limited selection of devices to try.
ESP32 (Unique ID Code snippet) <p>uint64_t chipid = ESP.getEfuseMac(); // MAC address of ESP32</p><p>uint16_t chip = (uint16_t)(chipid>>32); </p><p>char clientid[25]; </p><p>snprintf(clientid,25,"WIFI-Display-%04X",chip); </p><p>if (client.connect(clientid)) {</p>.......
ESP8266 (Unique ID Code snippet) <p>uint32_t chipid=ESP.getChipId(); </p><p>char clientid[25]; </p><p>snprintf(clientid,25,"WIFI-Display-%08X",chipid); //this adds the mac address to the client for a unique id </p><p>Serial.print("Client ID: "); </p><p>Serial.println(clientid); </p><p>if (client.connect(clientid)) {</p>......
Both of these snippets pretty much do the same thing. I am appending part of the MAC address to the name "WIFI-Display" in both sketches this is contained in the reconnect() function. It's in this function you'll find the topic name 'display1'
<p>Serial.println("connected"); // Once connected, publish an announcement... </p><p>//client.publish("Say", "-t 'hello world'"); // ... and resubscribe </p><p>client.subscribe("display1"); } else {</p>
I would highly recommend changing this to something else, otherwise you may end up getting messages you don't really want to be getting.
Near the top of the sketches, you'll find the typical "ssid" and password stuff, of course this needs to be changed for your network.
The ESP8266 version also has the follow commented out, you'll need to select one or make a change to the SDA, SCL pins. This code is at about line 18 or 19.
<p>//SSD1306 display(0x3c, 4, 5); //d1 mini<br>//SSD1306 display(0x3c, D1, D2); //ESP8266 w/OLED SSD1306 display(0x3c, D2, D1); //NodeMCU #define D1mini 0 //1 - using D1 mini</p>
Just uncomment the line for your device, and comment the other lines. You'll also see a define statement here.
The library doesn't official support the small display size of the D1 mini, and for that I added a little extra code that attempts to move the message to the best location on the small screen. Changing the zero in the define to a one (1) tells the code to use the small screen. (of course the default is for the 0.96" screens).
That is about it as far as the sketches go. Now we need to upload the code to our device, and send a test message.
Step 5: Connect to a MQTT Broker Send a Message....
At this point, it's time to publish something to your screen.
There are many different ways to do this. A lot of tools to do this, and a lot of websites.
I am using LinuxMint 18, and for me the easiest way is to install "mosquitto-clients" which is a command line utility.
sudo apt-get install mosquitto-clients
I now have a set of tools that I can use to publish and subscribe to MQTT topics.
What I want to do is publish to the topic 'display1' on broker test.mosquitto.org with the message 'test' this is done like:
$ mosquitto_pub -h test.mosquitto.org -t "display1" -m "test"
For people not using Linux, Mosquitto.org does have a functional but limited Websockets client.
http://test.mosquitto.org/ws.html There is a picture above of this, you'll see a "connect" button, a 'Topic' form, and a 'Payload' form. (Payload = message). You'll want to make sure you are connected to the broker, type 'display1' in the topic, and type your message into the payload. Click publish and you should see a message on your display. (OF course if you changed the topic name use your name)
HiveMQ has published a list of clients for other OSes including Mac and Android - most clients all use the same idea of broker, topic, message (or payload), and device (Clients are also devices and need a unique name).
http://www.hivemq.com/blog/seven-best-mqtt-client-...
The Library PubSubClient for Arduino also comes with examples to both publish and subscribe to topics. And you could use another Arduino connected to the network to publish a test message.
** Don't want to use a public broker.... have a raspberry pi? You could run a mosquitto broker on your pi. Plenty of tutorials on how to do that. ** A special note about running on the PI that I have found, for some reason the pubsubclient library doesn't like a .local in the host, I've found that I alway need to put the pi's IP address for it to work **
Step 6: The Video and Final Thoughts.
Known Limitations:
My screen formatting is pretty limited, and large messages can get cut off, this is really noticeable on the D1 Mini with the small OLED.
Messages are not guaranteed to be delivered. *There is a way to do this but it is way beyond the scope
Step 7: Bonus - Libraries and General Usage for V1.0, V1.1 and V2.0
TFT version (v1.0, v1.1) Need the Adafruit_GFX and Adafruit_ILI9341 library. I believe both can be found in the library manager.
OLED version.
SSD1306.h https://github.com/squix78/esp8266-oled-ssd1306
General Usage:
You will need to change the SSID and password for your network. Load the sketch to your device, you may need to reset your device after the IDE is done uploading the code (I've noticed I've had to do this for the ESP32 devices).
Both the ESP8266 and the ESP32 version of the sketch work in the same way. They will connect to your network get an ip address, create a website, and set a host-name (not necessarily in that order). It can take a few minutes for the host-name to show up on your network.
v1.1 and v2.0 both give some type of feedback via the web-browser. v1.0 does not (See pictures above).
It's a simple site, the idea is to just type or message after the hostname.local
IE:
http://hostname.local/this is my message
if your host name never shows up, the IP address works equally as well.
http://192.168.1.200/this is my message
Your IP address will be different. With the ESP8266 the current way to find your IP is look in the serial console.
The ESP32 displays it's IP address when it first starts.
My web browser requires the HTTP on the URL otherwise it doesn't work.
The ESP32 has some pretty limited screen formatting - actually it's build into the SSD1306 library.
The NODEMCU does not contain any type of screen formatting.
IF your message is too long, at least part of it will get lost.
My only other comment here is that if you wanted to use a ESP8266 with on board OLED you probably could, There would be some minor changes (namely how the device connects to the internet I think) to the ESP32 version of the sketch.