Tuesday, January 7, 2014

Raspberry Pi Journal #44

Raspi #44
Prevent screen from blanking

If you want to show picture slide shows for hours on end, you probably run into a "feature" that is quite annoying: screensavers. The gist is that the program will interrupt your display to save your screen. It is a prudent action in order to stop your monitor from burning static images. The issue isn't as common as before, but even with the latest LCD display, it is still present. Therefore, having an automatic screen saver feature is desirable.

The problem is when we want the screen to burn all the time, such as displaying photo slide show. How do we disable the screen saver? I'm sorry to say that the system is very complex and that there is no single way to disable the screen saver.

I suppose you can kill the process, but that's not a desirable solution in the long run.

The trick here, is to let the computer know that you want the screen is up all the time. So, press a key in the keyboard or jiggle that mouse. A robot that shakes the mouse all the time seems ideal. Alternatively, put the mouse in a shake box.

However, we can do better than that. Even if the solution is hackish, we should do it all in software. There is such a thing, and it is:


That's a python script. So far, that pygame is for Python 2.7. So we'll use that. Write a python program that will poll the keyboard/mouse event. Let's call it: unblank.py

  1. import pygame
  2. pygame.init()
  3. pygame.event.get()

And when you run this program:

python unblank.py

The screen saver process should terminate and the timer will restart. All you have to do is call it periodically and problem solved!

I'll just stick that line in my wallpaper rotation script

  1. #!/bin/bash

  2. for ((walltick=100;$walltick;walltick=$walltick-1))
  3. do 
  4.   PIC=$(ls wallpaper/*.jpg | shuf -n1)
  5.   pcmanfm -w $PIC
  6.   *python unblank.py*
  7.   sleep 100 
  8. done
  9. pcmanfm -w saber.png
  10. sleep 5
  11. exit 0

The whole process takes a couple second because python is not an insignificant process. So this answer is hackish and not very good.

And what do you know? It doesn't work! I would think that pygame.event.get() will reset the input, but apparently not. So, back to square one. The problem is, there are so many things that can be wrong, and you never know which one. That's very frustrating.

So, let's open up a window and see if that works. Here's the modified python script

  1. import pygame
  2. from time import sleep

  3. pygame.init()
  4. window=pygame.display.set_mode((32,24))

  5. while True:
  6.     pygame.event.get()
  7.     window.fill(pygame.Color(255,255,255))
  8.     pygame.display.update()
  9.     sleep(100.0)

Notice that this is an infinite loop, which is something I try to avoid. The problem is that it opens up a window, so I can do something to it, and that's not good. So, now, I'm running the script in the background, minimizing the window.

Minimizing the window needs to be done manually, which is a terrible solution. Worse, when I kill the process, the window still stays up! There's no way to terminate the window that I can see. Therefore, this command is useless:

  1. python unblank.py & pid=$!
  2. kill $pid

Because python script is killed yet the window is still up, there's no longer any way to close the window. It's definitely broken. So, now, I pull another shell just to run the program, keeping it in the background. That's another window open.

Of course, the right solution is to provide a refresh command, that we can use to reset the screensaver timer. How is it that we do not have such command?

No comments:

Post a Comment