Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Read out accelerometer and gyroscope from movement service (TI sensortag CC2650)
-
Hi, I am trying to read out the accelerometer and gyroscope from the ti sensortag cc2650. I took the example given in cb lib to try it out.
I gave a look at the cc2650 wiki (wiki and there is a configuration characteristic which should be set up to enable/disable the sensor.
In my case, I set this configuration as follows :
Bit 0 to 5 = 1
Bit 6 to 7 = 0
Bit 8 = 0
Bit 9 = 1 ---> so I wrote 0x011F in the configuration using the callback function did_discover_characteristics() but I receiving this output :
(-393, 0, 0, 0, 0, 0, 268, -341, 582) --> rawData converted from binary used the struct.unpack function. But it doesn't match. And I have this problem with every configuration.
Here is the part of the code where Iam reading out the data and convert it. What Iam doing wrong?def did_discover_characteristics(self, s, error): if 'AA80' in s.uuid: print('mpu9250 service') for c in s.characteristics: if 'AA82' in c.uuid: self.peripheral.write:characteristics_value(c, chr(0x011F), True) elif 'AA81' in c.uuid: self.peripheral.set_notify_value(c, True) def did_update_value(self,c, error): rawData=() #use unpack to convert binary..> little endian and 9x 2Bytes rawData = struct.unpack('<hhhhhhhhh', c.value) print(rawData)
This is the essential part of my code. So how you can see it should work but the output is not the expected one. Do you know where maybe what can be the problem?
-
The value for the configuration characteristic seems wrong to me.
chr(0x011F)
returns a unicode string, and you really want a byte string there.I think (can't try this here without the hardware)
bytes([0b11111100, 0b01000000])
should be correct for the bits you want to set (as the individual bits are relevant here, I think it makes sense to use binary notation instead of hex here). -
Hi thank you for the reply. Okay but when Iam using chr() forthe other settings e.g. to set up the period it works fine. Do you know the reason why this is like that? In the example given in cb lib chr is used as well. Another question why bytes(0b11111100, 0b01000000) ? Is only 0b11111100 not enough?
-
By the way I have tested it with bytes, but I didn't get any output :(.
Since I used the bytes notation I am not able to get any output of the values. The callback did_update_value is not called since I changed chr() to bytes in configuration characterisitc. -
@ProgrammingGo I think I wrote the sample code in the
cb
module docs when Pythonista didn't support Python 3 yet, and for single byte values, it should work fine anyway, but you're dealing with more than one byte for setting the configuration.Another question why bytes(0b11111100, 0b01000000) ? Is only 0b11111100 not enough?
Possibly, but you wanted to set bit 9 to 1 (setting the accelerometer range, I think?), so you'd need the second byte for that. I'm also not sure how the SensorTag behaves when you set the config to only one byte, as the wiki mentions that it's a two byte (16 bit) value.
Since I used the bytes notation I am not able to get any output of the values. The callback did_update_value is not called since I changed chr() to bytes in configuration characterisitc.
Maybe you need to either read the characteristic explicitly (via the
cb.Peripheral.read_characteristic_value
method), or perhaps write 0x0001 for the "Notification" characteristic (UUID 2902), as mentioned in the wiki?Did you check in your previous code if the
c
parameter indid_update_value
was actually the characteristic you were expecting? -
Hi, I have tested it with the Ti tool that I am sending the whole config once without splitting it out(enable axis, setting up range..) and it worked fine. So that was the reason why I did it without splitting it out.
okay but where I need to place the
cb.Peripheral.read_characteristic_value
because this method is calling the same callback did_update_value as the set notify_value method. Should I replace the set notify with the write method?
The previous c parameter was right but the values were not okay. E.g. when I enabled only the accelerometer axis and range 4G my output was like the following: (0,0,0,0,0, value, value,value, value). According to the wiki the order of the data is Gyroscope, Accelerometer, Magnetometer. How you can see it does not match.
I tried everything out but without success :( -
I think the bit order in the config bytes I suggested may be wrong, though I'm not really sure why you don't get any data at all...
Otherwise, I might have an explanation for the behavior you described in your first post:
chr(0x011F)
evaluates to the unicode string'ğ'
. Encoding this as a byte string with the default utf-8 encoding, this results inb'\xc4\x9f'
. The first byte (0xc4
) in binary notation would be0b11000100
. If we now assume that Bit 0 in the Wiki refers to the last (least significant) bit, and not the first (as I had assumed), those 8 bits represent the following configuration:1 1 0 0 0 1 0 0 ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | | | | | Gyro Z [❌] | | | | | Gyro Y [❌] | | | | Gyro X [✅] | | | Accel. Z [❌] | | Accel. Y [❌] | Accel. X [❌] Magnetometer (all axes) [✅]
Given this configuration, the output you're getting (
-393, 0, 0, 0, 0, 0, 268, -341, 582
) seems to make sense, as the non-zero values correspond to the things that are enabled.Anyway, could you try using
bytes([0b00111111, 0b00000010])
for the configuration?Also, perhaps you could implement
did_write_value
, if you haven't already, to check if there are errors. -
Hi, I tried it out and it seems that it works now because I am getting the following output:
(-34, 108, 221, 1326, 249, 3907, 0, 0, 0)
Now I am a bit confused: Does it mean that my bit 0 is on the right side and the highest on the left side like the following:
10 9 8 7 6 5 4 3 2 1 0 ? -->
0 = G_z
1 = G_y
2 = G_x
3 = A_z
4 = A_y
5 = A_x
6 = Magnetometer all axis
7 = Wake on
8 , 9 = Range ?I tried out to send all the settings into 1 byte but it seems that it does not work, I need to split it like you showed me.
I cannot understand this part: bytes([0b00111111, 0b00000010) --> It is clear that the first byte is to enable the axes of the sensors and the second for the range, but for the second byte there are only 8 bits and the range wouldn't be 8G because the bit 1 is set to 1. How is it is possible to set the 8 and 9th bit when you are only sending 8 bit? Let's say we want to set 16g I need to send 10bits. is the bytes operation bytes([bytes1,bytes2]) doing an OR-operation? -
The first byte contains bit 0 to bit 7, and the second byte contains bit 8 to bit 15.
Just 10 of those 16 bits are actually used for the configuration, but you can only send entire bytes.
When the second byte is
0b00000010
, bit 8 would be0
and bit 9 would be1
, which should correspond to a scale of 4G. If you want 16G, you should set both bits to 1 (11 is 3 in binary notation). -
Hi thank you so much, yeah it is clear now :). because we are starting from the right to the left so least significant bit 0 is starting from the right.
So it means that it is a little endian notation, because the incoming input is gyroX[0:7], gyroX[8:15]....... ?-> I used the unpack with little endian to display the values like the following:
struct.unpack('<hhhhhhhhh,' value)
So how I understood it with bytes([byte1,byte2]) I am sending 2 bytes so when I want to send more for example 3 or four, I should append it like that: bytes(byte1, byte2, byte3....).
Regarding using chr() and bytes, normally it should make a huge difference because it is the same number, only represented in a different way.
Do you know why it is a problem? - Setting the time period with chr() with hex-representation in AA83 is working fine. -
@omz said:
The first byte contains bit 0 to bit 7, and the second byte contains bit 8 to bit 15.
Just 10 of those 16 bits are actually used for the configuration, but you can only send entire bytes.
When the second byte is
0b00000010
, bit 8 would be0
and bit 9 would be1
, which should correspond to a scale of 4G. If you want 16G, you should set both bits to 1 (11 is 3 in binary notation).Do you mean 0b00000010, bit 8 '0' and bit '9'is 1 would correspond to 8G?
-
@ProgrammingGo said:
Do you mean 0b00000010, bit 8 '0' and bit '9'is 1 would correspond to 8G?
No, I think it would correspond to 4G. If I'm not mistaken, 8G would be
0b00000001
(I assume the last bit is bit 8, and the second-to-last is bit 9). -
@omz said:
@ProgrammingGo said:
Do you mean 0b00000010, bit 8 '0' and bit '9'is 1 would correspond to 8G?
No, I think it would correspond to 4G. If I'm not mistaken, 8G would be
0b00000001
(I assume the last bit is bit 8, and the second-to-last is bit 9).Hi yeah the last bit from the right is the 8th bit and the second-to -last is 9th bit. But according to the wiki of CC2650 this is written for the the range:
8:9 Accelerometer range (0=2G, 1=4G, 2=8G, 3=16G): 10 is for 8G --> so would this representation be wrong: 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 (Bits)
0 0 0 0 0 0 1 0 | 0 0 0 0 0 0 0 0 (Vakue) --> 10 would be 8G Is it not right? -
Hi, I tried out to set up 16g range to the accelerometer, activating only accelerometer with range of 16g like the following: bytes([0b00111000, 0b00000011] and the to convert the raw data I used the formula stated in the wiki of TI: http://processors.wiki.ti.com/index.php/CC2650_SensorTag_User's_Guide#Movement_Sensor
---> v = (raw(data * 1.0) / (32768/16) for every axes and the output seems to be not right because in static position I get the following values for x, y, z: 1.9414, 0.0786, 0.225. Normally the first value(x) should be around 0.981. When I am changing the configuration to bytes([0b00111000, 0b00000010] which should be 8G range and use the following formula: v = (raw(data * 1.0) / (32768/8) then seems to be correct and in static position I have following values: 0.920 , 0.005, 0.200. Do you know what is the problem? I checked the formula and the settings but it should be right. The problem is well known, but not solved , See here: https://evothings.com/forum/viewtopic.php?t=1875