Arduino Computer Display Rotator
2017-02-13 | By All About Circuits
License: See Original Project Arduino
Courtesy of All About Circuits
A lot of digital content these days is tall and narrow (portrait orientation), yet most computer screens are short and wide (landscape orientation). This means that a lot of screens have wasted real estate. Compare the screenshots below. In landscape view, only one and a half posts can be seen, whereas 3 can be seen in portrait.
Landscape Mode
Portrait Mode
For this reason, I like to rotate my computer monitor 90º when I browse social media, however, switching the display settings back and forth gets tedious. This is especially tedious if you have multiple monitors or a computer that doesn’t support the standard keyboard shortcuts. Luckily, there’s a fix for that. This project will show you how to build a device that automatically tells your computer to rotate its display when your monitor is physically rotated.
Working Principles
This device uses an Arduino, and is mounted to the back of a monitor. An accelerometer is used to sense direction. The accelerometer interprets gravity as an acceleration upwards of 9.8m/s2 when stationary. The accelerometer talks to the Arduino with the I2C protocol. The Arduino constantly looks at (polling) which direction the accelerometer thinks it's accelerating in. When that changes, it sends a signal to the computer via USB. A python script running on the computer reads the change, and tells the computer to rotate the display accordingly.
This article explains how to implement a display rotator on Windows and Linux. It can probably be done on Mac too, but since I don’t own one, I can't try it out. (The only difference would be the system command called by the Python script.)
Materials
You will need:
- Arduino – I used an Uno, but any Arduino should work
- Arduino prototyping shield - any style will do
- MMA7455 Accelerometer
- Sticky mounting pins
- Pushbutton
- 100kΩ Resistor
- A few wires
- A soldering iron and solder
Of course, you'll also need a monitor that can rotate. If your monitor doesn’t rotate, check to see if it has VESA mounting holes (These are usually 4 or 8 screw holes in the back of the monitor). You can buy VESA compatible monitor stands that can rotate for around $70.
Construction
Let’s grab our soldering irons and get started!
If you have experience with electronics, some of the accelerometer’s pin names should look familiar. VCC and GND will be tied to the Arduino's power rails. CS means "chip select". Since this project will only have one chip, we'll physically tie that to 5V. SDA and SCL are the communication lines used in the I2C protocol. If you're not using an Arduino Uno, the pins for SDA and SCL may be different.
Arduino Code
If you have don’t have experience with Arduinos, check out this Beginner's Guide to Arduino.
Get started by plugging the cape into the Arduino, then plug the Arduino into your computer via USB.
As mentioned before, we use an accelerometer to detect the monitor’s direction by measuring when a direction reads an acceleration of 9.8m/s2. The monitor will only ever be horizontal or vertical, so this will be easy! (Accounting for diagonal directions would make things more difficult.)
When programming, it’s good practice to separate the different aspects of your code into different files. We used the official MMA7455 library to make our own code for sensing orientation. This allows us to keep our main file simple by abstracting away the detail of how this is done. This file checks orientations with one function call, and writes a message to the computer when it changes.
You can download the full code on All About Circuits.
Open up monitor.ino in the Arduino IDE. Compile the code and run it. (All 3 Arduino files need to be kept in the same directory.) Open your serial monitor using Tools > Serial Monitor, or with ctrl shift M.
You should see something like this:
Freescale MMA7455 accelerometer
May 2012
The MMA7455 is okay
STATUS : 0
WHOAMI : 55
Assuming the device is Y_POS
Now hold the Arduino so it’s on a vertical plain. Rotate it around (still in a vertical plane). You should see something like this each time it rotates 90º:
Rotate Monitor
change detected
Rotate Monitor
change detected
Rotate Monitor
change detected
Rotate Monitor
Once you have the Arduino code set up, mount your new device on the back of your monitor and connect it to your computer via USB cable. There are several ways to mount it. I used adhesive hooks.
We’ll need to calibrate our accelerometer so it knows which direction it’s pointed in when we turn it it on. This initialization will run every time the Arduino is turned on. When used on your monitor, this may be whenever your computer is turned on. (This also depends on whether or not your USB ports supply power when your computer is off.) When your computer is turned on, the device will expect your monitor to be in whatever you defined as the default position. If it isn’t, the Arduino will tell your computer to rotate your display the wrong way, or it will get disoriented and won't tell your computer to rotate at all.
This is what our button is for. When it’s pressed, the Arduino will re-run the setup routine and tell the computer to rotate the display to START_ORIENTATION.
Take note of which direction is up when your monitor is in its default orientation when you mount the device on the back of your monitor.
There's a line of code in monitor.ino that you’ll need to change to accordingly. If the y arrow on the accelerometer is pointing up, leave it asY_POS. If the y arrow is pointing down, change it to Y_NEG. For the x-axis, use X_POS or X_NEG.
#define START_ORIENTATION Y_POS
If you want to understand what's happening in the code, read more here.
Computer Side Code
The Arduino sends information to the computer using the same serial interface we use to program and debug it. To avoid clashes, make sure that the serial monitor in the Arduino IDE is closed when you run this script. If it's open, some of the Arduino's messages can be gobbled up by the serial monitor, and the script won't see them, or will only see an incomprehensible portion of them.
We’ll be using Python for our computer side code. This will listen to what our Arduino writes to the serial line, and will make a system call to rotate the display.
Linux users should skip ahead to the Linux section.
Windows
First, you’ll need to download Python from Python.org. You’ll be asked during the install whether you want to add python to your path, say “yes”.
After you’ve downloaded Python, locate windows-script.py in the zip file.
Next, open up the Arduino IDE. Click on Tools > Serial Port. Have a look at which ports are listed, such as COM3.
If you see anything other than COM3, you’ll need to open up windows-script.py in a text editor. Locate the line below and change it to match what you saw in the Arduino IDE.
possibleDevices = ["COM3"]
Search for the following lines. You’ll need to change these numbers in order to suit your setup. The numbers are clockwise in degrees for each possible orientation.
translation = {"Y_POS":"90",
"X_POS":"180",
"X_NEG":"0",
"Y_NEG":"270"}
Now you’ll need to install the pySerial module, which is used to read data from the USB port. Open the command prompt. On Windows 8 and later, search forcmd. On Windows 7 and earlier, you’ll need to find the run utility in the start menu and open cmd.
Type the code below into the terminal that appears:
python -m pip install pyserial
Installing python modules can be finicky. Don’t proceed if it didn’t install successfully.
We have one last thing we need to do before we can run the script. Find the display utility shown in the Windows folder of the zip file listed above (which is from this website).
If you have multiple monitors, you’ll need to do the following. If you only have one monitor, you can skip this paragraph. Open the command prompt where you saved display.exe. (Open up a file browser in that location, then shift right click in the file browser background, and click open the command prompt.) Enter display.exe /listdevices into the command prompt. You should see an index for each monitor. Take note of what the index is for the monitor that you want to rotate.
This python script opens up a connection to the USB port. When a message from the Arduino is detected, it sends the corresponding command to display.exe, which rotates the display. You’ll need to locate the following line and change the directory to point to display.exe.
command = "C:/.../display.exe /rotate:" translation[direction]
Users with multiple monitors will also need to add /device x (where x is your monitor's index). So something like:
command = "C:/.../display.exe /device 2 /rotate:" translation[direction]
Navigate to the folder in your command prompt where you saved display.exe and windows-script.py. Use the cd command to do this. If they're saved in Documents/rotate, use:
cd Documents/rotate
Now type dir to see the list of files in that directory. Double check to make sure you see those two files. Now let's run the python script!
python windows-script.py
To make sure that it’s working, try rotating the device around. The screen should now rotate accordingly.
Now we’ll need to make Windows run this program in the background when the computer starts. By default, startup programs are opened visibly. We don't want a visible command window for this all the time. Instead, we'll create a batch file. This will run our python script in the background and then exit the batch file.
First, open your startup folder. This folder’s location varies depending on which version of Windows you're using. Next, press the Windows key then press R. This should make the run window appear. Type shell:startup and press enter. You should see your startup folder now. Create a new text file in that folder called monitor.bat, and paste the following code into that file. You’ll need to modify the path so it points to the python script.
@echo off
START pythonw C:\...\windows-script.py
We’re using pythonw instead of python because it’s necessary for hiding the the python script’s command window.
Now reboot your computer and see if it works. If it does, you can skip to the end!
Linux
Download Python 3 for Linux here. This can also be done through your package manager. If asked during installation whether you want to add python to your path, say yes.
Install the pySerial module.
python3 -m pip install pyserial
It can be tricky installing python modules. Do not proceed if you have received an error from the command above.
Open the Arduino IDE. Click on Tools > Serial Port and take a look at the ports listed, such as /dev/ttyACM1.
Next, you’ll need to find linux-script.py. This is located in the zip file you downloaded earlier. Open up linux-script.py in a text editor. Locate the line below, and modify it if necessary to add the port you saw.
possibleDevices = ["/dev/ttyACM0", "/dev/ttyACM1", "/dev/ttyACM2"]
The command we’ll need to run will depend on your specific setup. Open a terminal (ctrl alt T) and enter xrandr. You should see a display (or multiple displays), such as HDMI1 or eDP1. Take note of that name. Experiment with the commands below to see if it rotates your display.
For a single monitor with the name HDMI1:
xrandr --output HDMI1 --rotate left &
To put the display back,
xrandr --output HDMI1 --rotate left &
For two monitors, the eDP1 (non-rotating, on the right) and the HDMI1 (on the left), try:
xrandr --output HDMI1 --rotate left --primary --output eDP1 --auto --right-of HDMI1 &
To put it back:
xrandr --output HDMI1 --rotate normal --primary --output eDP1 --auto --right-of HDMI1 &
Take note of which command worked for your setup. Change the command = "xrandr --output ... line in your script to the appropriate display port, where normal or left is replaced with " translation[direction] " (including the double quotes).
Now run the script with:
python3 script.py
Try rotating the device around to see if the screen rotates accordingly.
If your screen rotates, but the rotation isn’t the correct one, you’ll need to modify the following line in the python script accordingly:
translation = {"Y_POS":"normal",
"X_POS":"right",
"X_NEG":"left",
"Y_NEG":"inverted"}
Now you just need to start the script automatically upon booting. The details of this will depend on your distro. Try searching for startup in the start menu. You can also add a cron job to do it.
Done!
Now sit back and enjoy that extra screen space!
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum