SMTPE Timecode

Hi

There is already a thread on this - However its 120 days old and advice is to open a new thread.

I have a project – The circuit is working just fine its a simple and I can read out the timecode perfectly on the LCD display. So the arduino is detecting and displaying timecode - All good with the silicon.

I wanted to take the project further …

Basically we have a small studio - When the cameras are recording I can make timecode run. And I can also hold timecode static when not running (Basically Rec Run Setting in the cameras)

The ardruino will happily hold the timecode on screen when its not running and will run it when it is - So its in a variable in the code.

So what I did was think about popping in a relay to the circuit - So that when the timecode is running we can turn the studio lights and doors red - and when its not running they would be normal

So to test this before I bother with the relay circuit I wanted to adapt the LED at pin 13 so that it would either be on or off depending on the Timecode running or not running - Just a simple test before I do more to the physical circuit.

Im looking for the variable timecode in the sketch and then saying if timecode = timecode then the timecode isn’t running so keep the LED off.

But if timecode is changing then the timecode is running then turn the led on.

BUT - Here is where Im stuck (My C is rustily) and Im hoping someone would be kind enough to look.

What it does is

The LED display will come on but stays on - Or if I turn the logic around will not come on

I know its probably trivial but Im missing the point on something - Can anyone spot my stupidity > ?

Its got something to do with the variable. ?

thanks in advance .

My code ads in this

pinMode(13, OUTPUT);

and then this

if (tc[8] not_eq tc[8]) digitalWrite(13, HIGH);
if (tc[8] = tc[8]) digitalWrite(13, LOW);

to the main code below

//
//
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define one_time_max 600 // these values are setup for PA video
#define one_time_min 400 // It’s the durstion of a one and zero with a little bit of room for error.
#define zero_time_max 1100 //
#define zero_time_min 900 //

#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 pin = 13;
volatile unsigned int bit_time; // volatile instructs the variable to be stored in RAM
volatile boolean valid_tc_word; // booleon can be either of two values true or false
volatile boolean ones_bit_count; // booleon can be either of two values true or false
volatile boolean tc_sync; // booleon can be either of two values true or false
volatile boolean write_tc_out; // booleon can be either of two values true or false
volatile boolean drop_frame_flag; // booleon can be either of two values true or false

volatile byte total_bits; //this stores a an 8-bit unsigned number
volatile byte current_bit; //this stores a an 8-bit unsigned number
volatile byte sync_count; //this stores a an 8-bit unsigned number

volatile byte tc[8]; //this stores a an 8-bit unsigned number
volatile char timeCode[11]; //this stores a an 8-bit unsigned number

/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect) //ISR=Interrupt Service Routine, and timer1 capture event
{
//toggleCaptureEdge
TCCR1B ^= _BV(ICES1); //toggles the edge that triggers the handler so that the duration of both high and low pulses is measured.

bit_time = ICR1; //this is the value the timer generates

//resetTimer1
TCNT1 = 0;

if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // this gets rid of anything that’s not what we’re looking for
{
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++) //creates tc[1-8]
{
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 this converst from binary to decimal giving us the last digit
timeCode[9] = (tc[1]&0x03)+0x30; // 10’s of frames this converst from binary to decimal giving us the first digit
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); //detects whether theree is the drop frame bit.

write_tc_out = true;
}
}
}

void setup()

{

lcd.begin (16, 2);
pinMode(icpPin, INPUT); // ICP pin (digital pin 8 on arduino) as input
pinMode(13, OUTPUT);
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;

lcd.print(“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 (timeCode[10]=timeCode[10])
//{
//digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level)
// delay(1000); // wait for a second
// else
// digitalWrite(13, HIGH); } // turn the LED off by making the voltage LOW
// delay(1000); // wait for a second

if (write_tc_out)
{
write_tc_out = false;
if (tc[8] not_eq tc[8]) digitalWrite(13, HIGH);
if (tc[8] = tc[8]) digitalWrite(13, LOW);
// else
// digitalWrite(13, HIGH);

if (drop_frame_flag)
lcd.print(“TC-[df] “);
else
lcd.print(“TC-NO DROP FRAME”);
lcd.setCursor(0, 1);
lcd.print((char*)timeCode);
lcd.print(”\r”);
lcd.setCursor(11, 1);
lcd.print("…");
delay (40);
lcd.clear(); } }

if (tc[8] not_eq tc[8])

This is ALWAYS going to be false. It’s equivalent to: if (water not_eq wet).
You need to save a copy of tc[8] in another variable and test that against tc[8] after sufficient time has elapsed for tc[8] to have changed.

Pinktomato, sorry if this is too late, but also note that tc is an array with 8 elements, so tc[8] is out of range and is going to point to some other indeterminate memory location.