I’m using a minlMU-9 interfaced with a Raspberry Pi via I2C. There is no problem interfacing, just with the compass readings. The compass is secured to a narrow board, allowing us to perform relatively accurate rotations (to within a few degrees). There is also no nearby magnetic interference which would skew our readings.
We’ve been benchmarking using an iPhone compass ap. At most, there should be a fixed offset between the two, but that hasn’t been the case. Also, when the minlMU-9 is rotated by 90 or 180 degrees, the amount of rotation (difference between the readings) is typically off from 90 or 180 by around 10 degrees. When slowly rotating the minlMU, sometimes the reading jumps by an offset which then sticks to all subsequent readings. I suspect a mechanical issue.
My lab partner is handling the coding (Python), which I think is stock code modified to calculate a heading from the raw data.
from __future__ import division from smbus import SMBus from time import sleep import math busNum = 1 b = SMBus(busNum) LSM = 0x1d LGD = 0x6b LSM_WHOAMI = 0b01001001 #Compass/Accelerometer self-id def twos_comp_combine(msb, lsb): #Function used to combine MSB & LSB twos_comp = 256*msb + lsb if twos_comp >= 32768: return twos_comp - 65536 else: return twos_comp #Control register addresses -- from LSM303D datasheet CTRL_0 = 0x1F #General settings CTRL_1 = 0x20 #Turns on accelerometer and configures data rate CTRL_2 = 0x21 #Self test accelerometer, anti-aliasing accel filter CTRL_3 = 0x22 #Interrupts CTRL_4 = 0x23 #Interrupts CTRL_5 = 0x24 #Turns on temperature sensor CTRL_6 = 0x25 #Magnetic resolution selection, data rate config CTRL_7 = 0x26 #Turns on magnetometer and adjusts mode #Registers holding twos-complemented MSB and LSB of magnetometer readings -- from LSM303D datasheet MAG_X_LSB = 0x08 # x MAG_X_MSB = 0x09 MAG_Y_LSB = 0x0A # y MAG_Y_MSB = 0x0B MAG_Z_LSB = 0x0C # z MAG_Z_MSB = 0x0D #Registers holding twos-complemented MSB and LSB of accelerometer readings -- from LSM303D datasheet ACC_X_LSB = 0x28 # x ACC_X_MSB = 0x29 ACC_Y_LSB = 0x2A # y ACC_Y_MSB = 0x2B ACC_Z_LSB = 0x2C # z ACC_Z_MSB = 0x2D #Registers holding 12-bit right justified, twos-complemented temperature data -- from LSM303D datasheet TEMP_MSB = 0x06 TEMP_LSB = 0x05 if b.read_byte_data(LSM, 0x0f) == LSM_WHOAMI: #testing compass/acc print 'LSM303D detected successfully.' else: print 'No LSM303D detected on bus '+str(busNum)+'.' b.write_byte_data(LSM, CTRL_1, 0b1010111) # enable accelerometer, 50 hz sampling b.write_byte_data(LSM, CTRL_2, 0x00) #set +/- 2g full scale b.write_byte_data(LSM, CTRL_5, 0b11100100) #high resolution mode, thermometer off, 6.25hz ODR b.write_byte_data(LSM, CTRL_6, 0b00100000) # set +/- 4 gauss full scale b.write_byte_data(LSM, CTRL_7, 0x00) #get magnetometer out of low power mode while True: magx = twos_comp_combine(b.read_byte_data(LSM, MAG_X_MSB), b.read_byte_data(LSM, MAG_X_LSB)) #raw magnetometer value for x magy = twos_comp_combine(b.read_byte_data(LSM, MAG_Y_MSB), b.read_byte_data(LSM, MAG_Y_LSB)) #raw magnetometer value for y magz = twos_comp_combine(b.read_byte_data(LSM, MAG_Z_MSB), b.read_byte_data(LSM, MAG_Z_LSB)) #raw magnetometer value for z #compass w/o pitch and roll if (magy > 0): com_deg2 = (90-(math.degrees(math.atan(magx/magy)))) if (magy < 0): com_deg2 = (270-(math.degrees(math.atan(magx/magy)))) if (magy == 0 and magx < 0): com_deg2 = 180 if (magy == 0 and magx > 0): com_deg2 = 0 print "Raw Magnetic field (x, y, z):", magx, magy, magz print "Degree: %.2f" % com_deg2 print "---" sleep(2.0)
Any help would be appreciated!