5

I am using RPi 3 and a RPi touchscreen as my primary display.

I would like to output an image to an HDMI display to be displayed for x seconds (to project an image for a 3D printer). HDMI output is:

  • image only
  • it doesn't need any sound, or mouse overs etc... just a simple image.
  • HDMI image is different to that displayed on touchscreen (i.e. screen mirroring will not suffice)
  • I may need to fire events on the RPi in between images

From my research, it looks like running dual display on RPi is complex (/impossible - I'm new). But since I'm only looking to fire just an image to the HDMI, is there a direction which can do this?

I am very flexible on learning new programming languages to achieve this.

Many thanks...

2 Answers 2

4

Summary: Finally, my solution used the Kivy framework. Kivy is a graphical framework for Python and, critically for my app, has the ability to output to both the RPi's LCD touchscreen and HDMI. Kivy can do a lot of UI heavy lifting, I was able to construct a rich control panel on the LCD touchscreen which served as a great front end for the machine.

Try the following steps, to get a very basic demo:

  1. Put Kivy on the Pi. The simplest way to is to use a KivyPie image to start with a clean, lightweight distribution with Kivy already setup.

  2. Create these 2 files in the same directory and run "dualoutput_main.py":

dualoutput_main.py

# Using Kivy Framework, this example module provides a basic touchscreen interface 
# on official RasPi 3 touchscreen.
# A button press runs a separate python app (dualoutput_sub.py)
# which is configured to run through RasPi HMDI output.
# It is important to note that both instances are unconnected - this is an undesirable
# sideffect of trying to get 2 different results on 2 different outputs on the RasPi 3.
# Comms between the two instances, if needed, is a separate topic ;-)

from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '440')
import os
os.environ["KIVY_BCM_DISPMANX_ID"] = "4" #LCD 

from  kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.base import runTouchApp
import subprocess


Builder.load_string("""

<TouchScreen>:

    BoxLayout:
        orientation: 'vertical'
        padding: 30
        spacing: 30
        Label:
            text: 'Click button to run HDMI app'
        Button:
            text: 'Run HDMI output'
            on_release: root.hdmi_go()

""")

class TouchScreen(Screen):

    def hdmi_go(self):
        print 'opening projector sequence'
        subprocess.Popen("python dualoutput_sub.py", stdout=subprocess.PIPE, shell=True)

runTouchApp(TouchScreen())

dualoutput_sub.py

# Example app to demonstrate kivy output on RasPi 3 HDMI
# Simple label counter ticks up to infinity

import os
os.environ["KIVY_BCM_DISPMANX_ID"] = "5" #HDMI 

from  kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.base import runTouchApp
from kivy.clock import Clock
from kivy.properties import NumericProperty # @UnresolvedImport (for Eclipse users)


Builder.load_string("""

<HDMITestScreen>:

    Label:
        font_size: 50
        text: str(root.label_number)                    

""")

class HDMITestScreen(Screen):

    label_number = NumericProperty(0)

    def __init__(self, **kwargs):
        super(HDMITestScreen, self).__init__(**kwargs)
        Clock.schedule_interval(self.increment_label_number, 1)

    def increment_label_number(self, dt):
        self.label_number += 1

runTouchApp(HDMITestScreen())

Notes:

  • KivyPie was a useful lightweight distribution for dev.
  • I ran the LCD instance as the main program, which called a subprocess for a separate HDMI instance.
  • Learning Python (coming from Java) and I found this site useful.
  • Learning Kivy is hard but worth learning, start here.
  • As a noob, all this tricky, but the results were definitely worth it (Kivy is very powerful for this kind of UI) and I will use this approach for future machines.
  • I have yet to find a better solution!
2
  • Thanks for sharing your solution. Could you share an example (or doco reference) of how to use Kivy to show different things on LCD and HDMI simultaneously? Commented Jun 13, 2017 at 2:46
  • @Christopher Biggs Hi, sorry this took a while to get to! Have edited with some very basic code to illustrate the approach in its simplest form.
    – Neex
    Commented Mar 6, 2018 at 1:27
1

I agree that general purpose dual display is intractable, I've struggled with that too (you can mirror, if that helps).

What is possible is using the HDMI for movie output while using the LCD for desktop.

So did you try rendering your image as a video clip, and use omxplayer to play it (eg like this http://linuxcommando.blogspot.com.au/2014/06/create-slide-show-from-pictures-part-1.html)

3
  • Thanks so much... this would be a great workaround, but I forgot to mention that in my case I need to fire events between HDMI images - I've updated the OP.
    – Neex
    Commented Apr 22, 2017 at 10:46
  • I think that still works, eg encode each image as a 3 second single-image video slideshow, then do play image 1, send event A, play image 2, send event B, etc. Commented Apr 23, 2017 at 21:39
  • So I tried this approach, and technically it works... but I abandoned in the end since ffmpeg installation was a mission on the pi, it attracted video quality nuances, and then the processing time to generate a video for each layer took too long with the Pi's power. I'll post the direction I ended up taking in the end. Many thanks though...
    – Neex
    Commented Jun 11, 2017 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.