Automated Screen Masking System

Overview and Background:
My home cinema uses a projection method known as Constant Image Height. With this system, different aspect ratios are displayed always using the full height of the screen, and therefore at the sides of the image there will be blank portions unless the image matches the same aspect ratio as the screen (2.35:1).
In order to maximise the apparent contrast ratio of the image, it is necessary to mask the unused portions of the screen with black, light absorbing material. As these unused portions change in size depending on the aspect ratio of the material being displayed, the masking needs to be adjustable.

One of the advantages of a Constant Image Height system is that only vertical masking is required, and this can be easily achieved using a standard corded curtain track. Full automation of the masking system is possible using VLC, which detects the aspect ratio of the video, and outputs this data for use by a custom masking control program.

VLC Player Configuration:
VLC player was chosen for my cinema because I am using two CRT projectors in an edge blending configuration. This is possible with VLC due to the panoramix plugin written by Cedric Coquebert, which by also using the VLC crop plugin splits the source video into two separate streams with an overlap, and a fade to black on the right side of the left image, and vice versa to create a seamless blend.

There are many other advantages of VLC, but the essential feature for the masking system is the automatic aspect ratio detection offered by the 'crop' module. This module detects the aspect ratio of the video, and outputs this as an integer to the STDERR output of VLC.

The VLC I am using currently is the 0.9.0 svn version. You need to enable the crop module in the Video Filters menu, and enable Automatic Cropping in the modules advanced configuration. You also need to set the max ratio depending on the maximum ratio of your screen (mine is set to 2350 for a 2.35:1 screen).

Drive mechanism:
I needed to find a suitable motorised curtain track mechanism. There are several units on the market, but the unit I have used is this one. This works well as a standalone curtain controller, but for our needs must be modified to add RS232 serial control, and to allow accurate absolute positioning of the curtains.

Here is the opener with cover removed:

The unit uses a reversible AC synchronous motor, which via a gearbox powers a single rubber drive wheel, with 2 additional idler wheels. The rubber wheels give a very positive grip on the track cord, and the motor has more than enough torque for even the heaviest curtains. The power PCB incorporates a regulated 5v supply that we can use to power our additional circuitry, and already integrates the relays required to switch the motor in either direction. Our new circuit attaches to the 5 pin header on the board, and directly replaces the original control board.

One main modification to the curtain controller is the addition of an optical rotary encoder to one of the idler wheels. This allows the unit to set the precise position of the curtains on the track, which is achieved in association with a limit switch (I am using reed switches) to set the starting position:

The opto-sensor used is an OPB704 reflective object sensor. The encoder wheel was made from a piece of silver foil and black insulating tape, and attached with double sided sticky tape. I also removed the other idler wheel as I found it not necessary, and wanted to reduce the maximum torque transferred to the curtain cord. The resolution of the encoder wheel shown above allows precision of the curtain movements to approx 1 cm increments.

Control system:
The replacement control system board is designed around a PICAXE microcontroller. This allows a minimal component count, and means we can easily modify the logic of the system if necessary by reprogramming. Here is a schematic of the circuit:

The PICAXE BASIC program can be downloaded here.

There are two reed switches which are mounted directly on the curtain track, with the magnet attached to the one runner. The 'Opened' switch is positioned at the maximum open position, i.e. the maximum aspect ratio of the screen. This is used during initialisation to set the starting point. The reed switches I am using are these ones.

The 'Closed' switch is at present only used as an overrun cutoff, but with program modification it could be used to assist in calibration, or could in fact be removed completely.

Circuit constructed on stripboard:

Opener with new board fitted into case:

Opener reassembled with D connector for RS232 and Reed switches mounted where the original LCD was located. Note this was taken before the optical sensor was added and the second idler wheel was removed.

Unit mounted and cord threaded onto drive wheel:

Communications protocol:
The unit has a very primitive protocol for communicating with the host PC. The RS232 serial parameters used by the controller are 2400 baud, 8 data bits, No Parity, 1 Stop bit, and each position command consists of 2 ASCII bytes. Byte 1 is the command type, and byte 2 is used directly as a relative position value 0-255.

Command ASCII values are as below, and should be immediately followed by a second byte to specify the value 0-255:

r – (Reset) Moves the track to the fully open position, stopping only when reaching the 'opened' limit switch. Used for initial absolute positioning. Note that the second byte is a dummy value, but must be specified in order to pad the command to 2 bytes.
o – (Open) Moves the track x increments in the open direction, or until the 'opened' limit switch is reached.
c – (Close) Moves the track x increments in the close direction, or until the 'closed' limit switch is reached.

For each command, an ASCII value of 'A' is returned when the track reaches the requested position. The unit will not listen for further commands until the acknowledge for the current command is sent, therefore the controlling host must buffer any further position requests.
The buffering, tracking of current position, and additional logic is handled by a Perl program that can be downloaded here. I use ActivePerl on Windows, and you will need to install the Win32::Serialport and Win32::API modules using the PPM provided with the ActivePerl package.
On executing, the program resets the masking system to fully open position, launches the VLC player, and listens to its STDERR output for 'ratio' statements from the VLC crop module. On detecting a change in aspect ratio, sends the necessary commands via the serial port to move the masking to the correct position.

However, before running this for the first time, some parameters must be set. This is because the unit will need to be calibrated depending on the maximum aspect ratio of the screen, and the size of the screen:

$current_position must be set to match the 'max ratio' crop setting in VLC, which corresponds to the aspect ratio of the screen (mine is 2350)
$mask_total is the number of counts of the optical position sensor to move from '$current_position' to a ratio of 0 (completely closed).

In order to determine the $mask_total value, you can use the perl program This accepts two arguments, first is the command, second is an integer 0-255, eg:

./ c 10

moves the track in the close direction by ten increments. Start by issuing a reset command (i.e. ./ r 0) then close in increments of approximately 10, until the curtains are fully closed. Trial and error will determine the exact value to move from a reset position (fully open) to fully closed – this is the $mask_total value.

Known problems, limitations, warnings etc:
The curtain opener has a massive amount of torque, even with one of the idler wheels removed. If the track is not FIRMLY attached to the wall and the controller drives past its open limit, it can pull the track off the wall! Therefore, if the reed switch or magnet is not positioned correctly the motor can overrun. Also, if the reed switch connector is not plugged in this will have the same effect. Some current limiting of the motor would be nice to have. Also, the PIC program could be modified to stop the motor drive after a time delay so it doesn't continue to run if no limit is reached (something must have gone wrong).

As the motor has some intertia it does not stop immediately, which means that after a number of ratio changes the curtain position can drift slightly. Resetting back to the home position corrects this – how often this is needed remains to be seen. I would suggest at least when a movie file is stopped and a new one played.

If the masking is to be also used as curtains,i.e. fully close over the screen after/before a movie starts playing, then the PIC code would need to be modified to allow for this.

This is still experimental at this stage, although it does work. If you have any comments, (or have improved the program and want to send me a copy!) please email me at