A few months ago I setup a web browser based dashboard running on a Raspberry Pi, displaying weather, time and transit information. It worked out well, but it’s success revealed another problem. Turning the screen on and off multiple times a day was getting old.
So I did what any technically inclined person would do. I decided to create a device to turn the screen on and off by responding to dramatic changes in ambient light. The device would also provide a manual power toggle and button to refresh the browser.
This is part 1 of 3, describing how to create a script to turn on and off the screen and hot keys to call this script.
- Arduino Screen Controller for Raspberry Pi Part 1 Hot Keys
- Arduino Screen Controller for Raspberry Pi Part 2 Hardware Prototype
- Arduino Screen Controller for Raspberry Pi Part 3 Hardware Final
Although intended to be used with a Raspberry Pi, the screen controller can be used to emulate a USB keyboard and send any desired keystrokes.
- Using Rasperry Pi Model B rev 2
- Monitor using HDMI port
- Raspbian wheezy
- X windows running with lxde
- USB keyboard for testing
- Github Arduino Screen Controller
Screen Control Commands
The Raspberry Pi has a utility called tvservice that controls the video hardware. Progammatically turning off the screen turned out to be quite simple, but turning it back on turned out to be more complex.
To turn back on, calling tvservice must be followed by calls to fbset and xrefresh. In fact, two fbset calls are required because fbset will not do anything if it thinks nothing has changed. Specifically, it is necessary to ‘bounce’ the color depth to 16 and back to 32. It appears that fbset is not aware that tvservice has turned off the video hardware and apparently reset the color depth.
NOTE: I have changed the default color depth for my Raspberry Pi to 32 bit, for details see Set Color Depth in Raspberry Pi Full Screen Browser. If you have not made this change, try setting the depth to 8 and then 16, this should have a similar effect.
/opt/vc/bin/tvservice -p && fbset -depth 16 && fbset -depth 32 && xrefresh -display :0.0
Test these commands out on your Raspberry Pi before continuing to make sure they work. They can be safely run from an ssh connection.
Screen Control Shell Script
The screen control commands were wrapped in a shell script which logs requests and is called by they hot keys. State is stored by the Arduino device.
This shell script should be created by the default user and in a place the user can access it. For example if the default user pi is used, it can be in /home/pi.
#!/bin/bash if [ ! -z "$1" ] && [ $1 = "on" ]; then echo "Turning screen on." echo "Turning screen on." >> ~/screen-control.log /opt/vc/bin/tvservice -p && fbset -depth 16 && fbset -depth 32 && xrefresh -display :0.0 elif [ ! -z "$1" ] && [ $1 = "off" ]; then echo "Turning screen off." echo "Turning screen off." >> ~/screen-control.log /opt/vc/bin/tvservice -o elif [ ! -z "$1" ] && [ $1 = "status" ]; then /opt/vc/bin/tvservice -s else echo usage: echo $0 on echo $0 off echo $0 status exit fi
Finally, make the file executable.
chmod u+x screen-control.sh
Next step is to create a hot key combination to turn on and off the screen, relying on sending the F5 key to refresh the dashboard in the web browser.
The hot keys are added to the lxde configuration file which is the default Raspbian window manager. The hot key combinations are:
Command + 0 to turn off
Command + 1 to turn on
The Apple Command Key and Windows Key can be used interchangeably.
Edit the lxde-rc.xml config file:
– Add to the <keyboard> section:
<!-- BEGIN Adding keybindings --> <keybind key="W-0"> <action name="Execute"> <command>~/screen-control.sh off</command> </action> </keybind> <keybind key="W-1"> <action name="Execute"> <command>~/screen-control.sh on</command> </action> </keybind> <!-- END Adding keybindings -->
Restart the window manager by rebooting.
After reboot test the script, plug in a usb keyboard and type Command + 0 to turn off and Command + 1 to turn on.