1

I am only new to Python, and currently reading 2 bytes from a digital compass using I2C on the Raspberry Pi. The MSB and LSB values are being stored in an array e.g.
a = [0x07, 0xFF]

I would like to join these two bytes into one variable such as
b == 0x07FF

How would I go about doing this?
I thought it would be as easy as multiplying the MSB by 256 and adding it to the LSB but I keep getting "IndexError: list index out of range"
Any help on this would be appreciated :)

My code is:

import smbus
import time
bus = smbus.SMBus(1)
addr = 0x1E
bus.write_byte_data(addr, 0x00, 0x70)
bus.write_byte_data(addr, 0x01, 0xA0)
bus.write_byte_data(addr, 0x02, 0x00)
time.sleep(0.006)
for i in range(0,10):
 x = bus.read_i2c_block_data(addr,0x03,2)
 y = bus.read_i2c_block_data(addr,0x07,2)
 z = bus.read_i2c_block_data(addr,0x05,2)
 xval = 256*x[2]+x[1]
 print x, y, z
 print xval
 time.sleep(1)
print 'exiting...'

The error I get is:

Traceback (most recent call last):
 File "compass2.py", line 18, in <module>
 xval = 256*x[2]+x[1]
IndexError: list index out of range
Asclepius
64.7k20 gold badges188 silver badges165 bronze badges
asked Oct 12, 2017 at 1:32
1
  • 2
    Python indexes start at 0. Change xval = 256*x[2]+x[1] to xval = 256*x[1]+x[0] Commented Oct 12, 2017 at 4:19

1 Answer 1

1

As noted in a comment, in Python, indexing begins at 0, not at 1. In your code, start at x[0], not x[1].

To merge two integers from 0 to 255:

Using bitwise

Credit: this answer

MAXINT = 255 # Must be a power-of-two minus one
NUM_BITS = MAXINT.bit_length()
def merge(a, b):
 c = (a << NUM_BITS) | b
 return c
def split(c):
 a = (c >> NUM_BITS) & MAXINT
 b = c & MAXINT
 return a, b
# Test:
EXPECTED_MAX_NUM_BITS = NUM_BITS * 2
for a in range(MAXINT + 1):
 for b in range(MAXINT + 1):
 c = merge(a, b)
 assert c.bit_length() <= EXPECTED_MAX_NUM_BITS
 assert (a, b) == split(c)

Using arithmetic

This technique works but is not preferred.

MAXINT_PLUS1 = 256
def merge(a, b):
 c = MAXINT_PLUS1 * a + b
 return c
def split(c):
 a, b = divmod(c, MAXINT_PLUS1)
 return a, b
# Test:
EXPECTED_MAX_NUM_BITS = (MAXINT_PLUS1 - 1).bit_length() * 2
for a in range(MAXINT_PLUS1):
 for b in range(MAXINT_PLUS1):
 c = merge(a, b)
 assert c.bit_length() <= EXPECTED_MAX_NUM_BITS
 assert (a, b) == split(c)
answered Oct 12, 2017 at 4:51
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.