IWEUA.COM

LTC using Arduino
A quick project to investigate the generation of LTC with an Arduino.

The structure of a Linear Time Code series of bytes is fairly straightforward, there are dozens of Internet sources to reference
from including the
Wiki.

A minimal implementation of LTC will be to populate the Frames, Seconds, Minutes and Hours, Bytes.
The last two bytes 8&9 are the Sync bytes which are fixed and never change, they can be hard coded.

At time HH : MM :: SS : FF     21:39:42:16     transmitted LSB FIRST the data packet would look like this, LSB first


 F Units         F Tens      Sec Units    Sec Tens    Min Units    Min Tens    Hr Units       Hr Tens          Sync            Sync   
 Byte 0           Byte 1        Byte 2         Byte 3        Byte 4         Byte 5         Byte 6         Byte 7         Byte 8         Byte 9
0101 0000  1000 0000  0100 0000  0010 0000 1001 0000  1100 0000  1000 0000  0101 0000  0011 1111  1111 1101
 6                 1                 2                 4                9                 3                 1                 2                 FIXED          FIXED      

You will note that BIT 59 has been manually flipped to value 1 to ensure an even number of Zeros ( 56 ) in this example.
Keeping an even number of Zeros and Ones in the LTC frame ensures Bit Zero will always have a rising ( or falling ) edge
indicated by the Arrow in the drawing below.
To Calculate Frames / Secs / Mins / Hours a series of little routines like below works

void FramesPlusPlus()
{
static int Frames;
Frames ++;
if ( Frames > 25 )
  {
   Frames = 0
   SecsPlusPLus();                // Etc ripple up to Mins/ Hours
  }
Calculate the Frames Packets for Low and High Bytes ( Byte 0 and Byte 1 of the LTC FRAME )
}


To Calculate BCD Values for numbers 00 - 59, I chose to use a look up array, it is fast and clear code.

The code  

The next iteration which currently has been written and does work, is reading incoming Serial data from a GPS U-Blox 6
outputting NEMA sentences ensuring that real time writing of LTC is not disrupted.

The next challenge will be to PLL the LTC output  to the 1 PPS output of the U-Blox and to sync the rising edge of the PPS
to the Frame Zero Byte 0 rising edge.

AG Jun 2020
For 25 Frames per Second ( FPS ) Linear Time Code, a ZERO is 500uS wide, a ONE, 250uS / 250uS wide.
The base time unit for 25 FPS is thus 250uS.

This is a real time application which needs to do other things between righting rising and falling edges so we need to poll the
sub routine to check if enough elapsed time has passed

The human readable code is something like this

void loop() {    IsTheCountdownTimerZero?()   }

void IsTheCountdownTimerZero?()
{
              long CurrentTime = micros();                                   // Record the Time you have entered the routine
static        long TimeOfNextEdgeToWrite;


If (  ( CurrentTime - TimeOfNextEdgeToWrite ) > 0 )               // Brackets!,  I can never remember operator precedence

YES >>
{
 FlipTheLTCOutputPin,

 Is the BIt We are Writing a One or a Zero?
 If it is a Zero,          TimeOfNextEdgeToWrite =  CurrentTime + 500uS      // Calculate the time to next change the Output Pin
 Else  (its a One )    TimeOfNextEdgeToWrite =  CurrentTime + 250uS
}

}

You need a little more code than this but this is essentially what you need to do.

In this code the frame is divided into 160 'Bits' or time segments, and a Frame start time recorded at the edge of Bit 0 Frame
Zero, all following bits referenced to this time point.
This code does not try to run synchronised / PLL ed with a one second PPS : future releases will.