SMPTE Timecode reader


Closed Thread
Results 1 to 10 of 10
  1. #1
    Join Date
    Jan 2006
    Posts
    76

    Default SMPTE Timecode reader

    Hey all.

    We are working in a production studio and all of our cameras are locked together by timecode. I would like a little timecode display in the control room so the logger is able to write down the timecode at varioius times.

    Basically I just need to read the 80 bit digital signal and display it on an LCD display.

    Its been a while since I coded anything so my picbasic is rusty. Maybe someone can check out these docs and get me on the right path.
    I have the code to work the display, I just need a refresher on detecting start & stop bits, reading and splitting strings to appropriate variables.

    thanks
    -brian

    http://www.philrees.co.uk/articles/timecode.htm#mod
    http://www.philrees.co.uk/articles/timecode.htm#bcd


    ps. right now using a 16F737 because I have one laying around.
    Last edited by docwisdom; - 16th August 2007 at 22:32.

  2. #2
    Join Date
    Jan 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    ah, c'mon. i know someone wants to dive into this.

    mr e, mel, you know you want to.

  3. #3
    Join Date
    Jan 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Unhappy

    nothin yet. Darn.

  4. #4
    Join Date
    Jan 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    ??
    anyone

  5. #5


    Did you find this post helpful? Yes | No

    Default A simple low speed BiPhase decoder

    Untried but should get you started.

    '************************************************* ***************
    '* Name : BiPhase 01.BAS *
    '* Author : Brian Taylor *
    '* Notice : Copyright (c) 2008 Brian Taylor *
    '* : All Rights Reserved *
    '* Date : 29/01/2008 *
    '* Version : 1.0 *
    '* Notes : *
    '* : *
    '************************************************* ***************

    ' an untried attempt at decoding the 2400 bps data stream used in the
    ' SMPTE LTC timecode system
    '
    'Defines go here

    ' Hardware definitions
    LineIn var portB.0 'or whatever moves you


    ' Software definitions
    A var byte
    B var byte
    C var byte
    Msg var byte[8] ' up to 64 bits of timecode data
    Valu var bit ' data bit from the biPhase data stream
    Width var byte ' the number of 20 uSec chunks in the bit period
    ' 2400 bps is approx 416 uSecs per bit
    ' a ZERO should return a count of approx 20
    ' a ONE should yield a count of approx 10
    Pattern var word ' this must match the SYNC pattern to start

    '************************* Initialise block *************************
    FlashLEDs: ' show em we are alive, etc
    PickNose: ' etc
    ScratchBum: ' etc

    goto start 'jump subroutines at startup

    '************************* Subroutines ****************************
    FindBit:
    ' This extracts the 0 or 1 data bits from the incoming data stream
    width = 0
    FindEdge:
    a = linein
    pauseus 20
    width = width + 1
    if width > 14 then foundzero ' can't be a ONE - must be a ZERO.
    ' important that we exit early so we have approx 100 uSecs for
    ' other tasks before the next data transition. Allow for jitter
    ' and don't make the width comparison too tight
    if linein = a then findedge
    ' sample a second time - repeat if no change
    FoundOne:
    'at this point we have a transition under 15 counts so must be a ONE.
    valu = 1
    goto findbitdone
    FoundZero:
    valu = 0
    FindBitDone:
    return

    '***************************** MAIN ******************************
    START:

    FindSync:
    ' The values of the sync bits are fixed as 0011 1111 1111 1101
    ' Make a sliding window comparator by sliding the bits in the Pattern word
    ' up one place and adding the latest bit to the end and comparing this
    ' with the Sync word. NOTE the MSB/LSB might need swapping end for end.
    gosub findbit
    pattern = pattern << 1 + valu ' slide up one place and add latest bit
    if pattern = %0011111111111101 then foundsync
    goto findsync 'get one more bit & check again - keep doing it until a match
    FoundSync:

    GetData:
    for b = 0 to 5 ' get 6 message bytes - bytes 6 & 7 are sync - so skip
    for a = 0 to 7 ' get 8 bits in each message byte
    gosub findbit
    c.0[a] = valu ' fill the 8 bits in the byte
    ' MAY need a tweak to get MSB/LSB sense correct
    next a
    msg[b] = c
    next b
    ' at this point you should have 6 bytes of message that needs
    ' to be broken down into the various data blocks per the
    ' SMPTE LTC specification

    DoWhatever:
    ' unpack the nibbles you are interested in.

    goto start


    HTH
    Brian

  6. #6
    Join Date
    Jan 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Smile

    Thanks brian
    ill give it a stab and come back with a report ( and questions most likely)

    -brian

  7. #7
    Join Date
    Jan 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    Brian,
    Thanks for the great help thus far. Here is where I am at the moment.
    Camera timecode out is wired to portc.2 and shield is connected to the circuits ground.
    So far, I get the 'TC reader' greeting on the LCD but no readout of Timecode.
    I threw in some LCDOUT lines for diagnostics. It gets to Found 0 and repeats there. So Found 1 doesn't seem to be occurring. Unless my pauses are causing problems.

    One thing that stand out in the code that I dont understand. The LineIn = A then a couple lines down A = LineIn, seems like it would create an infinite loop.

    '************************************************* ***************
    '* Name : Timecode.BAS *
    '* Author : Brian Critchlow & Brian Taylor *
    '* Notice : Copyright (c) 2007 Brian Critchlow & Brian Taylor *
    '* : All Rights Reserved *
    '* Date : 10/11/2007 *
    '* Version : 1.0 *
    '* Notes : PIC 16F737 *
    '* : *
    '************************************************* ***************
    TRISB = %00000000 'portb output
    TRISC = %11111111 'portc input
    ADCON1 = %11111111 'all ports digital

    define OSC 4 '4mhz oscillator

    DEFINE LCD_DREG PORTB ' Set LCD Data port
    DEFINE LCD_DBIT 0 ' Set starting Data bit (0)

    DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
    DEFINE LCD_RSBIT 4 ' Set LCD Register Select bit

    DEFINE LCD_EREG PORTB ' Set LCD Enable port
    DEFINE LCD_EBIT 6 ' Set LCD Enable bit

    DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 2 ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
    DEFINE LCD_DATAUS 50 ' Set data delay time in us
    pause 1000 '1 second delay

    '-------------------Begin timecode section---------------------------
    ' an untried attempt at decoding the 2400 bps data stream used in the
    ' SMPTE LTC timecode system
    '
    'Defines go here

    ' Hardware definitions
    LineIn var portC.2 'or whatever moves you

    ' Software definitions
    A var byte
    B var byte
    C var byte
    Msg var byte[8] ' up to 64 bits of timecode data
    Valu var bit ' data bit from the biPhase data stream
    Width var byte ' the number of 20 uSec chunks in the bit period
    ' 2400 bps is approx 416 uSecs per bit
    ' a ZERO should return a count of approx 20
    ' a ONE should yield a count of approx 10
    Pattern var word ' this must match the SYNC pattern to start

    '************************* Initialise block *************************
    FlashLEDs: ' show em we are alive, etc
    LCDOUT $FE, 1, "TC ", $FE, $C0, "Reader" 'tag line
    pause 1000 '1 second delay

    goto start 'jump subroutines at startup

    '************************* Subroutines ****************************
    FindBit:
    ' This extracts the 0 or 1 data bits from the incoming data stream
    width = 0
    FindEdge:
    a = linein
    pauseus 20
    width = width + 1
    if width > 14 then foundzero ' can't be a ONE - must be a ZERO.
    ' important that we exit early so we have approx 100 uSecs for
    ' other tasks before the next data transition. Allow for jitter
    ' and don't make the width comparison too tight
    if linein = a then findedge
    ' sample a second time - repeat if no change
    FoundOne:
    LCDOUT $FE, 1, "Found ", $FE, $C0, "1" 'tag line
    pause 500 '1 second delay
    'at this point we have a transition under 15 counts so must be a ONE.
    valu = 1
    goto findbitdone
    FoundZero:
    LCDOUT $FE, 1, "Found ", $FE, $C0, "0" 'tag line
    pause 500 '1 second delay
    valu = 0
    FindBitDone:
    return

    '***************************** MAIN ******************************
    START:
    FindSync:
    ' The values of the sync bits are fixed as 0011 1111 1111 1101
    ' Make a sliding window comparator by sliding the bits in the Pattern word
    ' up one place and adding the latest bit to the end and comparing this
    ' with the Sync word. NOTE the MSB/LSB might need swapping end for end.
    gosub findbit
    pattern = pattern << 1 + valu ' slide up one place and add latest bit
    if pattern = %0011111111111101 then foundsync
    goto findsync 'get one more bit & check again - keep doing it until a match
    FoundSync:
    LCDOUT $FE, 1, "Found ", $FE, $C0, "Sync" 'tag line
    pause 500 '1 second delay
    GetData:
    for b = 0 to 5 ' get 6 message bytes - bytes 6 & 7 are sync - so skip
    for a = 0 to 7 ' get 8 bits in each message byte
    gosub findbit
    c.0[a] = valu ' fill the 8 bits in the byte
    ' MAY need a tweak to get MSB/LSB sense correct
    next a
    msg[b] = c
    next b
    ' at this point you should have 6 bytes of message that needs
    ' to be broken down into the various data blocks per the
    ' SMPTE LTC specification

    DoWhatever:
    ' unpack the nibbles you are interested in.
    LCDOUT $FE, 1, Msg[0], $FE, $C0, Msg[1]

    goto start
    Last edited by docwisdom; - 3rd May 2008 at 03:08.

  8. #8
    Join Date
    Jan 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    still stuck in the same spot.
    anyone have any insight?

  9. #9
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    First, you can't have an accurate PAUSEUS 20 with 4MHz using PAUSEUS. See PBP manual.

    OR you could still use a Timer/Counter... or use few asm GOTO $+1 or NOP.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  10. #10


    Did you find this post helpful? Yes | No

    Default Faster will be better

    Hi Brian,
    I have not given your post its due consideration but a couple of things jump to mind.

    a/ Don't use LCDOUT in a time critical loop. The fastest indicator is to set a LED ON when the target event occurs and off at another part of the code.
    HIGH LED takes more time and code space than LED = 1 so make sure the relevant TRIS statement makes the LED pin an output then set LED = 1 instead of LCDOUT.

    b/ The statements....
    Findedge:
    A = linein
    ..dothings..
    if linein = A then Findedge

    make a looping structure that keeps going until linein changes state. It does not care whether LineIn is high or low, it just looks for a change. The assumption is that linein changes and stays changed for longer than a loop time in order to be found. Adding extras like LCDOUT can trip you up badly with fast toggling inputs. There is a problem with this approach if the state of linein changes during the ever so small time it takes to execute the 'if linein = A then findedge' line. If that happens you will miss finding sync but this will only be once every thousand or so blocks. It can be fixed.

    c/ I agree with mister-e and you really should be running a 20 MHz part at 20 MHz for anything that interacts with real world data communications.

    d/ The FindBit routine must run flat out. 20 MHz will be better than 4 MHz although it does look like 4 MH4 would be barely fast enough. You cannot have any LCDOUT or pauses in it or the routine will only find the first bit and the rest of the mesage will fall on the floor during the pause 500 line.

    You CANNOT have a pause 500 after finding sync or finding a one or zero. You must immediately gather in the full 48 or 64 bit data field and decode it. Any pauses where you show them will cause the code to immediately miss the following data bits.

    e/ I suggest the FindSync: routine should look something like.....

    FoundSync:
    LED = 1 'Shows we have met the SYNC conditions
    GetData:
    for b = 0 to 5 ' get 6 message bytes - bytes 6 & 7 are sync - so skip
    for a = 0 to 7 ' get 8 bits in each message byte
    gosub findbit
    c.0[a] = valu ' fill the 8 bits in the byte
    ' MAY need a tweak to get MSB/LSB sense correct
    next a
    msg[b] = c
    LED = 0 ' turn the LED off after one character time - about 4 mSecs
    next b

    -or- shift the LED = 0 command to after the 'next b' and have the LED on for 6 character times which may be easier to see.

    HTH
    Brian

Similar Threads

  1. Parallax RFID Reader code example
    By dan-tron in forum Code Examples
    Replies: 4
    Last Post: - 19th April 2013, 22:16
  2. How to generate SMPTE timecode?
    By gtvmarty in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 9th April 2009, 05:53
  3. Serial interface with RFID reader
    By brid0030 in forum Serial
    Replies: 8
    Last Post: - 23rd January 2007, 06:23
  4. Proximity Card Reader
    By Sphere in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 6th November 2005, 14:43
  5. Smart card reader with PIC16F84A
    By bangunprayogi in forum Serial
    Replies: 0
    Last Post: - 12th August 2005, 10:36

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts