Linking WT32-SC01 Display Module with Home Assistant using Tasmota

There’s not a massive amount of information on how to use the new HASP powered Tasmota GUI builder and the universal display driver offered, so I thought I’d share my config so that it may help others.

Product page (currently): https://en.wireless-tag.com/product-item-25.html

This is a simple 4 button little wall controller for things in my kitchen, and I’ll revisit this with more complexity in future (adding things like screen dimming etc).

First you’ll need to install the firmware to your device. In a compatible browser that offers serial links (Chrome) go to:
https://tasmota.github.io/install/

And install Tasmota32 LVGL by plugging in your device with USB and choosing the correct port. This will take about 2 mins and you will also set up your wifi and name of the device.

Once it is installed, go to the IP address on your network where it lands and go to Configuration->Other->Template and put the following into the text box:

{"NAME":"WT32-SC01","GPIO":[6210,1,1,1,1,1,0,0,1,704,736,768,1,1,640,608,1,800,1024,992,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}

Make sure to check the “Activate” box and hit save. This will set up the correct pins for the display, backlight, touchscreen etc.

With the new universal display driver, we no longer use the console to set it up, instead we have to upload a display.ini file which carries all of the config. Go to Tools->Manage File System and browse for your display.ini file, and press upload. You should see it listed on the panel after uploading. Here are the contents you need:

display.ini:

:H,ST7796,480,320,16,SPI,1,*,*,*,*,*,*,*,40
:S,2,1,1,0,40,20
:I
EF,3,03,80,02
CF,3,00,C1,30
ED,4,64,03,12,81
E8,3,85,00,78
CB,5,39,2C,00,34,02
F7,1,20
EA,2,00,00
C0,1,23
C1,1,10
C5,2,3e,28
C7,1,86
36,1,48
37,1,00
3A,1,55
B1,2,00,18
B6,3,08,82,27
F2,1,00
26,1,01
E0,0F,0F,31,2B,0C,0E,08,4E,F1,37,07,10,03,0E,09,00
E1,0F,00,0E,14,03,11,07,31,C1,48,08,0F,0C,31,36,0F
11,80
29,80
:o,28
:O,29
:A,2A,2B,2C
:R,36
:0,28,00,00,01
:1,88,00,00,02
:2,E8,00,00,03
:3,48,00,00,00
:i,20,21
:UTI,FT6336U,I1,38,*,*
RD A0
CP 02
RTF
RT
:UTT
RDM 00 16
MV 2 1
RT
:UTX
MV 3 2
RT
:UTY
MV 5 2
RT

Reboot your device and you should see thhttps://tasmota.github.io/install/e splash screen for Tasmota pop up and draw on screen as it boots.

Now that we have the display working properly, we are going to add a super simple gui with a title at the top, the time, wifi strength, and 4 buttons on screen to do things in Home Assistant.

We will do this with 2 files:
1. autoexec.be (runs on boot to set up various things and load the pages)
2. pages.jsonl (contains the details of what to draw on screen)

In my autoexec.be I first import the hasp and mqtt libraries, and then I define some actions that happen when pressing buttons (publishing to certain MQTT topics), then finally start running the GUI.

autoexec.be:

import haspmota
import mqtt

tasmota.add_rule("hasp#p1b1#event=down", / -> mqtt.publish("kitchenpanel/button/espresso", "pressed"))
tasmota.add_rule("hasp#p1b2#event=down", / -> mqtt.publish("kitchenpanel/button/toaster", "pressed"))
tasmota.add_rule("hasp#p1b3#event=down", / -> mqtt.publish("kitchenpanel/button/aircon", "pressed"))
tasmota.add_rule("hasp#p1b4#event=down", / -> mqtt.publish("kitchenpanel/button/neonc", "pressed"))

haspmota.start()

In my pages.jsonl I have 2 pages. Page 0 is a special page which is always shown in hasp, it’s like an overlay over everything else, and in mine I have a top bar with a title, a clock, and wifi signal strength. Page 1 is where I put my buttons which show in the middle. Both pages are shown simultaneously to make a single GUI.

pages.jsonl:

{"page":0,"comment":"---------- Upper stat line ----------"}

{"id":11,"obj":"label","x":0,"y":0,"w":480,"pad_right":90,"h":22,"bg_color":"#BD5B06","bg_opa":255,"radius":0,"border_side":0,"text":"Kitchen Control","text_font":"montserrat-20"}

{"id":15,"obj":"lv_wifi_arcs","x":450,"y":0,"w":29,"h":22,"radius":0,"border_side":0,"bg_color":"#000000","line_color":"#FFFFFF"}
{"id":16,"obj":"lv_clock","x":395,"y":3,"w":55,"h":16,"radius":0,"border_side":0}


{"page":1,"comment":"---------- Page 1 ----------"}
{"id":0,"bg_color":"#000000","bg_grad_color":"#000000","bg_grad_dir":1,"text_color":"#FFFFFF"}

{"id":1,"obj":"btn","x":35,"y":50,"w":200,"h":120,"text":"Espresso", "bg_color":"#BD5B06", "text_font":"robotocondensed-24"}
{"id":2,"obj":"btn","x":245,"y":50,"w":200,"h":120,"text":"Toaster", "bg_color":"#BD5B06", "text_font":"robotocondensed-24"}
{"id":3,"obj":"btn","x":35,"y":180,"w":200,"h":120,"text":"Air Conditioner", "bg_color":"#BD5B06", "text_font":"robotocondensed-24"}
{"id":4,"obj":"btn","x":245,"y":180,"w":200,"h":120,"text":"Neon C", "bg_color":"#BD5B06", "text_font":"robotocondensed-24"}

Make sure to upload these to Tasmota using the same method above, then reboot the device. You should now see the simple GUI being drawn on screen, as well as the buttons changing colour briefly when you press them.

But currently these buttons don’t connect to anything, as we’re not yet linked with our home assistant installation.

On your Tasmota interface webpage (the IP address of the device) go to Configuration->MQTT and fill in the important info:
Host: The IP or domain name of your Home Assistant host
Port: usually leave this as is (default 1883)
Client: usually leave as is (unique name)
User: username you connect your device to HA with
Password: password for this username
Topic: I like to name this the name of the device (“kitchenpanel” in this case)
Full Topic: Leave as is

Hit save

Head back to the main menu, and go to Tools->Console and type:
weblog 4
Which will show you full logging.

When you press a button on the device, you should now see messages like:

08:23:18.555 MQT: stat/kitchenpanel/RESULT = {"WebLog":4}
08:23:18.768 CFG: Saved, Count 104, Bytes 4096
08:23:20.447 TS : touched  x=169 y=107 gest=0x00 (raw x=213 y=169)
08:23:20.474 LVG: Refreshed 19095 pixels in 10 ms (1909 pix/ms)
08:23:20.485 MQT: kitchenpanel/button/espresso = pressed
08:23:20.489 HSP: publish {"hasp":{"p1b1":{"event":"down"}}}
08:23:20.517 LVG: Refreshed 19095 pixels in 10 ms (1909 pix/ms)
08:23:20.555 LVG: Refreshed 19095 pixels in 10 ms (1909 pix/ms)
08:23:20.564 TS : released x=169 y=107 (raw x=213 y=169)
08:23:20.570 BRY: GC from 24994 to 14905 bytes, objects freed 155/237 (in 2 ms) - slots from 649/655 to 228/594
08:23:20.592 LVG: Refreshed 19095 pixels in 10 ms (1909 pix/ms)
08:23:20.601 HSP: publish {"hasp":{"p1b1":{"event":"release"}}}
08:23:20.606 HSP: publish {"hasp":{"p1b1":{"event":"up"}}}

Notice the:
MQT: kitchenpanel/button/espresso = pressed
This means we’re sending a message of “pressed” to the topic “kitchenpanel/button/espresso” (I pressed the espresso button).

Now it’s time to plumb these messages over MQTT into an automation on Home Assistant so that they do things.

In HA, go to Settings->Automations&Scenes->Automations Tab and press “Create Automation” and “Create new automation”

Under the “When” header, press “add trigger” and type “MQTT” and press the plus symbol. We want the topic to be kitchenpanel/button/+ Which will catch all messages going to the button topic so that everything is nicely grouped together. Put pressed in the payload box.

Under the “Then Do” header, press “add action” and type “Choose” and press the plus symbol.
Press “add option” and type “Template”. Under the “Conditions” subheading press “add condition” and type “template” and we’re going to add the first button condition.
Put in the “value template”:
{{ trigger.topic == 'kitchenpanel/button/espresso' }}
To capture presses from only the espresso button.
Now we want an action in the action subheader, for mine, I’m adding an action based on device, so I’ve chosen the device as “espresso” (which matches my device name) and chosen “Toggle Espresso”.
Do this for the other three value templates:
{{ trigger.topic == 'kitchenpanel/button/toaster' }}
{{ trigger.topic == 'kitchenpanel/button/aircon' }}
{{ trigger.topic == 'kitchenpanel/button/neonc' }}

Now you should have full pass through of all of your buttons to devices!

I’ll do more on this in the near future with automatic dimming of the screen, more flexible layouts, and symbols instead of text for the buttons.

There’s also a pretty nice case here:
https://www.printables.com/model/380229-wt32-sc01-case

Also while we’re here, make sure to set your timezone so that the clock shows your local time, for me here in Melbourne Australia I set it through the console in Tasmota with this:
Backlog0 Timezone 99; TimeStd 1,1,4,1,3,600; TimeDst 1,1,10,1,2,660

(your local timezone will require looking up here: https://tasmota.github.io/docs/Timezone-Table/ )

Tasmota on ESP8266 can speak

I’m a huge fan of synthetic voices. I love devices around me chattering away letting me know things so I don’t have to look at another screen and interpret what’s being displayed.

But the thing is, these voices don’t have to be great. In fact I prefer if they’re a little clunky and jagged as they realise the dream of the future I had as a kid growing up in the 80s. I thought that when the year 2000 rolled around, we’d have talking robots wandering our houses, our kitchen appliances would announce when they’re being turned on and off, and our houses would announce “night mode” as dusk rolled around. Unfortunately the world has turned out to be far more conservative in weirdness than I had hoped, so I realised I had to make this happen for myself.

I already have home automation happening in my home, built with Home Assistant at its core, and with a focus on locally-processed everything rather than relying on cloud based services like Google and Amazon offer. This has allowed me the freedom to get as weird as I want, and to make the look and feel exactly what I want.

Part of this process has been to reflash every smart bulb and smart switch I use with the amazing open source Tasmota. It allows for truly locally processed and linked devices, that don’t need an external service, just your local Home Assistant controller. In my case I have Home Assistant running on a tiny Raspberry Pi 4 upstairs on the wall.

Tasmota is breathtaking in complexity and ability. It can adapt to almost every smart device and is constantly being expanded, and yet still fits on the super tiny and super cheap ESP8266 and ESP32 chips that are found in almost every smart iot device on the market (and of course you can buy them standalone for your own builds).

Recently I was forced to compile Tasmota from sources to enable some built in functions that aren’t enabled in the default binary builds (for a kitchen control interface requiring a multiplexor chip). While I was doing this I stumbled across some very promising libraries that were in the source code for audio and “SAM” text to speech. My heart skipped a beat.

For those not in the know, “SAM” (or Software Automated Mouth) was a program for the ancient Commodore 64 computer, that allowed for some of the earliest domestic speech synthesis. It’s very recognisable as it was in so many things from movies, to music, to TV, as well as being every 80s kid’s dream. A computer that can talk!

Turns out, this software was ported to a C library by Sebastian Macke and put up on GitHub some time ago, and then adapted to run on microcontrollers by Earle F. Philhower, III. (especially the ESP8266). This meant you could already make this happen if you wrote your own code from scratch and use the library on ESP8266, but somewhere along the way it was added to Tasmota. I couldn’t find documentation for it, but there it was, hiding away, along with commands to make your Tasmota speak.

I quickly realised, though, that in order to perform this trick, I’d need to also buy an I2S IC/board and amplifier as the audio output library relied on I2S which is a simple audio interfacing specification. Being that I wanted to use this voice inside my doorbell button, I didn’t want to spend the money, or make the doorbell button that large to fit all of this.

That’s where I did some digging and found that the ESP8266audio library had a mode where it could roughly bit-bang audio out of the RX pin of the ESP board. From this output, you could make a very simple amplifier with 2 basic transistors to drive a speaker at an audible volume.

Unfortunately, Tasmota source code didn’t have this ability yet, so I set about forking the source code, modifying it, and merging it back (pull request) to Tasmota’s team to add this ability.

The nimble team have already merged this into the Tasmota Development branch so it’s ready to use, but you’ll need to compile it yourself. I won’t go into setting up an IDE for Tasmota compilation from source as that’s been covered quite well by other people including in the readme for Tasmota itself (I recommend the Atom + PlatformIO method):

https://github.com/arendst/Tasmota

Make sure you clone the Development branch (as at 10th Feb 2021) – it’ll move into the main releases at some point.

In order to enable audio output for Tasmota without I2S hardare, you’ll need to add to your “tasmota/user_config_override.h” file the following:

#ifndef USE_I2S_AUDIO
#define USE_I2S_AUDIO
#endif

#ifdef USE_I2S_EXTERNAL_DAC
#undef USE_I2S_EXTERNAL_DAC
#endif

#ifndef USE_I2S_NO_DAC
#define USE_I2S_NO_DAC
#endif

This allows you to enable audio, override the default (to use an external I2S DAC board), and enable the use of direct output.

But before we do anything more, we definitely need to hook up at least one transistor to the output from the ESP chip as you definitely cannot drive a speaker directly (it’ll also probably burn out the chip, or the pin on the chip trying to do so). For the following I assume that you’re running your ESP board from 5V to its 5v/USB input so that it regulates its required 3.3v onboard. We’ll use some of this 5V to feed the transistor and in turn the speaker.

You’ll need:
1 x 2N3904 transistor (NPN type, driven by positive voltage, but switching the negative)
1 x 1k resistor
1 x 3w or so speaker (nothing under 4 ohms)

When driving the audio output with this method, it will always come out of the RX pin of the ESP board. So when I say audio output, I mean the RX pin.

  1. Connect the resistor between the RX pin and the base of the transistor (middle leg).
  2. Connect the collector of your transistor (right pin of transistor with flat face side facing you) to the negative side of your speaker
  3. Connect the positive side of your speaker to 5 volts
  4. Connect the emmitter of your transistor (left pin of transistor with flat face side facing you) to the Ground or negative from the 5V supply, or the ground of your ESP board.

This is a very basic single transistor amplifier. This is what’s outlined on the ESP8266audio library page here:

https://github.com/earlephilhower/ESP8266Audio

Yes the output can be a little rough, and yes if you went to use some of the other capabilities like playback of files, playing of web radio stations (Which is actually pretty cool), they would sound pretty rough which a whistle over the top, but the SAM voice sounds perfectly the same as it originally did.

So we’ve uploaded our custom-compiled Tasmota binary to the board, how can we make it speak? Well documentation is thin (I’ll contribute some to the Tasmota project to help out of course), but you only need to issue the following at the console of Tasmota:


I2SSay(text goes here)

If you’ve played with old speech synthesizers before, you’ll know that they don’t always pronounce words correctly, so you’ll need to craft words at times to sound the way they’re supposed to. For example the word “house” can sound a little strange, so I use the word “howse”. Sometimes adding an h after vowels in words can help too. It’s all up to experimentation.

So it can speak when we issue commands at the console of Tasmota now, but that’s not super useful yet. We want automation!

I use Home Assistant, combined with the MQTT integration for my Tasmota linked automation, so it’s quite easy to issue anything that can be done at the console in Tasmota as an MQTT message.

In whatever script or automation you’re building in Home Assistant, all you need to do is add action type “Call Service” with the service being “mqtt.publish”, and the service data as:

payload: (hello I am home assistant. I am pleased to meet you!)
topic: cmnd/speakboy/I2SSay

You’ll see in the topic above that my Tasmota device has “device name” in config -> other config set to “speakboy”. The payload is simply what you want to say, surrounded by brackets. You can of course put substitution into play to drop in current weather conditions, or variables or whatever you want using Home Assistant methods, as long as it comes out as something that SAM can say.

You may find in your case, like mine, that audio output wasn’t high enough in volume for your purposes. I’m using mine as a doorbell announcer (at the button end, to speak to visitors while they wait for me to run down the stairs for the door) so there is road noise to compete with.

The first step is to try the gain control. It is set at 10 by default, but I found a balance between loudness and distortion to be at 20. Simply issue the command in the console in Tasmota:

I2SGain 20

If we also want to improve the speaker, mount it in a hole in a hollow box or cavity, or even a short length of pvc pipe glued to the back. The back pressure will give the speaker more ooph, as well as allowing some more resonance.

If it still isn’t loud enough we can go further with another transistor. It’s quite easy to use a suitable PNP transistor in combination with the already explained NPN transistor to amplify that current even higher for the speaker.

I’m using a BC559 PNP transistor for the purpose. By modifying how we above ran our simple amplifier, we can get more current to the speaker:

  1. Disconnect the speaker, connect the collector on the 2N3904 to 5V
  2. Disconnect the emitter of the 2N3904 from ground and connect it instead to the base of the BC559 (middle pin)
  3. Connect the Collector of the BC559 (left pin when facing the flat front) to ground/negative.
  4. Connect the Emitter of the BC559 (right pin when facing the flat front) to the negative of the speaker.
  5. Connect the positive of the speaker to 5V

You should now be much MUCH louder, but just make sure you’re not overdoing it by feeling the transistors. They shouldn’t be getting hot.

A quick note here: Never connect this to an actual amplifier. It’s switched DC voltage, not variable AC which is what audio is. It’s also WAY too high for line level audio, at around 5 times the gain. Bad things will happen to the amplifier, and if they don’t, it’ll also sound terrible!

So there you have it. Tasmota speaking everywhere all the time! Get in touch if you have problems or comments – always happy to help!