All,

Sorry for not being more clear.  I think I was nearing my fill of
Python for the day when I wrote.

Now, refreshed, let me see if I can fill in the blanks a bit more.

- Bits that are shifted in either direction off the end of the
64-byte(or 'n' size) collection are of no use.  They are actually
phantom bits created by the hardware that I'm trying to get rid of by
using this shifting.  And, the desired data needs to be properly
aligned so I can work with it as well.

- Any bits that are shifted 'in' from either end are zeros.

- What follows is a mini version, the array could be any size up to 64 bytes

input:  10010010 . 11101111 . 01010011

shift 'x' (for example, I'll use 1)

output: 01001001 . 01110111 . 10101001

Some results that I've been getting appear as follows:

- 'stuck bits' output:

 input : 01010011 . 01110001 . 11000011
 output : 00101001 . 00111000 . 11100001

where the most significant bit of the word appears to 'stick'
regardless of the shifting.  This isn't the best example.

- 'roll over' output"

 input : 00000001 . 11110000 . 10001000
 output : 11111111 . 11111000 . 01000100

The most significant byte here has the 'roll over' issue.  I'm guess
this has something to do with sign extension of the byte in the larger
Python storage medium.

The above are not actual data that have been manipulated by the
software but illustrations of observations.  The real data is 'random'
so I'm doing the best to recall from memory what happens.

The data is being returned from the hardware as a bytearray but since
I'm reading it a byte at a time, it ends up being stored as a list.
I've been using for loops to cycle through the list.

Ideally, I'd love to be able to say :

# here's the array / list
rx_data = []

# read through all the bytes
# stash the results into the list
for x in range (bytes_of_data):
   rx_data[x] = read_data()[0]

# bit shift the entire lot
rx_data = rx_data >> bits_to_shift.

Which would provide me with the output described above.


Code I've been working with is as follows:

def bit_loop_report(disp, num_bits):

        if(disp): print "++Begin Report"

        num_bits = 0x00
        num_bytes = 0x00

        # define some constants to help in bit shifting
        rt_mask = array ('B', [0x00, 0x01, 0x03, 0x07,
                                                                        0x0F,   
0x1F, 0x3F, 0x7F])
        lt_mask = array ('B', [0xFF, 0x80, 0xC0, 0xE0,
                                                                        0xF0, 
0xF8, 0xFC, 0xFE])

        # account for partial bytes worth of stops
        # determine number of bytes
        num_bytes = num_bits / 8
        # if we have bits left over then save that count
        # between 1 and 7 inclusive
        if (num_bits > (num_bytes * 8)):
                num_bits = num_bits - (num_bytes * 8)
                print " num bits ", num_bits
        # if the number of bits left over is non-zero...
        if(num_bits != 0):
                # increment byte count to cover the additional bits
                num_bytes += 1
                # calculate the actual number of extra bits
                rs_extra_bits = 8 - (num_bits % 8)
                print " extra bits ", rs_extra_bits

        if(disp): print "Loop size bytes = ", num_bytes

        # some vars we'll use
        bit_on = False
        disp_bit_on = "ON"
        disp_bit_off = "OFF"
        bit_state_human_read = ""

        print "\n\n Use Ctrl-C to Exit \n\n"

        # create an array to store stop states
        # last read
        last_read_ary = array('B', (0x00,)*num_bytes)
        r_last_read_ary = array('B', (0x00,)*num_bytes)
        # current read
        curr_read_ary = array('B', (0x00,)*num_bytes)
        r_curr_read_ary = array('B', (0x00,)*num_bytes)
        # hold the stop change results
        stop_chng_ary = array('B', (0x00,)*num_bytes)
        # if num_bits is non-zero, we have to shift
        # the data in the array accordingly
        done_shft_ary = array('B', (0x00,)*num_bytes)

        # clear everything out
        bit_loop_flush(disp)

        # clear the registers
        bit_loop_clear(disp)

        # latch the states
        bit_loop_strobe(disp)

        # read in the initial state of the loop
        # bytes are read in backwards because the
        # MSByte comes from the hardware first
        # (MSByte -> LSByte) and MSbit first.
        for first_read in range (0, num_bytes):
                # read a byte and stash into the array
                r_last_read_ary[first_read] = bit_loop_read(disp)
                # reverse the byte order
                last_read_ary = list(reversed(r_last_read_ary))

        # now we enter a loop waiting for changes
        # to the data in the loop
        try:
                while (True):

                        # zero out the variables
                        read_stop = 0x00
                        temp_log = 0x00
                        changed = 0x00

                        # clear the registers
                        bit_loop_clear(disp)
                        # latch the states
                        bit_loop_strobe(disp)

                        # again, reading from hardware, backwards
                        for byte_num in range (0, num_bytes):
                                r_curr_read_ary[byte_num] = bit_loop_read(disp)
                                # reverse the byte order
                                curr_read_ary = list(reversed(r_curr_read_ary))

                        # go through the bytes and determine if there is a 
change
                        for byte_num in range (0, num_bytes):
                                stop_chng_ary[byte_num] = 
curr_read_ary[byte_num] ^ \
                                                                                
                        last_read_ary[byte_num]

                                # create a flag to know if we've got a change
                                # that we need to process
                                if(stop_chng_ary[byte_num] != 0):
                                        changed += 1

                        if(changed != 0):
                                if(disp): print " changed ", changed

                        # here we are shifting the bits across the array 
element boundaries
                                if(num_bits != 0):

                                # loop will go through all bytes in the changed 
bytes array
                                # remember that the 0th element is the MSByte 
and the nth
                                # element is the LSByte

                                        for byte_num in range (0, (num_bytes - 
1)):
                                                # shift
                                                done_shft_ary[byte_num] = 
stop_chng_ary[byte_num] >> rs_extra_bits
                                                if(disp): print byte_num, " 
done shift ", done_shft_ary
                                                # carry
                                                done_shft_ary[byte_num] |= 
(0xFF & (stop_chng_ary[byte_num + 1]
<< (8 - rs_extra_bits)))
                                                if(disp): print byte_num, " 
or'd ", done_shft_ary

                                        # MSByte just needs shift and no 'carry'
                                        done_shft_ary[num_bytes - 1] = 
stop_chng_ary[num_bytes - 1] >>
rs_extra_bits

                        # check through the shifted results for
                        # bytes that indicate a change
                                for num_mod in range (0, num_bytes):

                                        if(done_shft_ary[num_mod] != 0):
                                                if(disp):
                                                        print "\n", 
done_shft_ary[num_mod]
                                                        print " stop read = ", 
curr_read_ary
                                                        print " stop change = 
", stop_chng_ary
                                                        print " done shift = ", 
done_shft_ary

                                                # determine if stop is on or off
                                                if(stop_chng_ary[num_mod] & 
curr_read_ary[num_mod]):
                                                        bit_on = True
                                                        bit_state_human_read = 
disp_bit_on
                                                else:
                                                        bit_on = False
                                                        bit_state_human_read = 
disp_bit_off

                                                # determine bit position
                                                if(stop_chng_ary[num_mod] <= 0):
                                                        stop_change = 1


                                        # log/log(2) is base translation
                                                temp_log = 1 + 
(math.log(done_shft_ary[num_mod])/math.log(2))                   
                                                print "Position ", int(temp_log 
+ (8 * num_mod)), \
                                                                        "Stop 
State = ", bit_state_human_read

                                                if(disp):
                                                        print " stop byte read 
= ", hex(curr_read_ary[num_mod])
                                                        print " num_mod = ", 
num_mod
                                                        print " stop change = 
", hex(stop_chng_ary[num_mod])
                                                        print " Stop change = 
", ((num_mod * 8) + stop_chng_ary[num_mod])
                                                        print " Stop State = ", 
bit_state_human_read

                                        # update array with current state of 
stops
                                        last_read_ary = curr_read_ary[:]        
# copy ary to ary

        except KeyboardInterrupt:       # watches for ctrl-c
                # provides a clean exit
                print "\n\n Test Complete \n\n"

        if(disp): print " -- Report Complete"

        return



On 10/6/18, Peter Otten <__pete...@web.de> wrote:
> Chip Wachob wrote:
>
>> Hello,
>>
>> I was not able to find any answers in the archive on this one.
>>
>> I'm wondering if this task can be done in a better way than what I've
>> attempted..
>>
>> I have an array of bytes.  Up to 64, which makes for 512 bits.
>>
>> I am reading these bytes in serially, and once I have a collection of
>> them, I want to shift them by 'n' bits.  The size of the array and the
>> number of bits are both variable up to the limit of 64/512.
>>
>> Now, I've played around with looping through the bytes and taking the
>> LSByte and shifting it by 'n' bits using >> or << and that works for
>> the first byte.  But then I need to take the next byte in the sequence
>> and shift it in the opposite direction by 8-n bits using << or >>
>> (opposite the LSByte direction), respectively.  Then I OR the two
>> bytes and save them into the location of the LSByte and then move to
>> the next byte in the sequence and so on.  While this works most of the
>> time, I sometimes get strange behavior at the 'fringes' of the bytes.
>> Sometimes I end up with zero, or the shift seems to 'roll over'.
>>
>> I'm thinking that maybe there's a way to treat the array / list and
>> shift allowing the bits to transfer from byte to byte as needed.
>> Maybe by concatenating the bytes into one huge word and then breaking
>> it apart again?
>>
>> I'm thinking that you folks out there know of a built-in function, or,
>> an easier and more predictable way to accomplish the same.
>
> Here are two ways to implement the left shift:
>
> def bitshift(b, n, byteorder="big"):
>     size = len(b) + (n + 7) // 8
>     shifted = int.from_bytes(b, byteorder) << n
>     return shifted.to_bytes(size, byteorder)
>
>
> def bitshift2(b, n):
>     nbytes, nbits = divmod(n, 8)
>     if nbits:
>         a = [0]
>         for bb in b:
>             hi, lo = divmod(bb << nbits, 256)
>             a[-1] |= hi
>             a.append(lo)
>         b = bytes(a)
>     return b + b"\x00" * nbytes
>
>
> assert bitshift(b"\xaa\xbb", 12) == b"\x0a\xab\xb0\x00"
> assert bitshift2(b"\xaa\xbb", 12) == b"\x0a\xab\xb0\x00"
>
>
> _______________________________________________
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to