rm-hull / luma.lcd

Python module to drive PCD8544, HT1621, ST7735, ST7567 and UC1701X-based LCDs
https://luma-lcd.readthedocs.io
MIT License
156 stars 56 forks source link

Stray pixels when using diff_to_previous with ILI9341 #120

Closed mattblovell closed 3 years ago

mattblovell commented 3 years ago

Raspberry PI 3, Model B v1.2

Linux raspberrypi 5.4.51-v7+ #1333 SMP Mon Aug 10 16:45:19 BST 2020 armv71 GNU/Linux

I have a new 320x240 ILI9341 SPI LCD display. If I invoke the welcome.py demo with the options

--interface spi -d ili9341 --width 320 --height 240 --framebuffer full_frame

it operates as one would expect (albeit a bit slowly, varying with --spi-bus-speed).

If I leave off the --framebuffer option (using the default diff_to_previous), then

In the pi_logo demo, the diff_to_previous option allows dark pixels to momentarily appear around the rotating Pi logo.

Is the full_frame buffer inherently required when using an ili9341-based LCD?

image

rm-hull commented 3 years ago

I haven’t observed that with any other device that does diff-to-previous, so makes me wonder if the calculation here https://github.com/rm-hull/luma.lcd/pull/94/files#diff-09cfe7a0be1f525d8b47f131de856bd2R485 is the culprit, ... but unlikely as it is the same as the st7735 device.

I wonder if adding some bounding box margin with this method https://github.com/rm-hull/luma.core/blob/master/luma/core/framebuffer.py#L52 may fix the issue.

To be honest, I haven’t tried this implementation personally as I don’t own one of these displays - it was a contribution by @ric2b .. Ricardo are you able to have a look and reproduce please?

ric2b commented 3 years ago

Sorry, I don't currently have access to these screens, it will take me some time to test this.

My use case was focused on static images so I was using the full frame option, it's entirely possible that I missed some problems with partial updates.

mattblovell commented 3 years ago

I'm still in full-on experiment mode here, and I have the display still connected to the RPi. I can try out any diff / patch anyone would like to suggest.

rm-hull commented 3 years ago

@mattblovell:

  1. curious to know if you are running the demo's with either or both of --v_offset or -h_offset ?
  2. If you could checkout the latest commit on master in the luma.lcd repo, and in the ili9341 class, in the display class at line 611, alter it as follows:
        if self.framebuffer.redraw_required(image):
            self.framebuffer.inflate_bbox()   # <--- INSERT THIS LINE
            left, top, right, bottom = self.apply_offsets(self.framebuffer.bounding_box)
  1. Reinstall from source with sudo -H pip3 install -e . from the luma.lcd directory.
  2. Rerun the welcome demo and observe.

One of two things should happen - it will either fix it (🤞) or ... it will partially fix it by leaving a trail of breadcrumbs across the screen ( 😦 )

mattblovell commented 3 years ago

@rm-hull:

curious to know if you are running the demo's with either or both of --v_offset or -h_offset ?

No. I briefly gave those options a try, but they seemed to make matters worse.

The slight bounding box change unfortunately did not help matters. Here's a new photo:

IMG-0659_sm

... and a photo of just the white band, discussed below.

IMG-0664_sm

I don't know if they help, but here are some other tidbits:

I mention the hanging since I didn't observe any such behavior trying out a SSD1309 OLED panel.

Please let me know if there's anything else you'd like me to try.

(For my application, I am content to use full_frame. I'm trying to make a front panel display for Kodi, complete with album cover. luma.lcd has been working nicely for that!)

Thanks, Matt

rm-hull commented 3 years ago

I was always a bit reluctant to support higher resolution devices because they would always be slow with an interpreted language. The diff to previous framebuffer was introduced to allow for partial screen redraws to get a speed bump. There is a new PR in progress (see https://github.com/rm-hull/luma.core/pull/194) which may alleviate this, but that is some way off at the moment.

Your observations are very useful and interesting, especially around the hangs. This makes me wonder what RPi model are you using, and how many amps does your power supply provide? I ask only because I was recently suffering hangs and dropped network connections on a model B 4 whenever the cpu got busy. Using a decent 3A supply and all the problems vanished.

One other thing to try would be to add --gpio-reset-hold-time and --gpio-reset-release-time flags .. it may be that the reset line isn’t being held active for long enough.

I’ll try and get hold of an ili9341 device anyway, which will be useful for testing the Linux framebuffer driver implementation.

mattblovell commented 3 years ago

@rm-hull :

I was always a bit reluctant to support higher resolution devices because they would always be slow with an interpreted language.

I'm really glad luma added support for the ili9341, though. It's been quite fun to experiment with. (Photo of the front panel display I'm working on below.)

This makes me wonder what RPi model are you using, and how many amps does your power supply provide?

The board is a Raspberry Pi 3 Model B v1.2. The power supply I have for it claims to provide output of 2.4 A at 5.25 V.

I don't typically have much plugged into the RPi, but I can try unplugging the USB flash drive and USB mouse and see if that helps at all. The hangs that I reported are just of welcome.py; X and everything else stay up.

I also have an Odroid C4 that is my intended "target" for this project, if I can figure out what's necessary to get luma.core and luma.lcd up and running on an Odroid board.

One other thing to try would be to add --gpio-reset-hold-time and --gpio-reset-release-time flags

I'll give those a try later today.

Thanks for making luma such a flexible and (extremely) well-documented package! Matt


work-in-progress kodi_panel, on ili9341 using luma:

kodi_panel_photo

mattblovell commented 3 years ago

One other thing to try would be to add --gpio-reset-hold-time and --gpio-reset-release-time flags

That seems to help clean up the display wonderfully! Welcome.py still hangs, but the display is handled appropriately. The bounce demo is getting 10.6 to 11.1 fps when invoked with the following command line:

python3 bounce.py --interface spi -d ili9341 --width 320 --height 240 \
  --spi-bus-speed 32000000 --backlight-active high \
  --gpio-reset-hold-time 0.2 --gpio-reset-release-time 0.2

Without the reset timing options, bounce.py left tons of pixel trails, similar to what welcome.py does. (For reference, invoking bounce with the full_frame option drops the display rate about 8 fps.)

The hang from welcome.py is still unusual. Sometimes it occurs immediately at startup (i.e., the clears, this time correctly, but no initial text ever appears) and sometimes it now gets through 5 or 6 scroll-offs. The bounce demo is seemingly happy to run forever; I'm going to leave it up while I go do some chores and check on it later.

Update 1: bounce indeed seems to keep running. Being able to omit the full_frame option makes the animation in pi_logo quiet snappy. Several of the others are pretty reasonable as well, even with a 320x240 display.

Update 2: Nevermind, had the arguments messed up. The following seems happier:

serial = spi(port=0, device=0, gpio_DC=24, gpio_RST=25,
             reset_hold_time=0.2, reset_release_time=0.2)
device = ili9341(serial, active_low=False, width=320, height=240,
                 bus_speed_hz=32000000
                 )
mattblovell commented 3 years ago

The bounce.py demo has run for hours now without issue.

I almost wonder whether there is some font that balks at being rendered for the 320x240 display. Running welcome.py in Windows at that size, via --display pygame, it too stops!

thijstriemstra commented 3 years ago

via --display pygame, it too stops!

Ah that's a very useful test. Does the pygame emulator display exactly the same (issues)?

mattblovell commented 3 years ago

Does the pygame emulator display exactly the same (issues)?

It's never had the pixel artifacts / trails that the physical panel had (now resolved with the reset timing). The halting seems similar, though.

I'd been using the pygame emulator for my own development and just thought of trying out welcome.py in it this morning.

mattblovell commented 3 years ago

Off topic from this bug report, I know, but I hope you'll permit it to stay...

I also have an Odroid C4 that is my intended "target" for this project, if I can figure out what's necessary to get luma.core and luma.lcd up and running on an Odroid board.

I don't know if it's the "official" route of getting luma.core onto non-RPi boards or not, but I was able to install the RPi.GPIO-Odroid package from

https://github.com/awesometic/RPi.GPIO-Odroid

and get luma.oled alive. This route was successful for an Odroid C4 under both Ubuntu 20.04 and under CoreELEC (one has to make use of entware under CoreELEC, as apt isn't available).

The bounce.py demo gets 80 fps on an SSD1309 128x64 OLED display with the Odroid C4!

The tagline for luma.core mentions that it is for "small displays on the Raspberry Pi and other single board computers". It's been unclear to me, though, what was necessary for installation on other SBCs.

thijstriemstra commented 3 years ago

"small displays on the Raspberry Pi and other single board computers"

Any suggestions for a better tagline? :)

mattblovell commented 3 years ago

Any suggestions for a better tagline? :)

No, for that part does seem accurate!

Being relatively new to trying out this whole GPIO aspect of the SBCs, I found the plethora of alternatives just for the RPi a cause of confusion. The following seem roughly equivalent:

Separate from the above are efforts like Adafruit_Blinka (and, from what I can understand, several Python variants).

Once I understood what luma.core wanted to load, I could then search around for an Odroid equivalent.

My (naive) hope is that for such underlying infrastructure we could have settled on a particular Python package and then had clear per-platform versions of that for the various SBCs that are available. Perhaps there's still too many differences across them to have such a unified approach. It could be that things are simpler than I perceive and I just have yet to find the simplifying key!

Perhaps some hints or pointers on handling non-RPi platforms in the (otherwise excellent) documentation could help?

mattblovell commented 3 years ago

Back to the original topic of this issue, adding non-zero reset hold and release times appears to resolve the problems. I don't know if any code change is needed, other than perhaps changing the defaults for ili9341 (or suggesting non-zero reset times).

rm-hull commented 3 years ago

I wrote https://github.com/rm-hull/OPi.GPIO for orange pi sbc’s some time ago and used that with luma.* to drive displays successfully. Others have also had success with chip and odroid sbcs, but you’re right I think, there are platform divergencies that make it painful, although I think opi.gpio came close to unifying it on different platforms. I haven’t really kept up to date with what the latest is, but vaguely recall gpiod was in the ascendant at some point. Maybe we should look at it again to reassess.

Also it isn’t well documented how to use on non RPi devices 😬

rm-hull commented 3 years ago

Maybe welcome.py is a bit buggy.. I think it will try and pick some random offscreen area to scroll in from, then another to scroll out to. On smaller screens it probably works ok, but for a bigger screen maybe it’s not getting past this while loop https://github.com/rm-hull/luma.examples/blob/master/examples/welcome.py#L210

rm-hull commented 3 years ago

Related: https://github.com/rm-hull/luma.examples/issues/100

rm-hull commented 3 years ago

I think this issue can be closed .. we resolved the issue of the trailing pixels, and commit https://github.com/rm-hull/luma.examples/commit/da48c2e4dc00aa99e5f97791f5e5a09c13077805 should have fixed the welcome.py hang

mattblovell commented 3 years ago

Giving commit da48c2e a try on the RPi3 with the 2.8" display. Running nicely for over 10 minutes thus far, much longer than previously.