Demo Source Code

The Python source code of this demo is provided for reference purposes only.

2.4inch_LCD_demo.py:

#!/usr/bin/python
"""
Please make sure the 2.4inch LCD Moudle is connected to the correct pins.
The following table describes how to connect the 2.4inch LCD Module to the 40-pin header.
-------------------------------------------------
__2.4inch LCD Module___Pin Number_____Pin Name
    VCC                  17           3.3 V Power
    GND                  39             GND
    DIN                  19           SPI MOSI
    CLK                  23           SPI SCLK
    CS                   24           SPI CE0
    DC                   40            GPIO44
    RST                  11            GPIO42
    BL                   18            GPIO51
-------------------------------------------------
"""

import os
import sys
import time
import logging
from PIL import Image

sys.path.append("..")

import VisionFive.boardtype as board_t
from lib import LCD2inch4_lib

"""
Demo modification ans new function description
------------------------------------------------------------
  I.   add the clear() function to fill LCD screen with white
  II.  give a hexadecimal value of white
  III. cycle through multiple pictures
---------------------------------------------------------------
"""

WHITE = 0xFF


def main():
    print("-----------lcd demo-------------")

    # Determining cpu Type: 1 means visionfive1; 2 means visionfive 2
    vf_t = board_t.boardtype()
    if vf_t == 1:
        SPI_DEVICE = "/dev/spidev0.0"
    elif vf_t == 2:
        SPI_DEVICE = "/dev/spidev1.0"
    else:
        print("This module can only be run on a VisionFive board!")
        return 0

    """The initialization settings of 2inch and 2.4inch are distinguished"""
    disp = LCD2inch4_lib.LCD_2inch4(11, 40, SPI_DEVICE)
    # disp.lcd_init()
    disp.lcd_init_2inch4()

    disp.lcd_clear(WHITE)

    if vf_t == 1:
        image = Image.open("./visionfive.bmp")
    elif vf_t == 2:
        image = Image.open("./visionfive2.png")
    else:
        return

    disp.lcd_ShowImage(image, 0, 0)
    time.sleep(2)

    """add the part of displaying pictures circularly"""
    while True:
        try:
            print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))

            """rotate the picture 90 degrees anticlockwise"""
            """to keep consistent with the display direction of other pictures"""
            image = Image.open("./LCD_2inch4_parrot.bmp")
            image = image.transpose(Image.Transpose.ROTATE_90)
            disp.lcd_ShowImage(image, 0, 0)
            time.sleep(0.5)

            image = Image.open("./LCD_2inch.jpg")
            disp.lcd_ShowImage(image, 0, 0)
            time.sleep(0.5)

            if vf_t == 1:
                image = Image.open("./visionfive.bmp")
            elif vf_t == 2:
                image = Image.open("./visionfive2.png")
            else:
                return
            disp.lcd_ShowImage(image, 0, 0)
            time.sleep(0.5)

        except KeyboardInterrupt:
            break

    print("Exit demo!")


if __name__ == 
LCD2inch4_lib.py:
import os
import sys
import time
import logging
import VisionFive.spi as spi
import VisionFive.gpio as gpio
import numpy as np
from PIL import Image, ImageDraw, ImageFont


class LCD_2inch4:
    width = 240
    height = 320

    def __init__(self, rst_pin, dc_pin, dev):
        gpio.setmode(gpio.BOARD)
        
        self.rstpin = rst_pin
        self.dcpin = dc_pin
        self.spidev = dev
        spi.getdev(self.spidev)

        """Reset the maximum clock frequency of communication"""
        """The display speed of the picture is positively correlated with the clock frequency"""
        # spi.setmode(500000, 0, 8)
        spi.setmode(40000000, 0, 8)
        gpio.setup(self.rstpin, gpio.OUT)
        gpio.setup(self.dcpin, gpio.OUT)

    def __del__(self):
        spi.freedev()

    """add a short delay for each change of electrical level"""

    def lcd_reset(self):
        gpio.output(self.rstpin, gpio.HIGH)
        time.sleep(0.01)
        gpio.output(self.rstpin, gpio.LOW)
        time.sleep(0.01)
        gpio.output(self.rstpin, gpio.HIGH)
        time.sleep(0.01)

    def lcd_spisend(self, data):
        spi.transfer(data)

    def lcd_sendcmd(self, cmd):
        gpio.output(self.dcpin, gpio.LOW)
        spi.transfer(cmd)

    def lcd_senddata(self, data):
        gpio.output(self.dcpin, gpio.HIGH)
        spi.transfer(data)

    """write multiple bytes"""

    def lcd_sendnbytes(self, data):
        gpio.output(self.dcpin, gpio.HIGH)
        spi.write(data)

    """common registers' initialization of 2.4inch LCD module"""

    def lcd_init_2inch4(self):
        self.lcd_reset()

        self.lcd_sendcmd(0x11)  # sleep out

        self.lcd_sendcmd(0xCF)  # Ppower Control B
        self.lcd_senddata(0x00)
        self.lcd_senddata(0xC1)
        self.lcd_senddata(0x30)

        self.lcd_sendcmd(0xED)  # Power on sequence control
        self.lcd_senddata(0x64)
        self.lcd_senddata(0x03)
        self.lcd_senddata(0x12)
        self.lcd_senddata(0x81)

        self.lcd_sendcmd(0xE8)  # Driver Timing Control A
        self.lcd_senddata(0x85)
        self.lcd_senddata(0x00)
        self.lcd_senddata(0x79)

        self.lcd_sendcmd(0xCB)  # Power Control A
        self.lcd_senddata(0x39)
        self.lcd_senddata(0x2C)
        self.lcd_senddata(0x00)
        self.lcd_senddata(0x34)
        self.lcd_senddata(0x02)

        self.lcd_sendcmd(0xF7)  # Pump ratio control
        self.lcd_senddata(0x20)

        self.lcd_sendcmd(0xEA)  # Driver Timing Control B
        self.lcd_senddata(0x00)
        self.lcd_senddata(0x00)

        self.lcd_sendcmd(0xC0)  # Power Control 1
        self.lcd_senddata(0x1D)  # VRH[5:0]

        self.lcd_sendcmd(0xC1)  # Power Control 2
        self.lcd_senddata(0x12)  # SAP[2:0],BT[3:0]

        self.lcd_sendcmd(0xC5)  # VCOM Control 1
        self.lcd_senddata(0x33)
        self.lcd_senddata(0x3F)

        self.lcd_sendcmd(0xC7)  # VCOM Control 2
        self.lcd_senddata(0x92)

        self.lcd_sendcmd(0x3A)  # COLMOD:Pixel Format Set
        self.lcd_senddata(0x55)

        self.lcd_sendcmd(0x36)  # Memory Access Control
        self.lcd_senddata(0x08)

        self.lcd_sendcmd(0xB1)  # Frame Rate Control(In Normal Mode/Full Colors)
        self.lcd_senddata(0x00)
        self.lcd_senddata(0x12)

        self.lcd_sendcmd(0xB6)  # Display Function Control
        self.lcd_senddata(0x0A)
        self.lcd_senddata(0xA2)

        self.lcd_sendcmd(0x44)  # Set_Tear_Scanline
        self.lcd_senddata(0x02)

        self.lcd_sendcmd(0xF2)  # 3Gamma Function Disable
        self.lcd_senddata(0x00)

        self.lcd_sendcmd(0x26)  # Gamma curve selected
        self.lcd_senddata(0x01)

        self.lcd_sendcmd(0xE0)  # Set Gamma
        self.lcd_senddata(0x0F)
        self.lcd_senddata(0x22)
        self.lcd_senddata(0x1C)
        self.lcd_senddata(0x1B)
        self.lcd_senddata(0x08)
        self.lcd_senddata(0x0F)
        self.lcd_senddata(0x48)
        self.lcd_senddata(0xB8)
        self.lcd_senddata(0x34)
        self.lcd_senddata(0x05)
        self.lcd_senddata(0x0C)
        self.lcd_senddata(0x09)
        self.lcd_senddata(0x0F)
        self.lcd_senddata(0x07)
        self.lcd_senddata(0x00)

        self.lcd_sendcmd(0xE1)  # Set Gamma
        self.lcd_senddata(0x00)
        self.lcd_senddata(0x23)
        self.lcd_senddata(0x24)
        self.lcd_senddata(0x07)
        self.lcd_senddata(0x10)
        self.lcd_senddata(0x07)
        self.lcd_senddata(0x38)
        self.lcd_senddata(0x47)
        self.lcd_senddata(0x4B)
        self.lcd_senddata(0x0A)
        self.lcd_senddata(0x13)
        self.lcd_senddata(0x06)
        self.lcd_senddata(0x30)
        self.lcd_senddata(0x38)
        self.lcd_senddata(0x0F)
        self.lcd_sendcmd(0x29)  # Display on

    def lcd_setPos(self, Xstart, Ystart, Xend, Yend):
        self.lcd_sendcmd(0x2A)
        self.lcd_senddata(Xstart >> 8)
        self.lcd_senddata(Xstart & 0xFF)
        self.lcd_senddata((Xend - 1) >> 8)
        self.lcd_senddata((Xend - 1) & 0xFF)
        self.lcd_sendcmd(0x2B)
        self.lcd_senddata(Ystart >> 8)
        self.lcd_senddata(Ystart & 0xFF)
        self.lcd_senddata((Yend - 1) >> 8)
        self.lcd_senddata((Yend - 1) & 0xFF)
        self.lcd_sendcmd(0x2C)

    def lcd_clear(self, color):
        """Clear contents of image buffer"""

        _buffer = [color] * (self.width * self.height * 2)

        self.lcd_setPos(0, 0, self.width, self.height)
        gpio.output(self.dcpin, gpio.HIGH)

        """modify the original single byte write to multi byte write"""
        # for i in range(0,len(_buffer)):
        #    self.lcd_spisend(_buffer[i])
        self.lcd_sendnbytes(_buffer)

    def lcd_ShowImage(self, Image, Xstart, Ystart):
        """Set buffer to value of Python Imaging Library image."""
        """Write display buffer to physical display"""
        imwidth, imheight = Image.size

        if imwidth == self.height and imheight == self.width:
            img = np.asarray(Image)
            pix = np.zeros((self.width, self.height, 2), dtype=np.uint8)
            # RGB888 >> RGB565
            pix[..., [0]] = np.add(
                np.bitwise_and(img[..., [0]], 0xF8), np.right_shift(img[..., [1]], 5)
            )
            pix[..., [1]] = np.add(
                np.bitwise_and(np.left_shift(img[..., [1]], 3), 0xE0),
                np.right_shift(img[..., [2]], 3),
            )
            pix = pix.flatten().tolist()

            self.lcd_sendcmd(
                0x36
            )  # define read/write scanning direction of frame memory
            self.lcd_senddata(0x78)
            self.lcd_setPos(0, 0, self.height, self.width)

            gpio.output(self.dcpin, gpio.HIGH)

            """modify the original single byte write to multi byte write"""
            # for i in range(0,len(pix),1):
            #   self.lcd_spisend(pix[i])
            self.lcd_sendnbytes(pix)
        else:
            img = np.asarray(Image)
            pix = np.zeros((imheight, imwidth, 2), dtype=np.uint8)

            pix[..., [0]] = np.add(
                np.bitwise_and(img[..., [0]], 0xF8), np.right_shift(img[..., [1]], 5)
            )
            pix[..., [1]] = np.add(
                np.bitwise_and(np.left_shift(img[..., [1]], 3), 0xE0),
                np.right_shift(img[..., [2]], 3),
            )

            pix = pix.flatten().tolist()

            self.lcd_sendcmd(0x36)
            self.lcd_senddata(0x08)
            self.lcd_setPos(0, 0, self.width, self.height)

            gpio.output(self.dcpin, gpio.HIGH)

            """modify the original single byte write to multi byte write"""
            # for i in range(0,len(pix)):
            #    self.lcd_spisend(pix[i])
            self.lcd_sendnbytes(pix)