Module for MPU9150
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Module for MPU9150
I've tried increasing the delay in line 192. The results are somewhat erratic but I seem to get reliable operation with a value of 20mS. The values returned by the magnetometer are an order of magnitude higher than those I got with the original code and I no longer get the spurious zero values. The actual values now seem plausible: for example with the magnetometer Y axis pointing North I get
[-21.00853, 1.200487, -71.429]
I'm no expert but I think these values are credible for my location (UK, 53.2580°N, 2.1270°W).
I've not spotted anything in the datasheet regarding a value for this delay - is there any information out there on how to access the magnetometer?
Regards, Pete
[-21.00853, 1.200487, -71.429]
I'm no expert but I think these values are credible for my location (UK, 53.2580°N, 2.1270°W).
I've not spotted anything in the datasheet regarding a value for this delay - is there any information out there on how to access the magnetometer?
Regards, Pete
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 288
- Joined: Sun May 04, 2014 8:54 am
Re: Module for MPU9150
hey, nice to see my second user!
I just pushed an update to github.
TODO:
I just pushed an update to github.
- added passthrough mode - you no longer have to connect ESD and ESC
- changed mode() to wake() and sleep()
- the default setting after init know is awake, passthrough mode active, accel and gyro range set to 3
- added get_*_raw(), so you can store bytes if you are trying to log data as fast you can
- fixed get_mag(), so it now waits for data ready
TODO:
- adjust magnetometer values to sensitvity as described on page 59 in the register map
- make get_mag() none blocking by using yield
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Module for MPU9150
The new build does provide consistent magnetometer values. A non-blocking method would be great. I'm building a balancing robot so my main interest is the gyro and accelerometer until I get the control system sorted, but I'll return to the mag later. Looking at your code it seems clear how to do non-blocking access. I'll see what you come up with, otherwise I'll hack it using my threading library.
I'm still in the dark about the sample rate parameter. My application will read values at intervals of probably tens of milliseconds. Is there any merit in reducing the chip's sample rate? A web or datasheet reference would be fine but so far I've not spotted anything which explains it, nor have I spotted any empirical difference if I change it.
Regards, Pete
I'm still in the dark about the sample rate parameter. My application will read values at intervals of probably tens of milliseconds. Is there any merit in reducing the chip's sample rate? A web or datasheet reference would be fine but so far I've not spotted anything which explains it, nor have I spotted any empirical difference if I change it.
Regards, Pete
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 288
- Joined: Sun May 04, 2014 8:54 am
Re: Module for MPU9150
datasheet
http://dlnmh9ip6v2uc.cloudfront.net/dat ... -9150A.pdf
register map
http://dlnmh9ip6v2uc.cloudfront.net/dat ... 50A-00.pdf
I think the sample rate is pretty irrelevant for us. Lowering it may lower power consumption.
http://dlnmh9ip6v2uc.cloudfront.net/dat ... -9150A.pdf
register map
http://dlnmh9ip6v2uc.cloudfront.net/dat ... 50A-00.pdf
I think the sample rate is pretty irrelevant for us. Lowering it may lower power consumption.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Module for MPU9150
I've come across an issue which needs consideration. My application was freezing for a period at random intervals. Currently the only repeated call to the library is via get_gyro(): it turns out that the call, which normally takes about 5mS, occasionally takes 5 seconds! It also very occasionally crashes with
# File "mpu9150.py", line 247, in get_gyro
# TypeError: tuple indices must be integers, not NoneType
Both these behaviours are down to self._mpu_i2c.mem_read() timing out and returning None - the default timeout is 5 seconds. In the case of the crash I think it's prompted by scale[gr] where gr is None as a result of a timeout in self.gyro_range(). I'm not sure what's causing the timeout - it happens very roughly once a minute while I'm calling get_gyro() at 20Hz or so. I think the code needs to specify a much shorter timeout and to handle the return of None. I've changed the timeout to 20mS and modified get_gyro() so that, in the event of a timeout, it returns the last good value. This has fixed my immediate problem.
Unfortunately I suspect that this will apply to all accesses to the MPU9150 including the accel and mag. Clearly a five second lockup would have interesting consequences for anyone using this code to stabilise an aircraft...
It's possible that I have an unreliable device or electrical issues. However the kit is powered from a lab bench supply and the leads between the device and the Micropython board are only an inch long so I doubt that my problems are electrical. I wonder if you can replicate this problem?
Regards, Pete
# File "mpu9150.py", line 247, in get_gyro
# TypeError: tuple indices must be integers, not NoneType
Both these behaviours are down to self._mpu_i2c.mem_read() timing out and returning None - the default timeout is 5 seconds. In the case of the crash I think it's prompted by scale[gr] where gr is None as a result of a timeout in self.gyro_range(). I'm not sure what's causing the timeout - it happens very roughly once a minute while I'm calling get_gyro() at 20Hz or so. I think the code needs to specify a much shorter timeout and to handle the return of None. I've changed the timeout to 20mS and modified get_gyro() so that, in the event of a timeout, it returns the last good value. This has fixed my immediate problem.
Unfortunately I suspect that this will apply to all accesses to the MPU9150 including the accel and mag. Clearly a five second lockup would have interesting consequences for anyone using this code to stabilise an aircraft...
It's possible that I have an unreliable device or electrical issues. However the kit is powered from a lab bench supply and the leads between the device and the Micropython board are only an inch long so I doubt that my problems are electrical. I wonder if you can replicate this problem?
Regards, Pete
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 288
- Joined: Sun May 04, 2014 8:54 am
Re: Module for MPU9150
I have the exact same problem and until now I thought it was the SD card!
You finally found the real location if that bug for me! I'll look into it tomorrow.
You finally found the real location if that bug for me! I'll look into it tomorrow.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Module for MPU9150
Another observation. When looking for the bug, I removed gr = self.gyro_range() from get_gyro() - after all the range is known to the class instance because it set the value in the first place. This greatly reduced the frequency of the error. This perhaps suggests some kind of hardware issue with the MPU but given that these things are likely to be used in realtime applications it needs to be handled.
I'd suggest having the timeout as a class property defaulting to something more akin to 20mS than 5S, but changeable by the user.
Regards, Pete
I'd suggest having the timeout as a class property defaulting to something more akin to 20mS than 5S, but changeable by the user.
Regards, Pete
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 288
- Joined: Sun May 04, 2014 8:54 am
Re: Module for MPU9150
okay, this should now be fixed. i added timeouts to the i2c functions that will get looped and made the range functions store the selected range to a pseudo-private attribute, which is then used by the get functions.
thanks again for finding that bug!
thanks again for finding that bug!
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Module for MPU9150
The code looks good, I'll give it a thorough workout today. But I still have a concern. Your original version didn't have a bug as such: the code was fine, yet the hardware very occasionally took exception to the sequence of events and timed out. I wish we understood the reason for this: I think the hardware has some limitation which we need to discover. We've effectively implemented a workround by reducing the timeout and avoiding doing two I2C reads in quick succession.
Yesterday I hacked the gyro part of your code to effectively do the same as you're doing now, reducing the timeout to 10mS and avoiding reading the scaling from the hardware. Usually timeouts were handled fine but I still got occasional I2C crashes which could only be cleared by power cycling the hardware. I'll investigate further with your new code and report back.
Regards, Pete
Yesterday I hacked the gyro part of your code to effectively do the same as you're doing now, reducing the timeout to 10mS and avoiding reading the scaling from the hardware. Usually timeouts were handled fine but I still got occasional I2C crashes which could only be cleared by power cycling the hardware. I'll investigate further with your new code and report back.
Regards, Pete
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Module for MPU9150
I've run the new code for a long period today. Timeouts usually have no adverse consequences, but sometimes I'm seeing
Exception: HAL_I2C_Mem_Read failed with code 2
When this occurs the I2C bus seems to be locked solid. I tried to query the bus as follows when it was in this state
This contrasts with the normal situation
I'm baffled as to why timeouts occur, why it gets into this state, and how to retrieve the situation in code.
Regards, Pete
Exception: HAL_I2C_Mem_Read failed with code 2
When this occurs the I2C bus seems to be locked solid. I tried to query the bus as follows when it was in this state
Code: Select all
>>> import pyb
>>> a = pyb.I2C(2, pyb.I2C.MASTER)
>>> a.is_ready(104)
False
>>> a.scan()
[]
>>>
Code: Select all
>>> a = pyb.I2C(2, pyb.I2C.MASTER)
>>> a.is_ready(104)
True
>>> a.scan()
[12, 104]
>>>
Regards, Pete
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.