3

I would like to be able to switch my Pi between several different physical monitors that I have (one at a time). The screens are not all the same type or resolution.

For most of the monitors, the Pi's autodetection works fine and it displays at the "right" resolution with nothing specified in config.txt.

However for some of them I need to explicitly specify hdmi_mode or similar in config.txt to get it to display at the correct resolution. Unfortunately, this means that I need to edit config.txt every time that I want to switch between these screens.

Is there any way of avoiding this? Can I somehow get it to detect a specific brand/model of monitor (via EDID, presumably) but then go to a specific mode that I choose for that monitor instead of what it wants to do by default -- while still behaving normally for other monitors? Ideally right from boot, but it's probably ok if a boot script can change the resolution in flight.

I'm ok with modifying code to do this, if someone can point me at the program that would have to be changed.

6
  • With a bit of futzing around with tvservice and awk I've come up with something that seems to do the trick (it's ugly, but I'll post it if there's interest). But a remaining issue is that one of the monitors also needs an hdmi_cvt custom mode. I can still handle that via config.txt as long as there's only one of them, but if I ever get a second monitor that needs a different custom mode then I'll have a problem. Is there a way to emulate hdmi_cvt via tvservice as well? I couldn't see anything.
    – Miral
    Commented Sep 29, 2014 at 6:09
  • (Ideally there'd be something in config.txt itself, or separate files, that could use specific settings for certain display names. But I don't think I can change that myself.)
    – Miral
    Commented Sep 29, 2014 at 6:40
  • you may strongly consider getting one Pi for every monitor you have, it's not very expensive, you know...
    – lenik
    Commented Sep 29, 2014 at 9:17
  • Possibly I oversimplified. I do have more than one Pi, but I want to be able to swap the cards between them or just have identical copies of the same card without having to worry about matching the card to the monitor.
    – Miral
    Commented Sep 29, 2014 at 21:37
  • this contradicts to your another requirement: "I need to explicitly specify hdmi_mode or similar in config.txt to get it to display at the correct resolution. Unfortunately, this means that I need to edit config.txt every time that I want to switch between these screens."
    – lenik
    Commented Sep 29, 2014 at 23:26

2 Answers 2

0

The somewhat similar issue was posted here. A part of that post details a startup script that waits for a monitor to be connected and then reads the EDID, sets the preferred group/mode and then runs fbset to modify the frame buffer. For your use case, you'd need to make some changes to the line that looks for "preferred mode" to do whatever you want.

Another solution is to run a startup script that does almost the same thing except it then writes to /boot/config.txt automatically and then triggers a reboot if it actually changed the hdmi_group or hdmi_mode.

# Taken from http://blogs.wcode.org/2013/09/howto-boot-your-raspberry-pi-into-a-fullscreen-browser-kiosk/

# Wait for the TV-screen to be turned on...
while ! $( tvservice --dumpedid /tmp/edid | fgrep -qv 'Nothing written!' ); do
    bHadToWaitForScreen=true;
    printf "===> Screen is not connected, off or in an unknown mode, waiting for it to become available...\n"
    sleep 10;
done;

printf "===> Screen is on, extracting preferred mode...\n"
_DEPTH=32;
eval $( edidparser /tmp/edid | fgrep 'preferred mode' | tail -1 | sed -Ene 's/^.+(DMT|CEA) \(([0-9]+)\) ([0-9]+)x([0-9]+)[pi]? @.+/_GROUP=\1;_MODE=\2;_XRES=\3;_YRES=\4;/p' );

printf "===> Resetting screen to preferred mode: %s-%d (%dx%dx%d)...\n" $_GROUP $_MODE $_XRES $_YRES $_DEPTH
tvservice --explicit="$_GROUP $_MODE"
sleep 1;

printf "===> Resetting frame-buffer to %dx%dx%d...\n" $_XRES $_YRES $_DEPTH
fbset --all --geometry $_XRES $_YRES $_XRES $_YRES $_DEPTH -left 0 -right 0 -upper 0 -lower 0;
sleep 1;
1
  • As noted in a followup comment, I already have a script that does approximately this (although mine was less generic; it used an explicit model name -> resolution lookup table that I had to update each time a different display was used). However this doesn't work with hdmi_cvt custom modes, as tvservice doesn't support changing them after boot, which is what I was asking about.
    – Miral
    Commented Nov 24, 2014 at 6:49
0

FYI, after asking about this here I contacted the makers of the Pi directly and something was added to the config.txt file to support this more directly (at least for the case where the monitor is connected at startup -- if you want to switch monitors after boot then you'll still need a script).

See the documentation, specifically the section starting The [EDID=*] filter.

Essentially, you can use tvservice -n to find the unique EDID name of each monitor, and then use multiple [EDID=the_name] sections to provide the settings to use for each monitor.

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.