Combining two bytes to one 16-bit object

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
thejoker
Posts: 11
Joined: Sat Aug 04, 2018 2:14 pm

Combining two bytes to one 16-bit object

Post by thejoker » Sat Aug 04, 2018 2:51 pm

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.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Combining two bytes to one 16-bit object

Post by dhylands » Sun Aug 05, 2018 12:53 am

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

thejoker
Posts: 11
Joined: Sat Aug 04, 2018 2:14 pm

Re: Combining two bytes to one 16-bit object

Post by thejoker » Tue Aug 14, 2018 4:38 pm

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)?
Last edited by thejoker on Sat Aug 18, 2018 8:28 am, edited 1 time in total.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Combining two bytes to one 16-bit object

Post by dhylands » Tue Aug 14, 2018 11:16 pm

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.

kwiley
Posts: 140
Joined: Wed May 16, 2018 5:53 pm
Contact:

Re: Combining two bytes to one 16-bit object

Post by kwiley » Sun Oct 28, 2018 5:49 pm

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.
Last edited by kwiley on Wed Mar 27, 2019 3:55 am, edited 1 time in total.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Combining two bytes to one 16-bit object

Post by pythoncoder » Mon Oct 29, 2018 7:50 am

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.
Peter Hinch
Index to my micropython libraries.

Post Reply