Page 1 of 1

Combining two bytes to one 16-bit object

Posted: Sat Aug 04, 2018 2:51 pm
by thejoker
Hello,

I'm reading angular acceleration from a sensor in two bytes, the high bytes and the low bytes. Together they form a 16-bit integer. How can I concatenate the two bytes such that I obtain one 16-bit object?

Code:

highbyte = i2c.mem_read(1, address, addr)
lowbyte = i2c.mem_read(1, address, addr+1)
word = (highbyte << 8) + lowbyte # Shift highbyte 8 bits to the left, then add lowbyte to obtain 16-bit 'bytes' object

The word line gives an error. Highbyte and lowbyte are both of the type 'bytes'.
Any help is greatly appreciated.

Re: Combining two bytes to one 16-bit object

Posted: Sun Aug 05, 2018 12:53 am
by dhylands
mem_read returns a bytes object which can contain multiple bytes. So you need to pass in an index to pull out the first byte from the result. Something like this should work:

Code: Select all

highbyte = i2c.mem_read(1, address, addr)
lowbyte = i2c.mem_read(1, address, addr+1)
word = (highbyte[0] << 8) + lowbyte[0] # Shift highbyte 8 bits to the left, then add lowbyte to obtain 16-bit 'bytes' object
For many I2C devices you can read both bytes at the same time by doing:

Code: Select all

data = i2c.mem_read(2, address, addr)
word = (data[0] << 8) + data[1] # Shift highbyte 8 bits to the left, then add lowbyte to obtain 16-bit 'bytes' object

Re: Combining two bytes to one 16-bit object

Posted: Tue Aug 14, 2018 4:38 pm
by thejoker
Thank you for your reply. I found a different (maybe easier) way to concatenate two bytes from two 'bytes'-objects into one 'bytes'-object:

Code: Select all

highbyte = i2c.mem_read(1, address, addr)
lowbyte = i2c.mem_read(1, address, addr+1)
twobytes = highbyte + lowbyte 
dhylands wrote:
Sun Aug 05, 2018 12:53 am
...
For many I2C devices you can read both bytes at the same time by doing:

Code: Select all

data = i2c.mem_read(2, address, addr)
word = (data[0] << 8) + data[1] # Shift highbyte 8 bits to the left, then add lowbyte to obtain 16-bit 'bytes' object
That 's exactly what I'm looking for next! Do you know how I could check if the second byte read is actually from the next register (addr+1)?

Re: Combining two bytes to one 16-bit object

Posted: Tue Aug 14, 2018 11:16 pm
by dhylands
You'd need to consult the datasheet for the chip in questions.

Generally, that's how i2c devices work. With some devices there is an auto-increment register, and you may need to configure that properly. But all of this behavior is device specific.

Re: Combining two bytes to one 16-bit object

Posted: Sun Oct 28, 2018 5:49 pm
by kwiley
Aside from the response you already got, it's worth noting that it might be faster to manipulate bits and bytes with bit operators instead of arithmetic operators. So instead of adding the low byte trying ORing it instead:

Code: Select all

word = (high_byte << 8) | low_byte
Of course, you would have to write a timer test to determine whether this actually makes any difference in the wild.

Re: Combining two bytes to one 16-bit object

Posted: Mon Oct 29, 2018 7:50 am
by pythoncoder
kwiley wrote:
Sun Oct 28, 2018 5:49 pm
..it might be faster to manipulate bits and bytes with bit operators instead of arithmetic operators...
I doubt it would make any difference: on a modern chip at assembler level a 32 bit register add can be expected to be as fast as a logical operation. But this time is dwarfed by the time taken by the MicroPython VM to interpret the bytecode. Any difference in timing would surely be a quirk in the VM rather than a hardware issue.

FWIW I prefer logical ops, but purely because the intent is slightly clearer.