MQTT LED Matrix Display
My MQTT network at home moves up and down a lot of messages: sensor values, triggers, notifications, device statuses,… I use Node-RED to forward the important ones to PushOver and some others to a Blynk application. But I also happen to have an LED display at home and that means FUN.
LED displays are cool. Your team's score, your number in the IRS queue, the estimated arrival time for your next commute,… Now that TVs are replacing LED displays (like the later did with the electromechanical ones) they have acquire an almost vintage-status.
This LED display I own even has a name: The Rentalito. The Rentalito is an old friend, one of those projects you revisit because LED displays are cool… Originally it was an Arduino Uno with an Ethernet Shield in a fancy cardboard case. Then it went WiFi using a WiFly module. And then a SparkCore replaced the Arduino. Now… well, ESP8266 is driving my life.
Let me introduce you the latest iteration of the Rentalito, the MQTT LED matrix display.
The board
Nothing special about the board. A power jack, a regulator, the ESP12 module and the shrouded header for the display flat cable. I brought out VCC, GND, RX and TX to be able to program the ESP8266 the first time, from there on OTA is my preferred way: its a lot faster, specially when uploading the file system. A couple of buttons allow me to reset the controller and pull down GPIO0 to enter flash mode. They are mostly intended for development.
Like in the previous version I've added an IR receiver and a DHT22 temperature and humidity sensor. The DHT22 is completely optional, the IR receiver is meant to be able to set the device in sleep mode, so it would only display prioritary messages.
Soldering SMD parts
Most of the parts are SMD. I wanted to gain some practice soldering them and I wanted to keep the board under 50x50mm (cheaper to fab) while soldering parts only on one side of it.
To solder the SMD0805 resistors and capacitors I first added a small blob of solder to one of the pads, then placed the part in place and applied a fin iron tip for a very short time (a lot less than a second) while pressing with the tweezers to place it flat, then heat the other end and apply a small drop of tin. It's very doable for 0805 parts. And quite fast. I'm really happy with the result although it's obvious that it's been hand soldered. Only the electrolythic capacitors gave me some problems. For the bigger one (the one close to the regulator) the pad was completely hidden under the part. Next time I will give my heat gun a try.
The board was on the same batch as the RFM69 Gateway I wrote about a few weeks ago, and it has some of the same problems. Some texts are too small and unreadable, not a big deal but I needed the schematic to know the names and values of each part. Also the shrouded connector is too close to one of the holes so the screw head does not fit in… Luckily, none of these problems are critical.
The display
The display is actually a pair of 3216 Bicolor Red & Green LED 5mm Dot Matrix Display by Sure Electronics with 4 Holtek HT1362C datasheet drivers each. In total 64x16 or 1Kpixel. These come in a sturdy 241x147mm black PCB with connectors on both ends so you can daisy chain more boards, although the manufacturer recommends to connect “up to two boards” only.
There are shrouded connectors for data and power and screw terminals for power. According to the datasheet each board can use up to 1.37A when everything ON at 100% duty cicle. So if I want all the LEDs in orange (red+green) I should go for a 5V 3A power supply. In real life it very seldom overpasses the amp with the two boards connected.
The library to manage the driver is based on my own sparkcore-ht1632, which I ported from wildstray's ht1632c library for Arduino. This library is equivalent to wildstray's except that it only supports 32x16 geometries (the only one I had for testing) and does not have blinking effect. On the other side the library allows for two scroll buffers, so you can have texts scrolling in the same or different directions at the same time.
Code folder structure
I'm using the Arduino Core for ESP8266 and PlatformIO as build manager. In case you have never used PlatformIO I strongly recommend it.
This is what the project code folder looks like at the moment:
.
├── data
│ ├── images
│ | └── ...
│ └── index.html.gz
├── gulpfile.js
├── html
│ ├── checkboxes.css
│ ├── checkboxes.js
│ ├── custom.css
│ ├── custom.js
│ ├── grids-responsive-min.css
│ ├── images
│ | └── ...
│ ├── index.html
│ ├── jquery-1.12.3.min.js
│ ├── pure-min.css
│ └── side-menu.css
├── lib
│ ├── ht1632c
│ | └── ...
│ ├── JustWifi
│ | └── ...
│ └── readme.txt
├── package.json
├── pio_hooks.py
├── platformio.ini
└── src
├── debug.h
├── defaults.h
├── dht.ino
├── display.ino
├── main.ino
├── mqtt.ino
├── ota.ino
├── settings.ino
├── version.h
├── webserver.ino
├── websockets.ino
└── wifi.ino
The platformio.ini file defines the framework, board, and other build settings. You can define as many “environments” as you want. For instance: I use NodeMCU board to test because it's easy to carry with me so I have an environment for it, another one to flash rentalito via an FTDI programmer and yet another one to flash it over-the-air.
The “src” folder contains the firmware files (C++ code). Lately I'm splitting my code in different files (wifi, webserver, mqtt, ota,…), each for one functionality with extension “.ino”. This way I benefit from the preprocessing of ino files that prepend the declarations of all the defined functions, so I can mostly forget about dependencies between them. Splitting the files gives me a way to handle the code easily, which is a major benefit because the project has more than 1000 lines of code excluding libraries.
The “html” folder is the web interface development folder. I preprocess its contents before uploading them to the target board with Gulp. That's what the package.json (Gulp dependencies), gulpfile.json (processing definition) and pio_hooks.py (PlatformIO hook to automatically preprocess the files before uploading the file system) are there for. The preprocessing populates the “data” folder. The contents of the “data” folder are then flashed to the board. Preprocessing and compressing them makes the webserver in the ESP8266 more reliable and improves performance a lot. Check my post about optimizing files for SPIFFS with Gulp to learn more about it.
PlatformIO library manager handles most the library dependencies:
- Adafruit's DHT Sensor library
- Benoit Blanchon's impressive ArduinoJson library
- The already classic MQTT PubSubClient library by Nick O'Leary
- Markus Sattler WebSockets library
- The awesome Embedis library by David Turnbull, Tom Moxon and The PatternAgents
Only the ht1632c library and my custom WiFi manager (JustWifi) come bundled with the project under the “lib” folder.
The web interface
One of the requirements of the project was that the mapping between MQTT topics and the message displayed on the LED matrix must be configurable and not hardcoded. With the possibility to embed a webserver in the ESP8266 this has become much easier.
A little of jQuery and WebSockets and here you have an interface to add, edit and delete mappings. For each mapping you can define:
- The MQTT topic the Rentalito will be listening to
- The name of the value, it will be displayed in the first row of the matrix
- The value, I can use placeholder to format it
- A filter, so it will only match when the value matches the filter
- A priority switch that defines weather the message will be displayed right away or queued
- An expiration time in seconds
The normal use case is when you define a name (like “Temperature”) and a value using a the “{value}” placeholder (like “{value}ºC”). With the filter field empty and priority set to “no” the message will be queued and displayed until the expiration time passes. A new MQTT message on the same topic resets the expiration counter.
The pic below shows the use case of an alert: the empty value means the name will be displayed in big capital letters at full screen, the filter makes the rule match only when the MQTT topic value is “1” and the priority set to “yes” means it will displayed as soon as it is received. So a big “WASHER!!” message will be displayed as soon as the laundry is done. It will also be queued and displayed for the next half an hour.
Case (so to speak)
The previous version of the Rentalito was already a sandwich of methacrylate , very much like my Wordclock project. This time I decided to go for a smaller version and hide the board behind the display and to use polystyrene instead of methacrylate. Conclusions: bad idea.
The** polystyrene melts with the laser** and tends to rejoin after. The cut is **not sharp** and shows **small cracks**, the **surface is not crystal clear** because it has suffered from the heat of the laser. This effect is more visible where the plastic was in contact with the metallic bed of the laser cut machine.
Will go back to methacrylate, even thou it's more expensive.
Conclusions
The ESP8266-based Rentalito is the most powerful of all the iterations, also the most stable. i'm still working on the firmware and it will surely benefit from improvements I'll do in other projects. The “enclosure” is certainly a point to improve.
I'm very happy with my new display that notifies me when my laundry is done :)
This project code (firmware and web interface), PCB schematics and designs and enclosure models are available as free open source software & hardware on the Rentalito ESP8266 Bitbucket repository.
"MQTT LED Matrix Display" was first posted on 12 September 2016 by Xose Pérez on tinkerman.cat under Projects and tagged blynk, dht22, eeprom, embedis, esp12, esp8266, ethernet shield, holtek, ht1632c, ir receiver, jquery, methcrylate, node-red, platformio, polystyrene, pushover, rentalito, smd, sparkcore, spiffs, sure electronics, websockets, wifly.