Official touch display with ESP32.

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
User avatar
Posts: 4641
Joined: Fri Jul 18, 2014 8:01 am
Location: UK

Official touch display with ESP32.

Post by pythoncoder » Mon Nov 09, 2020 2:08 pm

I have tested my LCD160CR GUI with ESP32 and provided wiring information in the the docs. An ESP32 with this display provides a low cost way to build projects needing a GUI for user I/O.

Now resolved: see later message.

I would be interested in any views on my comments in the above docs link: I found that pins 18 and 19 produced I2C timeout errors despite the official docs recommending them. Before I spend time investigating does anyone know something I'm missing?
Peter Hinch

Posts: 31
Joined: Fri Sep 04, 2020 9:27 am
Location: Hanko, Finland

Re: Official touch display with ESP32. And a query.

Post by Divergentti » Thu Nov 19, 2020 1:39 pm

This is interesting topic.

I am about to begin my indoorairquality measurement setup.

Meanwhile I am waiting components to arrive, I implemented simple OLED (SPI) and CCS811 sensor script.

Later I will replace CCS811 with NIR (MH-Z19) and add either AHT10 or BMP280 for temp and rh and when those are up and running, I liike to implement user friendly, touch screen version of the gadget. In that phase I will give a try for lcd160cr.

In this simple test case I am using Pin21 for SCL and Pin22 for SDA in i2c for the sensor and it seems to work fine without timeouts.

You seem to have freq=1_000_000. I use only 400000. Perhaps that is causing timeouts?

Video how this code works in this youtube link

Code: Select all

OLED näytölle: sh1160-kirjastoa, jonka voit ladata täältä
CCS811 sensorille:

Näytön SPI kytkentä esimerkki:

SSD1306       NodeMCU-32S(ESP32)
      GND ----> GND
      VCC ----> 3v3 (3.3V)
       D0 ----> GPIO 18 SCK (SPI Clock)
       D1 ----> GPIO 23 MOSI (sama kuin SDA)
      RES ----> GPIO 17 Reset
       DC ----> GPIO 16 Data/Command select
       CS ----> GPIO  5 Chip Select

I2C kytkentä esimerkki:
    SCL = 22
    SDA = 21

CCS811 muista kytkeä nWake -> GND!


from machine import I2C, SPI, Pin

import sh1106
import ccs811
import time
import uasyncio as asyncio
import utime
import esp32

class SPI_naytonohjain():

    def __init__(self, res=17, dc=16, cs=5, sck=18, mosi=23, leveys=16, rivit=6, lpikselit=128, kpikselit=64):
        self.rivit = []
        self.nayttotekstit = []
        self.aika = 5  # oletusnäyttöaika
        """ Muodostetaan näytönohjaukseen tarvittavat objektit """
        # SPI-kytkennan pinnit
        self.res = Pin(res)  # reset
        self.dc = Pin(dc)  # data
        self.cs = Pin(cs)  # chip select
        # SPI-objektin luonti, sck = d0, mosi = SDA
        self.spi = SPI(2, baudrate=115200, sck=Pin(sck), mosi=Pin(mosi))
        # naytto-objektin luonti
        self.nayttoleveys = leveys  # merkkiä
        self.nayttorivit = rivit  # riviä
        self.pikselit_leveys = lpikselit  # pikseliä
        self.pikselit_korkeus = kpikselit
        self.naytto = sh1106.SH1106_SPI(self.pikselit_leveys, self.pikselit_korkeus, self.spi, self.dc,
                                        self.res, self.cs)
        self.kaanteinen = False

    async def pitka_teksti_nayttoon(self, teksti, aika):
        self.aika = aika
        """ Teksti (str) ja aika (int) miten pitkään tekstiä näytetään """
        self.nayttotekstit = [teksti[y-self.nayttoleveys:y] for y in range(self.nayttoleveys,
                              len(teksti)+self.nayttoleveys, self.nayttoleveys)]
        for y in range(len(self.nayttotekstit)):
        if len(self.rivit) > self.nayttorivit:
            sivuja = len(self.nayttotekstit) // self.nayttorivit
            sivuja = 1
        if sivuja == 1:
            for z in range(0, len(self.rivit)):
                self.naytto.text(self.rivit[z], 0, 1 + z * 10, 1)

    async def teksti_riville(self, teksti, rivi, aika):
        self.aika = aika
        """ Teksti (str), rivit (int) ja aika (int) miten pitkään tekstiä näytetään """
        if len(teksti) > self.nayttoleveys:
            self.naytto.text('Rivi liian pitka', 0, 1 + rivi * 10, 1)
        elif len(teksti) <= self.nayttoleveys:
            self.naytto.text(teksti, 0, 1 + rivi * 10, 1)

    async def aktivoi_naytto(self):
        await asyncio.sleep(self.aika)

    async def kontrasti(self, kontrasti=255):
        if kontrasti > 1 or kontrasti < 255:

    async def kaanteinen_vari(self, kaanteinen=False):
        self.kaanteinen = kaanteinen

    async def kaanna_180_astetta(self, kaanna=False):

    async def piirra_kehys(self):
        if self.kaanteinen is False:
            self.naytto.framebuf.rect(1, 1, self.pikselit_leveys-1, self.pikselit_korkeus-1, 0xffff)
            self.naytto.framebuf.rect(1, 1, self.pikselit_leveys - 1, self.pikselit_korkeus - 1, 0x0000)

    async def piirra_alleviivaus(self, rivi, leveys):
        rivikorkeus = self.pikselit_korkeus / self.nayttorivit
        alkux = 1
        alkuy = 8 + (int(rivikorkeus * rivi))
        merkkileveys = int(8 * leveys)
        if self.kaanteinen is False:
            self.naytto.framebuf.hline(alkux, alkuy, merkkileveys, 0xffff)
            self.naytto.framebuf.hline(alkux, alkuy, merkkileveys, 0x0000)

    async def resetoi_naytto(self):

class KaasuSensori():

    def __init__(self, i2cvayla=0, scl=22, sda=21, taajuus=400000, osoite=90):
        self.i2c = I2C(i2cvayla, scl=Pin(scl), sda=Pin(sda), freq=taajuus)
        self.laiteosoite = osoite
        self.sensori = ccs811.CCS811(self.i2c)
        self.eCO2 = 0
        self.tVOC = 0

    async def lue_arvot(self):
        if self.sensori.data_ready():
            self.eCO2 = self.sensori.eCO2
            self.tVOC = self.sensori.tVOC

def ratkaise_aika():
    (vuosi, kuukausi, kkpaiva, tunti, minuutti, sekunti, viikonpva, vuosipaiva) = utime.localtime()
    paivat = {0: "Ma", 1: "Ti", 2: "Ke", 3: "To", 4: "Pe", 5: "La", 6: "Su"}
    kuukaudet = {1: "Tam", 2: "Hel", 3: "Maa", 4: "Huh", 5: "Tou", 6: "Kes", 7: "Hei", 8: "Elo",
              9: "Syy", 10: "Lok", 11: "Mar", 12: "Jou"}
    #.format(paivat[viikonpva]), format(kuukaudet[kuukausi]),
    paiva = "%s.%s.%s" % (kkpaiva, kuukausi, vuosi)
    kello = "%s:%s:%s" % ("{:02d}".format(tunti), "{:02d}".format(minuutti), "{:02d}".format(sekunti))
    return paiva, kello

async def neiti_aika():
    while True:
        print("Uptime %s" % utime.time())
        await asyncio.sleep_ms(100)


async def main():
    naytin = SPI_naytonohjain()
    kaasusensori = KaasuSensori()
    # tyojono = asyncio.get_event_loop()
    while True:
        """ asyncio.create_task(naytin.pitka_teksti_nayttoon("Pitka teksti nayttoon", 5))
        asyncio.create_task(naytin.teksti_riville("Riville 3", 3, 10))
        asyncio.create_task(naytin.pitka_teksti_nayttoon("Viela pidempi teksti nayttoon", 5)) """
        #  Luetaan arvoja taustalla
        # await naytin.pitka_teksti_nayttoon("Ilmanlaatumonitorointi v0.01", 5)
        # await naytin.piirra_kehys()
        await naytin.teksti_riville("PVM: %s" % ratkaise_aika()[0], 0, 5)
        await naytin.teksti_riville("KLO: %s" % ratkaise_aika()[1], 1,  5)
        if kaasusensori.eCO2 > 1:
            await naytin.teksti_riville("eCO2: %s" % kaasusensori.eCO2, 3, 5)
            if kaasusensori.eCO2 > 1000:
                await naytin.kaanteinen_vari(True)
                await naytin.kaanteinen_vari(False)
        if kaasusensori.tVOC > 1:
            await naytin.teksti_riville("tVOC: %s" % kaasusensori.tVOC, 4, 5)
            if kaasusensori.tVOC > 500:
                await naytin.kaanteinen_vari(True)
                await naytin.kaanteinen_vari(False)

        await naytin.teksti_riville("Hall: %s" % esp32.hall_sensor(),5,5)
        await naytin.aktivoi_naytto()
        # await naytin.piirra_alleviivaus(3, 7)
        await asyncio.sleep_ms(100)

User avatar
Posts: 4641
Joined: Fri Jul 18, 2014 8:01 am
Location: UK

Official touch display with ESP32.

Post by pythoncoder » Thu Nov 19, 2020 5:57 pm

I have solved this and edited my initial post to reflect this.

It seems that the docs are wrong and it's necessary to specify the pins for hardware I2C. See my comments in this issue.

This file shows which invocation lines work and which don't. The rate of 1Mbps is based on the official driver and works fine.
Peter Hinch

Posts: 43
Joined: Fri Oct 12, 2018 11:50 pm

Re: Official touch display with ESP32.

Post by uCTRL » Thu Nov 19, 2020 8:06 pm

low cost way to build projects
Its not a low cost display at £28.80 each in micropython store. I understand that Damian needs to make money somewhere, but ...
For majority of hobbyists ILI9341 or similar TFT derivatives from Aliexpress is the way to go.

Would also be good to have full numeric keypad gui.

Still great work Peter.

User avatar
Posts: 4641
Joined: Fri Jul 18, 2014 8:01 am
Location: UK

Re: Official touch display with ESP32.

Post by pythoncoder » Fri Nov 20, 2020 8:06 am

Fair point, although my experience of cheap Chinese hardware is dispiriting. The products of George Robotics and Adafruit may cost more, but they do have a pronounced habit of working.

Re a full keyboard I have done this here but only on a much larger display. I don't think anything much smaller would be usable, at least with my fat fingers.
Peter Hinch

Post Reply