Bonus Accelerometer!

We're going to go back and revisit the mysterious Read command 0x32 that we fuzzed with for a bit. Its also in the logs, be sure to set your filter to show both Host-to-Device and Device-to-Host since its a 'read' not a 'write'
We were pretty close with our commands, it looks like we should be reading only 10 bytes. It also looks like the data doesn't really change much except for a bit further down…

The 7'th byte changes a lot right after we send it that bRequest 0x31 (motor movement). That implies that this data read is somehow affected by the motor, possibly a motor feedback byte?

Checking out a tear-down of the device (from iFixit) we see that there is an 'inclinometer'/accelerometer (Kionix KXSD9). The datasheet indicates it is used for image stabilization, and it has 3 axes (X Y and Z) with 10 bits of data per axis.

Lets continuously read that data

import usb.core
import usb.util
import sys
import time
 
# find our device
dev = usb.core.find(idVendor=0x045e, idProduct=0x02B0)
 
# was it found?
if dev is None:
    raise ValueError('Device not found')
 
dev.set_configuration()
 
while True:
    # Get data from brequest 0x32
    ret = dev.ctrl_transfer(0xC0, 0x32, 0x0, 0x0, 10)
    print map(hex, ret)

Shaking the Kinect while running the script you'll see clearly that the data changes with movement.

To identify the accelerometer axes, rotate it only one way at a time and note what changes. You can also see how this data is in bytes but the accelerometer data should be a signed word because there are flips from 0xfff7 to 0x0007 which would indicate a negative to positive conversion.

We can cast two bytes to a signed value by 'hand' (in C this is a little easier, we know)
import usb.core
import usb.util
import sys
import time
 
# find our device
dev = usb.core.find(idVendor=0x045e, idProduct=0x02B0)
 
# was it found?
if dev is None:
    raise ValueError('Device not found')
 
dev.set_configuration()
 
while True:
    # Get data from brequest 0x32
    ret = dev.ctrl_transfer(0xC0, 0x32, 0x0, 0x0, 10)
    #print map(hex, ret)
 
    x = (ret[2] << 8) | ret[3]
    x = (x + 2 ** 15) % 2**16 - 2**15     # convert to signed 16b
    y = (ret[4] << 8) | ret[5]
    y = (y + 2 ** 15) % 2**16 - 2**15     # convert to signed 16b
    z = (ret[6] << 8) | ret[7]
    z = (z + 2 ** 15) % 2**16 - 2**15     # convert to signed 16b
 
    print x, "\t", y, "\t", z
Now when you run the script you'll see the signed data appear properly.
Last updated on 2015-11-19 at 06.21.45 PM Published on 2012-07-29 at 11.58.38 AM