2019-02-27 10:10:09 +01:00
|
|
|
Character-Based LCD Display
|
|
|
|
===========================
|
2018-08-22 22:05:28 +02:00
|
|
|
|
2018-11-14 22:12:27 +01:00
|
|
|
.. seo::
|
2019-02-27 10:10:09 +01:00
|
|
|
:description: Instructions for setting up character-based LCD displays.
|
2018-11-14 22:12:27 +01:00
|
|
|
:image: lcd.jpg
|
|
|
|
|
2019-02-27 10:10:09 +01:00
|
|
|
.. _lcd-pcf8574:
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
lcd_pcf8574 Component
|
|
|
|
---------------------
|
2019-02-27 10:10:09 +01:00
|
|
|
|
2019-02-27 18:32:47 +01:00
|
|
|
The ``lcd_pcf8574`` display platform allows you to use standard character-based LCD displays like
|
|
|
|
`this one <https://docs.labs.mediatek.com/resource/linkit7697-arduino/en/tutorial/driving-1602-lcd-with-pcf8574-pcf8574a>`__
|
2019-02-27 10:10:09 +01:00
|
|
|
with ESPHome. This integration is only for LCD displays that display individual characters on a screen (usually 16-20 columns
|
|
|
|
and 2-4 rows), and not for LCD displays that can control each pixel individually.
|
|
|
|
|
2021-01-11 17:46:37 +01:00
|
|
|
This version of the LCD integration is for LCD displays with a PCF8574 connected to all the data pins. This has
|
2019-02-27 10:10:09 +01:00
|
|
|
the benefit that you only need to connect two data wires to the ESP instead of the 6 or 10 with the :ref:`lcd-gpio`.
|
|
|
|
As the communication with the :ref:`I²C Bus <i2c>`, you need to have an ``i2c:`` section in your configuration.
|
|
|
|
|
|
|
|
.. figure:: images/lcd-pcf8574.jpg
|
|
|
|
:align: center
|
|
|
|
:width: 75.0%
|
|
|
|
|
|
|
|
The PCF8574 chip attached to the LCD Display.
|
|
|
|
|
|
|
|
.. figure:: images/lcd-hello_world.jpg
|
|
|
|
:align: center
|
|
|
|
:width: 60.0%
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
# Example configuration entry
|
|
|
|
i2c:
|
|
|
|
sda: D0
|
|
|
|
scl: D1
|
|
|
|
|
|
|
|
display:
|
|
|
|
- platform: lcd_pcf8574
|
|
|
|
dimensions: 18x4
|
|
|
|
address: 0x3F
|
|
|
|
lambda: |-
|
|
|
|
it.print("Hello World!");
|
|
|
|
|
|
|
|
Configuration variables:
|
|
|
|
************************
|
|
|
|
|
2019-11-12 15:37:46 +01:00
|
|
|
- **dimensions** (**Required**, string): The dimensions of the display with ``COLUMNSxROWS``. If you're not
|
2019-02-27 10:10:09 +01:00
|
|
|
sure, power the display up and just count them.
|
|
|
|
- **address** (*Optional*, int): The :ref:`I²C <i2c>` address of the PCF8574 chip, defaults to ``0x3F``.
|
|
|
|
- **lambda** (*Optional*, :ref:`lambda <config-lambda>`): The lambda to use for rendering the content on the display.
|
|
|
|
See :ref:`display-lcd_lambda` for more information.
|
|
|
|
- **update_interval** (*Optional*, :ref:`config-time`): The interval to re-draw the screen. Defaults to ``1s``.
|
|
|
|
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
|
|
|
|
|
|
|
|
.. _lcd-gpio:
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
lcd_gpio Component
|
|
|
|
------------------
|
2019-02-27 10:10:09 +01:00
|
|
|
|
2018-08-22 22:05:28 +02:00
|
|
|
The ``lcd_gpio`` display platform allows you to use standard character-based LCD displays like `this one <https://www.adafruit.com/product/181>`__
|
2019-02-16 23:25:23 +01:00
|
|
|
with ESPHome. This integration is only for LCD displays that display individual characters on a screen (usually 16-20 columns
|
2018-08-22 22:05:28 +02:00
|
|
|
and 2-4 rows), and not for LCD displays that can control each pixel individually. Also, this is the GPIO version of the LCD
|
|
|
|
integration where each of the data pins of the LCD needs a dedicated GPIO pin on the ESP. These LCD displays are also
|
2019-02-27 10:10:09 +01:00
|
|
|
commonly sold with a PCF8574 chip which only need two lines to the ESP, for that see :ref:`lcd-pcf8574`.
|
2018-08-22 22:05:28 +02:00
|
|
|
|
|
|
|
.. figure:: images/lcd-full.jpg
|
|
|
|
:align: center
|
|
|
|
:width: 75.0%
|
|
|
|
|
|
|
|
LCD Display.
|
|
|
|
|
2018-11-19 18:32:16 +01:00
|
|
|
.. code-block:: yaml
|
2018-08-22 22:05:28 +02:00
|
|
|
|
|
|
|
# Example configuration entry
|
|
|
|
display:
|
|
|
|
- platform: lcd_gpio
|
|
|
|
dimensions: 18x4
|
|
|
|
data_pins:
|
|
|
|
- D0
|
|
|
|
- D1
|
|
|
|
- D2
|
|
|
|
- D3
|
|
|
|
enable_pin: D4
|
|
|
|
rs_pin: D5
|
|
|
|
lambda: |-
|
|
|
|
it.print("Hello World!");
|
|
|
|
|
|
|
|
Configuration variables:
|
2019-02-27 10:10:09 +01:00
|
|
|
************************
|
2018-08-22 22:05:28 +02:00
|
|
|
|
2019-11-12 15:37:46 +01:00
|
|
|
- **dimensions** (**Required**, string): The dimensions of the display with ``COLUMNSxROWS``. If you're not
|
2018-08-22 22:05:28 +02:00
|
|
|
sure, power the display up and just count them.
|
|
|
|
- **data_pins** (**Required**, list of :ref:`Pin Schemas <config-pin_schema>`): A list of the data pins you
|
|
|
|
have hooked up to the LCD. The list can either be 8 items long (when you have connected all 8 data pins), or
|
|
|
|
4 items long (if you're operating in 4-bit mode with either the first 4 data pins connected or the last 4 data
|
|
|
|
pins connected).
|
|
|
|
- **enable_pin** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The pin you have ``EN`` hooked up to.
|
|
|
|
- **rs_pin** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The pin you have ``RS`` hooked up to.
|
|
|
|
- **rw_pin** (*Optional*, :ref:`Pin Schema <config-pin_schema>`): Optionally set the pin you have ``RW`` hooked up to.
|
|
|
|
You can also just permanently connect that pin to GND.
|
|
|
|
- **lambda** (*Optional*, :ref:`lambda <config-lambda>`): The lambda to use for rendering the content on the display.
|
|
|
|
See :ref:`display-lcd_lambda` for more information.
|
|
|
|
- **update_interval** (*Optional*, :ref:`config-time`): The interval to re-draw the screen. Defaults to ``1s``.
|
|
|
|
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
|
|
|
|
|
|
|
|
.. _display-lcd_lambda:
|
|
|
|
|
|
|
|
Rendering Lambda
|
|
|
|
----------------
|
|
|
|
|
2019-02-07 18:07:16 +01:00
|
|
|
The LCD displays has a similar API to the fully fledged :ref:`display-engine`, but it's only a subset as LCD displays
|
2018-08-22 22:05:28 +02:00
|
|
|
don't have a concept of individual pixels. In the lambda you're passed a variable called ``it``
|
2019-06-03 19:34:17 +02:00
|
|
|
as with all other displays. In this case however, ``it`` is an instance of either ``GPIOLCDDisplay`` or ``PCF8574LCDDisplay``.
|
2018-08-22 22:05:28 +02:00
|
|
|
|
|
|
|
The most basic operation with LCD Displays is writing static text to the screen as in the configuration example
|
|
|
|
at the top of this page.
|
|
|
|
|
|
|
|
Each of the three methods (``print``, ``printf`` and ``strftime``) all optionally take a column and row arguments at the
|
|
|
|
beginning which can be used to print the text at a specific position. These arguments are set to ``0`` (column) and ``0`` (row)
|
|
|
|
by default which means the character at the top left.
|
|
|
|
|
2018-11-19 18:32:16 +01:00
|
|
|
.. code-block:: yaml
|
2018-08-22 22:05:28 +02:00
|
|
|
|
|
|
|
display:
|
|
|
|
- platform: lcd_gpio # or lcd_pcf8574
|
|
|
|
# ...
|
|
|
|
lambda: |-
|
|
|
|
// Print 0 at the top left
|
|
|
|
it.print("0");
|
|
|
|
|
|
|
|
// Print 1 at the second row and second column.
|
|
|
|
it.print(1, 1, "1");
|
|
|
|
|
|
|
|
// Let's write a sensor value (let's assume it's 42.1)
|
2018-10-20 14:53:27 +02:00
|
|
|
it.printf("%.1f", id(my_sensor).state);
|
2018-08-22 22:05:28 +02:00
|
|
|
// Result: "42.1" (the dot will appear on the "2" segment)
|
|
|
|
|
|
|
|
// Print a right-padded sensor value with 0 digits after the decimal
|
2018-10-20 14:53:27 +02:00
|
|
|
it.printf("Sensor value: %8.0f", id(my_sensor).state);
|
2018-08-22 22:05:28 +02:00
|
|
|
// Result: "Sensor value: 42"
|
|
|
|
|
|
|
|
// Print the current time
|
2018-12-02 13:12:27 +01:00
|
|
|
it.strftime("It is %H:%M on %d.%m.%Y", id(my_time).now());
|
2018-08-22 22:05:28 +02:00
|
|
|
// Result for 10:06 on august 21st 2018 -> "It is 10:06 on 21.08.2018"
|
|
|
|
|
2018-12-02 13:12:27 +01:00
|
|
|
# (Optional) For displaying time:
|
|
|
|
time:
|
|
|
|
- platform: sntp
|
|
|
|
id: my_time
|
|
|
|
|
2018-08-22 22:05:28 +02:00
|
|
|
.. note::
|
|
|
|
|
|
|
|
If you're not seeing anything on the display, make sure you try turning the contrast potentiometer around.
|
|
|
|
|
|
|
|
Please see :ref:`display-printf` for a quick introduction into the ``printf`` formatting rules and
|
|
|
|
:ref:`display-strftime` for an introduction into the ``strftime`` time formatting.
|
|
|
|
|
2019-06-03 19:34:17 +02:00
|
|
|
Backlight Control
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
For the GPIO based display, the backlight is lit by applying Vcc to the A pin and K connected to ground.
|
|
|
|
The backlight can draw more power than the microcontroller output pins can supply, so it is advisable to use
|
|
|
|
a transistor as a switch to control the power for the backlight pins.
|
|
|
|
|
|
|
|
With the ``lcd_pcf8574`` the backlight can be turned on by ``it.backlight()`` and off by ``it.no_backlight()`` in the
|
2020-05-10 21:27:59 +02:00
|
|
|
display lambda definition. The jumper on the PCF8574 board needs to be closed for the backlight control to work.
|
|
|
|
Keep in mind that the display lambda runs for every ``update_interval``, so if the backlight is turned on/off there,
|
2019-06-03 19:34:17 +02:00
|
|
|
it cannot be overridden from other parts.
|
|
|
|
|
|
|
|
Here is one solution for a typical use-case where the backlight is turned on after a motion sensor activates and
|
|
|
|
turns off 90 seconds after the last activation of the sensor.
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
display:
|
|
|
|
- platform: lcd_pcf8574
|
|
|
|
id: mydisplay
|
|
|
|
# ...
|
|
|
|
|
|
|
|
binary_sensor:
|
|
|
|
- platform: gpio
|
|
|
|
# ...
|
|
|
|
on_press:
|
|
|
|
then:
|
|
|
|
- binary_sensor.template.publish:
|
|
|
|
id: backlight
|
|
|
|
state: ON
|
|
|
|
- binary_sensor.template.publish:
|
|
|
|
id: backlight
|
|
|
|
state: OFF
|
|
|
|
- platform: template
|
|
|
|
id: backlight
|
|
|
|
filters:
|
|
|
|
- delayed_off: 90s
|
|
|
|
on_press:
|
|
|
|
then:
|
|
|
|
- lambda: |-
|
|
|
|
id(mydisplay).backlight();
|
|
|
|
on_release:
|
|
|
|
then:
|
|
|
|
- lambda: |-
|
|
|
|
id(mydisplay).no_backlight();
|
|
|
|
|
2022-03-24 07:38:01 +01:00
|
|
|
User Defined Characters
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
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`` (i.e. ``\x08`` can be used instead of the ``\0`` that can
|
|
|
|
be problematic in strings). Each character has eight lines of five bits, with the first line on the top
|
|
|
|
and the most significant bit on the left, meaning that ``0b10000`` followed by six zeros and a ``0b00001``
|
|
|
|
defines a dot at the upper left and lower right of the character.
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
display:
|
|
|
|
- platform: lcd_pcf8574
|
|
|
|
id: mydisplay
|
|
|
|
# ...
|
|
|
|
user_characters:
|
|
|
|
- position: 0
|
|
|
|
data:
|
|
|
|
- 0b00000
|
|
|
|
- 0b01010
|
|
|
|
- 0b00000
|
|
|
|
- 0b00100
|
|
|
|
- 0b00100
|
|
|
|
- 0b10001
|
|
|
|
- 0b01110
|
|
|
|
- 0b00000
|
|
|
|
- position: 7
|
|
|
|
data:
|
|
|
|
- 0b00000
|
|
|
|
- 0b01010
|
|
|
|
- 0b00000
|
|
|
|
- 0b00100
|
|
|
|
- 0b00100
|
|
|
|
- 0b00000
|
|
|
|
- 0b01110
|
|
|
|
- 0b10001
|
|
|
|
lambda: |-
|
|
|
|
it.print("Hello, world \x08 \x07!");
|
|
|
|
|
2018-08-22 22:05:28 +02:00
|
|
|
See Also
|
|
|
|
--------
|
|
|
|
|
|
|
|
- :doc:`index`
|
2019-02-27 10:10:09 +01:00
|
|
|
- :doc:`/components/switch/gpio`
|
|
|
|
- :doc:`/components/binary_sensor/gpio`
|
|
|
|
- :doc:`/components/pcf8574`
|
2019-05-12 22:44:59 +02:00
|
|
|
- :apiref:`lcd_base/lcd_display.h`
|
2018-08-24 22:44:01 +02:00
|
|
|
- `Arduino LiquidCrystal Library <https://www.arduino.cc/en/Reference/LiquidCrystal>`__
|
2019-02-07 13:54:45 +01:00
|
|
|
- :ghedit:`Edit`
|