0

I am a newbie in Arduino and I am trying to decode time from ltc audio. For this I got Arduino UNO.

I got a sample code from here.. Here my code:

#define icpPin 8        // ICP input pin on arduino
#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)


#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);
  //Serial.println("Inter");
 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
*/

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

       drop_frame_flag = bit_is_set(tc[1], 2);

     write_tc_out = true;
   }
 }
}


void setup()
{
 Serial.begin(9600);
 pinMode(8, 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");
   }
}

I am generating LTC audio from this link. On running my code I am getting this output:-

Finished setup
?>-00-0000??-??-77=??>-??-;?????-??-?>???>-:?-=????>-??-?=???>-;=-??5>?>-;=-??=7?>-?;-??=>?>-?:-??=7?>-;=-??>??>-;;-??=7??-?=-=7?>?>->7-?????>-;;-??=7?>-;>->??:??-?=-7????>-;?-??5>?>-;?-?=?>??-?=-?7>??>-7:-?67=?>-;?-???5?>-;=-7?==?>-;;-??=7?>-7=-??>>?>-:?-7????>-;=-?;;=??-?=->?=5?>-;=-???=?>-;?-?=5>??-?;->=???>-?>-7>;???-?;->????>-;?-?7=??>-;>-??>;?>-;=-;?5>?>-??-=7;7?>-;=-;?=??>-;=-??=7?>-;=-??:??>->7-=?????-?7-=?>>?>-?6-??;>?>-7;-???=?>-??-;=???>-;=-?7=7?>-?=-??>;?>-:?->??

So, can anyone one tell me where is mistake.

1 Answer 1

1
((tc[0]&0xF0)>>4)+0x30

Will generate values in the range x30 to x3F, which are 0 to 9 :;<=>? This is what you are seeing in you output (because you are adding in x2D '-')

I'm not sure what you are expecting to see, but as far as I can tell there are no mistakes and your code is working fine.

If you are trying to turn tc[0] into a hex digit then I would use this function

char ToHex (const char input)
{
    char output = '0';
    if (input > 9)
    { 
        output = (input - 10) + 'A';
    }
    else
    {
        output = input + '0';
    }
    return output;
}
char TCToHex (const char input)
{
    return ToHex(((input & 0xF0) >> 4));
}
char* CharToHex(const char input, char buffer[3])
{
    buffer[0] = ToHex((input & 0xF0) >> 4);
    buffer[1] = ToHex((input & 0x0F));
    buffer[2] = '\0'; // Always null terminate a string
    return buffer;
}

So what you will get if you call the functions is

    char buffer[3];
printf("CharToHex 0x%s\n", CharToHex('A', buffer));  //0x41 65 in decimal, ASCII A
printf("TCToHex = 0x%c \n", TCToHex(0x50)); // 5, because this function only takes the high nibble.
printf("ToHex = 0x%c \n", ToHex(0x0f)); // F

Hope that helps.

2
  • I am trying to send time stamp on serial port. But your code is not working. Any idea?
    – tabish
    Jun 16, 2016 at 6:09
  • Unless your timestamp is in the same format as the TC array then no it won't. I'll edit the answer to provide you with a more generic solution too. Jun 16, 2016 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.