Hey All,
I am having a bizarre error with the gyroscope/magnetometer inside the MPU9150. I am writing a lightweight I2C driver to extract scaled data from the sensor. However, if I choose to read from the magnetometer, it overwrites the gyroscope z-axis value with one of the magnetometer values.
This is very odd to me because, as far as I can perceive, I am not reassigning these variables within my own code. This seems to imply that the overwrite is occurring within the sensor itself...
I know that there are already libraries available for this sensor, but I wanted to write my own in order to streamline the code a little bit, and to use later with an AHRS library.
I have enabled I2C access to the AK8975, and set it to perform a single measurement through every loop.
I have also tried reading the AK8975 data-ready register before performing a read, but i get the same error.
Ultimately I would like to measure exactly how long it takes to become ready so that I can put it on a timer and waste no time with the delay () function.
Any ideas on this one gang?
Here is the datasheet and register map:
Datasheet: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/IMU/PS-MPU-9150A.pdf
Register Map: http://www.invensense.com/mems/gyro/documents/RM-MPU-9150A-00v4_2.pdf
I read through your code, and could not see anything obviously wrong with it.
How thoroughly have you tested yours "twoscomplement" function ?
I don't have one of these 9150 devices but I have a bunch of 6050's. If it was my problem, I'd try the following things to see if the cause of the problem emerged:
Try printing the exact bytes you get from the I2C.
Try reading the magnet registers separately from the 6050 ones.
Try reading two bytes at a time from the magnet registers.
Try reading a single byte at a time from the magnet registers.
This should make it apparent if there is actually some strange defect with the device. If you can read actual single bytes from the device, then there is a problem somehow with your process for manipulating six bytes. If you can't read single bytes from the device, chuck it and buy a new one.
Try changing the order of the public variables in your class, or adding some dummy variables, to exclude the possibility that the error arises because you are somehow overwriting the bounds of one of those arrays and overwriting the adjacent array.
Read the datasheet again, very carefully, to check the timing of how the values available in the device register, are replaced with new values.
You seem to be taking an array of 6 bytes for your magnet data and rearranging into three 16 bit ints, which seems to be correct.
You are also taking an array 14 bytes for your other data and rearranging those into 7 16 bit ints, and then trying to put those 7 ints into an array which you have defined, with 6 elements.
Thank you so much for the help! I have been working on this project for so long I have tunnel vision.
Making that array change did the trick!
I'll be putting my work on github if it is of interest.
I found something in the sketch when reading from the sensor.
You write the 'regAddr' between 'beginTransmission()' and 'endTransmission()', that is good.
But you request the data also between 'beginTransmission()' and 'endTransmission()', that is wrong.
You don't use 'available()' when reading a single register, but a good sketch uses that also in that situation to see if a byte is received.
To request data, the 'requestFrom()' is a full i2c transfer, with begin and end included in the function. The function actually waits until the i2c transfer has finished. The 'Wire.read' reads the data from a buffer that was filled by 'requestFrom'.