Shop OBEX P1 Docs P2 Docs Learn Events
How do I extract a set number of bits? — Parallax Forums

How do I extract a set number of bits?

MJG300MJG300 Posts: 3
edited 2013-02-10 10:46 in BASIC Stamp
Hey everyone,

I am trying to write a program for the BS2px. It takes a word sized number (Ex: 8000) and break it down to bits 0 thru 6 and bits 7 thru 13. I would like to make bits 0 to 6 a seperate byte as well as bits 7 to 13.

Example: 1500 * 4 = 6000

11101110000

The reason for this is I am using the Pololu Micro Maestro 6. I am using their Compact Protocol. Bits 6 to 0 is 10000,bits 13 to 7 is 01110. By turning these into decimals, I will be able to write the commands easier. I have the Basic Stamp Syntax and Reference Manual. It talks about highbyte and lowbyte but does not talk about a specific set of bits that I give a variable name to. Any help would be appreciated.

Thanks to everyone for the help
Mark

Comments

  • Hal AlbachHal Albach Posts: 747
    edited 2013-02-09 21:10
    Good Evening, Mark,

    If I understand the Compact Protocol, each command packet consists of 4 bytes, each 8 bits; a command byte with bit 7 always a 1, and the three remaining bytes with bit 7 always 0, which poses a slight challenge when trying to convert a 16 bit word to two bytes consisting of 7 data bits each and forcing the 7th bit of each byte to 0.

    One solution would be to take the word size value and maybe copy it to another Word so we can work on it without destroying the original value. Lets call this Word PMM6. Now create two aliases from this Word and call them PMM6High and PMM6Low:

    PMM6High VAR PMM6.HIGHBYTE
    PMM6Low VAR PMM6.LOWBYTE

    Now do a left shift of the Word PMM6 followed by a right shift of the BYTE, PMM6Low. PMM6Low now holds bits 0-6 of your Word value with bit 7 set low. PMM6High now contains bits 7-13 of your Word value with bit 7 low.

    PMM6 = PMM6 << 1
    PMM6Low = PMM6Low >> 1

    I hope this helps,

    Hal
  • Mike GreenMike Green Posts: 23,101
    edited 2013-02-09 21:31
    Similarly, you can break up the word PMM6 as follows:

    lowValue = PMM6 & $7F ' mask off the low 7 bits
    highValue = (PMM6>>7) & $7F ' shift the next 7 bits right and mask off

    To put these back together, you'd do:

    PMM6 = (highValue<<7) | lowValue ' this assumes that each value is only 7 bits
  • Hal AlbachHal Albach Posts: 747
    edited 2013-02-10 06:19
    Good Morning, Mike:

    I believe that Mark is trying to format a 16 bit number which is comprised of two full 8 bits to two bytes where bit 7 of each has to be 0, according to Pololu . Therefore bit 7 of the low half must become bit 0 of the upper half, that's why I shifted the entire word left once followed by a right shift of the lower half.

    Hal
  • Mike GreenMike Green Posts: 23,101
    edited 2013-02-10 07:23
    Yes, maybe I stated things from the opposite perspective. lowValue and highValue are the bytes whose most significant bits are zeroes. PMM6 is the 14-bit unsigned value made up from the two 7-bit fragments. There are lots of ways to convert one form to the other.
  • MJG300MJG300 Posts: 3
    edited 2013-02-10 09:26
    Hi all,

    First off, Thanks to Hal and Mike for the feedback.

    I tried what Hal suggested. It worked to a point. When I entered 1000 microseconds, the low byte was off. I tried 1250 microseconds next, but it too was off by one shift. 1500 uSec. was good as well as 2000. Here is my program.

    ' {$STAMP BS2px}
    ' {$PBASIC 2.5}
    '
    ' This program calculates the control values of the Pololu Micro Maestro 6.
    ' Inputting the value in microseconds multiplied by 4 then taking bits 0 thru 6 and determining
    ' the decimal value for the first set. Then bits 7 thru 13 for the second set.
    '
    '
    product VAR Word 'answer when microseconds multiplied by 4
    usec VAR Word 'microseconds inputted by user
    product1 VAR Word
    hiProd VAR Byte
    loProd VAR Byte
    '
    '
    '
    Main:
    DEBUG "Enter your value in microseconds ",CR
    DEBUGIN DEC usec
    product = usec * 4
    DEBUG DEC product,CR
    product1 = product

    loProd = product1.LOWBYTE
    hiProd = product1.HIGHBYTE
    hiProd = hiProd << 1

    DEBUG DEC hiProd,CR
    DEBUG BIN hiProd,CR
    DEBUG DEC loProd,CR
    DEBUG BIN loProd,CR
    DEBUG CR

    GOTO Main
  • Hal AlbachHal Albach Posts: 747
    edited 2013-02-10 10:46
    The shifting is wrong.

    loProd = product1.LOWBYTE
    hiProd = product1.HIGHBYTE
    hiProd = hiProd << 1

    Should be ;

    loProd = product1.LOWBYTE
    hiProd = product1.HIGHBYTE
    product1 = product1 << 1 ' Shift all 16 bits of product1 left one place, moves lo bit 7 over to hi bit 0
    loProd = loProd >> 1 ' Shift the lower byte back to its original condition excep that lo bit 7 is forced to 0 as a result of the right shift

    Lets check with 4000 ( input was 1000)
    .........dec 4000 = bin 0000 1111 1010 0000 = product1
    shift product1 left 1 = 0001 1111 0100 0000 = 8000 OK so far
    .shift loProd right 1 = 0001 1111 0010 0000 = 7968 What????!!!! But wait.....
    when sent to Pololu it will see 001 1111 010 0000 notice that the hi bits of each byte are not there since it uses bits 7 of data bytes as a flag

    adding from the right, 32 + 128 + 256 + 512 + 1024 + 2048 = 4000

    hope this clears it up

    Hal
Sign In or Register to comment.