Reverse-Engineering & Emulating the Kogan Active-Shutter 3D TV IR Protocol

In an earlier post, I looked at the provided active-shutter 3D glasses from Kogan and aftermarket compatible glasses which can be used with their TVs. A key sticking point of that article was that different TVs often use different synchronization standards and the details on the synchronization used by Kogan TVs are rather scant.

As we have no reliable information on OEM, or protocol implementation, it makes shopping for glasses difficult. While some protocols have been documented, there is a lack of documentation in general for cheaper TVs.

I took it upon myself to look at the Kogan TV protocol to see if it has similarities with other protocols and just how it works.

Measuring the Data Stream

As this TV uses infrared communication, it is inherently much easier to work with than one which involves Bluetooth. One merely has to get a working infrared-sensitive photodiode or similar to receive the signal.

A key point to understand is that regular remote control receivers specified for 38khz carrier or 36khz carrier will not be useful. These receivers contain internal filtering and decode logic which looks for the presence of a 38khz or 36khz modulated wave and toggles its output to indicate its presence.

A search of parts online yielded one result from element14 – the Vishay TSOP35D25TR 3D TV IR Receiver. A brief gander through the datasheet revealed that 25khz seems to be the carrier frequency used in order to avoid interference from other signals. Unfortunately, I could not take this snippet of information too seriously as it is very easy to engineer a sender that does something entirely differently.

So I made do with what I had – the non-working Gonbes OEM IR+Bluetooth glasses were disassembled for the use of its IR receiver. Its type is unknown, but easily determined by measurement.

Gonbes IR Receiver

In the course of performing this, I “sacrificed” this $22 set of glasses because of operational conveniences. I de-soldered the flex for each eye-piece as they would easily tear with manipulation required to probe the output of the IR receiver continuously. I also had to re-solder the battery connections to the battery and to the glasses as they were quite brittle. It was a bit of a challenge, given I was unable to walk properly, to move things between the TV and my workstation.

Putting the glasses into scan mode allowed for the IR receiver to be powered for about 30 seconds before the glasses slept again. A quick probe revealed the pin-out to be:

Gonbes IR Sensor

To begin with, I hooked the data and ground (as illustrated, which resulted in a negative signal, hence the actual polarity is swapped around I believe) to my PoScope 2 basic. I will re-iterate, it’s not a very good piece of test equipment, and it was definitely showing its limits with this experiment.

I kept the TV in 3D mode by engaging some 3D content (or activating the 2D to 3D conversion), and powered on the glasses. The scope was set to the shortest time division available (5uS/sample) and negative edge trigger, which resulted in a very fuzzy result:

PoScope-SingleToken

Note that I had to tweak the buffer settings because I was getting signal corruption resulting in partial tokens scattered all over the place. It’s actually this that caused me to distrust my test equipment at all times – a good thing to be aware of.

The token itself consists of 12 “pulses” by the looks of it, but the accuracy of this is insufficient to measure the token too clearly.

PoScope-TokentoToken

Stepping back in the time divisions (and noting that this thing is not properly anti-aliased, resulting in fairly “vague” representations of the signal), the token appears to be sent every 66.667ms which corresponds to 15Hz rate. The TV is likely operating at 120Hz, so the glasses are being “phase referenced” only once every 8 pictures (or 4 pairs of left-right images). Initially with the buffer corruption, it seemed that we were getting tokens much more frequently to the point of implausibility – so beware, PoScope and “maximum” sample rates can lie.

Measurement Redux

Noting my inherent distrust in the PoScope results (lets just say, it looked worse initially, but I discarded that data), I pulled out another trusty ol’friend – the Velleman PCSU1000. I purchased this one second-hand from a fellow Electrical Engineering student at UNSW and it’s been with me for a while – I only use it when required because the miniature relays inside have a habit of failing and naturally, you really don’t want to waste its life for nothing.

PCSU1000-SingleToken

There’s a single token, measured similarly to what the PoScope was telling us. There’s not much more information here, but we can get closer (unlike the PoScope).

PCSU1000-PulseTrain

A close-up of the pulse train gives us a clear image – 12 pulses, with the “on” time much shorter than the off time. Lets take a close look at just one of the pulses:

PCSU1000-CloseUpPulse

As you can see – it looks like it’s 8uS on, 48uS off for a period of 56uS. There are 12 repetitions to form the token – this measures out to be direct modulation or carrier wave at 17857Hz (or pretty much 18kHz). So much for the “3D TVs send 25kHz carrier” theory.

PCSU1000-TokentoToken

Likewise, the measurement from the PCSU1000 confirms the token to token interval as about 66.667mS. There are the parameters!

The big question was – is this the only token?

PCSU1000-Spurious

Occasionally, we get supriae – malformed pulses which occur somewhat randomly “relative” to the token position. These happened about once in every 80 triggers – noting that I am receiving from a receiver of unknown character, I resolved that these are likely interference noise, or spurious output from the TV itself which are not part of the synchronization system at all.

Emulating the System

The step to emulating the system takes upon a very similar character to the effort to emulate the Nikon ML-L3 IR Remote which involves using an Arduino board with an IR LED and resistor, formulating code and tweaking it for timing.

IR LED on Arduino

The code itself was very simple initially:

void setup() {
  pinMode(A0,OUTPUT);
  digitalWrite(A0,LOW);
  pinMode(A1,OUTPUT);
  digitalWrite(A1,LOW);
}

void loop() {
  int count=0;
  while(count<12) {
    digitalWrite(A1,HIGH);
    delayMicroseconds(3);
    digitalWrite(A1,LOW);
    delayMicroseconds(44);    
    count++;  
  }
  delay(65);
  delayMicroseconds(995);
}

There are some subtleties – the numbers are not expected as they take into account the overhead of processing the instructions. They were tweaked using the PoScope for reference (as my PCSU1000 wasn’t installed on the machine I was coding with).

This resulted in a scope output as follows:

Emulated-Pulse-Train

If you note the cursor readings, which themselves aren’t very reliable, the first pulse measures 7.4uS (ideally, should be 8uS), and the pulse train measures 641.3uS (actually, this should be 624uS but the cursor is placed a little far to the right so it’s probably quite close), although this reading does jitter slightly from loop to loop. It’s a pretty good effort, although if you tune the numbers a bit more, you might get closer.

Emulated-Pulse-to-Pulse

The token-to-token timing is pretty much bang-on at 66.60ms (should be 66.67ms). The reason that the signals don’t have to be perfect is the same reason we have these signals themselves – these signals are to synchronize the glasses to the TV, where the TV can “vary” its refresh rate slightly depending on the source material. As a result, variations in the token-to-token timing will allow for testing the “range” of refresh rates a certain pair of glasses would sync to. This might be a project for a future investigation.

Not satisfied with this, I went one step further. I wanted an indication of frame order. I decided to leverage the Arduino’s onboard LED to blink on for a short period after each token to indicate the token is “sent” and this is “left-eye” time.

void setup() {
  pinMode(A0,OUTPUT);
  digitalWrite(A0,LOW);
  pinMode(A1,OUTPUT);
  digitalWrite(A1,LOW);
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void loop() {
  int count=0;
  while(count<12) {
    digitalWrite(A1,HIGH);
    delayMicroseconds(3);
    digitalWrite(A1,LOW);  
    delayMicroseconds(44);    
    count++;  
  }
  digitalWrite(13,HIGH);
  delayMicroseconds(3800);
  digitalWrite(13,LOW);
  delay(61);
  delayMicroseconds(995);
}

The code itself does work – you can see it in action in the following video:

How the Protocol Works

This is a one token protocol which provides phase reference to the glasses. The token itself is sent once every 8-alternations of left-right to indicate the beginning of the left frame. While I don’t have sophisticated equipment to measure this, I know this is true because a pair of glasses which works correctly syncs with the LED bright in the left eye. The frame inverted glasses sync with the LED bright in the right eye.

As a result, this one-token system is relatively inflexible – it’s up to the glasses to “freewheel” the timing in-between and determine its most optimal duty cycle. As a result, there may be a variation in the performance of different 3D glasses with the TV (although I haven’t noted any significant differences myself).

Referencing the work done by A. Woods and J. Helliwell of Curtin University helped me understand to some degree just how these systems are comparable to other systems. I could only conclude by examining their diagrams that this system is different to the 11 systems they had already documented. In fact, it’s extremely simple – it’s like sending an 18khz “beep” across IR every eight frames.

With this in mind, tweaking the code might reveal just how “universal” these universal glasses are – they may be capable of learning and determining how to sync just based on the repetition of patterns and timing between repetition of patterns.

Conclusion

It was a challenge for me to reverse engineer and emulate the Kogan active-shutter 3D TV IR protocol within a day, especially without the proper use of one of my ankles, but I was capable of doing it even with the equipment constraints I had.

The results of the analysis proves that it’s a simple IR protocol that emits a burst of carrier about 18khz every 8 pictures. With an 18khz centred IR receiver, this would manifest itself as a simple pulse. In-between, glasses will need to “freewheel” and determine the intermediate timings themselves. The sync is left-eye first relative to the token, and the screen does operate at 120Hz (rather than the 100Hz often confusingly referred to in Kogan literature, likely due to the fact that Australian PAL is 50-fields per second, doubled. LCD TVs need not follow this, especially as they are expected to sync to a multitude of frame rates – e.g. 23.976, 24, 25, 29.97, 30, 50, 60).

It appears that this protocol is different to the ones identified for major brands by previous work. Emulation was successful, and if used, can be a method to determine whether a pair of glasses is working, has the correct frame order and will sync to a Kogan TV.

About lui_gough

I'm a bit of a nut for electronics, computing, photography, radio, satellite and other technical hobbies. Click for more about me!
This entry was posted in Electronics and tagged , , , , , . Bookmark the permalink.

6 Responses to Reverse-Engineering & Emulating the Kogan Active-Shutter 3D TV IR Protocol

  1. diimdeep says:

    Hello, is it possible this way to control independently each eye as an alternative way to achieve http://www.instructables.com/id/Liquid-Crystal-Glasses-for-Amblyopia-Alternating-O/

    • lui_gough says:

      I don’t belive that is possible via the IR signal, as it expects a periodic timing signal which is linked to the video refresh rate. Much slower signals or out of spec cause the unit to lose synchronization altogether and just open both eyes. You will probably have to modify the unit and drive the liquid crystal shutters yourself.

      – Gough

    • Gabriel J M Daniel says:

      Hi, would it be possible to sync it to 60Hz signal instead of 120Hz? Experimenting with the token you found on a 60Hz video makes it locking mid frame, showing half a screen per eye, which is to be expected if it is trying to lock on a 120Hz signal. Maybe there is a different token to change that? Thank you for the great work.

  2. Mark Balliet says:

    I just picked up 2 pairs of Excelvan G03-A glasses at Goodwill for $4 a piece, hoping maybe I could get it to work with the VESA connector on my DLP projector. After a bunch of searching on Google this was my first stop for some code to try. It worked perfectly with the glasses I have, LED shows on the left or the right depending on the frame order I select. Next step is hooking into the VESA port on my projector and seeing if I can synchronize this code to the pulse from that port. Thanks so much for posting a great in-depth analysis and your code, it’s already helping me out 🙂

    • lui_gough says:

      You might be able to fashion up something without a microcontroller especially when using an analog source that has separate V-sync by feeding the V-sync into a digital counter to divide it down by the requisite amount to drive another timer (or R-C circuit) that generates a pulse of the requisite length into a MOSFET driving an IR LED. However, most video sources are now digital which makes things more complicated.

      Best of luck with your endeavour.

      – Gough

  3. Mark Balliet says:

    I found a VESA IR emitter on eBay for $15. It might work directly as-is, if not I’ll remove a few parts and splice an ATTiny in and write code to make it work. Either way $15 is reasonable for the parts to build the rest.

Leave a Reply to Mark BallietCancel reply