1605

Big clock display with temperatue based on ESP32 and MQTT.

Mr. Krugmann started this project a while ago. As you may have read in the magazine sadly he is no longe among us.
As we have done a "small" overhaul of the software we will use this page till to provide you with the latest firmware and information about the ongoing development, also due to the added functionalaty of the clock we decided to rename the Bedroomclock to MQTT Sensor Hub ( M.S.H ). But to still show how this project has begun, we keep the words or the initiator.

Krugmann:
"
Some years ago I bought 4 large 7-segment display  SA40-19SRWA and now I found the best controller ESP32 to get the time from NTP and the temperature via MQTT from my home automation server. So I build a system with 3 components:

1. Sensor modul based on ESP32 and DHT22 sensor.

2. HAS home automation server based on RaspberryPi and MQTT.

3. 4 digit display with large 7 segment modules and ESP32.

"

Firmware Versions:

Version 2.0

What is new:
  • ArduinoOTA support added
  • System works now as Sensor Hub for MQTT
  • Renambed to MQTT Sensor Hub ( M.S.H )
  • Added support for BME280
  • Added support for Veml6070
  • Added support for Tsl2561
  • Added support for DHT11 / DHT22
  • Send detected sensorvalues with MQTT to a broker
  • MQTT interval can be set in seconds
  • MQTT messages from other sensors are not displayed

Bugfixes:
none



Version1.1

What is new:
  • Just a bugfix release

Bugfixes:
  • Fixed daylight saving adding additional hours


Version 1.0:

Inital version for the Clock. Reads time from a NTP Server and process incomming MQTT messages.




For the latest Software have a look at GitHub

 

Hardware of the clock



We have build the clock with a few modifications to it. To build the clock in a convinient way we designed a PCB to hold the big seven segment displays in place. The dimensions of the pcb are quiet big with 372mm x 122mm and has several mounting holes so you can attach it to a self build frame or housing. Besides giving you a nice clock for your bedroom, it also is a nice clock to have in the office. The powerconsumtion during the labtest was around 320mA@12V. Be aware that the currentflow through the leds is only regulated by the resistors, so using more than 12V may damage the display.

As a bonus you can choose on which side you like to gave the barrel-jack for power connectivity.

The powersupply has been build arround a LM7805 and the ESP32 onboard linear regualtor, but dissipates a bunch of heat. You can run it without additional cooling but a DC/DC converter replacment will be a good choise in therms of efficency and also heat, you may can use the Würth replacement for the 7805 , this ones can also be used to replace the 7805 in other existing designs. There are also other vendors and projects that can be used to replace a 7805. Be aware that with this type of regulater you get some higher rf noise in the supplylines.

ESP32 supply advice: Even if you can swap the 7805 wit a DC/DC converter the datasheet of the ESP32 strongly advices to use a supply monitor. On the ESP32-PICO-KIT this is not included, so you may struggle in a situation where the chips starts to the bootloader after power up unwanted. The reason for this is that the risetime from 0 to 5 Volt is on the original 7805 shorter than those found on most DC/DC converter. To have a reliable boot you need to add a 10uF capacitor between the EN and GND pin. This will delay the startup for ~100ms and gets the DC/DC converter enough time to have its output stable and let the ESP32 read the correct values ot the bootstrap pins. Other MCUs have a better working Burn-Out detection that keeps trak of this problem. With e.g. a Atmel SAM3N this problem hasen't been seen and the Burn-Out detection of the ESP32 is a topic of its own.
For the seven segments to dirve we used the same chips as in the original design but changed to the smd eqivalent of them. The Display LD2 has in this design changed to be upside down to get a niche dubble point for the time. To have some better routing om the PCB the pins for the driver also have altered as you may can see from the schematic.

Also pins that have not been used to drive the display are accessable on the pin header K1, K2, K3, K4 and K5, so you can attach your own hardware to extend the clock in a way we have currently not thought of. With K2 you have the possibility to add one of thoese cheap raspberry pi rtc modules.

Software

As we have build a few clock in the near past, we now got a good framework for the ESP32 and ESP8266 chips. So we used the code from the pinnball clock as a base and removed the pinball from it to get a bare clock. Also this time the Software has currently stipped out the support for the i2c-realtimeclock, this can be added later, as this one rely on a NTP in the network to get the current time. What we have keept is the idea of having MQTT to show a outside temperature on the clock. From the authos version we extended it to set the MQTT settings from within the webinterface and display every ninth miniute ( 09, 19, 29, ... ) for one minute the temperature if we got a update within that timespan.

The original software used the SevenSeg library to control the segments of the clock. One disadvantage here is that the code needs to be called as quick as possible to get a good brightness. As this is dependent of the code run in the loop()-function we changed that to have a load independent way. So the more advanced part of the software is in the way we control the led brightness. The ESP32 used in this clock has a LEDC ( PWM) module that chan be clock up to 40MHz and get the PWM form from that base. This means we can devide a down to a signal with 13Bit resulution and get 5000Hz periode rate. The good thing is that we can use any gpio ( be aware that the pins 35,34,39 and 37 input only ). We use this feature to switch the PMW signal for the individiual segment and we use a 13Bit PWM with 5kHz. Every 2.5ms we set the output fo an other display so we get 100Hz screen refresrate and also can dim the segments.

The question that arose is how to change the brigness of the display. This can be done easy through the webinterface of the clock. Also we can later extend the MQTT datatransport to include light values of the room if we add a sutable sensor and dim the clock automatically. As said in the beginning the clock is, besides being a clock, more, in this case currently also a display for a outside thermometer. The insight of how the clock works can be taken from the sourcecode, also the code from the binball clock as this is the base of this one. As you can see we added a new MQTT Page to the menu.


 
Firmware 1.x settings
The rest for the settings in the webinterface, concerning time, are the same as the pinballclock has. New is the MQTT settings page. Here you can enter the settings to connect to a MQTT broker in your network an receive MQTT messages. The clock itself will listen to MQTT messages formated in json to get the current temperature. If a update is older than 9 minutes the last received value will no longer be used and the display of the temperautre skipped until it gets a new value. The new page requieres a few entrys to be set. This is the MQTT Hostname, the name of the clock, here e.g. Bedroom Clock. Also we need to supply the name or the IP of the MQTT broker and the port, default is 1883.


For firmware lower 2.0:
The importent parts are the topic we want to listen to. Here we use "/weather/outside" to get the messages produced by or outside temperature and humidity sensor. The last step is to enter the cedentials for the server. In this sample case it's the pi user and password you have choosen on your system. Be aware that after you have entered and submitted a password you need to retype it completly if you need to change something.

For firmware 2.0 and newer:
Fimrware 2.0 and newer
You need specify where you like to publish the information of the attached sensors to.Also we need to set the interval in seconds, we like the data to be send.The rest of the settings. You will also note that you won't get any values form an external sensor anymore. This is currently for the version 2.0 but will change in the future.

OTA Update for Fimrware 2.0 and newer

You also may note that now it is possible to uploade you code over wifi directly to the ESP32, also the new webcontent. We added the ArduinoOTA function to the clock with this firmware. During the process you will requier to enter a password. At this point the clock will show the password needed on the 4 displays as hex value you need to enter. If you connect the first time, the clock won't show the password by itself, only after a first faild attemp. To trigger the password you can press the BOOT button on the back of the clock, or simply gess a password. If that is wrong the clock will display the password. Be aware that all hex letters must be entered as capital ones.


If you boot the clock the display will display the state on the boot process and afterwards will show "STA" or "AP" if the clock is running as wifi station or accesspoint. Afterwards it will show the ip, so you can reach the clock.

But wasen't there a mini version of the clock?

Yes, but we are still not sattisfied with it, so this means back to the drawingboard and fix some generic issues you can come accross when using the ESP32. In this case we also run in the problem of slow rising VCC on the 5 Volt rail. Currently to solve such issues we use as a general rule of thumb a 10uF capacitor between GND and EN to delay the boot of the EPS32 untill VCC becomes stable. The better but a bit more expensive way would be to use a power supervisour chip.

Hardware of the outside sensor for temperatur and humidity

It would be easy to construct a new PCB just housing the sensor, but why take that effort if you can modify existing hardware? We used our airpolution sensor ( 170182) for this purpose and added a connector to attach a DHT11 or DHT22 sensor, one of those low priced ones you find at the usual sources. As the hardware has only an added connector there is not much to say about it. The magic is inside the software happening.
 

Software of the outside sensor for temperatur and humidity

The software of the airpolution sensor has altered in a way that we can now also send data to a MQTT broker and have your webinterface up and running all the time. We use for the MQTT part here a seperate thread on one of the ESP32 cores, like done in the clock. If the access to the mqtt broker blocks it means that the other parts of the software can keep up running.
The freertos manual can give more hints on how this can be done.







From the webinterfae you can enter the settings for the MQTT broker, but be aware that we are using a http site so all your data is transmitted in plain text.  We enter here for the MQTT Hostname "Outdoor Sensor X" and use the rest as seen for the clock. If you don't attatch DHT11 / DHT22 sensor to the airpolution sensor just the values of the airpolution sensor will be used. If you connect the sensor to thingspeak the data of the humidity and temperatursensor will NOT be transmitted. If you already have a version 1.0 baord of 170182 you can attatch the sensor to the pins shown in the schematic and updatet to the new firmware with all the advantages and disadvantages new software brings. As the MQTT part is a modular approch we will it soner or later also incooperate to the waterstation to use your data with your own MQTT broker. The data collected is transmitted as json formatted string every 30 seconds. In the current fimrwarestage this can't be changed from the webinterface and is for this project hardcoded. But as you can see from the 3-displays alarm clock we takte featurerequest and try to get them incooperated as good as possible so this restrictions may change in the future.

 

Bring it all together, there will be PI for that....

Well the last peace is the MQTT broker running on the raspberry and also NODE-RED for the dataprocessing and the nice show dashbaord form the original material. At the end one device is producinf MQTT-messages and the other one is consuming it, but we need a broker in the middle that lsitens for new messages and sends them to those who are interrested. For this we start with a fresh Rasbian image on our PI and install the requiered components. You need a internetconnection ( at best a working one ) to install the software.
On linux you use as broker for MQTT mosquitto. After you have written the software to the SD-Card and initially configured you PI we need a terminal and type in some commands. First we need to upgrade the system to the current version of the installed packages. In a Terminal we type:
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get dist-upgrade
This will gie us the latest packages for our pi. We than need to install mosquitto and need to type in the terminal the following:
    sudo apt-get install mosquitto mosquitto-clients

After this has done we finally configure mosquitto to autostart every boot by typing:
sudo systemctl enable mosquitto

This is the first part done. The next is to install the current version of NODE-RED. For this follow the instructions given here. The last thing to do is now the installation of the node-red-dashboard. Open a webbrowser and go to http://[IP_OF_PI]:1880 and the NODE-RED page will show up.













Click on the menubutton and select Manage palette. This will give you a chouse of installed and to be installed add-ins.













you now choose in Install node-red-dashboard and install it. After completion you now can import the dataflow. To do so yue from the menue the Import and choose here Clipboard. You now can past the following into the window:
[
    {
        "id": "ed4fda19.d9467",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "e1e85bab.836de",
        "type": "mqtt in",
        "z": "ed4fda19.d9467",
        "name": "Outside values",
        "topic": "/weather/outside",
        "qos": "2",
        "broker": "537a7633.f1b2c",
        "x": 100,
        "y": 140,
        "wires": [
            [
                "4ca84fe4.012158"
            ]
        ]
    },
    {
        "id": "936bb796.3c36d8",
        "type": "mqtt out",
        "z": "ed4fda19.d9467",
        "name": "",
        "topic": "weather/lastupdate",
        "qos": "",
        "retain": "",
        "broker": "537a7633.f1b2c",
        "x": 1170,
        "y": 320,
        "wires": []
    },
    {
        "id": "8625714f.d39bc8",
        "type": "function",
        "z": "ed4fda19.d9467",
        "name": "",
        "func": "if ( !msg.timestamp ) msg.timestamp = Math.round(+new Date());\n\nvar dt   = new Date(msg.timestamp);\nvar day  = dt.getDate();\nvar mon  = dt.getMonth() + 1;\nvar year = dt.getFullYear();\nvar hh   = dt.getHours();\nvar mm   = dt.getMinutes();\n\nif (day < 10)\n  day =\"0\" + day;\n  \nif (mon < 10)\n  mon = \"0\" + mon;\n  \nif (hh <10)\n  hh = \"0\" + hh;\n\nif ( mm < 10)\n  mm = \"0\" + mm;\n\nmsg.payload = day;\nmsg.payload += \".\" + mon;\nmsg.payload += \".\" + year;\nmsg.payload += \" - \" + hh + \":\" + mm;\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 890,
        "y": 260,
        "wires": [
            [
                "936bb796.3c36d8",
                "7c0ec50a.2e1684"
            ]
        ]
    },
    {
        "id": "207da54e.c207ca",
        "type": "ui_text",
        "z": "ed4fda19.d9467",
        "group": "6a4589cf.e9f658",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "Temperatur",
        "label": "Temperature",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1150,
        "y": 180,
        "wires": []
    },
    {
        "id": "75659832.cb79b",
        "type": "ui_text",
        "z": "ed4fda19.d9467",
        "group": "6a4589cf.e9f658",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Humidity",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1140,
        "y": 220,
        "wires": []
    },
    {
        "id": "7c0ec50a.2e1684",
        "type": "ui_text",
        "z": "ed4fda19.d9467",
        "group": "6a4589cf.e9f658",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Version",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1140,
        "y": 280,
        "wires": []
    },
    {
        "id": "e32023cc.0dd9d",
        "type": "ui_chart",
        "z": "ed4fda19.d9467",
        "name": "",
        "group": "3fbd176c.c51e78",
        "order": 0,
        "width": 0,
        "height": 0,
        "label": "Temperature",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": "12",
        "removeOlderPoints": "2000",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "useOldStyle": false,
        "x": 1150,
        "y": 120,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "ecac1264.6b329",
        "type": "function",
        "z": "ed4fda19.d9467",
        "name": "",
        "func": "  \n  msg.payload += \" °C\";\n  \nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 890,
        "y": 180,
        "wires": [
            [
                "207da54e.c207ca"
            ]
        ]
    },
    {
        "id": "1e0e769a.ff7939",
        "type": "function",
        "z": "ed4fda19.d9467",
        "name": "",
        "func": "\n    msg.payload += \" %\";\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 890,
        "y": 220,
        "wires": [
            [
                "75659832.cb79b"
            ]
        ]
    },
    {
        "id": "4ca84fe4.012158",
        "type": "json",
        "z": "ed4fda19.d9467",
        "name": "Parsed JSON",
        "property": "payload",
        "action": "obj",
        "pretty": false,
        "x": 300,
        "y": 140,
        "wires": [
            [
                "7983c5cd.f2704c"
            ]
        ]
    },
    {
        "id": "7983c5cd.f2704c",
        "type": "function",
        "z": "ed4fda19.d9467",
        "name": "Spit object values",
        "func": "var msg1={};\nvar msg2={};\n\nmsg1.payload = msg.payload.temperature;\nmsg2.payload = msg.payload.humidity;\n\nreturn [msg1 , msg2];\n",
        "outputs": 2,
        "noerr": 0,
        "x": 590,
        "y": 140,
        "wires": [
            [
                "ecac1264.6b329",
                "e32023cc.0dd9d"
            ],
            [
                "1e0e769a.ff7939",
                "8625714f.d39bc8"
            ]
        ],
        "inputLabels": [
            "JSON Object"
        ],
        "outputLabels": [
            "temperature",
            "temperature"
        ]
    },
    {
        "id": "537a7633.f1b2c",
        "type": "mqtt-broker",
        "z": "",
        "name": "",
        "broker": "localhost",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    },
    {
        "id": "6a4589cf.e9f658",
        "type": "ui_group",
        "z": "",
        "name": "Daten",
        "tab": "ebb3177a.a9a6f",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "3fbd176c.c51e78",
        "type": "ui_group",
        "z": "",
        "name": "Chart",
        "tab": "ebb3177a.a9a6f",
        "order": 2,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "ebb3177a.a9a6f",
        "type": "ui_tab",
        "z": "",
        "name": "MQTT-Sensor-Daten",
        "icon": "dashboard",
        "order": 0
    }
]













After you confirm the action with Import you are good to go and the pi is ready for service. You can now access the UI with http://[YOUR_PI_IP]:1880/ui/ and the browser shall show this: