TFT LCD Screen module

OK I seemed to have everything working well for both a little 1.77" ST7735 screen and a 2.4" ILI9341 screen.

See the demo at OpenMv screen - YouTube

I have written hopefully a user friendly driver and it can be found at GitHub - OutOfTheBots/OpenMV_TFT

Feel free to fork and use as you like it is MIT license

I have some nice ideas for making some little PCBs for these screens with some nice features that hopefully OpenMV designers will like and want to use and especially I hope the users of OpenMV cam will like them. Stay tuned :slight_smile:

1 Like

Hello,
I adjusted TFT_demo.py for ILI9341 in the following way:

sensor.set_framesize(sensor.QVGA)
screen = TFT(spi, TFT.ili9341)
screen.set_window(0,0,320,240)

and got the wrong picture of double screens 160 wide and about 80 high
in upper part of the screen [ ][ ].
Correct picture occured only with 0,0,160,120 but only as part of the screen.

I can confirm that the library does not work with the latest firmware version. I had the same problem. I managed to make the screen to work correctly though using the fixed firmware : http://forums.openmv.io/download/file.php?id=536

I have an Openmv H7 and I wanted to use it with a ili9341 240x320 2.8" display without the need of the IDE. The camera works fine when connected to the OpenMV IDE. Nice display good frame rate etc… But when I hook it to the 2.8" display all I get is a small strip of the video. I can see the display is active by waving my hand in front of the camera so I know it’s getting the video feed. it’s just restricted to a small edge of the display. I make the changes in the scripts of “Screen =TFT(spi, TFT.ili9341)” and “screen.set_window(0,0,320,240)” I have read and searched the forums and have tried several different firmware’s suggested but to no avail. I’ve read in the forums where it has been a ongoing problem. Has the issue of the ili9341 interface been corrected for the H7? If so can someone send me in the right direction? Thanks.
OpenMV IDE Info:
Board H7, Sensor OV7725, Frimware: 3.6.0 Port COM3

I don’t believe we support that display. Another user wrote a library for it however if you search the forums for that display.

FYI: Using latest OpenMV IDE and an H7 w/ latest firmware…

I have successfully integrated the Adafruit 2.2" ILI9340C TFT module into my project, using the following TFT driver (referenced in this thread - thanks OutOfTheBots!):

→ GitHub - OutOfTheBots/OpenMV_TFT

First, copy the file “OpenMV_TFT.py” to the USB flash storage of the H7. Then, run the (slightly modified) code below:

#TFT screen demo to steam frame buffer to a external SPI screen

import sensor, image, time
from machine import SPI
from OpenMV_TFT import TFT

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)

clock = time.clock()

spi = SPI(2, baudrate=54000000) #create an SPI bus

#create an instance of the screen driver
#you mustr pass a SPI bus and type of screen (ili9341 or st7735
#optional can pass cs pin and dc pin default is cs='P3' and dc='P9'
screen = TFT(spi, TFT.ili9341)

#set window on screen to write to (x_start, Y_start, width, height)
#the window needs to be inside the resolution of the screen and must match the exact size of fb
screen.set_window(0,0,320,240)


while(True):
    clock.tick()
    img = sensor.snapshot()

    # some image processing code goes here...

    screen.write_to_screen(img) #send the fb to the screen
    print(clock.fps())

Key points: Note DC==9 per the comments. Also BACKLIGHT (LED) & RESET are connected to 3.3v.

Thanks for the library!

I followed the steps as you said and it doesn’t display on the screen, maybe it’s because the latest software is not compatible?

You are correct, there have been changes made that affect how someone writes to an LCD. The new display.SPIDisplay() function should be used to setup a custom LCD. I recently had to make those changes and successfully used it with my ST7789 based display.

The most important point is to now import the display module instead of “lcd”:

import sensor, image, time, display

…and then update the relevant setup code so that the display module is correctly configured, for example:

myLCD=display.SPIDisplay(width=240,height=240,refresh=60,bgr=False,byte_swap=False,triple_buffer=False)

I also had to update the function to write the image to the display:

myLCD.write(img)

I believe those are the most important changes when migrating to the “new way” of interfacing a SPI LCD display.

FYI: There is more detail about my work to implement a custom driver in this thread that I created - however please be aware this references the old “lcd” module…otherwise the content is very useful:

Can no longer drive ST7789V SPI TFT w/ firmware 3.8.0 (works for <= 3.6.7) - OpenMV Products - OpenMV Forums

Very happy to receive your answer, I based it on your code and tried it on TFT9341 screen but without success, you can see the code below:

# Untitled - By: NguyenQuy - Sun Jan 21 2024


import sensor, image, time, display
from pyb import SPI, Pin
from micropython import const
from ustruct import pack

_SWRESET = const(0x01) # Software Reset
_SLPOUT = const(0x11) # Sleep Out
_COLMOD = const(0x3A) # Colour Mode
_DISPON = const(0x29) # Display On
_MADCTL = const(0x36) # Memory Data Access
_CASET = const(0x2A) # Column Address Set
_RASET = const(0x2B) # Row Address set
_RAMWR = const(0x2C) # Write to screen memory
_INVON = const(0x21) # Inversion On

cs = Pin('P3', Pin.OUT)
dc = Pin('P8', Pin.OUT)

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames()

clock = time.clock()

spi = SPI(2, SPI.MASTER, baudrate=54000000)

myLCD=display.SPIDisplay(width=320,height=240,refresh=60,bgr=False,byte_swap=False,triple_buffer=False)


#Note DC is pin 8, CS is pin 3
#  ILI9341

for command, data in (
      (0xef, b'\x03\x80\x02'),
      (0xcf, b'\x00\xc1\x30'),
      (0xed, b'\x64\x03\x12\x81'),
      (0xe8, b'\x85\x00\x78'),
      (0xcb, b'\x39\x2c\x00\x34\x02'),
      (0xf7, b'\x20'),
      (0xea, b'\x00\x00'),
      (0xc0, b'\x23'),  # Power Control 1, VRH[5:0]
      (0xc1, b'\x10'),  # Power Control 2, SAP[2:0], BT[3:0]
      (0xc5, b'\x3e\x28'),  # VCM Control 1
      (0xc7, b'\x86'),  # VCM Control 2
      (0x36, b'\xF8'),  # Memory Access Control
      (0x3a, b'\x55'),  # Pixel Format
      (0xb1, b'\x00\x18'),  # FRMCTR1
      (0xb6, b'\x08\x82\x27'),  # Display Function Control
      (0xf2, b'\x00'),  # 3Gamma Function Disable
      (0x26, b'\x01'),  # Gamma Curve Selected
      (0xe0, b'\x0f\x31\x2b\x0c\x0e\x08\x4e\xf1\x37\x07\x10\x03\x0e\x09\x00'), # Set Gamma
      (0xe1, b'\x00\x0e\x14\x03\x11\x07\x31\xc1\x48\x08\x0f\x0c\x31\x36\x0f')):  # Set Gamma

    dc.value(False) #set data/command pin
    cs.value(0)
    spi.send(bytearray([command]))
    cs.value(1)

    dc.value(True)  #set data/command pin
    cs.value(0)
    spi.send(data)
    cs.value(1)

dc.value(False) #set data/command pin
cs.value(0)
spi.send(bytearray([0x11]))
cs.value(1)

time.sleep(10)

dc.value(False) #set data/command pin
cs.value(0)
spi.send(bytearray([0x29]))
cs.value(1)

dc.value(False) #set data/command pin
cs.value(0)
spi.send(bytearray([_INVON]))#inversion on
cs.value(1)

while(True):
    clock.tick()

    #show camera image on LCD
    myLCD.write(sensor.snapshot())

That is really cool.
I have a bigger screen like that, i ahve a question… are we able to swap out the smaller screen for the bigger one with the same board ?

Per feedback from folks we will add this feature soon:

modules/py_display: Add user SPI LCD register control. by kwagyeman · Pull Request #2068 · openmv/openmv (github.com)

It will allow you to create a display controller class which does register reads/writes to setup the display. This will then make it simple for anyone to use any SPI display they want.

This works for DSI displays already, and will work for SPI displays soon.