vindar / ILI9341_T4

Optimized ILI9341 screen driver library for Teensy 4/4.1, with vsync and diff. updates.
GNU Lesser General Public License v2.1
70 stars 12 forks source link

Visual glitches upon touch input #16

Open Volcano339 opened 1 year ago

Volcano339 commented 1 year ago

I'm using a Teensy 4.1 with a display using the default pins. Whenever I touch the center of the display, the screen starts having weird artifacts (colors inverted, image misaligned and repeated, flickering, and usually a white screen after the others).

Sometimes, I don't even need to touch the display (this usually happens if any pin other than PIN_BACKLIGHT is set to 255). When this is the case, the display usually alternates between a white screen and another white screen with gray horizontal stripes.

This happens with every demo except for touch calibration.

The visual problems go away after rebooting (as long as you don't use touch again).

This is the sketch where the screen goes white if you touch the center: https://gist.github.com/Volcano339/621a4a85d2d7d4b0491ddec014bf92fb

I don't know if this is a hardware issue or not, but the fact that the glitches go away after rebooting suggests to me that it is more likely a software issue.

If you think it is a hardware issue, feel free to ask questions about the hardware. This might just be a simple hardware mistake.

Any help is appreciated!

vindar commented 1 year ago

Hi,

I just tried your sketch but it works without glitches for me. The only difference with my hardwired test setup is that the backlight pin of the display is directly connected to +3.3v and not to PIN 2. All the other connections are the same.

I suspect it is a wiring problem... Maybe a loose connection ? How long are your wires, breadboard wires longer than 20/30cm do not work well with high SPI speed. You can try setting the SPI speed to 10Mhz just to see if it helps.

It also looks like the touchscreen may be interfering with the display. Are you sure that T_CS is routed to PIN 4 on the Teensy ?

With the sketch provided, the complete wiring should be:

What happens if you physically disconnect all the touchscreen pins (ie all the T_* ones) from the teensy and set PIN_TOUCH_IRQ and PIN_TOUCH_CS to 255 in the sketch ? Are there still glitches ?

Finally, do you use the usual cheap red ILI9341 breakout board ? Some of those boards do not even have a touchscreen present even though the touch pins are still present on the PCB. Can you post a picture of your setup ?

Volcano339 commented 1 year ago

I tried it without the T_* pins and it seemed to not have any problems.

I made sure that all connections were correct and I set the SPI speed to 10Mhz. I still get issues if the T_* pins are connected.

The touch chip is soldered to the display breakout and the touch calibration wizard works just fine.

Maybe it has something to do with how I'm powering it. The power supply outputs 5V.

The LED is being powered by pin 2 with a 110Ohm resistor.

Maybe my unit is just defective.

Here is a picture of it: My project

vindar commented 1 year ago

That is weird indeed.. I do not understand why it works with the touchscreen calibration demo and not the others sketches...

I will try to replicate your exact setup on a breadboard this evening when I have some time.

Two remarks:

Volcano339 commented 1 year ago

I tried it with USB power and connected the backlight to a 3.3V pin (with the 110Ohm resistor) and it made no difference. I might just have to get a replacement display.

Let me know if you have any more questions about my wiring. I think your tests are my last hope before I return the display.

vindar commented 1 year ago

Hi,

I replicated your setup on a breadboard (with the LED pin connected to +3.3V through a 100Ohm resistor).

It works ok. No bug/freeze when I touch the screen. I just let it run for 30 minutes without any error. I guess it really is an hardware problem on your side...

IMG_20230614_231255

Volcano339 commented 1 year ago

Thanks for the help! I guess I'll just get a replacement.

There is something that is still bothering me though.

If the issue really is on the hardware side, why does the touch calibration demo have no issues?

vindar commented 1 year ago

Yes, I do not really understand why the touch calibration demo works.

However, it is worth noting that while doing performing calibration the driver is not using all the fancy features like DMA transfers, double buffering, vsync... This may make this mode of operation more resilient to failure/noise/temporary disconnection between the MCU and the display (e.g. if the signal on some lines SCK/MISO/MISO is shortly interrupted) and may enable it to recover... But that is just a guess.

Volcano339 commented 1 year ago

Now I have to figure out if the problem lies with the display itself or if my wiring is just not good. Unfortunately, results from testing are horribly inconsistent. One last observation I made is that the problem can be triggered if the T_* wires are at all moved (sometimes this has no effect). I think this might also happen with the backlight wire, but the tests are too inconsistent to really tell. The only thing that breaks the display every time is applying pressure to the center of the screen.

Do you think I should just try it with a different display, or are there other things that I should look out for with my wiring?

vindar commented 1 year ago

I do not know the answer really :) My feeling is that, even if the wiring is inconsistent, your display is faulty anyway since pressing the screen always freeze/crashes the program... These display are very cheap (I usually buy them on aliexpress for a few euros) so I would simply get another one...

Volcano339 commented 1 year ago

Alright, I got a replacement display and I still have the exact same issues. I tried using the alternate pins, but the problem persists (with USB power). The only thing I can do that will stop the problem is not connect the T_* pins.

Now I'm really confused :/

I wonder why it's the T_* pins specifically that cause problems. Could something be wrong with my wiring? Could something be wrong with my Teensy? Maybe the breadboards have issues?

Any ideas?

vindar commented 1 year ago

That is really weird...

I have never had any problem with a Teensy 4 (I did burn a couple of them inadvertently but it was my fault and they just stopped working completely). Just in case, you can try resetting the teensy to it's default state by pressing the button on the board for about 15 second and then releasing it when the led starts to blink. I do not expect this will really help but it won't hurt and does not cost anything to try...

As for the breadboard, I did get a faulty one once where some connections did not work. It took me some time to figure it out... Maybe yours also has some defects ? Can you use another one or at least change the position of the display on the breadboard?

Finally, you may also try shorter breadboard wire. Long ones cause problem with high SPI rates. You should also lower the SPI rate to 10Mhz during testing...

Apart from those generic advices, I cannot help much because I have never experienced these particular problems, sorry! Hopefully you will find what is wrong.

Volcano339 commented 1 year ago

I moved the display to the other half of the breadboard and it still has problems.

The SPI speed is set to 10Mhz and all wires are <30cm.

I wrote a test program for the Teensy that makes every pin alternate between high and low every 0.5s, and every pin seemed to work just fine. Is it safe to assume that the Teensy isn't the problem if the test program worked?

The two weirdest behaviors from this have been the fact that this only happens if the touch pins are connected, and that the touch calibration demo has no issues.

I'm running out of ideas

vindar commented 1 year ago

:(

I am also running out of ideas...

Do the problem still appears if you disconnect the touch_irq wire and set it to 255 in the code ? The IRQ pin is not mandatory to use the touchscreen.

Also, what happens if you leave everything connected but set all touch related pin to 255 in the driver and add:

pinmode(4, OUTPUT) digitalWrite(4, HIGH)

before the begin() call to the driver to disable SPI communication with the touch device. More generally, you may test which touch pin/ wire causes problem.

Also, when the screen freeze, what is the output on the serial monitor. Does the driver still print the stats periodically or does the program completely hang ?

Volcano339 commented 1 year ago

I don't think the program itself has ever frozen. It seems to work now without touch_irq connected. I tried connecting touch_irq to pin 28, but it has the same issues.

What functionality am I missing out on if I don't use touch_irq, and do you have any idea why touch_irq specifically would cause problems?

vindar commented 1 year ago

Good, seems like we are narrowing on the issue !

The IRQ pin is used by the display to indicate when the screen is being touched. When connected to the Teensy and registered within the ILI9341_T4 driver, it will trigger an interrupt which register the current time. In this way, when readTouch() is called, the method can check whether the screen was touched since the previous call to readTouch(). If not, then it is not necessary update the touch status which saves a SPI transaction. On the other hand, when the IRQ pin is not set, any call to readTouch() will require a SPI transaction and will therefore need to block/wait until the current screen update completes which may be inefficient when called often.... Also, if the IRQ pin is not set within the driver, the lastTouched() method will always return -1.

The IRQ pin can be connected to any (unused) pin on the Teensy. I find it surprising that the IRQ pin is the one causing troubles. Can you try whether the bug occurs in any of the following two cases ?

  1. The IRQ is connected to the Teensy but the corresponding TOUCH_IRQ is set to 255 in the sketch (so we pretend is it not connected).
  2. The IRQ pin is disconnected but TOUCH_IRQ is set to a pin pull up to +3.3V (so we pretend it is connected but we make sure the interrupt never fires since it is active low).

As you mention that the program itself has never frozen, what does serial output when the display stops working ? Does it keep outputting the periodic printStats() in the sketch as usual ?

Volcano339 commented 1 year ago

Sorry for the wait. It looks like the issue still happens if touch_irq is connected, even when TOUCH_IRQ is set to 255.

Here is the output of printStats() during the white screen with touch_irq connected to pin 28 and TOUCH_IRQ set to 255:

----------------- ILI9341Driver Stats ----------------
[Hardware]
- SPI BUS            : SPI1 [MOSI=26 , MISO=1, SCK=27, CS=9]
- DC pin             : 0  *** Hardware acceleration enabled ***
- SPI speed          : write=30000000  read=4000000
- IRQ priority       : 128
- XPT2046 Touchscreen: enabled [TOUCH_CS=4, TOUCH_IRQ=255]

[Configuration]
- screen orientation : 3 (LANDSCAPE_320x240_FLIPPED)
- refresh rate       : 119.7Hz  (mode 3)
- buffering mode     : 2 (DOUBLE BUFFERING)
- vsync_spacing      : 1  (VSYNC ENABLED).
- requested FPS      : 119.7Hz [=refresh_rate/vsync_spacing]
- diff. updates      : ENABLED - 2 diffs buffers.
- diff [gap]         : 4
- diff [compare_mask]: STRICT COMPARISON.

[Statistics]
- average framerate  : 112.6 FPS  (6499 frames in 57719ms)
- instant. framerate : 113 FPS  [min=95 , max=118] std=4.1
- upload rate        : 465.5 FPS  (19.07x compared to full redraw)
- upload time / frame: avg=2148us [min=12us , max=42995us] std=2301us
- CPU time / frame   : avg=550us [min=11us , max=3245us] std=342us
- pixels / frame     : avg=2310 [min=0 , max=76800] std=2378
- transact. / frame  : avg=564 [min=0 , max=4093] std=463
- teared frames      : 24 (0.4%)
- real vsync spacing : avg=1.01 [min=1 , max=5] std=0.17
- margin / frame     : avg=277 [min=-1012 , max=320] std=59

First diff buffer:
------------------- DiffBuff Stats -------------------
- max. buffer size   : 8192
- overflow ratio     : 0.2%  (8 out of 3249 computed)
- buffer size used   : avg=1311 [min=3 , max=8192] std=916
- computation time   : avg=956us [min=839us , max=1461us] std=85us

Second diff buffer:
------------------- DiffBuff Stats -------------------
- max. buffer size   : 8192
- overflow ratio     : 0.3%  (9 out of 3250 computed)
- buffer size used   : avg=1310 [min=3 , max=8192] std=917
- computation time   : avg=956us [min=839us , max=1473us] std=85us

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

Could you elaborate on what exactly you want me to do for test case 2?

vindar commented 1 year ago

Well, it is getting wierder...

So if I understand correctly, the simple fact of connecting the TOUCH_IRQ pin make the screen freeze when the touchscreen is pressed and this happens even if the driver is not aware of the pin that TOUCH_IRQ is connected to (because you set it to 255 in the sketch) ?

Then what happens if you move TOUCH_IRQ to some other pins on the teensy (you can any digital pin) ? Could you also add add a small resistor on this line (say in the range between 100Ohms and 1K) ? Can you please also try to add pinMode(PIN_NUMBER, INPUT_PULLUP) before the tft.begin() call (where PIN_NUMBER is pin number the TOUCH_IRQ is connected to one the Teensy) but still set TOUCH_IRQ to 255 in the driver.

Volcano339 commented 1 year ago

I think it might be important to note that not every touch will break the display. There seems to be a specific spot where it will be most likely to break when touched. It's also easier to trigger the glitches with my thumb, as opposed to the stylus (I think it might have something to do with a wider surface area?). The same behavior happens with the other display.

I connected the touch_irq to pin 28 with a 110Ohm resistor. I set PIN_TOUCH_IRQ to 255. I called pinMode(28, INPUT_PULLUP); before tft.begin(SPI_SPEED);.

I don't think these steps made any difference in behavior.

Here is the updated sketch: https://gist.github.com/Volcano339/55a048626da193856df4910a7909ce7d

Volcano339 commented 1 year ago

Is there anything else I can try, or do I just have to accept the additional SPI transactions?

vindar commented 1 year ago

Well, I must admit I am running out of ideas !

I do not understand how connecting the the IRQ wire to the Teensy can have any effect at all if TOUCH_IRQ is not set (i.e. =255)... If the teensy pin is set as input, it should be completely invisible...

Also, the fact that the way the touchscreen is pressed matter hints at a hardware issue but then the freezing should also happen when the IRQ pin is completely left disconnected. Finally, the fact that the calibration sketch works without problem is also perplexing...

Sorry I do not know how I can help much more. I just tested again with several ILI9341 screens and a T4 and a T4.1 but could not reproduce the issue on my side...

Volcano339 commented 1 year ago

Maybe a video of the issue will help?

This is a recording of my Teensy running the exact sketch from the last gist: https://youtu.be/sg1bdBmmF-M

I don't get it either...

Also, is it safe for me to connect the backlight to a digital pin on the Teensy again? Do I still need a resistor for the backlight?

I still get a very brief white flash when the backlight turns on. Is there a way to get the pixels to start black instead of white?