Using the Texas Instruments DLP4710EVM-LC for generating visual stimuli at 180 and 1440 Hz

In brief: what it is and what it can do

The DLP4710EVM-LC is an evaluation module made by Texas Instruments (the inventor of the DLP projector) in order for engineers who design projectors and other equipment to be able to evaluate their latest components. Out of the box, it works as a ordinary DLP video projector, taking in video signals through its HDMI port and outputting images at 1920 × 1080 × 60 Hz × 24 bits per pixel. But with a little additional work, it can be made to operate in two unusual modes:

At 180 Hz the unit makes an excellent CRT replacement. At 1440 Hz it gives access to stimuli (for instance very high-speed motion) that can only be matched by one other commercially available display (see below), but for a small fraction of the price.

At 60 and 180 Hz, the projector should be compatible with any system. (But to switch to 180 Hz mode, you will need need a Windows PC — or figure out how to send I2C signals from your Mac or Linux machine.) In 1440 Hz mode, you will need to make sure that your video card sends RGB signals without modification. This seems to be possible on:

On the other hand, this does not seem to be possible on MacOS because it doesn't seem to allow access to low-level graphics card parameters. To summarize, you should have no trouble displaying in 180 Hz mode on any system (but will need a Windows machine to switch modes). Your best bet for 1440 Hz is Windows with an NVIDIA graphics card.

In terms of software, if you use either Matlab + Psychophysics Toolbox version 3, or OpenGL directly (from Python or C), you should be able to display stimuli at 180 or 1440 Hz with minimal modification of your code.

This page gives advice, pointers, and sample code for using this projector to display at 180 and 1440 Hz, from the point of view of a psychophysicist.

In detail

As far as your graphics card is concerned, the projector always operates as a 60 Hz display. In order to go to higher refresh rates, you have to do two things: And before you start, you will probably have to update the projector's firmware.

Before using the projector for the first time

In order to use 180 and 1440 Hz modes, the firmware on the projector needs to be updated. This has to be done on a Windows PC using TI's graphic control tool.

To check the version of firmware that you've installed, click the "Get" button in the lower-right corner of the first tab (Information) of graphic control tool.

How to squeeze multiple frames into every frame

60 Hz

In 60 Hz mode, the projector operates as regular display, with each pixel having 24 bits of color and luminance: 8 bits for red (256 luminance levels), 8 for blue, and 8 for green.

180 Hz

180 Hz mode is 8-bit monochrome. You must choose which color you want: red, green, or blue, but not all three simultaneously — so no gray. You will get 256 luminance levels in your chosen color. Because 180 = 60 × 3, you will need to squeeze 3 frames into every image. You do this by drawing the chronologically first of three frames in the blue channel, the second in the green, and the third and last in the red. After drawing these three frames you do an ordinary buffer flip. When the projector receives the data, it will show the three frames in chronological sequence, all in the same color, each frame being shown for 1000/180 ≈ 5.6 ms.

You might be tempted to use your regular drawing code but to draw your first frame in blue, the second in green, and the third in red. This probably won't work, though, because in ordinary drawing mode the color you assign to a pixel overwrites the color that was there before — whereas what you want is to accumulate or add up colors. For example, if you draw your first image in shades of blue, and then the next images in shades of green (so with 0 for blue and red), this will erase the previous blue image — and the same thing for the following red image.

You can solve this problem by using color masks. If you mask a particular color or colors, any drawing command will have no effect on the masked colors. Thus, you can mask green and red while drawing the first frame in blue, then mask blue and red while drawing the second frame in green (which won't erase the blue image because it's now masked), and finally mask the blue and green while drawing the third frame in red.

In Matlab + Psychophysics Toolbox, this can be done as follows:

Screen('BlendFunction', window, GL_ONE, GL_ZERO, [0 0 1 1])

before drawing the first (blue) frame, then

Screen('BlendFunction', window, GL_ONE, GL_ZERO, [0 1 0 1])

before drawing the second (green) frame, and finally

Screen('BlendFunction', window, GL_ONE, GL_ZERO, [1 0 0 1])

before drawing the last (red) frame. (If you're using alpha blending, then you'll want to use other values in place of GL_ONE and GL_ZERO.)

If you're using using OpenGL directly, then the equivalent calls to those above are:

glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE)

To summarize, you can keep using your regular drawing code, but instead of clearing the back buffer, drawing to it, and flipping buffers on every frame, for every three frames you

You'll find examples of this in Matlab and Python, including simple classes that take care of the bookkeeping, in the code below.

1440 Hz

1440 Hz mode is has only 1 bit of luminance, so your resulting images are black and green, black and red, or black and blue (without intermediate shades). Here, you need to squeeze 24 1-bit images into one 24-bit image, and you do so by drawing them into the 24 bitplanes. Imagine each 24-bit color value as binary number, with the lowest 8 bits representing the blue channel, the next 8 bits the green, and the most significant 8 bits the red. Further, assume that the lowest bit of each 8-bit group represents the least luminous bit in that channel. Thus, the binary number 1 = 000000000000000000000001 would represent the darkest blue, and 111111110000000000000000 the brightest red. Then the least-significant bit codes the first image to be displayed chronologically, the second-least-significant bit the second image, ..., and the most-significant (24th) bit the 24th and final image.

This is the equivalent of drawing

Since you cannot easily mask out individual bit planes, another simple solution can be used: alpha blending. While alpha blending is usually used to simulated transparency, it can also be used to add every color to the color already at the pixel, rather than overwriting — which is exactly what we want. To do this in Matlab, we need to set the alpha blending factors like this

Screen('BlendFunction', window, GL_ONE, GL_ONE)

Then, for every sequence of 24 frames, on every frame we set the RGB color to the corresponding color in the above list and then draw our stimulus (taking care never to change the color). We clear only on the first of the 24 frames, and flip only the last one. An example can be found below, together with a class to simplify the bookkeeping.

In pure OpenGL, another mechanism can be used: logical operators. By setting the logical operator to bitwise OR, incoming colors are added to previous colors at each pixel. This is done by calling

glEnable(GL_COLOR_LOGIC_OP)
glLogicOp(GL_OR)

Then, on each frame out of groups of 24, we set the corresponding color and draw the stimulus. As in Matlab, we clear only on the first of the 24 frames, and flip only the last one. Examples and helper classes can be found below.

How to change mode using the USB channel

In Windows, one way to switch modes is by using TI's graphic control tool. First, make sure your computer is connected to the projector's USB port. Then, when you run the tool