Closed demitrix closed 5 months ago
Yup, that's what it is. LVGL is handling the rotation internally. I removed the transforming of the pointer coordinates due to LVGL handling this internally.
I think that should finish this driver up.
If you still get phantom touches at all you can change the threshold value for the Z axis. it is defaulted to 400 and you can up that number if you want to filter out any random touches if they occur. You can set the threshold per instance or globally across all XPT2046 indevs.
To set it at the instance level..
indev1 = xpt2046.XPT2046(...)
indev1.touch_threshold= 600
indev2 = xpt2046.XPT2046(...)
indev2.touch_threshold= 800
and to set it globally.
xpt2046.XPT2046.touch_threshold = 600
indev1 = xpt2046.XPT2046(...)
indev2 = xpt2046.XPT2046(...)
Also I wanted to say thanks for adding the expandable/collapsible code blocks. It makes it a lot nicer when scrolling through an issue.
I like to use those when dealing with large code blocks or pasting logging data. 👍 for doing that.
Yeah realized things were getting lengthy and wanted to clean it up haha. I'll give this a shot tomorrow and see what happens 🤞
Think everything looks good here. Closing this issue.
rotation is working properly?
Sure is. I think everything is solid. While there may be improvements down the road, everything is in working order as of now.
Can someone tell me how to set the parameters for touch calibration ?
With the old touch driver I used :
touch = xpt2046(cs=32 ,cal_x0=3840, cal_x1 = 393, cal_y1=220, cal_y0 = 3719)
the calibration program has not had all of the kinks ironed out with it yet. I am going to be working on that soon.
So, if I understand well, I can't enter the calibration values manually ?
I'm doing some tests and like @demitrix I confirm that it works fine. Unfortunately I detect a misalignment between the graphic position and the touch pointer, which effectively makes it unusable.
You can enter them manually but they don't use the typical calibration coordinates that you have seen in the past. I went for an easier approach. which is recording the left, right top and bottom boundaries. It is very rudimentary as it doesn't handle if the touch panel has been rotated at all. to handle the rotation of the display I needed to have the ability to store floats into the NVS on the esp32. I did add that ability but have not gotten to updating the calibration so it is more complete.
if you wanted to pass the left, right top and bottom boundaries that can be done by doing the following.
class TouchCal:
def __init__(self),
left = 0
right = 0
top = 0
bottom = 0
def save():
pass
cal = TouchCal()
import xpt2046
xpt2046.XPT2046(spi_bus, touch_cal=cal)
you change the values in the __init__
to what you need and pass an instance of that class to the touch driver as seen above. It's very basic at the moment but at least it is something. I have been focusing on getting the bus drivers working properly and fixing some things in MicroPython that caused serious limitations on being able to use things like the touch, display and an SD card being on the same SPI bus... I still have to fix the SDCard driver that is built into MicroPython to get this to work properly..
I also want to update the SPI display bus driver so it can take an instance of the SPI driver from MicroPython. Being able to do that is going to take a little bit more work.
@ikkesia
I updated the calibration routine. The new design uses a more complex way of handling the touch panel to screen alignment. I never looked at the xpt2046 driver code in the official binding so I do not know what their calibration was all about. I can tell you that what is being used is not something that is considered typical.
My design doesn't not require any hard coding of the calibration numbers either. The calibration data gets stored in non volatile memory so it is persistent between power cycles and restarts. This is a better design for a production environment where the user is able to calibrate the display without needing to change and flash any source code.
It is easy to launch the screen calibration
# display driver and display bus code
import machine
import xpt2046
import task_handler
spi_bus = machine.SPI(...)
indev = xpt2046.XPT2046(spi_bus)
th = task_handler.TaskHandler()
if not indev.is_calibrated:
indev.calibrate()
You have to make sure that the task handler has been started prior to running the calibration.
I do have to make some tweaks to it still and I am going to mess about with that now.
@kdschlosser
I would have worked with the manual setting as you suggested, but having a calibration routine is great. Thank you very much for this update.
Unfortunately I can't try it quickly because my development kit broke. I'm waiting for a new one at the beginning of the week.
For m the calibration is not working:
indev.calibrate()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pointer_framework.py", line 45, in calibrate
File "touch_calibrate.py", line 275, in __init__
File "touch_calibrate.py", line 117, in build_crosshair
ValueError: need more than 2 values to unpack
give it a try. I think it should be fixed now.
/lvgl_micropython/ext_mod/lcd_bus/esp32_src/spi_bus.c: In function 'spi_init':
/esp/lvgl_micropython/ext_mod/lcd_bus/esp32_src/spi_bus.c:181:5: error: 'ret' undeclared (first use in this function)
Yeah I know there are going to be some errors now from me working on getting the SDCard to play nice and share the SPI bus with other things.
You have to give me a day to get them all sorted out.
Now that everything seems a bit more stable, I resume the touch screen calibration tests. I see that the parameters for manually setting the calibration parameters have changed, if I use
class TouchCal:
def __init__(self),
left = 0
right = 0
top = 0
bottom = 0
def save():
pass
cal = TouchCal()
import xpt2046
xpt2046.XPT2046(spi_bus, touch_cal=cal)
I get an error. I will study the new drivers to understand which new parameters to use and how to calculate them.
I also tried running the new calibration code according to the example above and I get an error
Traceback (most recent call last):
File "<stdin>", line 93, in <module>
File "xpt2046.py", line 43, in __init__
File "pointer_framework.py", line 16, in __init__
File "_indev_base.py", line 23, in __init__
RuntimeError: the display driver must be initilized before the pointer driver
Then I initialize the display driver and get this screen
Touch screen is responsive (debug=True), but calibration does not proceed.
Any suggestions ?
The calibration program still needs some work done to it. I am working on getting my display up and running to be able to work on the calibration program.
You must call the init() method for the display driver prior to initializing the touch driver. This is due to the touch driver collecting the width and the height of the display from the display driver.
paste me the code you are using...
Here is the code that is run for the touch screen data.
That file is the calibration screen and the link is the function where the calculations are done.
I suspect it is getting stuck because you have not started the task handler prior to running the calibration.
This is my code
from micropython import const
from machine import SPI
import time
import sys
import lcd_bus
#Display settings
_WIDTH = const(240)
_HEIGHT = const(320)
# Display SPI bus settings
_LCD_SPI_HOST = const(1)
_LCD_SPI_FREQ = const(40_000_000)
_LCD_MOSI_PIN = const(23)
_LCD_MISO_PIN = const(25)
_LCD_SCLK_PIN = const(19)
_LCD_CS_PIN = const(22)
# display additional pins
_LCD_RST_PIN = const(18)
_LCD_DC_PIN = const(21)
_LCD_BKL_PIN = const(5)
_LCD_PWR_PIN = None
# touch panel SPI settings
_TP_SPI_HOST = const(1)
_TP_SPI_FREQ = const(1_000_000)
_TP_CS_PIN = const(32)
_TP_INT_PIN = const(-1)
#cal_x0=3840, cal_x1 = 393, cal_y1=220, cal_y0 = 3719,
class TouchCal:
def __init__(self):
# self.left = 3840
# self.right = 393
# self.top = 3719
# self.bottom = 220
self.left = 0
self.right = 0
self.top = 0
self.bottom = 0
def save():
pass
# create the SPI bus for the display
spi_bus = SPI(
_LCD_SPI_HOST,
_TP_SPI_FREQ,
miso=_LCD_MISO_PIN,
mosi=_LCD_MOSI_PIN,
sck=_LCD_SCLK_PIN,
cs=_TP_CS_PIN
)
display_bus = lcd_bus.SPIBus(
spi_bus=spi_bus,
dc=_LCD_DC_PIN,
freq=_LCD_SPI_FREQ,
cs=_LCD_CS_PIN
)
import ili9341
import lvgl as lv
display = ili9341.ILI9341(
data_bus=display_bus,
display_width=_WIDTH,
display_height=_HEIGHT,
reset_pin=_LCD_RST_PIN,
reset_state=ili9341.STATE_LOW,
power_pin=_LCD_PWR_PIN,
backlight_pin=_LCD_BKL_PIN,
backlight_on_state=ili9341.STATE_HIGH,
color_space=lv.COLOR_FORMAT.RGB565,
# color_byte_order=ili9341.BYTE_ORDER_BGR,
rgb565_byte_swap=False
)
# start the display driver
display.init()
display.invert_colors()
#display.set_rotation(lv.DISPLAY_ROTATION._90)
#cal = TouchCal()
import xpt2046
indev = xpt2046.XPT2046(spi_bus, touch_cal=None, debug=True)
print('is_calibrate is', indev.is_calibrated)
import task_handler
th = task_handler.TaskHandler()
time.sleep_ms(1000)
if not indev.is_calibrated:
indev.calibrate()
Due to work done under https://github.com/kdschlosser/lvgl_micropython/issues/42 XPT2046 driver needs to be adapted to use new custom SPI implementation. Creating this issue as a place to track that progress.