# smpte timecode reader

**URL:** <https://forum.arduino.cc/t/smpte-timecode-reader/8298>\
**Category:** Exhibition\
**Created:** [December 13, 2007, 5:11am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298 "2007-12-13T05:11:49Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [December 13, 2007, 5:11am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/1 "2007-12-13T05:11:49Z")

</div>

I'm working on a project that will have four tc readers and a video display. I got the reader code working and thought perhaps someone else might find it useful. Most of the very few examples I was able to find on the web were in asm or basic. This is my first real project with the Arduino, and as a beginner I'm sure there far better ways to accomplish this then the ones I've chosen.

To all the folks who posted example code for timecode readers, thank-you, I stole bits and pieces from you all.

```cpp
#define icpPin 8        // ICP input pin on arduino
#define one_time_max          475 // these values are setup for NTSC video
#define one_time_min          300 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max         875 // 80bits times 29.97 frames per sec
#define zero_time_min         700 // equals 833 (divide by 8 clock pulses)
                                   
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

volatile unsigned int bit_time;
volatile boolean valid_tc_word;
volatile boolean ones_bit_count;
volatile boolean tc_sync;
volatile boolean write_tc_out;
volatile boolean drop_frame_flag;

volatile byte total_bits;
volatile byte current_bit;
volatile byte sync_count;

volatile byte tc[8];
volatile char timeCode[11];

/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect)
{
  //toggleCaptureEdge
  TCCR1B ^= _BV(ICES1);

  bit_time = ICR1;
  
  //resetTimer1 
  TCNT1 = 0;

  if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
  {
    //Serial.println(bit_time, DEC);
    total_bits = 0;
  }
  else
  {
    if (ones_bit_count == true) // only count the second ones pluse
      ones_bit_count = false;
    else
    {    
      if (bit_time > zero_time_min)
      {
        current_bit = 0;
        sync_count = 0;
      }
      else //if (bit_time < one_time_max)
      {
        ones_bit_count = true;
        current_bit = 1;
        sync_count++;
        if (sync_count == 12) // part of the last two bytes of a timecode word
        {
          sync_count = 0;
          tc_sync = true;
          total_bits = end_sync_position;
        }
      }

      if (total_bits <= end_data_position) // timecode runs least to most so we need
      {                                    // to shift things around
        tc[0] = tc[0] >> 1;
  
        for(int n=1;n<8;n++)
        {
          if(tc[n] & 1)
            tc[n-1] |= 0x80;
        
          tc[n] = tc[n] >> 1;
        }
  
        if(current_bit == 1)
          tc[7] |= 0x80;
      }
      total_bits++;
    }

    if (total_bits == end_smpte_position) // we have the 80th bit
    {
      total_bits = 0;
      if (tc_sync)
      {
        tc_sync = false;
        valid_tc_word = true;
      }
    }
    
    if (valid_tc_word)
    {
      valid_tc_word = false;

      timeCode[10] = (tc[0]&0x0F)+0x30;      // frames
      timeCode[9] = (tc[1]&0x03)+0x30;      // 10's of frames
      timeCode[8] =  '.';
      timeCode[7] = (tc[2]&0x0F)+0x30;      // seconds
      timeCode[6] = (tc[3]&0x07)+0x30;      // 10's of seconds
      timeCode[5] =  ':';
      timeCode[4] = (tc[4]&0x0F)+0x30;      // minutes
      timeCode[3] = (tc[5]&0x07)+0x30;      // 10's of minutes
      timeCode[2] = ':';
      timeCode[1] = (tc[6]&0x0F)+0x30;      // hours
      timeCode[0] = (tc[7]&0x03)+0x30;      // 10's of hours
      
      drop_frame_flag = bit_is_set(tc[1], 2);

      write_tc_out = true;
    }
  }
}

void setup()
{
  beginSerial (115200);
  pinMode(icpPin, INPUT);                  // ICP pin (digital pin 8 on arduino) as input

  bit_time = 0;
  valid_tc_word = false;
  ones_bit_count = false;
  tc_sync = false;
  write_tc_out = false;
  drop_frame_flag = false;
  total_bits =  0;
  current_bit =  0;
  sync_count =  0;

  //Serial.println("Finished setup ");
  //delay (1000);

  TCCR1A = B00000000; // clear all
  TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
  TCCR1C = B00000000; // clear all
  TIMSK1 = B00100000; // ICIE1 enable the icp

  TCNT1 = 0; // clear timer1
}

void loop()
{
    if (write_tc_out)
    {
      write_tc_out = false;
      if (drop_frame_flag)
        Serial.print("TC-[df] ");
      else
        Serial.print("TC-[nd] ");
      Serial.print((char*)timeCode);
      Serial.print("\r");
    }
}

```

/me

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [December 14, 2007, 12:21am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/2 "2007-12-14T00:21:49Z")

</div>

Thought I should add this (figured out how to post an image) Below is a simple timecode generator to Arduino interface. You could get the parts at Radio Shack.

Douglas

[http://home.comcast.net/~ds-fraser/forumimages/timecode-input.gif](http://home.comcast.net/~ds-fraser/forumimages/timecode-input.gif)

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [December 19, 2007, 1:23am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/3 "2007-12-19T01:23:53Z")

</div>

Hah, that's cool! I'm actually a member of SMPTE and attend the engineering committee meetings regarding extending SMPTE 12M timecode to 60p (and perhaps beyond).

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 2, 2008, 3:46am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/4 "2008-08-02T03:46:06Z")

</div>

> Thought I should add this (figured out how to post an image) Below is a simple timecode generator to Arduino interface. You could get the parts at Radio Shack.
> 
> Douglas
> 
> [http://home.comcast.net/~ds-fraser/forumimages/timecode-input.gif](http://home.comcast.net/~ds-fraser/forumimages/timecode-input.gif)

For a total newb to all this, how does one visualize this timecode? Does the xlr jack plug into some sort of display device? I'm looking to drive a motion controlled device that will step based on timecode.

---

<div class="post-metadata">

**Author:** ![mem](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mem/32/213477_2.png) [@mem](https://forum.arduino.cc/u/mem)\
**Post date:** [August 2, 2008, 4:32am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/5 "2008-08-02T04:32:29Z")

</div>

> For a total newb to all this, how does one visualize this timecode? Does the xlr jack plug into some sort of display device? I'm looking to drive a motion controlled device that will step based on timecode.

Hi Dan, the code and circuit in this thread are designed to take industry standard pulses from professional video equipment and make them available to an arduino sketch.

If your application needs to respond to time intervals it would be much easier for you to get the time from a real time clock or use the internal arduino time (there is an arduino software time library here: [http://www.arduino.cc/playground/Code/DateTime](http://www.arduino.cc/playground/Code/DateTime))

Why not create a new thread in the hardware/interfacing section to describe your application and start a discussion on possible solutions.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 2, 2008, 7:39am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/6 "2008-08-02T07:39:01Z")

</div>

> > For a total newb to all this, how does one visualize this timecode? Does the xlr jack plug into some sort of display device? I'm looking to drive a motion controlled device that will step based on timecode.
> 
> Hi Dan, the code and circuit in this thread are designed to take industry standard pulses from professional video equipment and make them available to an arduino sketch.
> 
> If your application needs to respond to time intervals it would be much easier for you to get the time from a real time clock or use the internal arduino time (there is an arduino software time library here: [http://www.arduino.cc/playground/Code/DateTime](http://www.arduino.cc/playground/Code/DateTime))
> 
> Why not create a new thread in the hardware/interfacing section to describe your application and start a discussion on possible solutions.

Thanks for the info mem, eventually I will be looking to run this unit from a sync pulse from out of a video or film camera. All just Ideas at the moment though. I will definitely start a thread when I am ready to sink my teeth into it. Just gathering info at the moment. 😉

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 21, 2008, 2:54am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/7 "2008-08-21T02:54:40Z")

</div>

It's been awhile since I been on here (work gets in the way of fun). I finished the 4 port timecode reader and a couple of simpler video clocks. The output video display is handled by a MAX7456 OSD chip. A rather new video overlay chip running around $18 in single quantity.

With the 4 port reader I had to go to straight 'C' with the Mega168 instead of the Arduino, there was just too much demand for the Arduino OS to keep up with. In fact with the final build I used all Mega48's because the code fit and I could save my Arduino's for other prototyping.

I also put together a shield with the MAX7456 (built on a nkc protoshield) so I can play with / learn this neat OSD.

If anyone has any interest I will put some drawings and code together and post it.

dfraser

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 21, 2008, 6:05am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/8 "2008-08-21T06:05:59Z")

</div>

> If anyone has any interest I will put some drawings and code together and post it.

Yes, please. 🙂

--Phil.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 29, 2008, 5:45am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/9 "2008-08-29T05:45:41Z")

</div>

I finished a small project to build a shield for playing with the MAX7456 OSD chip. This is the video output section I used in my timecode readers. I will post all of this in a new thread 'Arduino + Max7456 OSD'

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [November 20, 2009, 10:11am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/10 "2009-11-20T10:11:37Z")

</div>

here is the schematic again, from dfraser

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 3, 2010, 9:10pm UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/11 "2010-05-03T21:10:53Z")

</div>

Is this code frame accurate?

I am hoping to build a box with timecode and tally reading to generate an shot log from a live shoot.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [July 7, 2010, 2:16pm UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/12 "2010-07-07T14:16:29Z")

</div>

On Live you get a mixer.... the videomixer has normaly rs232 output for tally's

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [July 27, 2010, 8:31am UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/13 "2010-07-27T08:31:17Z")

</div>

**For pal: 25 and 24 Fps** 😃

#define one\_time\_max 588 // these values are setup for NTSC video  
#define one\_time\_min 422 // PAL would be around 1000 for 0 and 500 for 1  
#define zero\_time\_max 1080 // 80bits times 29.97 frames per sec  
#define zero\_time\_min 922 // equals 833 (divide by 8 clock pulses)

**For User bit :**

userBit[9] = ((tc[0]&0xF0)\>\>4)+0x30; // user bits 8  
userBit[8] = ((tc[1]&0xF0)\>\>4)+0x30; // user bits 7  
userBit[7] = ((tc[2]&0xF0)\>\>4)+0x30; // user bits 6  
userBit[6] = ((tc[3]&0xF0)\>\>4)+0x30; // user bits 5  
userBit[5] = '-';  
userBit[4] = ((tc[4]&0xF0)\>\>4)+0x30; // user bits 4  
userBit[3] = ((tc[5]&0xF0)\>\>4)+0x30; // user bits 3  
userBit[2] = '-';  
userBit[1] = ((tc[6]&0xF0)\>\>4)+0x30; // user bits 2  
userBit[0] = ((tc[7]&0xF0)\>\>4)+0x30; // user bits 1

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 4, 2010, 4:30pm UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/14 "2010-08-04T16:30:15Z")

</div>

Lucky I stumbled on this, Im actually looking to build my own clapperboard/time code slate (which ever you prefer).

There are iPhone apps that do the same thing but not as well. However there is one app I recently discovered called JumpStart LTC (Longitudinal Time Code) it uses the headphone jack to set the time code on the slate.

Im wondering, 1. would this app and the arduino code here work the same way? (or is it just for video), 2. how hard would making a slate be? (I have no arduino experience, but no timetable for the slate ie could take forever and i dont care)

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 6, 2021, 6:42pm UTC](https://forum.arduino.cc/t/smpte-timecode-reader/8298/15 "2021-05-06T18:42:57Z")

</div>

Closed on May 6, 2021, 6:42pm UTC


