03-Machine-3-display_and_touch.py K230外接液晶显示屏与电容触摸屏功能演示

display_and_touch.py 为K230外接液晶显示屏与电容触摸屏功能演示程序,实现的效果为在屏幕上随机位置绘制"Hello World!,你好世界!!!"字符串,同时响应触摸事件,在触摸点绘制红色十字。

K230 支持 电容屏电阻屏 的触摸输入,提供了基于 RT-Smart 封装的 TOUCH 类接口。可使用它读取触点坐标、事件类型等信息,广泛应用于 HMI、交互终端等场景。01Studio配套的mipi LCD分无触摸版本和带触摸版本,带触摸版本配的是电容触摸,支持单点和多点触控,使用时直接调用即可。

基本的使用方式如下:

python 复制代码
from machine import TOUCH

# 实例化触摸设备 0
tp = TOUCH(0)

# 可选:启用坐标旋转(旋转 90 度),适配屏幕方向
# tp = TOUCH(0, 1)

# 读取当前触摸点数据
p = tp.read()

# 输出完整的触摸数据结构
print(p)

# 如有触摸点,可访问第一个触点的坐标与事件类型
# print(p[0].x)       # X 坐标
# print(p[0].y)       # Y 坐标
# print(p[0].event)   # 事件类型(如 Touch Down、Move、Up)

接口说明

接口名 说明
TOUCH(id) 创建触摸屏实例,id=0 表示设备号
TOUCH(id, rotate) 实例化并启用屏幕坐标旋转,rotate=1 代表旋转 90 度
read() 返回当前触摸点信息,通常是一个列表结构

示例详解

1. 实例化设备

复制代码
tp = TOUCH(0)

创建 TOUCH 设备对象,表示使用触摸通道 0。

可选参数 TOUCH(0, 1) 用于对坐标做旋转,适用于竖屏方向的设备。

2. 读取触摸数据

复制代码
p = tp.read()
print(p)

返回的 p 通常是一个包含多个触点对象的列表。每个对象包含:

  • x: X 坐标

  • y: Y 坐标

  • event: 触摸事件(如 Touch Down、Move、Touch Up)

3. 示例输出参考

复制代码
[<TouchPoint x=120 y=65 event=0>]

如果有多个触点,例如支持多指操作:

复制代码
[<TouchPoint x=120 y=65 event=0>, <TouchPoint x=250 y=130 event=0>]

应用场景

场景 示例
图形界面交互 基于触摸点驱动按钮点击、滑动切换
自定义手势识别 多点滑动、旋转等操作识别
简单绘图板或签名板 基于触点轨迹做线条绘制

常见问题

Q:没有读取到触摸点,返回是空列表? A:此时说明屏幕未被触摸。tp.read() 只在屏幕被按下时返回触点。

Q:如何处理多点触控? A:读取到的是一个包含多个 TouchPoint 的列表,使用 for 循环逐个读取即可。

Q:是否支持旋转坐标系? A:支持,通过第二个参数 TOUCH(0, 1) 可开启坐标旋转(90 度顺时针)。

显示接口API 介绍

01studio k230 canMV开发板上外接的是01官方提供的ST7701显示驱动器的3.5寸液晶显示屏。

init

描述

初始化 Display 通路,包括 VO 模块、 DSI 模块和 LCD/HDMI。
必须在 MediaManager.init()之前调用

语法

复制代码
init(type=None, width=None, height=None, osd_num=1, to_ide=False, flag=None, fps=None, quality=90)

参数

参数名称 描述 输入 / 输出 说明
type 显示设备类型 输入 必选
width 分辨率宽度 输入 可选参数,默认值根据 type 决定
height 分辨率高度 输入 可选参数,默认值根据 type 决定
osd_num show_image 时支持的 LAYER 数量 输入 越大占用内存越多
to_ide 是否将屏幕显示传输到 IDE 显示 输入 开启时占用更多内存
flag 显示 标志 输入
fps 显示帧率 输入 仅支持 VIRT 类型
quality 设置 Jpeg 压缩质量 输入 仅在 to_ide=True 时有效,范围 [10-100]

返回值

返回值 描述

show_image

描述

在屏幕上显示图像。

语法

复制代码
show_image(img, x=0, y=0, layer=None, alpha=255, flag=None)

参数

参数名称 描述 输入 / 输出 说明
img 显示的图像 输入
x 起始坐标的 x 值 输入
y 起始坐标的 y 值 输入
layer 显示到 指定层 输入 仅支持 OSD 层,若需要多层请在 init 中设置 osd_num
alpha 图层混合 alpha 输入
flag 显示 标志 输入

返回值

返回值 描述

deinit

描述

执行反初始化, deinit 方法会关闭整个 Display 通路,包括 VO 模块、 DSI 模块和 LCD/HDMI。
必须在 MediaManager.deinit()之前调用
必须在 sensor.stop()之后调用

语法

复制代码
deinit()

返回值

返回值 描述

bind_layer

描述

sensorvdec 模块的输出绑定到屏幕显示。无需用户手动干预即可持续显示图像。
必须在 init 之前调用

语法

复制代码
bind_layer(src=(mod, dev, layer), dstlayer, rect=(x, y, w, h), pix_format, alpha, flag)

参数

参数名称 描述 输入 / 输出 说明
src sensorvdec 的输出信息 输入 可通过 sensor.bind_info() 获取
dstlayer 绑定到 Display 的 显示层 输入 可绑定到 videoosd
rect 显示区域 输入 可通过 sensor.bind_info() 获取
pix_format 图像像素格式 输入 可通过 sensor.bind_info() 获取
alpha 图层混合 alpha 输入
flag 显示 标志 输入 LAYER_VIDEO1 不支持

返回值

返回值 描述

width

描述

获取屏幕或某一图层的显示宽度

语法

复制代码
width(layer = None):

参数

参数名称 描述 输入 / 输出 说明
layer 指定获取 显示层 的宽度,如果不传则表示获取屏幕的分辨率宽度

返回值

返回值 描述
width 屏幕或显示层的宽度信息

height

描述

获取屏幕或某一图层的显示高度

语法

复制代码
height(layer = None):

参数

参数名称 描述 输入 / 输出 说明
layer 指定获取 显示层 的高度,如果不传则表示获取屏幕的分辨率高度

返回值

返回值 描述
height 屏幕或显示层的高度信息

数据结构描述

type

类型 参数取值 备注
VIRT 640x480@90 默认值 IDE 调试专用,不在外接屏幕上显示内容 用户可自定义设置分辨率 (64x64)-(4096x4096) 和帧率 (1-200)
DEBUGGER 调试屏幕专用
ST7701 Display.init(Display.ST7701, width = 800, height = 480) 默认值 800x480
Display.init(Display.ST7701, width = 480, height = 800) 480x800
Display.init(Display.ST7701, width = 854, height = 480) 854x480
Display.init(Display.ST7701, width = 480, height = 854) 480x854
Display.init(Display.ST7701, width = 640, height = 480) 640x480
Display.init(Display.ST7701, width = 480, height = 640) 480x640
Display.init(Display.ST7701, width = 368, height = 552) 368x552
Display.init(Display.ST7701, width = 552, height = 368) 552x368
HX8399 Display.init(Display.HX8399, width = 1920, height = 1080) 默认值 1920x1080
Display.init(Display.HX8399, width = 1080, height = 1920) 1920x1080
ILI9806 Display.init(Display.ILI9806, width = 800, height = 480) 默认值 800x480
Display.init(Display.ILI9806, width = 480, height = 800) 480x800
ILI9881 Display.init(Display.ILI9881, width = 1280, height = 800) 默认值 1280x800
Display.init(Display.ILI9881, width = 800, height = 1280) 800x1280
LT9611 Display.init(Display.LT9611, width = 1920, height = 1080, fps = 30) 默认值 1920x1080@30
Display.init(Display.LT9611, width = 1920, height = 1080, fps = 60) 1920x1080@60
Display.init(Display.LT9611, width = 1280, height = 720, fps = 60) 1280x720@60
Display.init(Display.LT9611, width = 1280, height = 720, fps = 50) 1280x720@50
Display.init(Display.LT9611, width = 1280, height = 720, fps = 30) 1280x720@30
Display.init(Display.LT9611, width = 640, height = 480, fps = 60) 640x480@60

layer

K230 提供 2 层视频图层支持和 4 层 OSD 图层支持。分列如下:

显示层 说明 备注
LAYER_VIDEO1 仅可在 bind_layer 中使用,支持硬件旋转
LAYER_VIDEO2 仅可在 bind_layer 中使用,不支持硬件旋转
LAYER_OSD0 支持 show_imagebind_layer 使用
LAYER_OSD1 支持 show_imagebind_layer 使用
LAYER_OSD2 支持 show_imagebind_layer 使用
LAYER_OSD3 支持 show_imagebind_layer 使用

flag

标志 说明 备注
FLAG_ROTATION_0 旋转 0
FLAG_ROTATION_90 旋转 90
FLAG_ROTATION_180 旋转 180
FLAG_ROTATION_270 旋转 270
FLAG_MIRROR_NONE 不镜像
FLAG_MIRROR_HOR 水平镜像
FLAG_MIRROR_VER 垂直镜像
FLAG_MIRROR_BOTH 水平与垂直镜像

导入模块

复制代码
import time, os, urandom, sys
from media.display import *
from media.media import *
from machine import TOUCH
  • time: 用于时间控制

  • os: 操作系统接口

  • urandom: 生成随机数

  • media.displaymedia.media: 显示和媒体相关功能

  • TOUCH: 触摸屏驱动

常量定义

复制代码
DISPLAY_WIDTH = ALIGN_UP(800, 16)  # 显示宽度,对齐到16像素
DISPLAY_HEIGHT = 480               # 显示高度

初始化

复制代码
tp = TOUCH(0)  # 初始化触摸屏设备0

主函数 display_test()

1. 图像缓冲区创建

复制代码
img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
img2 = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
  • img: 主显示图像缓冲区

  • img2: 触摸点显示图像缓冲区(用于绘制触摸轨迹)

  • ARGB8888: 32位颜色格式(Alpha, Red, Green, Blue各8位)

2. 显示系统初始化

复制代码
Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
MediaManager.init()
  • 初始化ST7701显示控制器

  • to_ide=True: 可能表示同时输出到IDE预览

3. 主循环

触摸处理部分
复制代码
point = tp.read(1)  # 读取触摸点数据
if len(point):
    pt = point[0]
    if pt.event == 0 or pt.event == TOUCH.EVENT_DOWN or pt.event == TOUCH.EVENT_MOVE:
        img2.draw_cross(pt.x, pt.y, color=(255,0,0), width=1, think_ness=1)
        Display.show_image(img2, layer=Display.LAYER_OSD2, alpha=128)
  • 检测触摸事件(按下、移动)

  • 在触摸位置绘制红色十字

  • 在OSD2图层显示触摸轨迹,设置半透明效果(alpha=128)

文字显示部分
复制代码
x = (urandom.getrandbits(11) % img.width())
y = (urandom.getrandbits(11) % img.height())
img.draw_string_advanced(x, y, 32, "Hello World!,你好世界!!!", color=(0,0,255))
Display.show_image(img)
  • 在随机位置显示中英文文字

  • 文字颜色为蓝色

  • 将图像显示到屏幕上

循环控制
复制代码
img.clear()  # 清空主图像缓冲区
time.sleep(0.05)  # 50ms延迟,控制刷新率

4. 异常处理和清理

复制代码
except KeyboardInterrupt as e:
    print("user stop: ", e)
except BaseException as e:
    sys.print_exception(e)

Display.deinit()  # 释放显示资源
MediaManager.deinit()  # 释放媒体资源

程序入口

复制代码
if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    display_test()
  • 启用退出点机制,允许安全中断程序

  • 调用主测试函数

程序功能总结

  1. 显示测试: 在屏幕随机位置显示"Hello World!,你好世界!!!"

  2. 触摸测试: 检测触摸并在触摸位置绘制红色十字轨迹

  3. 多图层显示: 使用不同图层分别显示文字和触摸轨迹

  4. 实时更新: 以约20FPS的速率刷新显示

程序用于嵌入式设备的显示和触摸屏功能验证。

源程序如下:

python 复制代码
import time, os, urandom, sys

from media.display import *
from media.media import *

from machine import TOUCH

DISPLAY_WIDTH = ALIGN_UP(800, 16)
DISPLAY_HEIGHT = 480

tp = TOUCH(0)

def display_test():
    print("display and touch test")

    # create image for drawing
    img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
    img.clear()

    img2 = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
    img2.clear()

    # use lcd as display output
    Display.init(Display.ST7701, width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT, to_ide = True)
    # init media manager
    MediaManager.init()

    try:
        while True:
            os.exitpoint()
            point = tp.read(1)
            if len(point):
                print(point)
                pt = point[0]
                if pt.event == 0 or pt.event == TOUCH.EVENT_DOWN or pt.event == TOUCH.EVENT_MOVE:
                    img2.draw_cross(pt.x, pt.y, color=(255,0,0), width = 1, think_ness = 1)
                    Display.show_image(img2, layer = Display.LAYER_OSD2, alpha = 128)

            x = (urandom.getrandbits(11) % img.width())
            y = (urandom.getrandbits(11) % img.height())
            img.draw_string_advanced(x,y,32, "Hello World!,你好世界!!!", color = (0, 0, 255),)
            # draw result to screen
            Display.show_image(img)
            img.clear()
            time.sleep(0.05)
    except KeyboardInterrupt as e:
        print("user stop: ", e)
    except BaseException as e:
        import sys
        sys.print_exception(e)

    # deinit display
    Display.deinit()
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    # release media buffer
    MediaManager.deinit()

if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    display_test()
相关推荐
远创智控研发中心016 小时前
基于以太网转换器的工业交换机接入方案提升数据传输效率与稳定性
数据采集·触摸屏·西门子plc·以太网模块·工业自动化
Freak嵌入式4 天前
WIZnet-EVB-Pico2开始,用MicroPython玩转以太网开发
arm开发·人工智能·python·嵌入式硬件·机器人·嵌入式·micropython
远创智控研发中心015 天前
无需修改程序!S7-200 PLC加装以太网桥接器即可联动S7-1200与触摸屏
数据采集·触摸屏·西门子plc·以太网模块·工业自动化
捷米特网关模块通讯5 天前
基于以太网转换模块的三菱A系列PLC联网方案提升产线数据采集效率
上位机·数据采集·三菱plc·触摸屏·工业自动化·总线协议
远创智控研发中心016 天前
工厂MES系统数据采集痛点:串口转以太网模块让老PLC焕发新生
数据采集·触摸屏·西门子plc·以太网模块·工业自动化
一个平凡而乐于分享的小比特9 天前
还在手动挡写单片机?MicroPython 一脚油门踩进 Python 硬件世界
单片机·嵌入式硬件·micropython
qdprobot16 天前
ESP32S3 AiTall V3 Mixly 图形化编程开发AI小智 MCP AIOT大模型对话开发视频教程Micropython小智AI系统
人工智能·micropython·esp32s3·图形化编程·mcp·mixly小智ai·大模型对话
SM0.0观测者18 天前
触摸屏的双报警条显示
触摸屏·报警条
Freak嵌入式22 天前
亲测可用!可本地部署的 MicroPython 开源仿真器
ide·驱动开发·嵌入式·仿真·micropython·upypi
远创智控研发中心0122 天前
欧姆龙CPM2AH PLC通过以太网模块实现焊接产线多设备互联互通案例
上位机·数据采集·触摸屏·以太网模块·工业自动化·欧姆龙plc