Skip to content

Ecran couleur TFT 320x240 SPI

Présentation

La boutique Elektor propose un écran TFT couleur de 320x240 pixel, à communication SPI, connecteur Dupont classique. Ce modèle n'est pas tactile, seulement l'afficheur graphique. Ce module dispose par contre d'un emplacement pour carte SD card, SPI également.

Info

Cet afficheur est le même que celui utilisé par M5Stack Core !

Ce module utilise le driver ILI9341

Brochage :

Comme pour tout dispositif SPI, on a :

  • Vcc : 3.3V à priori
  • GND
  • MOSI
  • MISO
  • CLK
  • CS

2 broches additionnelles sont nécessaires :

  • dc : data command
  • rst : reset

Point important : la broche LED doit être également connectée au 3.3V et correspond à la mise sous tension de l'afficheur.

Une broche doit à priori être utilisable ici.

Le module utilise donc 6 broches au total.

Librairie Micropython

Une version ici, orientée M5stacks (ESP32) et affichage de polices : https://github.com/jeffmer/micropython-ili9341 elle-même basée sur celle-ci : https://github.com/tuupola/micropython-ili934x

Cette librairie ne dispose pas des fonctions de dessins...

Celle que je conseille :

Une autre version ici plus "classique" (ESP 32) avec plein d'exemples - c'est la lib du projet ci-dessous et qui contient des primitives de dessins, etc. : https://github.com/rdagger/micropython-ili9341 Un projet très excellent ici par l'auteur de cette lib' (utilise un modèle avec touchscreen, mais c'est pas grave si sans) : https://www.rototron.info/projects/esp32-pwned-password-checker/

Warning

Pour les écrans au-delà d'une certaine dimension, l'utilisation du framebuffer n'est pas ou plus intéressante car il en découle une mobilisation trop grande de la RAM, etc.

Une discussion ici : https://forum.micropython.org/viewtopic.php?f=18&t=9368 Difficile à utiliser avec Nano-Gui donc.

Montage

Dans mon cas, sur le Pi Pico, on va utiliser :

  • GP16 : SPI RX = MISO
  • GP17 : CS
  • GP18 : SCK
  • GP19 : SPI TX = MOSI
  • GP20 : dc
  • GP21 : Reset
  • GND : à GND
  • 3.3V à Vcc ET LED (LED à 3.3V sinon écran reste éteint)

Test dans l'interpréteur

Pi Pico

D'après : https://github.com/rdagger/micropython-ili9341/blob/master/demo_shapes.py

>>>from ili9341 import Display, color565
>>>from machine import Pin, SPI
>>>spi=machine.SPI(0, baudrate=40000000, sck=Pin(18), mosi=Pin(19),miso=Pin(16))
>>>display = Display(spi, dc=Pin(20), cs=Pin(17), rst=Pin(21))
>>>display.clear(color565(64, 0, 255)) # bleu violet
>>> display.clear() # affiche noir

>>>display.draw_hline(10, 319, 229, color565(255, 0, 255))
>>>display.draw_hline(50, 319, 229, color565(255, 0, 255))
x-coordinate: 278 above maximum of 239.
>>>display.draw_hline(0,0,239, color565(255, 0, 255)) # draw_hline(self, x, y, w, color)
>>>display.draw_hline(0,0,10, color565(255, 0, 255)) # draw_hline(self, x, y, w, color)
>>>display.clear()
>>>display.draw_hline(0,0,10, color565(255, 0, 255)) # draw_hline(self, x, y, w, color)

ESP 32 - M5Stack

Une version de la librairie pour afficheur ILI9341 ici : https://github.com/jeffmer/micropython-ili9341

Ici, une version pour ILI9342C avec driver C compilé dans le Micropython : https://github.com/russhughes/ili9342c_mpy

Une version ici qui semble être la plus rapide, incluant driver C : https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki/display Pour carte avec psRam de 4Mb...

La discussion est ici : https://forum.micropython.org/viewtopic.php?t=5209

Test avec M5 Stacks avec la lib' Pi Pico : bof bof...

>>> power=Pin(32, Pin.OUT)
>>> power.on()
>>> spi=SPI(2, baudrate=40000000, sck=Pin(18), mosi=Pin(23))
>>> display = Display(spi, dc=Pin(27), cs=Pin(14), rst=Pin(33))
>>> display.clear(color565(64, 0, 255))
>>>display = Display(spi, dc=Pin(27), cs=Pin(14), rst=Pin(33), rotation=90)
>>> display.draw_hline(0,0,10, color565(255, 0, 255))
>>> display.clear(color565(64, 0, 255))
>>> display.draw_pixel(100,100,color565(0, 0, 0))

Fonctionne un peu avec rotation, mais c'est pas çà...

Test avec Micropython + driver pour ILI2342C : la solution qui fonctione "out of the box"

https://github.com/russhughes/ili9342c_mpy

On installe le firmware micropython avec le driver intégré.J'ai pris le généric qui a fonctionné sans problème.

Ensuite, on peut tester avec un code de démo : https://github.com/russhughes/ili9342c_mpy/blob/main/examples/M5STACK/hello.py

"""
hello.py

    Writes "Hello!" in random colors at random locations on a
    M5Stack core display.

"""
import time
import random
from machine import Pin, SPI

import ili9342c
import vga1_bold_16x32 as font


def main():
    tft = ili9342c.ILI9342C(
        SPI(2, baudrate=60000000, sck=Pin(18), mosi=Pin(23)),
        320,
        240,
        reset=Pin(33, Pin.OUT),
        cs=Pin(14, Pin.OUT),
        dc=Pin(27, Pin.OUT),
        backlight=Pin(32, Pin.OUT),
        rotation=0,
        buffer_size=16*32*2)

    tft.init()
    tft.fill(ili9342c.BLACK)
    time.sleep(1)

    while True:
        for rotation in range(4):
            tft.rotation(rotation)
            tft.fill(0)
            col_max = tft.width() - font.WIDTH*6
            row_max = tft.height() - font.HEIGHT

            for _ in range(1000):
                tft.text(
                    font,
                    "Hello!",
                    random.randint(0, col_max),
                    random.randint(0, row_max),
                    ili9342c.color565(
                        random.getrandbits(8),
                        random.getrandbits(8),
                        random.getrandbits(8)),
                    ili9342c.color565(
                        random.getrandbits(8),
                        random.getrandbits(8),
                        random.getrandbits(8))
                )


main()

Test dans l'interpréteur :

>>> import ili9342c
>>> from machine import Pin, SPI
>>> spi=SPI(2, baudrate=60000000, sck=Pin(18), mosi=Pin(23))
>>> tft = ili9342c.ILI9342C(
        spi,
        320,
        240,
        reset=Pin(33, Pin.OUT),
        cs=Pin(14, Pin.OUT),
        dc=Pin(27, Pin.OUT),
        backlight=Pin(32, Pin.OUT),
        rotation=0,
        buffer_size=16*32*2)
>>> tft.init()
>>> tft.fill(0)
>>> tft.fill(ili9342c.BLUE)
>>> tft.fill(ili9342c.RED)
>>> tft.fill(ili9342c.BLACK)
>>> tft.fill(ili9342c.color565(255,255,255))
>>> tft.pixel(100,100,ili9342c.BLUE)
>>> tft.fill(ili9342c.BLACK)
>>> tft.pixel(100,100,ili9342c.BLUE)
>>> tft.pixel(10,10,ili9342c.BLUE)
>>> tft.pixel(10,10,ili9342c.color565(255,255,255))
>>> tft.pixel(100,100,ili9342c.color565(255,0,0))
>>> tft.pixel(100,100,ili9342c.color565(255,255,0))
>>> tft.line(0,0,tft.width(), tft.height(),ili9342c.color565(255,255,0))
>>> tft.rect(10,10,50,50,ili9342c.color565(255,0,0))
>>> tft.fill_rect(10,10,50,50,ili9342c.color565(255,0,0))

Détail des fonctions ici : https://github.com/russhughes/ili9342c_mpy#methods

Code de test

Voici un code qui affiche une palette de couleurs sur l'écran sous forme de colonne de disques colorés :

D'après : https://github.com/rdagger/micropython-ili9341/blob/master/demo_color_wheel.py

"""ILI9341 demo (color palette)."""
from time import sleep
from ili9341 import Display, color565
from machine import Pin, SPI


def hsv_to_rgb(h, s, v):
    """
    Convert HSV to RGB (based on colorsys.py).
        Args:
            h (float): Hue 0 to 1.
            s (float): Saturation 0 to 1.
            v (float): Value 0 to 1 (Brightness).
    """
    if s == 0.0:
        return v, v, v
    i = int(h * 6.0)
    f = (h * 6.0) - i
    p = v * (1.0 - s)
    q = v * (1.0 - s * f)
    t = v * (1.0 - s * (1.0 - f))
    i = i % 6

    v = int(v * 255)
    t = int(t * 255)
    p = int(p * 255)
    q = int(q * 255)

    if i == 0:
        return v, t, p
    if i == 1:
        return q, v, p
    if i == 2:
        return p, v, t
    if i == 3:
        return p, q, v
    if i == 4:
        return t, p, v
    if i == 5:
        return v, p, q


def test():
    """Test code."""
    # Baud rate of 40000000 seems about the max
    spi=machine.SPI(0, baudrate=40000000, sck=Pin(18), mosi=Pin(19),miso=Pin(16)) # miso pas indisp ?
    display = Display(spi, dc=Pin(20), cs=Pin(17), rst=Pin(21))

    c = 0
    for x in range(0, 240, 20):
        for y in range(0, 320, 20):
            color = color565(*hsv_to_rgb(c / 192, 1, 1))
            display.fill_circle(x + 9, y + 9, 9, color)
            c += 1
    sleep(9)
    display.cleanup()


test()

Où acheter ?