
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.
I also need to explore if the code can be written in the form of a PWM using the internal Atmega timers.. to be updated
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.