From c3d59efe2a7d4591b76dd44d9a4c31919a7f95f0 Mon Sep 17 00:00:00 2001 From: AIWintermuteAI Date: Wed, 14 Apr 2021 22:28:39 +0800 Subject: [PATCH] added amigo lvgl touch screen demo, lvgl multiple screens demo, fixed pin definition --- board/config_maix_amigo_ips.py | 4 +- .../gui/lvgl/amigo_touchscreen/README.md | 4 + .../gui/lvgl/amigo_touchscreen/test_touch.py | 115 ++++++++++++++++++ .../gui/lvgl/amigo_touchscreen/touch.py | 103 ++++++++++++++++ multimedia/gui/lvgl/lvgl_multiple_screens.py | 111 +++++++++++++++++ 5 files changed, 335 insertions(+), 2 deletions(-) create mode 100644 multimedia/gui/lvgl/amigo_touchscreen/README.md create mode 100644 multimedia/gui/lvgl/amigo_touchscreen/test_touch.py create mode 100644 multimedia/gui/lvgl/amigo_touchscreen/touch.py create mode 100644 multimedia/gui/lvgl/lvgl_multiple_screens.py diff --git a/board/config_maix_amigo_ips.py b/board/config_maix_amigo_ips.py index e9381f1..dcd1ec5 100644 --- a/board/config_maix_amigo_ips.py +++ b/board/config_maix_amigo_ips.py @@ -22,8 +22,8 @@ config = { 'LED_G': 15, 'LED_B': 17, 'LED_W': 32, - 'BACK': 31, - 'ENTER': 23, + 'BACK': 23, + 'ENTER': 16, 'NEXT': 20, 'WIFI_TX': 6, 'WIFI_RX': 7, diff --git a/multimedia/gui/lvgl/amigo_touchscreen/README.md b/multimedia/gui/lvgl/amigo_touchscreen/README.md new file mode 100644 index 0000000..e9fede8 --- /dev/null +++ b/multimedia/gui/lvgl/amigo_touchscreen/README.md @@ -0,0 +1,4 @@ +LVGL Touchscreen demo for Maix Amigo + +Place touch.py in the device SPIFFS memory (using uPyLoader or MaixPy IDE), restart device and then run test_touch.py + diff --git a/multimedia/gui/lvgl/amigo_touchscreen/test_touch.py b/multimedia/gui/lvgl/amigo_touchscreen/test_touch.py new file mode 100644 index 0000000..cc669c4 --- /dev/null +++ b/multimedia/gui/lvgl/amigo_touchscreen/test_touch.py @@ -0,0 +1,115 @@ +import lvgl as lv +import lvgl_helper as lv_h +import lcd +import time +from machine import Timer +from machine import I2C +from touch import Touch, TouchLow +import KPU as kpu +import gc + +config_touchscreen_support = True +board_m1n = False + +lcd.init() + +TOUCH = None +DEBUG = False + +def read_cb(drv, ptr): + # print(ptr, b) + data = lv.indev_data_t.cast(ptr) + TOUCH.event() + if DEBUG: + print(TOUCH.state, TOUCH.points) + data.point = lv.point_t({'x': TOUCH.points[1][0], 'y': TOUCH.points[1][1]}) + data.state = lv.INDEV_STATE.PR if TOUCH.state == 1 else lv.INDEV_STATE.REL + return False + +if config_touchscreen_support: + i2c = I2C(I2C.I2C0, freq=1000*1000, scl=24, sda=27) # 24 27) + devices = i2c.scan() + print("devs", devices) # devs 0 [16, 38, 52, 56] + TouchLow.config(i2c) + TOUCH = Touch(480, 320, 200) + +lv.init() + +disp_buf1 = lv.disp_buf_t() +buf1_1 = bytearray(320*10) +lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4) +disp_drv = lv.disp_drv_t() +lv.disp_drv_init(disp_drv) +disp_drv.buffer = disp_buf1 + +disp_drv.flush_cb = lv_h.flush +if board_m1n: + disp_drv.hor_res = 240 + disp_drv.ver_res = 240 +else: + disp_drv.hor_res = 480 + disp_drv.ver_res = 320 +lv.disp_drv_register(disp_drv) + +if config_touchscreen_support: + indev_drv = lv.indev_drv_t() + lv.indev_drv_init(indev_drv) + indev_drv.type = lv.INDEV_TYPE.POINTER + indev_drv.read_cb = read_cb + lv.indev_drv_register(indev_drv) + +lv.log_register_print_cb(lambda level,path,line,msg: print('%s(%d): %s' % (path, line, msg))) + +def event_handler(obj, event): + global btn, box, bg + + if event == lv.EVENT.CLICKED: + if obj == btn: + box.set_hidden(0) + bg.set_hidden(0) + elif obj == box: + box.set_hidden(1) + bg.set_hidden(1) + +#create screen object +scr = lv.obj() + +#create button in center with callback +btn = lv.btn(scr) +btn.align(scr, lv.ALIGN.CENTER, 0, 0) +btn.set_event_cb(event_handler) +label = lv.label(btn) +label.set_text("Press me") +label.set_size(20,20) + +#create semi-transparrent background and set it to hidden +bg = lv.obj(scr) +bg.set_pos(0, 0) +bg.set_size(scr.get_width(), scr.get_height()) +modal_style = lv.style_t() +lv.style_copy(modal_style, lv.style_plain_color) +modal_style.body.main_color = modal_style.body.grad_color = lv.color_make(0,0,50) +modal_style.body.opa = 75 +bg.set_style(modal_style) +bg.set_hidden(1) + +#create message box and set it to hidden +box = lv.mbox(scr) +box.set_text("Congratulations, you pressed the button! Now do it again, here"); +box.add_btns(["OK", ""]) +box.set_width(200) +box.set_event_cb(event_handler) +box.align(None, lv.ALIGN.CENTER, 0, 0) +box.set_hidden(1) + +lv.scr_load(scr) + +def on_timer(timer): + lv.tick_inc(5) + lv.task_handler() + gc.collect() + +timer = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=5, unit=Timer.UNIT_MS, callback=on_timer, arg=None) + +while True: + pass diff --git a/multimedia/gui/lvgl/amigo_touchscreen/touch.py b/multimedia/gui/lvgl/amigo_touchscreen/touch.py new file mode 100644 index 0000000..13761b0 --- /dev/null +++ b/multimedia/gui/lvgl/amigo_touchscreen/touch.py @@ -0,0 +1,103 @@ +# This file is part of MaixUI +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +import time + +FT_DEVIDE_MODE = 0x00 +FT_ID_G_MODE = 0xA4 +FT_ID_G_THGROUP = 0x80 +FT_ID_G_PERIODACTIVE = 0x88 + +FT6X36_ADDR = 0x38 + +class TouchLow: + i2c3 = None + addr = 0x0 + + def config(i2c3, addr=FT6X36_ADDR): + TouchLow.i2c3 = i2c3 + TouchLow.addr = addr + + def write_reg(reg_addr, buf): + TouchLow.i2c3.writeto_mem(TouchLow.addr, reg_addr, buf, mem_size=8) + + def read_reg(reg_addr, buf_len): + return TouchLow.i2c3.readfrom_mem(TouchLow.addr, reg_addr, buf_len, mem_size=8) + + def config_ft6x36(): + TouchLow.write_reg(FT_DEVIDE_MODE, 0); # 进入正常操作模式 + TouchLow.write_reg(FT_ID_G_THGROUP, 12); # 设置触摸有效值,触摸有效值,12,越小越灵敏 + TouchLow.write_reg(FT_DEVIDE_MODE, 14); # 激活周期,不能小于12,最大14 + + def get_point(): + if TouchLow.i2c3 != None: + #data = self.read_reg(0x01, 1) + #print("get_gesture:" + str(data)) + data = TouchLow.read_reg(0x02, 1) + #print("get_points:" + str(data)) + if (data != None and data[0] == 0x1): + data_buf = TouchLow.read_reg(0x03, 4) + y = ((data_buf[0] & 0x0f) << 8) | (data_buf[1]) + x = ((data_buf[2] & 0x0f) << 8) | (data_buf[3]) + #print("1 point[{}:{}]".format(x,y)) + if ((data_buf[0] & 0xc0) == 0x80): + #print("2 point[({},{}):({},{})]".format( + #x, y, self.width - x, self.height - y)) + return (x, y) + return None + +class Touch: + + idle, press, release = 0, 1, 2 + + def __init__(self, w, h, cycle=1000, invert_y=False): + self.cycle = cycle + self.last_time = 0 + self.points = [(0, 0, 0), (0, 0, 0)] + self.state = Touch.idle + self.width, self.height = w, h + self.invert_y = invert_y + + def event(self): + tmp = TouchLow.get_point() + if tmp != None: + x, y = tmp + + if self.invert_y: + y = self.height - y + if x < 0: x = 0 + if y < 0: y = 0 + + self.last_time = time.ticks_ms() + if self.state != Touch.press: + self.state = Touch.press + self.points[0] = (x, y, time.ticks_ms()) + self.points[1] = (x, y, time.ticks_ms()) + + # timeout return ilde. + if time.ticks_ms() > self.last_time + self.cycle: + if self.state == Touch.release: + self.state = Touch.idle + self.points = [(0, 0, 0), (0, 0, 0)] + return + if self.state == Touch.press: + self.state = Touch.release + return + +if __name__ == "__main__": + + import lcd + from machine import I2C + + i2c = I2C(I2C.I2C3, freq=1000*1000, scl=24, sda=27) # amigo + devices = i2c.scan() + print(devices) + TouchLow.config(i2c) + tmp = Touch(480, 320, 200) + while 1: + tmp.event() + print(tmp.state, tmp.points) diff --git a/multimedia/gui/lvgl/lvgl_multiple_screens.py b/multimedia/gui/lvgl/lvgl_multiple_screens.py new file mode 100644 index 0000000..b6d9c90 --- /dev/null +++ b/multimedia/gui/lvgl/lvgl_multiple_screens.py @@ -0,0 +1,111 @@ +#this demo shows how to create multiple screens, load and unload them properly without causing memory leak + +import lvgl as lv +import lvgl_helper as lv_h +import lcd +import time +from machine import Timer +from machine import I2C +from touch import Touch, TouchLow +import KPU as kpu +import gc + +config_touchscreen_support = True +board_m1n = False + +lcd.init() + + +TOUCH = None + +def read_cb(drv, ptr): + data = lv.indev_data_t.cast(ptr) + TOUCH.event() + data.point = lv.point_t({'x': TOUCH.points[1][0], 'y': TOUCH.points[1][1]}) + data.state = lv.INDEV_STATE.PR if TOUCH.state == 1 else lv.INDEV_STATE.REL + return False + + +if config_touchscreen_support: + i2c = I2C(I2C.I2C0, freq=1000*1000, scl=24, sda=27) # 24 27) + devices = i2c.scan() + print("devs", devices) # devs 0 [16, 38, 52, 56] + TouchLow.config(i2c) + TOUCH = Touch(480, 320, 200) + +lv.init() + +disp_buf1 = lv.disp_buf_t() +buf1_1 = bytearray(320*10) +lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4) +disp_drv = lv.disp_drv_t() +lv.disp_drv_init(disp_drv) +disp_drv.buffer = disp_buf1 + +disp_drv.flush_cb = lv_h.flush +if board_m1n: + disp_drv.hor_res = 240 + disp_drv.ver_res = 240 +else: + disp_drv.hor_res = 480 + disp_drv.ver_res = 320 +lv.disp_drv_register(disp_drv) + +if config_touchscreen_support: + indev_drv = lv.indev_drv_t() + lv.indev_drv_init(indev_drv) + indev_drv.type = lv.INDEV_TYPE.POINTER + indev_drv.read_cb = read_cb + lv.indev_drv_register(indev_drv) + + +lv.log_register_print_cb(lambda level,path,line,msg: print('%s(%d): %s' % (path, line, msg))) + +class UI: + + def __init__(self): + self.scr1 = self.create_scr1() + self.scr2 = self.create_scr2() + + def create_scr1(self): + scr1 = lv.obj() + btn1 = lv.btn(scr1) + btn1.align(scr1, lv.ALIGN.CENTER, 0, 0) + label1 = lv.label(btn1) + label1.set_text("Button 1") + label1.set_size(20,20) + return scr1 + + def create_scr2(self): + scr2 = lv.obj() + btn2 = lv.btn(scr2) + btn2.align(scr2, lv.ALIGN.CENTER, 0, 0) + label2 = lv.label(btn2) + label2.set_text("Button 2") + label2.set_size(20,20) + return scr2 + +ui = UI() +kpu.memtest() + +def on_timer(timer): + lv.tick_inc(5) + lv.task_handler() + gc.collect() + +timer = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=5, unit=Timer.UNIT_MS, callback=on_timer, arg=None) + +while True: + tim = time.ticks_ms() + while time.ticks_ms()-tim < 500: + pass + + lv.scr_load(ui.scr1) + kpu.memtest() + + tim = time.ticks_ms() + while time.ticks_ms()-tim < 500: + pass + + lv.scr_load(ui.scr2) + kpu.memtest()