Active Shutter 3D glasses

I have had my gamecube displaying 480p via hdmi for a little while now and after reading about a DIY vectrex 3D imager using LCD shutter glasses, I started to wonder if it was possible to display a stereoscopic 3D image at 480p on the gamecube using shutter glasses. I started to research if it had been done before and the only thing I could find was this nugget of gold from the wikipedia luigi's mansion page under the development subtitle.

"All GameCube systems support the display of stereoscopic 3D, and Luigi's Mansion was developed to utilize this feature.[23] However, 3D televisions were not widespread at the time, and it was deemed that compatible displays would be too cost-prohibitive for the consumer. As a result, the feature was never enabled outside of development."

So it is possible to display a stereoscopic 3d image through the gamecube, however no game or homebrew ever did this and therefore no technical details about how it can be done are available. After some more digging I found some technical details about how the gamecube maybe able to display a stereoscopic 3d image from patent U.S. Pat. 6,609,977. It looks like the gamecube can in fact supported two ways to display stereoscopic 3d images.

Video interface

The video interface on the gamecube can be put into 3D display mode be setting the DLR bit in the Display Configuration Register, if this bit is set the video interface will combine two separate frame buffer images (left and right) into one video image stream. Sending two pixels from the first image buffer and then sending two images from the second image buffer and alternating this until the image stream has sent both images. This is the full quote from the patent

"Video interface can support a 3D liquid crystal display by merging two frame buffer images (left and right) into a single stream of video. The output interleaves between the left and right pictures every two pixels. FIG. 11G shows an example timing diagram."   

Serial interface

The second way is to use the serial interface to control a pair of LCD shutter glasses, there are bits within the SI poll register called VBCPY0-3 these bits if set will sync the polling of the serial interface with the video interfaces vblank period. This can be used as quoted from the patent to

"When this bit is asserted, main processor writes to channel 0's SIC0OUTBUF will only be copied to the outbuffer on vblank. This is used to control the timing of commands to 3D LCD shutter glasses connected to the VI."

Which method is best ?

From a technical point of view sending the two images as one stream to the TV would be the best option as this would allow for example a 3DTV to split the image into left and right and control the active shutter glasses directly giving the best stereoscopic 3D image. But and for me this is a big but you would need to convert the combined stream into something the 3DTV can understand, or find a 3DTV that supports the gamecube combined image stream format. As I don't know which input formats a 3DTV supports or if any TV will support the gamecubes combined image format directly. I will go with controlling the LCD shutter via the serial interface. This has the advantage that I will not be tied to certain makes of TV / monitor manufacturer and it will be cheaper. However the downside is the LCD shutter vblank period will be tied to the gamecube and will not be the same as the TV / monitor vblank period this will introduce image lag and increased likelihood of image ghosting.

Active shutter control circuit

I want to keep the cost and re-work to a minimum for this project so I am going to copy most of the shutter drive logic / circuit from the excellent vectrex project over at

https://github.com/mountaingoate/vectrex/blob/master/hardware/3dglasses/3d_glasses.pdf

However the shutter will be controlled via the gamecubes serial interface so we will not need any of the vectrex connections, also the arduino uno r3 control logic will need to re-written for handling gamecube serial interface commands but the vectrex project is a good starting point.

Required parts

Arduino uno r3                  sourced from ebay cost 5

Joypad extension cord      sourced  from ebay cost 4

H-bridge L293D                 sourced from ebay cost 1.25

PS3 Active 3D shutter glasses model CECH-ZEG1U     sourced from ebay cost 10

or

Panasonic Viera TY-ER3D4MU glasses    (untested by me but should work as they are used in the vectrex project)

Breadboard diagram

The drive circuit below is the same as the vectrex project I have only added the required serial interface data line from the gamecube pad port.

Note:

Prototype build

Breadboard layout showing h-bridge drive circuit wiring

PS3 3D shutter glasses taken apart, circuit board removed and wires added directly to shutter glass connections

Schematic Diagram

After getting prototype board working I decided a small PCB that would only contain the atmega328 / h-bridge and a voltage doubler (5 volts to 10V) so no external 10-12 volt supply is required. As you can see from the schematic diagram here only the 4 wires from the GC serial port is required, these being 5 volts / 3.3 volts / data-in and gnd.

PCB layout

Here is the artwork for the PCB and here is the OSH park gerber link https://oshpark.com/profiles/gamecube-projects and finally a pic of the finished board

(need to update the silk screen on this board also the holes in connector J2 are a little small).

BOM

Atmega328P (DIL package) with arduino boot loader already installed and 16Mhz crystal with two  22pf caps (sourced from ebay cost 1.99)

H-bridge L293D (sourced from ebay cost 1.25)

Diode 1N5817  (source farnell 2675093 cost 0.15)

MAX660             (source farnell 1564673 cost 1.44)

10uF 16v  x2      (source farnell 1288204 cost 0.12)

Arduino uno code

Because the gamecubes serial interface runs at 250Khz each bit is 4us long however each bit is divide into four pulses, 3 low and 1 high for low bit and one low and 3 high for a high bit. Therefore the Arduino uno needs to sample four 1us pulses I found that Arduino uno code libraries are to slow to properly sample at this rate as the atmega is only clocked at 16mhz.. I decided to still use the Arduino board as it is cheap and used by a lot of people but I switched to programming the atmega in assembler to speed things up. To do this I download atmel studios 7 and created a assembler project source code is here, and to actually program the Arduino board with the generated hex from the assembler project all I had to do was add an external tool. From the tools menu with the atmel studios choose external tool you should see the following window

in the Command: text box you need to put the path to the ardunino installed copy of avrdude.exe in my case this was

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avrdude.exe

then I just needed to add the following Arguments

 -C "C:\Program Files (x86)\Arduino\hardware\tools\avr\etc\avrdude.conf" -p atmega328p -c arduino -P COM119 -b 115200 -U flash:w:"$(ProjectDir)Debug\$(TargetName).hex":i  

Note: you will need to change the com port number to the one that your Arduino board uses on your system

Gamecube code 

I wrote a small dol that loads two images from the SD card one for the left eye and one for the right it then puts the serial interface pad port two into it polling on video interrupt mode (by setting it VBCPY1 in the SI POLL register), it also modifies the poll command to send 0x3D0000. The program then enters a loop display the left image then the right over and over again at 480p. With the Arduino uno board connect to pad port two via the joypad extension cord and on seeing the 0x3D0000 poll command it will start to control the shutter open / close timings at this point the user should see a stereoscopic 3d images if wearing the 3D glasses.

To start with I had had two test images one display a green strip (see left_cal.bmp in the zip file below) and one display displaying a red strip (see right_cal.bmp in the zip file below) with the dol displaying these images I slowly changed the shutter open / close timing in the atmega assembler code trying to get to a point where the left eye only displayed the green strip and the right eye only displayed the red strip. After I had calibrated the timing I actually wanted to see if it displayed a stereoscopic 3d images so I changed the left and right images (see left.bmp and right.bmp in zip file below) to this

(all credit go to artist pockn over at https://www.reddit.com/r/spacex/comments/3pavj1/cgdragon_crew_3d_image_please_put_on_3d_redblue/ I had nothing to do with the creation of this image it just looks cool so I borrowed it ;-)) and it actually worked! ok its no oculus rift and the image does flicker (30hz in each eye) but I was actually surprised it worked at all on a cheap monitor with a bad response time. Here is the zip file contain the dol and cal / test images.

3D Shutter glasses control timings 

The gamecubes video interface is clocking out one pixel every 1/27Mhz when in 480p@60Hz mode, therefore it will take 640 * 480 * (1/27Mhz) = 11.3ms to show all the active pixels (it will actually take 1/60Hz = 16.6ms to display the whole frame including vblank etc etc) so the left and right shutter need to be open alternately for approximately 11ms. Ideally the gamecubes video interrupt would generate an interrupt (blue line in diagram) and then a serial port poll command would be issued (red block in diagram) at this point the left or right eye shutter would be opened for 11ms (note for some reason the gamecube issues a second poll command towards the end of the frame also shown in red).

 

Implemented 3D shutter timings

The timings above dont take into account any delay between the pixel being outputted from the video interface and it actually being drawn on the monitor screen for example the screen response time is not taken into account. To get my cheap monitor (model number Technika 22E21B-FHD) to display the stereoscopic image I need to change these timing to

As you can see the timing is quite different and I think this is all down to the response timing of my monitor being on the slow side :-( I wonder if I had a 2ms response time monitor if the shutter open time would be more centred in the middle of the frame. I also wonder if these timing only work with my technika monitor, different monitors need to tested with this setup to answer that question.