Page 1 of 10 1 2 3 ... LastLast
Results 1 to 10 of 91

Thread: Clocking data - the best way to do it?

  1. #1
    Senior Member
    Join Date
    Jan 1970
    Location
    Dunedin, NEW ZEALAND
    Posts
    1,531

    Question Clocking data - the best way to do it?

    I have to be able to clock 16-bit words into a SOMO sound module using the bit-banging approach. I know what the words are going to be.

    Is there a more simple method then just:

    Code:
    start:
      pulsout 1,200  'Start bit
      high 2  'Put data on data line
      pulsout 1,50  'Clock the module
      high 2  'Put data on data line
      pulsout 1,50  'Clock the module
      low 2  'Put data on data line
      pulsout 1,50  'Clock the module
      .
      .
      .
    This is long and memory intensive(although it does work), especially if you need to store several different commands - 34 lines per command(16x 2 lines for every bit + 1x start bit and 1x stop bit) - there must be a more efficent method. Can anyone offer me any alternatives?
    Last edited by Grogster; 09-11-2009 at 10:38.

  2. #2
    Moderator
    Join Date
    Mar 2008
    Location
    Western Australia
    Posts
    10,074

    Default

    Have a look at the code in PICAXE manual 2 under the SHIFTOUT command.

    Starts at page 192 and there are bit-bashing examples on page 193.

    You could use a word instead of a byte and change the bits value from 8 to 16
    westaust55

    Hey Hamlet, 2B OR NOT 2B = $FF

  3. #3
    Senior Member
    Join Date
    Jan 1970
    Location
    Dunedin, NEW ZEALAND
    Posts
    1,531

    Default

    OK, thanks, but still a little confused - where do I load the word I want to send?
    I think this must be w6 in the symbols list at the start of shiftin, so do I just plop in the decimal value of the binary word I want to send at that point?

    Example:
    Say I want to send 65000, do I have a line which says let w6 = 65000(or let var_out = 65000), then gosub the routine?

    Assume that symbol bits = 16 and symbol MSBvalue = 65535.

    EDIT: Not working - all I get is sdata high all the time with the sclk pulsing away in the background, but there are no lows as their should be. 65000 = 1111110111101000 binary, so there should be some pulses where the data-LED is off. I have two LED's on the two pins - one on the sclk pin, and one on the sdata pin so I can see what is happening, but at no point in the proceedure does the sclk LED pulse while the sdata LED is off, because the sdata LED remains on from fire up until power-down. *sigh* I increased the pulsout time to 5000 to slow things down so I can see what is going on, and so it is not so fast I can't visually follow it.

    Enough for tonight - 10 to one in the morning here - need sleep...
    Last edited by Grogster; 09-11-2009 at 11:54.

  4. #4
    Moderator
    Join Date
    Mar 2008
    Location
    Western Australia
    Posts
    10,074

    Default

    Quote Originally Posted by Grogster View Post
    OK, thanks, but still a little confused - where do I load the word I want to send?
    I think this must be w6 in the symbols list at the start of shiftin, so do I just plop in the decimal value of the binary word I want to send at that point?

    Example:
    Say I want to send FFFFh, do I have a line which says let w6 = 65535(or let var_out = 65535), then gosub the routine?

    Assume that symbol bits = 16 and symbol MSBvalue = 65535.
    Yes you are on the right path/track.


    Code:
    SYMBOL var_out = w6
    SYMBOL bits = 16
    SYMBOL MSBValue = $8000
    var_out = 65535
    
    gosub shiftout_MSBFirst
    
    
    ‘ ***** Shiftout MSB first *****
    shiftout_MSBFirst:
    for counter = 1 to bits ‘ number of bits
    mask = var_out & MSBValue ‘ mask MSB
    low sdata ‘ data low
    if mask = 0 then skipMSB
    high sdata ‘ data high
    skipMSB: pulsout sclk,1 ‘ pulse clock for 10us
    var_out = var_out * 2 ‘ shift variable left for MSB
    next counter
    return
    westaust55

    Hey Hamlet, 2B OR NOT 2B = $FF

  5. #5
    Senior Member
    Join Date
    Jan 1970
    Location
    Dunedin, NEW ZEALAND
    Posts
    1,531

    Default

    Cheers - will try that shortly and let you know.
    I changed the var_out from 65535 to 65000 so there were some low's in the binary word, otherwise the LED would not change if var_out was all 1's.
    Doing conversion of 8000h is 1000000000000000, which puts the MSB at bit-16, so this is where I was stuffing up last morning
    It was very late...
    Sleep has recharged my brain a little, but I still need coffee.

    EDIT1: Not working. I get ONE pulse one the sclk, then sdata stays high and there are no more pulses from sclk. More coffee...

    EDIT2: Put a wait 1 before the next x in the gosub, and I can see what is happening now, but the data is inverted - what should be highs are lows and vise-versa. I checked this bit-by-bit, and it is definetly inverted. Sending 65000 decimal, which is 1111110111101000 binary, and the data line shows me 0000001000010111 - 535 decimal. Confused.

    EDIT3: Swapped high sdata for low sdata and vise-versa in the gosub, and the data is almost correct now, but the last 2-bits pulse through as highs(can just visually detect a flash from the sdata LED during the clock pulse) when they should be low. The actual output binary is therefore 1111110111101011 which is 65003 so still not right. The experiment continues...
    Last edited by Grogster; 09-11-2009 at 21:22.

  6. #6
    Senior Member
    Join Date
    Jan 1970
    Location
    Dunedin, NEW ZEALAND
    Posts
    1,531

    Default

    I've re-written a routine to do what I want, using DATA/EEPROM statements and the READ command.

    Code:
    output 1	'Output 1 is the clock line
    output 2	'Output 2 is the data line
    low 1
    low 2
    
    symbol x = b1
    symbol bit = b2
    
    
    stp:
      pulsout 1,2500		'Start bit pulse
      for x = 1 to 16
        read x,bit
        bit = bit - 48
          if bit=1 then high 2
            endif
          if bit=0 then low 2
            endif
      pulsout 1,1000		'Clock the module
      pause 500
      debug bit
      next x
      wait 5
      goto stp
      
    data_sub:
    data 1,("1111110111101000")	'Command 65000 binary
    This works extremely well, and also allows me to keep the binary "Word" within the data statements. This method also does not have the problem of the last 2-bits being high when they should not be. Plus this is easier for me to follow then the other method.

    This needs a bit more tidying up, but it works beautifully.

    If I need more then 15 commands, I will have to use external EEPROM chip, but it might be a good chance for me to play with one of those at the same time...
    Last edited by Grogster; 10-11-2009 at 01:31.

  7. #7
    Senior Member
    Join Date
    Apr 2009
    Location
    us-sc
    Posts
    134

    Default

    Quote Originally Posted by Grogster View Post
    If I need more then 15 commands, I will have to use external EEPROM chip, but it might be a good chance for me to play with one of those at the same time...
    Could you use TABLE/READTABLE to store some data in PROGRAM MEMORY?

  8. #8
    Senior Member
    Join Date
    Jan 1970
    Location
    Dunedin, NEW ZEALAND
    Posts
    1,531

    Default

    Quote Originally Posted by kewakl View Post
    Could you use TABLE/READTABLE to store some data in PROGRAM MEMORY?
    A beautiful idea.
    I'd have to change chips from 18X to 20X2, but it would give me a chance to play with the 20X2, and it is a few bucks cheaper too.

  9. #9
    Moderator
    Join Date
    Mar 2008
    Location
    Western Australia
    Posts
    10,074

    Default

    here is a version - added a few more SYMBOL statements to clarify
    which does work using the method in manual 2

    Code:
    SYMBOL var_out = w6
    SYMBOL counter = b3
    SYMBOL MASK = w5
    SYMBOL bits = 16
    SYMBOL MSBValue = $8000
    SYMBOL sdata = 2
    SYMBOL sclk = 3
    
    var_out = $5555
    
    gosub shiftout_MSBFirst
    
    
    ‘ ***** Shiftout MSB first *****
    shiftout_MSBFirst:
    for counter = 1 to bits ‘ number of bits
    mask = var_out & MSBValue ‘ mask MSB
    low sdata ‘ data low
    if mask = 0 then skipMSB
    high sdata ‘ data high
    skipMSB: pulsout sclk,1 ‘ pulse clock for 10us
    var_out = var_out * 2 ‘ shift variable left for MSB
    next counter
    return
    to use the table memory as suggested by kewakl, this is also available in the X1 PICAXE parts.
    westaust55

    Hey Hamlet, 2B OR NOT 2B = $FF

  10. #10
    Technical Support
    Join Date
    Jan 1970
    Location
    UK
    Posts
    18,495

    Default

    A note on optimising code ...

    if bit=1 then high 2
    endif
    if bit=0 then low 2
    endif

    This can be represented as -

    If bit = 1 Then
    High 2
    Else
    Low 2
    End If

    Or -

    Low 2
    If bit = 1 Then
    High 2
    End If

    And best of all -

    outpin2 = bit

Bookmarks

Posting Permissions

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