CircuitPython Exercise: Touch buttons on ILI9341 SPI LCD with FT6336 Cap. Touch

My former post show ESP32-S3/CircuitPython exercises for Capacitive Touch Screen, to display on 3.2" 320x240 IPS LCD (ILI9341 SPI) and read capacitive touch (FT6336).

This post I list further exercises to implement a useful Touch Button on the Capacitive Touch Screen, using Adafruit Display_Button Library.


For the connection, read the former post.

Remark for using irq_pin in Adafruit_FocalTouch (CircuitPython driver for common low-cost FocalTech capacitive touch chips. Currently supports FT6206 & FT6236):

In case you create Adafruit_FocalTouch object using a Bus I2C port and using an interrupt pin (IRQ) like below:

ft = adafruit_focaltouch.Adafruit_FocalTouch(i2c, debug=False, irq_pin=irq)

The interrupt pin (irq_pin) is used to prevent read errors from the FocalTouch chip.

In my test with irq_pin=touch_irq, reading ft.touched will not return if not touched; such that the program will be blocked untill touched. As shown in the video.

You can check it in adafruit_focaltouch.py source code here:
https://github.com/adafruit/Adafruit_CircuitPython_FocalTouch/blob/main/adafruit_focaltouch.py


Exercise Code:

cpyS3_ili9341_FT6336_single_TouchButtons_270.py
"""
CircuitPython exercise run on ESP32-S3,
with ILI9341 SPI LCD + FT6336 cap. touch.

To display and detech single touch buttons.
(adafruit_cursorcontrol is used to display the touch point for info only,
not necessory for touch button.)

---------------------------

Display Module:
3.2 inch IPS SPI Module ILI9341 with cap. touch FT6336U

Test on:
dev. board:     Espressif ESP32-S3-DevKitC-1
CircuitPython:  9.0.5

Libraries needed:
- adafruit_ili9341.mpy
- adafruit_focaltouch.mpy
- adafruit_display_text folder
- adafruit_button folder
- adafruit_cursorcontrol folder

- adafruit_display_shapes folder
  (It's needed by adafruit_button, so you have to load in /lib folder.)
  
* with rotation=270, touch x/y no adjustment needed.
"""
import os, sys
import board
import busio
import terminalio
import displayio
import fourwire
from adafruit_display_text import label
import adafruit_ili9341
import bitmaptools

from digitalio import DigitalInOut, Direction
import adafruit_focaltouch
import adafruit_cursorcontrol.cursorcontrol

from adafruit_button import Button

import time

ILI9341_INVOFF = 0x20   #Display Inversion OFF
ILI9341_INVON  = 0x21   #Display Inversion ON

# Release any resources currently in use for the displays
displayio.release_displays()

#===init display ======================
#Connection to ILI9341/SD
DISP_CS  = board.IO17
DISP_RES = board.IO16
DISP_DC  = board.IO15
SPI_MOSI = board.IO7
SPI_SCL  = board.IO6
DISP_BL  = board.IO5
SPI_MISO = board.IO4
SD_CS    = board.IO43

#Connection to FT6336U
TOUCH_SCL = board.IO42
TOUCH_SDA = board.IO1
TOUCH_INT = board.IO44
TOUCH_RST = board.IO2

touch_irq = DigitalInOut(TOUCH_INT)
touch_irq.direction = Direction.INPUT

touch_res = DigitalInOut(TOUCH_RST)
touch_res.direction = Direction.OUTPUT
touch_res.value = True
time.sleep(0.1)
touch_res.value = False
time.sleep(0.1)
touch_res.value = True
time.sleep(0.5)

spi = busio.SPI(clock=SPI_SCL,
                MOSI=SPI_MOSI,
                MISO=SPI_MISO)

#On CircuitPython 9  FourWire moved from displayio to fourwire
display_bus = fourwire.FourWire(spi, command=DISP_DC, chip_select=DISP_CS, reset=DISP_RES)

touch_i2c = busio.I2C(TOUCH_SCL, TOUCH_SDA)


#In my test with irq_pin=touch_irq,
#reading ft.touched (in Main Loop) will not return if not touched;
#such that the Main Loop blocked, and the text not scrolled.
ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False)
#ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False, irq_pin=touch_irq)

#--- Setup display, rotated 270 ---
# for 3.2" 320x240 SPI ILI9341 TFT
disp_width = 240
disp_height = 320
display = adafruit_ili9341.ILI9341(display_bus,
                                   width=disp_width,
                                   height=disp_height,
                                   backlight_pin=DISP_BL,
                                   rotation=270
                                   )

display_bus.send(int(ILI9341_INVON), "") #invert color

sysinfo = sys.implementation[0] + " " + os.uname()[3] + "\nrun on " + os.uname()[4]
drv_info = adafruit_ili9341.__name__ + " " + adafruit_ili9341.__version__ +"\n" \
           + adafruit_focaltouch.__name__ + " " + adafruit_focaltouch.__version__
print("========================================")
print("coXXect.blogspot.com")
print("----------------------------------------")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("========================================")
print(drv_info)
time.sleep(2)
# Make the display context
bgGroup = displayio.Group()

display.root_group = bgGroup

bg_bitmap = displayio.Bitmap(display.width, display.height, 2)
bg_palette = displayio.Palette(2)
bg_palette[0] = 0x000000 # Black
bg_palette[1] = 0xFFFFFF # White
bg_sprite = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette, x=0, y=0)
bgGroup.append(bg_sprite)

# Draw label
text_group = displayio.Group(scale=2, x=10, y=120)
text = "coXXect.blogspot.com"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF)
text_group.append(text_area)  # Subgroup for text scaling
bgGroup.append(text_group)

info_group = displayio.Group(scale=1, x=10, y=180)
info_label = label.Label(terminalio.FONT,
                         text=sysinfo + "\n" + drv_info,
                         color=0xFFFFFF)
info_group.append(info_label)  # Subgroup for text scaling
bgGroup.append(info_group)

time.sleep(2)

bgGroup.remove(text_group)

# X_text/y_text are used to display touch position,
# for info only.
x_group = displayio.Group(scale=2, x=10, y=20)
x_text = "---"
x_area = label.Label(terminalio.FONT, text=x_text, color=0xFFFFFF)
x_group.append(x_area)
bgGroup.append(x_group)
y_group = displayio.Group(scale=2, x=10, y=40)
y_text = "---"
y_area = label.Label(terminalio.FONT, text=y_text, color=0xFFFFFF)
y_group.append(y_area)
bgGroup.append(y_group)

# Prepare touch button
BUT_FILL_SELECTED = 0x505050
BUT_FILL_UNSELECTED = 0x202020
 
# Main User Interface Buttons
button_view = Button(
    x=40,
    y=60,
    width=display.width-(40*2),
    height=50,
    label="Touch Button",
    label_font=terminalio.FONT,
    label_color=0xFF0000,
    fill_color=BUT_FILL_UNSELECTED,
    outline_color=0x767676,
    selected_fill=0x1A1A1A,
    selected_outline=0x2E2E2E,
    selected_label=0x525252,
)

bgGroup.append(button_view)

#--- End of prepare buttons ---

# Prepare cursor, just to display the touch position for info only.
# Draw labels to display touch x/y
# initialize the mouse cursor object
# place over all others
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=bgGroup)
mouse_cursor.x = int(display.width/2)
mouse_cursor.y = int(display.height/2)

running_symbols = ['-', '\\', '|', '/']
running_symbol_idx = 0

# Main Loop
while True:
    # if the screen is being touched print the touches
    if ft.touched:
        touches = ft.touches
        
        #sometimes ft.touches is [], empty!
        #so I check len to prevent IndexError: index out of range
        if len(touches)>0:
            #print(touches)
            x = touches[0]['x']
            y = touches[0]['y']
            
            #with rotation=270, touch x/y no adjustment needed.
            mouse_cursor.x = x
            mouse_cursor.y = y

            x_area.text = str(x)
            y_area.text = str(y)

            touch = [mouse_cursor.x, mouse_cursor.y]
            if button_view.contains(touch):
                print("Button touched")
                button_view.fill_color = BUT_FILL_SELECTED 
            else:
                print("NO Button touched")
                button_view.fill_color = BUT_FILL_UNSELECTED

        else:
            print('no touch')

    # print a running symbol on REPL Shell without new-line,
    # to check if it's in:
    # running : no irq_pin parameter passed in creating Adafruit_FocalTouch
    # blocked : with irq_pin=touch_irq in creating Adafruit_FocalTouch
    running_sym = running_symbols[running_symbol_idx]
    print(running_sym, end="\r")
    running_symbol_idx = running_symbol_idx + 1
    if running_symbol_idx == len(running_symbols):
        running_symbol_idx = 0
    
    time.sleep(0.05)


print("~ bye ~")


cpyS3_ili9341_FT6336_grouped_TouchButtons_scrollingText.py
"""
CircuitPython exercise run on ESP32-S3,
with ILI9341 SPI LCD + FT6336 cap. touch.

To handle grouped touch buttons.
(adafruit_cursorcontrol is used to display the touch point for info only,
not necessory for touch button.)

---------------------------

Display Module:
3.2 inch IPS SPI Module ILI9341 with cap. touch FT6336U

Test on:
dev. board:     Espressif ESP32-S3-DevKitC-1
CircuitPython:  9.0.5

Libraries needed:
- adafruit_ili9341.mpy
- adafruit_focaltouch.mpy
- adafruit_display_text folder
- adafruit_button folder
- adafruit_cursorcontrol folder

- adafruit_display_shapes folder
  (It's needed by adafruit_button, so you have to load in /lib folder.)
"""
import os, sys
import board
import busio
import terminalio
import displayio
import fourwire
from adafruit_display_text import label
import adafruit_ili9341
import bitmaptools

from digitalio import DigitalInOut, Direction
import adafruit_focaltouch
import adafruit_cursorcontrol.cursorcontrol

from adafruit_button import Button

import time

ILI9341_INVOFF = 0x20   #Display Inversion OFF
ILI9341_INVON  = 0x21   #Display Inversion ON

# Release any resources currently in use for the displays
displayio.release_displays()

#===init display ======================
#Connection to ILI9341/SD
DISP_CS  = board.IO17
DISP_RES = board.IO16
DISP_DC  = board.IO15
SPI_MOSI = board.IO7
SPI_SCL  = board.IO6
DISP_BL  = board.IO5
SPI_MISO = board.IO4
SD_CS    = board.IO43

#Connection to FT6336U
TOUCH_SCL = board.IO42
TOUCH_SDA = board.IO1
TOUCH_INT = board.IO44
TOUCH_RST = board.IO2

touch_irq = DigitalInOut(TOUCH_INT)
touch_irq.direction = Direction.INPUT

touch_res = DigitalInOut(TOUCH_RST)
touch_res.direction = Direction.OUTPUT
touch_res.value = True
time.sleep(0.1)
touch_res.value = False
time.sleep(0.1)
touch_res.value = True
time.sleep(0.5)

spi = busio.SPI(clock=SPI_SCL,
                MOSI=SPI_MOSI,
                MISO=SPI_MISO)

#On CircuitPython 9  FourWire moved from displayio to fourwire
display_bus = fourwire.FourWire(spi, command=DISP_DC, chip_select=DISP_CS, reset=DISP_RES)

touch_i2c = busio.I2C(TOUCH_SCL, TOUCH_SDA)

ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False)
#In my test with irq_pin=touch_irq,
#reading ft.touched (in Main Loop) will not return if not touched;
#such that the Main Loop blocked, and the text not scrolled.
#ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False, irq_pin=touch_irq)

#--- Setup display ---
# for 3.2" 320x240 SPI ILI9341 TFT
disp_width = 320
disp_height = 240
display = adafruit_ili9341.ILI9341(display_bus,
                                   width=disp_width,
                                   height=disp_height,
                                   backlight_pin=DISP_BL,
                                   )

display_bus.send(int(ILI9341_INVON), "") #invert color

sysinfo = sys.implementation[0] + " " + os.uname()[3] + "\nrun on " + os.uname()[4]
drv_info = adafruit_ili9341.__name__ + " " + adafruit_ili9341.__version__ +"\n" \
           + adafruit_focaltouch.__name__ + " " + adafruit_focaltouch.__version__
print("=============================================")
print("coXXect.blogspot.com")
print("---------------------------------------------")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("=============================================")
print(drv_info)
time.sleep(2)
# Make the display context
bgGroup = displayio.Group()

display.root_group = bgGroup

bg_bitmap = displayio.Bitmap(display.width, display.height, 2)
bg_palette = displayio.Palette(2)
bg_palette[0] = 0x000000 # Black
bg_palette[1] = 0xFFFFFF # White
bg_sprite = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette, x=0, y=0)
bgGroup.append(bg_sprite)

# Draw label
text_group = displayio.Group(scale=2, x=10, y=120)
text = "coXXect.blogspot.com"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF)
text_group.append(text_area)  # Subgroup for text scaling
bgGroup.append(text_group)

info_group = displayio.Group(scale=1, x=10, y=180)
info_label = label.Label(terminalio.FONT,
                         text=sysinfo + "\n" + drv_info,
                         color=0xFFFFFF)
info_group.append(info_label)  # Subgroup for text scaling
bgGroup.append(info_group)

time.sleep(2)

bgGroup.remove(text_group)

# X_text/y_text are used to display touch position,
# for info only.
x_group = displayio.Group(scale=2, x=10, y=20)
x_text = "---"
x_area = label.Label(terminalio.FONT, text=x_text, color=0xFFFFFF)
x_group.append(x_area)
bgGroup.append(x_group)
y_group = displayio.Group(scale=2, x=10, y=40)
y_text = "---"
y_area = label.Label(terminalio.FONT, text=y_text, color=0xFFFFFF)
y_group.append(y_area)
bgGroup.append(y_group)

# Prepare button group of three touch buttons
BUTTON_Y = 100
BUTTON_HEIGHT = 40
BUTTON_WIDTH = int(display.width / 3)
BUTTON_GAP = 10
BUT_FILL_SELECTED = 0x505050
BUT_FILL_UNSELECTED = 0x202020

# This group will make it easy for us to read a button press later.
buttons = []
 
# Main User Interface Buttons
button_view1 = Button(
    x=0+BUTTON_GAP,  # Start at furthest left
    y=BUTTON_Y,  # Start at top
    width=BUTTON_WIDTH-(BUTTON_GAP*2),  # Calculated width
    height=BUTTON_HEIGHT,  # Static height
    label="View 1",
    label_font=terminalio.FONT,
    label_color=0xFF0000,
    fill_color=BUT_FILL_UNSELECTED,
    outline_color=0x767676,
    selected_fill=0x1A1A1A,
    selected_outline=0x2E2E2E,
    selected_label=0x525252,
    style = Button.SHADOWRECT,
)
buttons.append(button_view1)  # adding this button to the buttons group

button_view2 = Button(
    x=BUTTON_WIDTH+BUTTON_GAP,  # Start after width of a button
    y=BUTTON_Y,
    width=BUTTON_WIDTH-(BUTTON_GAP*2),
    height=BUTTON_HEIGHT,
    label="View 2",
    label_font=terminalio.FONT,
    label_color=0x00FF00,
    fill_color=BUT_FILL_UNSELECTED,
    outline_color=0x767676,
    selected_fill=0x1A1A1A,
    selected_outline=0x2E2E2E,
    selected_label=0x525252,
    style = Button.ROUNDRECT,
)
buttons.append(button_view2)  # adding this button to the buttons group

button_view3 = Button(
    x=BUTTON_WIDTH * 2 +BUTTON_GAP,  # Start after width of 2 buttons
    y=BUTTON_Y,
    width=BUTTON_WIDTH-(BUTTON_GAP*2),
    height=BUTTON_HEIGHT,
    label="View 3",
    label_font=terminalio.FONT,
    label_color=0x0000FF,
    fill_color=BUT_FILL_UNSELECTED,
    outline_color=0x767676,
    selected_fill=0x1A1A1A,
    selected_outline=0x2E2E2E,
    selected_label=0x525252,
    style = Button.SHADOWROUNDRECT,
)
buttons.append(button_view3)  # adding this button to the buttons group


# Add all of the main buttons to the splash Group
for b in buttons:
    bgGroup.append(b)

#--- End of prepare buttons ---

# Prepare cursor, just to display the touch position for info only.
# Draw labels to display touch x/y
# initialize the mouse cursor object
# place over all others
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=bgGroup)
mouse_cursor.x = int(display.width/2)
mouse_cursor.y = int(display.height/2)

# scrolling text
# ref:
# https://learn.adafruit.com/rgb-led-matrices-matrix-panels-with-circuitpython/example-simple-two-line-text-scroller
def scroll(line):
    line.x = line.x - 1
    line_width = line.bounding_box[2]
    if line.x < -line_width:
        line.x = display.width
        
def reverse_scroll(line):
    line.x = line.x + 1
    line_width = line.bounding_box[2]
    if line.x >= display.width:
        line.x = -line_width

# Main Loop
while True:
    # if the screen is being touched print the touches
    if ft.touched:
        touches = ft.touches
        
        #sometimes ft.touches is [], empty!
        #so I check len to prevent IndexError: index out of range
        if len(touches)>0:
            #print(touches)
            x = touches[0]['x']
            y = touches[0]['y']

            #with rotation=0, have to adjust touch x/y to project on screen.
            mouse_cursor.x = y
            mouse_cursor.y = display.height-x
            x_area.text = str(x)
            y_area.text = str(y)

            touch = [mouse_cursor.x, mouse_cursor.y]
            button_pressed = False
            for i, b in enumerate(buttons):
                if b.contains(touch):
                    print("["+str(i)+"]:", b.label, "pressed.")
                    b.fill_color = BUT_FILL_SELECTED
                    info_label.color = b.label_color
                    button_pressed = True
                else:
                    b.fill_color = BUT_FILL_UNSELECTED
            
            if not button_pressed:
                info_label.color = 0xFFFF00
                print("No Button pressed")

        else:
            print('no touch')


    scroll(info_label)
    display.refresh(minimum_frames_per_second=0)


print("~ bye ~")





More exercise:
It's prepared for next exercise: CircuitPython ESP-NOW: Remote control on-board RGB LED via wireless, between ESP32-S3.



cpyS3_ili9341_FT6336_grouped_color_TouchButtons.py
"""
CircuitPython exercise run on ESP32-S3,
with ILI9341 SPI LCD + FT6336 cap. touch.

To handle grouped color touch buttons.

---------------------------

Display Module:
3.2 inch IPS SPI Module ILI9341 with cap. touch FT6336U

Test on:
dev. board:     Espressif ESP32-S3-DevKitC-1
CircuitPython:  9.0.5

Libraries needed:
- adafruit_ili9341.mpy
- adafruit_focaltouch.mpy
- adafruit_display_text folder
- adafruit_button folder
- adafruit_cursorcontrol folder

- adafruit_display_shapes folder
  (It's needed by adafruit_button, so you have to load in /lib folder.)
"""
import os, sys
import board
import busio
import terminalio
import displayio
import fourwire
from adafruit_display_text import label
import adafruit_ili9341
import bitmaptools

from digitalio import DigitalInOut, Direction
import adafruit_focaltouch
import adafruit_cursorcontrol.cursorcontrol

from adafruit_button import Button

import time

ILI9341_INVOFF = 0x20   #Display Inversion OFF
ILI9341_INVON  = 0x21   #Display Inversion ON

# Release any resources currently in use for the displays
displayio.release_displays()

#===init display ======================
#Connection to ILI9341/SD
DISP_CS  = board.IO17
DISP_RES = board.IO16
DISP_DC  = board.IO15
SPI_MOSI = board.IO7
SPI_SCL  = board.IO6
DISP_BL  = board.IO5
SPI_MISO = board.IO4
SD_CS    = board.IO43

#Connection to FT6336U
TOUCH_SCL = board.IO42
TOUCH_SDA = board.IO1
TOUCH_INT = board.IO44
TOUCH_RST = board.IO2

touch_irq = DigitalInOut(TOUCH_INT)
touch_irq.direction = Direction.INPUT

touch_res = DigitalInOut(TOUCH_RST)
touch_res.direction = Direction.OUTPUT
touch_res.value = True
time.sleep(0.1)
touch_res.value = False
time.sleep(0.1)
touch_res.value = True
time.sleep(0.5)

spi = busio.SPI(clock=SPI_SCL,
                MOSI=SPI_MOSI,
                MISO=SPI_MISO)

#On CircuitPython 9  FourWire moved from displayio to fourwire
display_bus = fourwire.FourWire(spi, command=DISP_DC, chip_select=DISP_CS, reset=DISP_RES)

touch_i2c = busio.I2C(TOUCH_SCL, TOUCH_SDA)

#ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False)
#In my test with irq_pin=touch_irq,
#reading ft.touched (in Main Loop) will not return if not touched;
#such that the Main Loop blocked, and the text not scrolled.
ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False, irq_pin=touch_irq)

#--- Setup display ---
# for 3.2" 320x240 SPI ILI9341 TFT
disp_width = 320
disp_height = 240
display = adafruit_ili9341.ILI9341(display_bus,
                                   width=disp_width,
                                   height=disp_height,
                                   backlight_pin=DISP_BL,
                                   )

display_bus.send(int(ILI9341_INVON), "") #invert color

sysinfo = sys.implementation[0] + " " + os.uname()[3] + "\nrun on " + os.uname()[4]
drv_info = adafruit_ili9341.__name__ + " " + adafruit_ili9341.__version__ +"\n" \
           + adafruit_focaltouch.__name__ + " " + adafruit_focaltouch.__version__
print("=============================================")
print("coXXect.blogspot.com")
print("---------------------------------------------")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("=============================================")
print(drv_info)
time.sleep(1)
# Make the display context
bgGroup = displayio.Group()

display.root_group = bgGroup

bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = 0x000000 # Black
bg_sprite = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette, x=0, y=0)
bgGroup.append(bg_sprite)

# Draw label
text_group = displayio.Group(scale=2, x=10, y=120)
text = "coXXect.blogspot.com"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF)
text_group.append(text_area)  # Subgroup for text scaling
bgGroup.append(text_group)

info_group = displayio.Group(scale=1, x=10, y=180)
info_label = label.Label(terminalio.FONT,
                         text=sysinfo + "\n" + drv_info,
                         color=0xFFFFFF)
info_group.append(info_label)  # Subgroup for text scaling
bgGroup.append(info_group)

time.sleep(1)

bgGroup.remove(text_group)
bgGroup.remove(info_group)

# Create color buttons panel ---
PANEL_WIDTH = 300
PANEL_HEIGHT = 200
PANEL_OFFSET_X = int((display.width - PANEL_WIDTH)/2)
PANEL_OFFSET_Y = 10

panel_bitmap = displayio.Bitmap(PANEL_WIDTH, PANEL_HEIGHT, 1)
panel_palette = displayio.Palette(1)
panel_palette[0] = 0x808080
panel_sprite = displayio.TileGrid(panel_bitmap, pixel_shader=panel_palette, x=PANEL_OFFSET_X, y=PANEL_OFFSET_Y)
bgGroup.append(panel_sprite)

# max len = num_of_roW * num_of_col
color_set= [ 0x000000, 0xFF0000, 0x00FF00, 0x0000FF, 
             0x808080, 0x800000, 0x008000, 0x000080,
             0xA0A0A0, 0x008080, 0x800080, 0x808000,
             0xFFFFFF, 0x00FFFF, 0xFF00FF, 0xFFFF00,
             ]

num_of_row = 4
num_of_col = 4
row_width = int(PANEL_WIDTH/num_of_row)
col_height = int(PANEL_HEIGHT/num_of_col)
btn_gap_x = 5
btn_gap_y = 3
btn_width = row_width - (2 * btn_gap_x)
btn_height = col_height - (2 * btn_gap_y)

col_btn = []

r = 0
c = 0

for i in range(len(color_set)):
    btn = Button(x= r * row_width + btn_gap_x + PANEL_OFFSET_X,
                 y= c * col_height + btn_gap_y + PANEL_OFFSET_Y,
                 width=btn_width,
                 height=btn_height,
                 fill_color=color_set[i],
                 outline_color=0x000000,
                 )
    col_btn.append(btn)
    bgGroup.append(col_btn[i])
    r = r + 1
    if r == num_of_row:
        r = 0
        c = c + 1

#--- End of Create color buttons panel ---

# Prepare cursor, just to display the touch position for info only.
# initialize the mouse cursor object
# place over all others
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
    display, display_group=bgGroup)
mouse_cursor.x = int(display.width/2)
mouse_cursor.y = int(display.height/2)

running_symbols = ['-', '\\', '|', '/']
running_symbol_idx = 0

# Main Loop
while True:
    # if the screen is being touched print the touches
    if ft.touched:
        touches = ft.touches
        
        #sometimes ft.touches is [], empty!
        #so I check len to prevent IndexError: index out of range
        if len(touches)>0:
            #print(touches)
            x = touches[0]['x']
            y = touches[0]['y']

            #with rotation=0, have to adjust touch x/y to project on screen.
            mouse_cursor.x = y
            mouse_cursor.y = display.height-x

            touch = [mouse_cursor.x, mouse_cursor.y]
            button_pressed = False
            for i, b in enumerate(col_btn):
                if b.contains(touch):
                    bg_palette[0] = b.fill_color
                    print("["+str(i)+"]:",  f'{b.fill_color:0>6X}')
                    button_pressed = True
            
            if not button_pressed:
                print("pressed outside buttons")

        else:
            print('no touch')
            
    # print a running symbol on REPL Shell without new-line,
    # to check if it's in:
    # running : no irq_pin parameter passed in creating Adafruit_FocalTouch
    # blocked : with irq_pin=touch_irq in creating Adafruit_FocalTouch
    running_sym = running_symbols[running_symbol_idx]
    print(running_sym, end="\r")
    running_symbol_idx = running_symbol_idx + 1
    if running_symbol_idx == len(running_symbols):
        running_symbol_idx = 0

    time.sleep(0.05)

print("~ bye ~")




Comments

Popular posts from this blog

480x320 TFT/ILI9488 SPI wih EP32C3 (arduino-esp32) using Arduino_GFX Library

MicroPython/ESP32-C3 + 1.8" 128x160 TFT ST7735 SPI, using boochow/MicroPython-ST7735 library.