Graphical front panel display

@noggin, this may interest you…

With the 2.0.0 release of luma.core, it now provides a linux_framebuffer device:

https://luma-core.readthedocs.io/en/latest/device.html

I’ve updated kodi_panel_fb.py on github to make use of that, rather than the Pytoronix framebuffer.py. It’s not necessarily fast (I think it’s doing a full update of the display presently), but one can just use “RGB” for the Pillow Image. One can always adjust the kodi_panel’s sleep time in the update loop (which I’ve done for what I pushed to github, appropriate for my current panel).

The changes amount to eliminating most of the luma-related imports at the start, leaving just:

from luma.core import device

and changing the device instantiation to

# Use a Linux framebuffer via luma.core.device
device = device.linux_framebuffer("/dev/fb1")

adjusting for whatever framebuffer you need, of course.

I’ve opened an issue for luma.core inquiring whether one can make use of its more efficient diff_to_previous algorithm for the framebuffer update.

On a separate topic, I’ve also decided to give up on making use of the RPi4’s two HDMI outputs – at least for now. I still want to upgrade from the TN panel I currently have, though. I’m thus going to give the 3.5" IPS 320x480 panel from Waveshare a try. It’s using (I believe) an ILI9486L controller. It should not take much to get that working with luma.lcd.

Cheers,
Matt

A somewhat similar thread for a project that got started in Nov 2019 from a Volumio user:

Volumio with 3.5” TFT Touch Screen (GPIO) RPi 3B+
https://community.volumio.org/t/volumio-with-3-5-tft-touch-screen-gpio-rpi-3b/11265

From what I can tell thus far, both Volumio and moOde Audio support a local display by starting up a web browser within X, making use of that normally-remote interface for the attached display.

Added it and PyAudioTFT to the running summary post above.

Yep - I think the Volumio local-screen-via-webbrowser is pretty popular with people using the Pi Foundation DSI display, as there are nice, HAT DAC-compatible cases for it.

I’m taking your earlier advice, @noggin, and ordered an Rpi Zero W to experiment with, in addition to several connectors and ribbon cables to make DIY HDMI and USB connections. We’ll see how well the Zero can drive the HDMI display. (It’s nearing Christmas, so the SO is letting me indulge my hobby!)

An update is in-progress for luma.core that should improve its performance when driving a framebuffer. Basically, the same diff-to-previous algorithm that only re-draws the portion(s) of the display that have changed is also going to get used for the framebuffer. For kodi_panel, since the progress bar and timer are kept fairly close to each other, only a small portion of the framebuffer gets updated. This may help the CPU load you mentioned in an earlier post.

I don’t think the changes have been merged into luma.core’s master branch yet, but it shouldn’t be too long.

We’re certainly not the only ones with some time on our hands… Check out the photos in the opening post for this Volumio forum thread.

I like the machined case! PeppyMeter may also be worth looking into.

The Pi Zero has no problems driving displays up to 1080p60. I managed to get a pre-Pi 4B model to drive a 2160p24 HDMI display - and I think I even got a Zero to do it.

The Pi is great at letting you program custom timings if the OS doesn’t have native support for what you want - not just for DPI displays but also for HDMI. I also got Pis to feed iPad Retina displays interfaced with an HDMI->Displayport (these are quite rare) adaptor and then a DisplayPort to eDisplayPort and backlight driver designed for the iPad screen (Adafruit and a couple of other places do them) in native resolution via a custom HDMI timing.

Standard CEA and PC resolutions should ‘just work’ if the display correctly flags via EDID.

Ok, it’s still a work in progress, and I’ve not yet submitted the pull request to luma.lcd, but I have the Waveshare 3.5" IPS panel (based on an ILI9486 controller) working.

I’ve also worked to separate kodi_panel’s drawing / rendering code from the code that’s responsible for opening the SPI interface and getting the display (or framebuffer) going. I’ve also pulled out almost all of the setup into a TOML file.

So, the whole program to try out the Waveshare display is now just this:

from luma.core.interface.serial import spi
from luma.core.render import canvas
from luma.lcd.device import ili9486

# kodi_panel modules
import config
import kodi_panel_display

# ----------------------------------------------------------------------------

# SPI interface
serial = spi(port=0, device=0, gpio_DC=24, gpio_RST=25,
             reset_hold_time=0.2, reset_release_time=0.2)

# LCD display
device = ili9486(serial, active_low=False, width=320, height=480,
                 rotate=1,
                 bus_speed_hz=32000000
)

if __name__ == "__main__":
    try:
        kodi_panel_display.main(device)
    except KeyboardInterrupt:
        kodi_panel_display.shutdown()
        pass

I’ve not scaled anything or changed positions. All of that is now in the settings.toml file, so it should be straightforward.

2 Likes

I’ve updated kodi_panel on github to version 0.90. Details…

Switched to a TOML setup file, simplifying the executable scripts. Added an example layout for a 480x320 display.

Executable scripts are now the following:

  • kodi_panel_ili9341.py: the original version, using a 320x240 ILI9341 SPI display
  • kodi_panel_ili9486.py: new example using a 480x320 ILI9486 display (luma.lcd support not yet released)
  • kodi_panel_demo.py: pygame emulator example, courtesy of luma.lcd functionality
  • kodi_panel_fb.py: framebuffer version

All of those scripts make use of the code that now resides in kodi_panel_display.py.

Screen layout is entirely determined by the settings made in setup.toml. Two example files, at two different resolutions, provided. I also added several new fonts in the fonts/ directory.

Here’s the latest 480x320 layout, making use of Google’s Roboto font.

kodi_panel_demo_480x320

The fullscreen and fullscreen w/vertical progress bar screens still exist too.

If anyone has ideas regarding alternate display layouts, just let me know. Fields can be omitted just by commenting them out in setup.toml. New fields depend upon extending the JSON-RPC query, so a little bit of coding is needed.

Finally, I played a little bit with the RPi Zero driving a 4" HDMI IPS panel. It can certainly drive it, but I’m worried about computational speed a little bit. Having Python manage the contents of an 800x480 framebuffer, even with an actual device driver managing the HDMI display, may be asking too much of the Zero.

Cheers!
Matt

1 Like

BTW, @noggin, I found the following to work to stop the cursor from blinking (or from even appearing, unfortunately) if using the same framebuffer on which the console is being displayed…

Add the following to the kernel command line:

vt.global_cursor_default=0

For the RPi, the kernel command line is set via /boot/cmdline.txt.

Below is a photo kodi_panel running via framebuffer on a 480x800 panel. I’ll upload the setup.toml file to github.

I took advantage of the wider aspect ratio to move the album title and artist name to the right of the cover art. I could also make the track title somewhat larger. The cover art in the photo is 400x400 pixels.

The luma.core framebuffer support is coming. There are updates that rm-hull is working on for the 32 bps support and ability to pass bgr option to the linux_framebuffer device.

The main portion of the necessary execution script is below. I’m currently running the HDMI panel attached to an RPi2, where it’s the sole display. So, the fb0 and bgr are the unique changes.

from luma.core import device

# kodi_panel modules
import config
import kodi_panel_display

# ----------------------------------------------------------------------------

# Use a Linux framebuffer via luma.core.device
device = device.linux_framebuffer("/dev/fb0",bgr=1)

# Don't try to use luma.lcd's backlight control
kodi_panel_display.USE_BACKLIGHT = False

if __name__ == "__main__":
    try:
        kodi_panel_display.main(device)
    except KeyboardInterrupt:
        kodi_panel_display.shutdown()
        pass

Now I have to decide whether I want to hang an RPi3 off the back of the display and deploy that.

The IPS display bake-off… The photo doesn’t quite capture the display appearance.

1 Like

A while back I mentioned the problems I was having trying to retrieve Airplay cover art in the same way as other coverart (i.e., call PrepareDownload and then fetch the image via an HTTP get). When running kodi_panel on the same SBC as Kodi itself, one can just access the file directly (it’s down within .kodi/temp), so that’s what I used for a while.

Turns out the solution is to add special://temp as a path within one of Kodi’s list of media sources.

That list of sources is distinct from the sources listed within Kodi’s File Manager. I kept trying to add the special paths there, with no success.

So, now I can retrieve Airplay artwork over the network. The only tricky thing is that Kodi reuses that file over and over again. (There’s a reason it’s in temp, I suppose.) A file modification time examination is therefore necessary to see if the thumbnail has been updated since the last fetch.

Cheers,
Matt

1 Like

The latest github master for kodi_panel has

  • an updated example setup for 800x480 layout (fullscreen modes fixed, layout modified) and
  • improved (hopefully) text wrapping, rather than just text truncation.

Only the 800x480 example currently makes use of wrapping. In text fields that are to be wrapped, one must specify max_width and max_lines.

Here’s the modified layout. I think the wrapped album title makes better use of the available space.

  • kodi_panel_ili9486.py: new example using a 480x320 ILI9486 display (luma.lcd support not yet released)

Version 2.8.0 of luma.lcd was just released with support for the ILI9486 – at least the Waveshare implementation of it.

https://pypi.org/project/luma.lcd/2.8.0/

@noggin, Version 2.2.0 of luma.core modifies the linux_framebuffer support. It now supports both 24- and 32-bit framebuffers and alternate color orders.

The display bake-off continues… The RPi 4 on the left is driving the ILI9486 3.5-inch display, and there’s an RPi 3 piggy-backed behind the 4-inch HDMI display on the right.

Neither here nor there, and I know it’s silly to judge from photos of display devices, but based on both of your recent “bake off” side-by-side photos, the display with the visible blue mounting holes appears to have the better colour saturation.

Yes, it’s always hard to judge by photos! :slight_smile:

The HDMI display has an unfair advantage since its brightness is turned down via PWM. The other display is still at full brightness. (Adding a little solder blob, in lieu of a 0 ohm resistor, would get PWM working for that display as well.) The 3.5-inch display is also at a bit of an angle in the photo.

Both displays are really nice in-person, particularly with regard to viewing angle.

EDIT: The mounting holes and the higher resolution are definitely pointing in one direction for the “winner”. :grin:

1 Like

Once all the Christmas hoopla is done and over with, I’m looking forward to having a go at retracing your footsteps and adapting wherever needed to suit my N2. This has been a really enjoyable project to follow and as they say imitation is the sincerest form of flattery.

1 Like

Back in October, @RAMALPHA wrote:

Version 0.99 on github now has some preliminary support for showing screens during movie / video playback. See the new VLAYOUT_NAMES and VLAYOUT dictionary examples in the example_setup_800x480.toml file.

I’m hoping others will submit changes as needed for TV episode support. See the VideoPlayer-related JSON-RPC call that’s in the update_display() function of kodi_panel_display.py for the list of fields presently available for info screens.

1 Like

Hi Matt ! That’s great ! Very good news !
I think I will use a raspberry Pi with HDMI output as a separate device, connected to the local network via Ethernet for this purpose. I hope it will be possible in the near future. The HTPC that I built around the odroid N2 does not have enough room for an 800x480 screen, that would involve rebuilding everything.
Keep up the great job Matt !

1 Like