Small project in between: a weather display.





This is a small weather display I've put together out of pretty much standard components without much soldering of boards.
It includes a motion sensor, which switches on the LCD display for 5 minutes. It displays time, day of week, date and a few information about the current weather.
The enclosure I've printed with PLA. The stl file I've uploaded here: thingiverse weather display


To make it work I took a sonoff board and a 2004A LCD display with an I2C interface. I am using this model: 2004A I2C LCD

The sonoff board is a version TH_V1.1 (2017-5-5) It has the serial port plus one more I/O-port which is needed to connect display and the motion sensor.
First I've flashed the sonoff board with a tasmota version supporting display drivers ( here ).
How flashing of a sonoff with tasmota works is easy to find in the internet, just google for sonoff and tasmota, there are tons of how-to's out there.

If sonoff is flashed, we need to configure which of the pins we are using what for, meaning where to connect the display and where to connect the motion sensor to:


In principle it doesn't matter which connection is allocated to which GPIO, as long as it is GPIO 1,3 or 14, as these are the only ones which are accesible on a standard sonoff board with a 5 pin connector.
If configured like above the connections on the sonoff board are in the red marked area from top to bottom:


  1. 3.3 volts (square shaped contact)
  2. GPIO3: SDA (I2C interface)
  3. GPIO1: SCL  (I2C interface)
  4. GND 
  5. GPIO14: Switch2 (input for the motion sensor)

SDA and SCL on GPIO3 and GPIO1 and GND needs to be connected to the corresponding connections on the I2C interface of the 2004A display:

The part which is a bit more tricky is the VCC for the display, as it needs 5 volts, so the 3.3v from the sonoff connector are not enough. 
But there are 5v available on the sonoff board:

One warning: big parts of the sonoff board are connected directly to mains. So it needs to be disconnected/unplugged when doing anything with it while it is not in an isolated enclosure! Touching anything connected to mains is dangerous and can be fatal.

5v on the sonoff board (at least this version) can be found on the soldering point with the label "D5" next to it. If you connect a cable to it, make sure that it leaves underneath the board as shown with the blue line above, so there is more distance to high voltage connections on the sonoff board.

As motion sensor I'm using the very small AM312. Beside the small form factor it works with 3.3v which makes it compatible to the GPIO port logic level of the sonoff board. So its signal out (middle pin) can get directly connected with GPIO14 of the sonoff board.
(for connection layout just google for AM312, it seems to be quite popular)

There are a few configuration commands that needs to be done on the tasmota console:
displaycols 20
displayrows 4
displayaddress 39
switchmode2 1
switchtopic display01req
topic display01
rule on Time#Minute do DisplayText [t] endon
rule 1
pulsetime2 400
ledpower 0
savedata 0

And it is necessary to setup the address of an mqtt server correctly in the configuration dialog, so the tasmota firmware can talk to it.

The first three command are setting up the display. In my case 20x4 displays had the address 39, the smaller 16x2 the address 63. I'm not quite sure, why that is (as I thought that I'm addressing the I2C interface). But somehow that was the only setup that worked for that kind of displays.

The two switch commands configure what will be send to the MQTT server and how the second switch (which is the motion sensor in this case) will behave.

The rule part takes care of that the time will be updated in the display automatically every minute, so we don't need to do that via network.

The pulsetime2 command switches of the background light of the lcd display after 5 minutes.
A full explanation of all possible commands for tasmota is available here.


The whole setup is connected to an MQTT server and node red running on a raspberry pi. For setup of both just google mqtt server raspberry and node red raspberry. There are several manual in the internet how to install them.

Within node red I've setup a few flows for two of those displays:


For getting the weather data I'm using a free account from https://openweathermap.org . It works quite well and there is a node for that which just needs the API-ID and works out of the box then.

There are two events where I need to update the weather display with the forecast:
  1. Whenever there is an weather update the first "Weather Update" node will send this to the "Display Text" node, where the message for the display is build. This doesn't happened in a fix interval, but only if the weather data itself is changing.
  2. The second case is, when the weather display device gets switched on at all. In order to avoid waiting for a new weather status to get it send to the display, node red is listening to a state-update from that device. If there is one (weather display was connected to power), it triggers the weather node, which pushes in return the weather data to the DisplayText node.
The motion detector also generates a MQTT message (display01req) which gets checked if it is an "ON" event and if yes, will send a message to switch on the display light. 

I guess that would be also possible with a tasmota rule locally in the display device itself. I just didn't figure it out yet. So to handle that via node red was just more quick and dirty. 

The java script in the function node DisplayText works like this:
(This was my first quick java script, so it was a lot of try and error, that's how the source code looks as well. But it works...)


function pad(l, width, x) {
  x = x || '0';
  l = l + '';
  return l.length >= width ? l : new Array(width - l.length + 1).join(x) + l;
}
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var days = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
var day = days[today.getDay()];
var da = today.getDate();
var mo = today.getMonth()+1;
var ye = today.getFullYear();
var t = pad(h,2) + ":" + pad(m,2) + " " + day + " " +
        pad(da,2)+ "." + pad(mo,2) + "." + ye;

var w = msg.payload.weather + "/" + msg.payload.detail
w = w.padEnd(20, ' ');
w = w.substr(0,20);
var distext = t + w + "Tmp:";
distext = distext + pad(Math.round(msg.payload.tempc), 2, ' ') + 
          " Max:" + pad(Math.round(msg.payload.temp_maxc), 2, ' ') + 
          " Min:" + pad(Math.round(msg.payload.temp_minc), 2, ' ');
sunset = new Date( msg.payload.sunset * 1000);
distext = "[z]" + distext + "Sunset:"+pad(sunset.getHours(),2)+":"+pad(sunset.getMinutes(),2);
var NewMsg = { payload: distext};
return NewMsg;



If all works well, you should see something like this on the display:






Comments

  1. Finally a very quick and well explained way to connect a 4x20 display to Tasmota with the correct wiring. Keep going Tjareson, thank you!

    ReplyDelete
  2. Thank you very much for your post. It works like a charm, no hassle to get 5V somewhere, just plug the Sonoff in.
    Tip: If you use "switchtopic 0" and "switchmode2 14", the AM312 PIR gets handeled internally.

    ReplyDelete

Post a Comment