Open tetopik opened 2 days ago
import lcd_bus
import machine
from micropython import const
spi_bus = machine.SPI.Bus(
host=1,
mosi=11,
miso=9,
sck=7
)
display_bus = lcd_bus.SPIBus(
spi_bus=spi_bus,
dc=5,
cs=12,
freq=40000000
)
import ili9488
import lvgl as lv
fb1 = display_bus.allocate_framebuffer(480*320*2/10, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)
fb2 = display_bus.allocate_framebuffer(480*320*2/10, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)
display = ili9488.ILI9488(
data_bus=spi_bus,
display_width=480,
display_height=320,
frame_buffer1 = fb1,
frame_buffer2 = fb2,
reset_pin=1,
reset_state=ili9488.STATE_LOW,
power_on_state=ili9488.STATE_HIGH,
backlight_pin=3,
offset_x=0,
offset_y=0,
color_space=lv.COLOR_FORMAT.RGB888,
color_byte_order=ili9488.BYTE_ORDER_BGR,
rgb565_byte_swap=True
)
display.set_power(True)
display.init()
display.set_backlight(100)
import task_handler
th = task_handler.TaskHandler()
you are passing the wrong "Bus" to the display driver. You need to be passing the lcd_bus.SPIBus
instance to the display driver not the SPI.Bus
instance.
Working great now, thank you.
But now how to properly calibrate the display? Because calling the indev.calibrate()
seems laggy and still invalid touch detected. I'm using the same SPI bus as the display.
import lcd_bus
import machine
from micropython import const
import ili9488
import lvgl as lv
import task_handler
import xpt2046
spi_bus = machine.SPI.Bus(host=1, mosi=11, miso=9, sck=7)
display_bus = lcd_bus.SPIBus(spi_bus=spi_bus, dc=5, cs=12, freq=40000000)
display = ili9488.ILI9488(
data_bus=display_bus,
display_width=320,
display_height=480,
reset_pin=1,
reset_state=ili9488.STATE_LOW,
backlight_pin=3,
backlight_on_state=ili9488.STATE_PWM,
color_space=lv.COLOR_FORMAT.RGB888,
color_byte_order=ili9488.BYTE_ORDER_RGB,
rgb565_byte_swap=True
)
display.init()
display.set_backlight(50)
display.set_rotation(lv.DISPLAY_ROTATION._90)
touch_dev = machine.SPI.Device(spi_bus=spi_bus, freq=10_000_000, cs=18)
indev = xpt2046.XPT2046(touch_dev, startup_rotation=lv.DISPLAY_ROTATION._90, debug=True)
th = task_handler.TaskHandler()
Same thing also happen using my ili9341 display, anything I missed? I also noticed that by default the touch y point is mirrored, is there any way to just flip it away?
reduce the color depth to 16 bit by changing color_space=lv.COLOR_FORMAT.RGB888
to color_space=lv.COLOR_FORMAT.RGB565
That will help with the speeds. I have some work I need to do with the touch calibration as it has some issues in it. I will be working on that today at some point.
What an effort you put on this repo.
Just a little suggestion if it's really possible to have a choice to attach the touch IRQ pin instead of just periodically polling the screen since we are using a very slow frameworks.
LVGL is not written to be able to inject touch input. It is only able to poll for touch input. Well... Not easily anyway, I would have to code in a work around. The functions that process input in LVGL are not exposed in any header files, so they are not public, In order to make it work I would have to make a copy of the functions which would cause an increase in the program size. MCU's have very limited resources. I did provide a function that does allow the polling to work better.
indev.enable_input_priority()
This bypasses the normal mechanics of
task_handler -> update display if 33 milliseconds has passed -> read indev if 33 milliseconds has passed -> process input if any -> exit task handler -> user code main loop -> task_handler -> update display if 33 milliseconds has passed.
and turns it into
task_handler -> read indev if 33 milliseconds has passed -> if input then process -> update display -> read indev -> if input then process -> update display -> continue this loop as long as there is input. once input stops then exit the loop and continue the normal task_handler cycle
You can see where the problem is with the first one. You can end up with a really long time from when input occurs until it gets realized on the display. it can be at least 33 milliseconds later, usually it is longer and depending on how long it takes the user code in the main loop to run you could see a much higher latency.
That function bypassed the typical mechanics and keeps reading the indev in a continuous loop so long as there is active input. This places user interaction with the GUI above all other thing in terms of priority.
I think that indev.enable_input_priority()
function should be the default setup, but in my case I feel noting's difference after I put it after indev init and before the task handler. At least for now.
And also, my board didn't update the display when I switched the setup to color_space=lv.COLOR_FORMAT.RGB565
as you mentioned above.
Anyway, what is the proper spi freq to use for this xpt2046 driver? I've used this driver before with vanilla micropython and the driver from https://github.com/rdagger/micropython-ili9341/blob/master/xpt2046.py
and it working great on 1MHz freq, but on this one is it really need 10Mhz?
Oh ya, once more, is it possible to do the calibration using arduino eSPI touch calibrate function instead, and than just put the result into the cal-data
in the indev init?
, is it possible to do the calibration using arduino eSPI touch calibrate function instead
You cannot use the same calibration numbers from eSPI. They are calculated differently I believe.
and it working great on 1MHz freq, but on this one is it really need 10Mhz?
I believe that 1 mhz is the speed you need to use for the touch panel. You would need to read the datasheet to find out if that is the case.
but in my case I feel noting's difference after I put it after indev init and before the task handler. At least for now.
not sure what you mean by this.
And also, my board didn't update the display when I switched the setup to color_space=lv.COLOR_FORMAT.RGB565 as you mentioned above.
I would have to check and see if this color depth is supported by your display. It may not be. Give me a few minutes to check on that.
OK so your display only supports RGB888 when using an SPI Bus. That is quite a bit of additional work that needs to be done with that added byte to not a huge amount of perceived color difference due to the size of the display.
If you have a mess of widgets and some of those widgets are outside of the viewable area on the display that will activate scrolling. When you scroll the display is when you will really notice a difference with the touch set to high priority vs not having it set.
I noticed that calling this indev.enable_input_priority()
function allow me to initialize the touch driver with 1Mhz freq instead of 10Mhz. But still didn't manage to finish the calibration.
OK the touch calibration should now be fixed.
OK the touch calibration should now be fixed.
I can confirm that touch calibration is working pretty well right now, but the touch orientation seem flipped here and there. On rotation._0 , the y is mirrored On rotation._90, the x,y is flipped and than the x is mirrored, and y seems random.
Even after the calibration succeed, indev.is_calibrated
keeps returning False
.
display.init()
display.set_backlight(100)
display.set_rotation(lv.DISPLAY_ROTATION._90)
touch_dev = machine.SPI.Device(spi_bus=spi_bus, freq=1_000_000, cs=18)
indev = xpt2046.XPT2046(touch_dev, startup_rotation=lv.DISPLAY_ROTATION._90, debug=True)
indev.enable_input_priority()
th = task_handler.TaskHandler()
if not indev.is_calibrated: indev.calibrate()
I'll try using my ILI9341 board later to see if ithe touch also got messy, I'm a little bit busy right now, gotta post here after getting the test result.
If you flash your ESP32 at all that is going to erase the stored calibration settings.
I will check to see what could be causing the values to not be saved. If the values are working after you calibrate the only way they could work is if they have been saved. The indev driver reads the calibration values from NV memory. the calibration saves the values to the NV memory.
I will look into it later on today. It is 4:00 am where I am at so I am going to lay down for a few hours.
Using ILI9341 my touch now working perfectly fine. Didn't tested on ILI9488 yet, will come back later.
Here is the catch:
lv.DISPLAY_ROTATION._0
or lv.DISPLAY_ROTATION._180
the calibration should be done as the display is on potrait 0°.lv.DISPLAY_ROTATION._90
or lv.DISPLAY_ROTATION._270
the calibration should be done as the display is on flipped-potrait 180°, don't follow the actual red square shown on the screen.indev.is_calibrated
always returns False
.display.init(1)
indev = XPT2046(tch_bus)
indev.enable_input_priority()
th = TaskHandler()
if not indev.is_calibrated: indev.calibrate()
display.set_rotation(lv.DISPLAY_ROTATION._90)
Didn't tested on ILI9488 yet, will come back later.
I can peacefully say that same thing happen with my ILI9488 display, it's fully working now. One thing left is the calibration data isn't automatically being saved after the calibration.
I'm struggling to find any valid documentation on how to create a config to initialize my setup. I've been trying a couple code from this issues tab but nothing's really works. One yelled 'Bus' object has no attribute 'init'.
Please help!
My code provided below