Big characters using 20x4 LCD with EspHome?

Hi to all!

I want to use a 20x4 LCD display to show HA info (of course :joy:) and as wall clock too.

Is there a way to show, i.e. a “big numbers clock” as a display page, using all display lines with EspHome? I have found some projects to Arduino, but i want to use It with a esp32 mcu and alternate “big clock” page with “normal text” pages.

Like this.

Thanks in advance if someone can help me.

Regards.

Dani

It might help if you posted a link to the actual LCD display board with specs. There is a bunch of display hardware already supported, and it’s possible one of those setups will work with this board:

I have a lot of Espressif modules running with esphome on my home setup yet, one of them with those display.

It works flawlessly but i want to show a big numbers clock as a display page, like previous post picture.

I’m not sure how anyone can help you with just a picture of the display. Without the display information this feels like just a guessing game. Could you at least show the YAML you’ve tried to get it working?

Assuming the display hardware is supported this should be possible. The ESPHome LCD display engine supports up to 8 user defined characters. Combine those with some lambda code and it should be fairly easy.

IDK if it will work 100% but, this is what you need.

Here is a pixel generator I found to help you.
https://omerk.github.io/lcdchargen/

I made a “0” and that arrayor 8 lines starting with 0b… Those 8 lines will create the character “0” so those are what you need.

0b11111,
	0b11111,
	0b11011,
	0b11011,
	0b11011,
	0b11011,
	0b11111,
	0b11111


The documentation sais there is a limit of 7 characters though…

The LCD display has the possibility to define up to eight user defined characters occupying the characters `0` to `7` and mirrored at `8` to `15`

Sorry if my English can make any mistakes or missunderstand.

I have a working display yet, but “1 line text” is too small and make it hard to read at 2-3 meter of distance. Not able to use It as advanced wall clock…

In fact, all i know is if exists any project that can be use a 20x4 display to show larger numbers working with esphome, mixed with standard size text too, by chasing between pages or scrolling text, or large numbers…

Seeking at github, i’ve found same working projects (esp32 or esp8266 + 20x4 display) that combines short and large numbers, scrolling text, etc. About this, obviously can be done using that devices… This have a great potential to do it:

There are some pics inside repo files:

But, how can integrate it with esphome and HA? Any ready-to-deploy idea?

Hope It helps to explain my idea.

Thanks in advance :smile:

You need to write the code using yaml and lambda (C++) using the ESPHome environment. If you can program using the Arduino framework you should have no issues.

No. The resources that have been linked a couple of times above show you how to connect and write to a LCD, and how to create the special characters that the clock in your picture uses.

We are always happy to assist - but you will need to start it off by using ESPHome to, for starters, just display something on a LCD, then stuff from sensors or HA, then your clock. Start small and work your way up and you will learn as you go.

I normally dont like to discourage people from what they’re working on for something else just because its easier but, this may be a good scenario for doing that.

Displays are relatively cheap and you could get a better lcd display where you can easily configure how things are displayed and their size and they’re actually intended to do things like that where older lcd displays use a specific character size and character space and not really intended for what you want and so it requires more effort to make it do work in a way that is unintended. Its just an unnecessary fight you will have to do, just for something so minor… Pick your fights and dont try fighting silly things.

I would strongly suggest you save your lcd display for a future project that it woul be appropriate for and for this one, go buy a more capable lcd/tft display. You can buy those cheap yellow ones with a built-in esp32 for 15$ and they’re really good displays!

I have one of these and the sky is the limit as far as creatively displaying what you need.

Hello @DaniEP ! I was thinking about the same thing but as you see is not possible in esphome directly. One ideea can be to program the esp+lcd in arduino IDE and with MQTT to send data from HA (hour, minute, temperature, etc) . In arduino code just take this values and show them with bigfont on the lcd…

Oh, it’s possible!


I wrote the code; it may not be pretty (28 if statements in total), but it works.

Cool! Share please.

Let me explain a bit.
This is one of my first lambda codes. I couldn’t figure out how to properly create an “if” loop, so everything is conditional.
The variable “i” changes its value every second and defines a “:” between hours and minutes.
Then, a few lines extracting individual characters from the time, then displaying specific numbers using user-defined characters.
The whole thing could be written better and more optimally, but I was working on it late at night and wanted it to work, not look pretty.
Some variables and comments are written in Polish; it was more convenient for me. :slight_smile:

i2c:
  sda: GPIO18
  scl: GPIO19
  scan: true

time:
- platform: homeassistant
  id: my_time

globals:
  - id: i
    type: int
    restore_value: no
    initial_value: '0'

display:
  - platform: lcd_pcf8574
    dimensions: 16x2 
    address: 0x3f
    id: lcd_screen
    update_interval: 1s
    user_characters:
      - position: 0
        data:
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b00000
          - 0b00000
          - 0b11111
          - 0b11111
          - 0b11111
      - position: 1
        data:
          - 0b11100
          - 0b11110
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
      - position: 2
        data:
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b01111
          - 0b00111
      - position: 3
        data:
          - 0b00000
          - 0b00000
          - 0b00000
          - 0b00000
          - 0b00000
          - 0b11111
          - 0b11111
          - 0b11111
      - position: 4
        data:
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b00000
          - 0b00000
          - 0b00000
          - 0b00000
          - 0b00000
      - position: 5
        data:
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
      - position: 6
        data:
          - 0b00111
          - 0b01111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
      - position: 7
        data:
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11111
          - 0b11110
          - 0b11100
    lambda: |-
      if (id(i) == 0) {
        it.print(8,0,"\x03");
        it.print(8,1,"\x03");
        id(i) = 1;
      } else {
        it.print(8,0," ");
        it.print(8,1," ");
        id(i) = 0;
      }
      std::string  h_str = id(my_time).now().strftime("%H");
      std::string  h1_str = h_str.substr(0,1).c_str();
      std::string  h2_str = h_str.substr(1,2).c_str();
      std::string  m_str = id(my_time).now().strftime("%M");
      std::string  m1_str = m_str.substr(0,1).c_str();
      std::string  m2_str = m_str.substr(1,2).c_str();
      // pierwszy znak
      int kolejnosc = 1;
      if (h1_str == "0") {
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x04");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      }
      if (h1_str == "1") {
        it.print(kolejnosc,0,"\x04");
        it.print(kolejnosc+1,0,"\x01");
        it.print(kolejnosc+2,0," ");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x05");
        it.print(kolejnosc+2,1,"\x03");
      }
      if (h1_str == "2") { 
        it.print(kolejnosc,0,"\x08");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x03");
      } 
      // drugi znak
      kolejnosc = 5;
      if (h2_str == "0") {
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x04");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      }
      if (h2_str == "1") {
        it.print(kolejnosc,0,"\x04");
        it.print(kolejnosc+1,0,"\x01");
        it.print(kolejnosc+2,0," ");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x05");
        it.print(kolejnosc+2,1,"\x03");
      }
      if (h2_str == "2") { 
        it.print(kolejnosc,0,"\x08");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x03");
      } 
      if (h2_str == "3") { 
        it.print(kolejnosc,0,"\x08");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (h2_str == "4") { 
        it.print(kolejnosc,0,"\x02");
        it.print(kolejnosc+1,0,"\x03");
        it.print(kolejnosc+2,0,"\x05");
        it.print(kolejnosc,1," ");
        it.print(kolejnosc+1,1," ");
        it.print(kolejnosc+2,1,"\x05");
      } 
      if (h2_str == "5") { 
        it.print(kolejnosc,0,"\x02");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x08");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (h2_str == "6") { 
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x08");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (h2_str == "7") { 
        it.print(kolejnosc,0,"\x04");
        it.print(kolejnosc+1,0,"\x04");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1," ");
        it.print(kolejnosc+1,1," ");
        it.print(kolejnosc+2,1,"\x05");
      } 
      if (h2_str == "8") { 
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (h2_str == "9") { 
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1," ");
        it.print(kolejnosc+1,1," ");
        it.print(kolejnosc+2,1,"\x05");
      } 
      // trzeci znak
      kolejnosc = 9;
      if (m1_str == "0") {
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x04");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      }
      if (m1_str == "1") {
        it.print(kolejnosc,0,"\x04");
        it.print(kolejnosc+1,0,"\x01");
        it.print(kolejnosc+2,0," ");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x05");
        it.print(kolejnosc+2,1,"\x03");
      }
      if (m1_str == "2") { 
        it.print(kolejnosc,0,"\x08");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x03");
      } 
      if (m1_str == "3") { 
        it.print(kolejnosc,0,"\x08");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (m1_str == "4") { 
        it.print(kolejnosc,0,"\x02");
        it.print(kolejnosc+1,0,"\x03");
        it.print(kolejnosc+2,0,"\x05");
        it.print(kolejnosc,1," ");
        it.print(kolejnosc+1,1," ");
        it.print(kolejnosc+2,1,"\x05");
      } 
      if (m1_str == "5") { 
        it.print(kolejnosc,0,"\x02");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x08");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      // czwarty znak
      kolejnosc = 13;
      if (m2_str == "0") {
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x04");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      }
      if (m2_str == "1") {
        it.print(kolejnosc,0,"\x04");
        it.print(kolejnosc+1,0,"\x01");
        it.print(kolejnosc+2,0," ");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x05");
        it.print(kolejnosc+2,1,"\x03");
      }
      if (m2_str == "2") { 
        it.print(kolejnosc,0,"\x08");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x03");
      } 
      if (m2_str == "3") { 
        it.print(kolejnosc,0,"\x08");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (m2_str == "4") { 
        it.print(kolejnosc,0,"\x02");
        it.print(kolejnosc+1,0,"\x03");
        it.print(kolejnosc+2,0,"\x05");
        it.print(kolejnosc,1," ");
        it.print(kolejnosc+1,1," ");
        it.print(kolejnosc+2,1,"\x05");
      } 
      if (m2_str == "5") { 
        it.print(kolejnosc,0,"\x02");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x08");
        it.print(kolejnosc,1,"\x03");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (m2_str == "6") { 
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x08");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (m2_str == "7") { 
        it.print(kolejnosc,0,"\x04");
        it.print(kolejnosc+1,0,"\x04");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1," ");
        it.print(kolejnosc+1,1," ");
        it.print(kolejnosc+2,1,"\x05");
      } 
      if (m2_str == "8") { 
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1,"\x02");
        it.print(kolejnosc+1,1,"\x03");
        it.print(kolejnosc+2,1,"\x07");
      } 
      if (m2_str == "9") { 
        it.print(kolejnosc,0,"\x06");
        it.print(kolejnosc+1,0,"\x08");
        it.print(kolejnosc+2,0,"\x01");
        it.print(kolejnosc,1," ");
        it.print(kolejnosc+1,1," ");
        it.print(kolejnosc+2,1,"\x05");
      } 

If you like it, leave a “like.” :smiley:

1 Like

Now I’ve enclosed this watch in an old TV box casing. It looks like this.