LSM303DLHC in Python on the Raspberry Pi

Breakout boards, sensors, Drawdio, Game of Life, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Thu Feb 21, 2013 7:52 pm

Hi Guys, I was wondering if anyone has already ported the Library for the LSM303 chip's to Python?

I'm new to I2C on the Pi and not much of a coder myself and was hoping to find something already started/done but google has turned up nothing but C for me so far.

I'm hoping to use my LSM303 for some fun with magnet's type educational stuff.
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby adafruit_support_mike » Sat Feb 23, 2013 1:56 am

I Googled around a bit and couldn't find anything for that specific chip, but did find this Instructable on using I2C with python on the RasPi: http://www.instructables.com/id/Raspber ... 2C-Python/

The RasPi forums also led to this page: http://think-bowl.com/raspberry-pi/i2c- ... pberry-pi/ which has more I2C code in Python. You might talk to the guy who writes that blog, since he seems to have his I2C chops down pretty well.

I know those aren't a perfect match, but I2C is a fairly straightforward protocol once you get past all the bit-timing and Start/Stop/ACK/NAK stuff. You send a command to the device and it sends you a reply. Now granted, the LSM303 has a fairly.. ample.. command and reply set, but you can probably piece together some working code from the C libraries and the datasheet (http://www.adafruit.com/datasheets/LSM303DLHC.PDF).

I'll be happy to help you get over the speed bumps if you'd like.
When you void a product warrany, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 1379
Joined: Thu Feb 11, 2010 1:51 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Sat Feb 23, 2013 5:35 am

Hey thanks for your reply!

I've been looking at the links you posted as well as digging through some other, similar info. so far I'm still totally baffled by the LSM303.

For simplicity at this stage I'm only looking at the Mag portion of this chip(Chapter 7.2+), i'll worry about the accel's after I've got something working here first.

Unlike the CMPS03 in your first link, the LSM seems to need a lot more setup to get it to update it's data. This is my first time doing this, or really looking at datasheets so I'm fumbling a bit, but if we look at 7.2.1 CRA_REG_M (00h), table 70, it has 8 boxes, i assume these represent an 8bit value for this register. From left to right they read as TEMP_EN, 0(1), 0(1), DO2, DO1, DO0, 0(1), 0(1). There is a note saying (1) must be set to 0 to work.

So DO0-2 are in a table saying they set the data output rate, 1, 0, 0 should set it to 15Hz, for example. So if I set register 0 to 10010000(binary) or 90(hex) I should have my temp sensor enabled and refresh rate at 15Hz right? so
Code: Select all
sudo i2cset -y 1 0x1e 0x00 0x90
in the terminal, in python bus.write_byte_data(address, 0, 90)? is that something like what I should be doing?

So following the datasheet further down to the "7.2.4 OUT_X_H_M (03), OUT_X_LH_M (04h)" heading reads "X-axis magnetic field data. The value is expressed as 2’s complement", so I'm guessing this means it's a 16bit value and i need to read both registers 3 and 4, combine them, and convert that to a decimal. reading [0x03] gives me a value of [0xfe] and [0x04] gives me [0xb8], or [sudo i2cget -y 1 0x1e 0x03 w] gives me [0xb8fe], without looking up how to convert to nanoTesla's yet let's just turn the sensor 90° and see what our readings are.... they don't change. This is where I'm stuck.

At this stage just getting values to change as I move the sensor would be a huge win.
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Sat Feb 23, 2013 9:59 am

Well, that was an interesting learning curve. And I'm certainly better off for it. I've got the sensors working for me now, and learned a few things about python and I2C in the process. Now the final piece of this puzzle for me is to turn the outputs into something standardized, and calibrated.
G's, nanoTesla's and °C would be nice, but until then I'll leave my code here for anyone else who has one of these and wants to play with it in python.

This document has some helpful pieces in it too, and it's a great starting point for people just learning about the Earth's Mag field and how we use a 6DOF like this: LSM303DLH Configuration

Code: Select all
import smbus
import time
import math

bus = smbus.SMBus(1)

LSM303_ADDRESS_ACCEL = 0x19 #Default Accel address
LSM303_ADDRESS_MAG = 0x1e # Default Mag address

# Accel registers

LSM303_REGISTER_ACCEL_CTRL_REG1_A = 0x20   # 00000111   rw
LSM303_REGISTER_ACCEL_CTRL_REG2_A = 0x21   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG3_A = 0x22   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG4_A = 0x23   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG5_A = 0x24   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG6_A = 0x25   # 00000000   rw
LSM303_REGISTER_ACCEL_REFERENCE_A = 0x26   # 00000000   r
LSM303_REGISTER_ACCEL_STATUS_REG_A = 0x27   # 00000000   r
LSM303_REGISTER_ACCEL_OUT_X_L_A = 0x28
LSM303_REGISTER_ACCEL_OUT_X_H_A = 0x29
LSM303_REGISTER_ACCEL_OUT_Y_L_A = 0x2A
LSM303_REGISTER_ACCEL_OUT_Y_H_A = 0x2B
LSM303_REGISTER_ACCEL_OUT_Z_L_A = 0x2C
LSM303_REGISTER_ACCEL_OUT_Z_H_A = 0x2D
LSM303_REGISTER_ACCEL_FIFO_CTRL_REG_A = 0x2E
LSM303_REGISTER_ACCEL_FIFO_SRC_REG_A = 0x2F
LSM303_REGISTER_ACCEL_INT1_CFG_A = 0x30
LSM303_REGISTER_ACCEL_INT1_SOURCE_A = 0x31
LSM303_REGISTER_ACCEL_INT1_THS_A = 0x32
LSM303_REGISTER_ACCEL_INT1_DURATION_A = 0x33
LSM303_REGISTER_ACCEL_INT2_CFG_A = 0x34
LSM303_REGISTER_ACCEL_INT2_SOURCE_A = 0x35
LSM303_REGISTER_ACCEL_INT2_THS_A = 0x36
LSM303_REGISTER_ACCEL_INT2_DURATION_A = 0x37
LSM303_REGISTER_ACCEL_CLICK_CFG_A = 0x38
LSM303_REGISTER_ACCEL_CLICK_SRC_A = 0x39
LSM303_REGISTER_ACCEL_CLICK_THS_A = 0x3A
LSM303_REGISTER_ACCEL_TIME_LIMIT_A = 0x3B
LSM303_REGISTER_ACCEL_TIME_LATENCY_A = 0x3C
LSM303_REGISTER_ACCEL_TIME_WINDOW_A = 0x3D

#Mag registers

LSM303_REGISTER_MAG_CRA_REG_M = 0x00
LSM303_REGISTER_MAG_CRB_REG_M = 0x01
LSM303_REGISTER_MAG_MR_REG_M = 0x02
LSM303_REGISTER_MAG_OUT_X_H_M = 0x03
LSM303_REGISTER_MAG_OUT_X_L_M = 0x04
LSM303_REGISTER_MAG_OUT_Z_H_M = 0x05
LSM303_REGISTER_MAG_OUT_Z_L_M = 0x06
LSM303_REGISTER_MAG_OUT_Y_H_M = 0x07
LSM303_REGISTER_MAG_OUT_Y_L_M = 0x08
LSM303_REGISTER_MAG_SR_REG_Mg = 0x09
LSM303_REGISTER_MAG_IRA_REG_M = 0x0A
LSM303_REGISTER_MAG_IRB_REG_M = 0x0B
LSM303_REGISTER_MAG_IRC_REG_M = 0x0C
LSM303_REGISTER_MAG_TEMP_OUT_H_M = 0x31
LSM303_REGISTER_MAG_TEMP_OUT_L_M = 0x32

#LSM303_REGISTER_MAG_CRB_REG_M (Mag Gain) values

LSM303_MAGGAIN_1_3 = 0x20,  # +/- 1.3
LSM303_MAGGAIN_1_9 = 0x40,  # +/- 1.9
LSM303_MAGGAIN_2_5 = 0x60,  # +/- 2.5
LSM303_MAGGAIN_4_0 = 0x80,  # +/- 4.0
LSM303_MAGGAIN_4_7 = 0xA0,  # +/- 4.7
LSM303_MAGGAIN_5_6 = 0xC0,  # +/- 5.6
LSM303_MAGGAIN_8_1 = 0xE0   # +/- 8.1

def WRITE_ACCEL(register,value):
        bus.write_byte_data(LSM303_ADDRESS_ACCEL, register, value)
        return -1

def WRITE_MAG(register,value):
        bus.write_byte_data(LSM303_ADDRESS_MAG, register, value)
        return -1

def READ_ACCEL(register):
        bus.read_byte_data(LSM303_ADDRESS_ACCEL, register)
        return -1

def READ_MAG(register):
        bus.read_byte_data(LSM303_ADDRESS_MAG, register)
        return -1

def accelDatax():
        gxhi = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_X_L_A)
        gxlo = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_X_H_A)
        gxtotal = ((gxhi << 8) | gxlo)
        return gxtotal

def accelDatay():
        gyhi = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Y_L_A)
        gylo = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Y_H_A)
        gytotal = ((gyhi << 8) | gylo)
        return gytotal

def accelDataz():
        gzhi = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Z_L_A)
        gzlo = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Z_H_A)
        gztotal = ((gzhi << 8) | gzlo)
        return gztotal

def accelDataTotal():
        gtotal = (((accelDatax()**2)+(accelDatay()**2)+(accelDataz()**2))**0.5)
        return gtotal

def magDatax():
        hxhi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_X_H_M)
        hxlo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_X_L_M)
        hxtotal = ((hxhi << 8) | hxlo)
        return hxtotal

def magDatay():
        hyhi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Y_H_M)
        hylo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Y_L_M)
        hytotal = ((hyhi << 8) | hylo)
        return hytotal

def magDataz():
        hzhi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Z_H_M)
        hzlo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Z_L_M)
        hztotal = ((hzhi << 8) | hzlo)
        return hztotal
       
def magDataTotal():
        htotal = (((magDatax()**2)+(magDatay()**2)+(magDataz()**2))**0.5)
        return htotal
       
def magDataTemp():
        thi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_TEMP_OUT_H_M)
        tlo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_TEMP_OUT_L_M)
        ttotal = ((thi << 8) | tlo)
        return ttotal

WRITE_ACCEL(LSM303_REGISTER_ACCEL_CTRL_REG1_A, 0x27) #initialise the Accelerometer
WRITE_ACCEL(LSM303_REGISTER_ACCEL_CTRL_REG4_A, 0x40)

WRITE_MAG(LSM303_REGISTER_MAG_MR_REG_M, 0x00) #initialise the Magnetometer

while True:
        print "LSM303DLHC Raw Data \nMagnetometer output: \nHx: ", magDatax()
        print "Hy: ", magDatay()
        print "Hz: ", magDataz()
        print "Htotal: ", magDataTotal(), "\n"
        print "\nAccelerometer output: \nGx: ", accelDatax()
        print "Gy: ", accelDatay()
        print "Gz: ", accelDataz()
        print "Gtotal: ", accelDataTotal(), "\n"
        print "Temp: ", magDataTemp()
        time.sleep(5)
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Sat Feb 23, 2013 7:49 pm

Having another look at this today, trying to make sense of the output I'm getting. According to the Sensor Characteristics page of the datasheet, The product is factory calibrated at 2.5 V. I'm powering it too the Pi's 3V3 rail, so I assume my readings will need to be adjusted down due to the 0V8 power increase.

The output of my program at the moment looks like this

Code: Select all
LSM303DLHC Raw Data                                                                                                                                                                                 
Magnetometer output:                                                                                                                                                                                 
Hx:  65480                                                                                                                                                                                           
Hy:  65133                                                                                                                                                                                           
Hz:  407                                                                                                                                                                                             
Htotal:  92358.5607185                                                                                                                                                                               
                                                                                                                                                                                                     
                                                                                                                                                                                                     
Accelerometer output:                                                                                                                                                                               
Gx:  64640                                                                                                                                                                                           
Gy:  128                                                                                                                                                                                             
Gz:  16384                                                                                                                                                                                           
Gtotal:  66684.1918298                                                                                                                                                                               
                                                                                                                                                                                                     
Temp:  1600


The Breakoutboard is sitting face up on my Pi Dish so I would expect low accel readings from both X & Y, and a negative reading on Z. However I don't know what 0 is or what to scale it by to get usable G's. The Gx value will change to 0 or close to it if I tilt the board slightly, I assume 65535 is the max value it can give (0xffff) but why would it read that if it's only just tilted past level? Do I take the value and take 65535 from it to get my negative value? can anyone shed some light on how I interpret these values?

Also, regarding the chip temp sensor output. According to the datasheet, TEMP_OUT_H_M outputs TEMP11 -> TEMP4, TEMP3 -> 0 are output on TEMP_OUT_L_M followed by 4 unused bits. Do I need to chop those 4 bits off and reverse the bit order of these registers to get the temp?
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby adafruit_support_mike » Sat Feb 23, 2013 9:49 pm

Dang man.. you move fast! ;-)

WRT the large values you're getting, that's two's-complement binary math. The high-end bit indicates the number's sign.

The 8-bit value 255 (bit pattern 1111 1111) translates to the value -1 in two's complement notation. The formal way to take the two's complement of a number is to invert the bits then add 1. In high-level languages, something like this should work:

Code: Select all
if number >= 32768
    number = number ^ 65535
    number += 1
When you void a product warrany, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 1379
Joined: Thu Feb 11, 2010 1:51 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby adafruit_support_mike » Sat Feb 23, 2013 10:03 pm

Atticus wrote:Also, regarding the chip temp sensor output. According to the datasheet, TEMP_OUT_H_M outputs TEMP11 -> TEMP4, TEMP3 -> 0 are output on TEMP_OUT_L_M followed by 4 unused bits. Do I need to chop those 4 bits off and reverse the bit order of these registers to get the temp?

Nope.. you just need to shift them.

Technically the operation looks like this:
Code: Select all
temp = (TEMP_OUT_H_M << 4) + (TEMP_OUT_L_M >> 4)

but that's kind of bit-logic intensive. In more human terms, it looks like this:

Code: Select all
temp = (TEMP_OUT_H_M * 16) + (TEMP_OUT_L_M / 16)
When you void a product warrany, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 1379
Joined: Thu Feb 11, 2010 1:51 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Sun Feb 24, 2013 4:08 am

OK, thanks to your advise I now have what appears to be °C spitting out from my temp sensor
Code: Select all
def magDataTemp():
        thi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_TEMP_OUT_H_M)
        tlo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_TEMP_OUT_L_M)
        ttotal = ((thi * 16) + (tlo / 16))
        return ttotal
        print "Temp: ", (magDataTemp() - 32) * 5/9, "C"


though it's only giving me whole integers, and seems to go up or down in 2° at a time or something. 12bit's I would think should be able to give me something more accurate, but it's not external temp anyway so it's not like I can use it for ambient logging so it's not important.

However I'm still trying to work out two's compliment and how to get it to work for me. Though now I have a direction to research, so I should be able to get somewhere. Math's was never my strong point though.
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Sun Feb 24, 2013 5:18 am

I almost have what I'm after, I think...

This code:
Code: Select all
import RPi.GPIO as GPIO
import smbus
import time
import math
import struct

GPIO.setmode(GPIO.BCM)
LED = 4
GPIO.setup(LED, GPIO.OUT)

bus = smbus.SMBus(1)

LSM303_ADDRESS_ACCEL = 0x19 #Default Accel address
LSM303_ADDRESS_MAG = 0x1e # Default Mag address

# Accel registers

LSM303_REGISTER_ACCEL_CTRL_REG1_A = 0x20   # 00000111   rw
LSM303_REGISTER_ACCEL_CTRL_REG2_A = 0x21   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG3_A = 0x22   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG4_A = 0x23   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG5_A = 0x24   # 00000000   rw
LSM303_REGISTER_ACCEL_CTRL_REG6_A = 0x25   # 00000000   rw
LSM303_REGISTER_ACCEL_REFERENCE_A = 0x26   # 00000000   r
LSM303_REGISTER_ACCEL_STATUS_REG_A = 0x27   # 00000000   r
LSM303_REGISTER_ACCEL_OUT_X_L_A = 0x28
LSM303_REGISTER_ACCEL_OUT_X_H_A = 0x29
LSM303_REGISTER_ACCEL_OUT_Y_L_A = 0x2A
LSM303_REGISTER_ACCEL_OUT_Y_H_A = 0x2B
LSM303_REGISTER_ACCEL_OUT_Z_L_A = 0x2C
LSM303_REGISTER_ACCEL_OUT_Z_H_A = 0x2D
LSM303_REGISTER_ACCEL_FIFO_CTRL_REG_A = 0x2E
LSM303_REGISTER_ACCEL_FIFO_SRC_REG_A = 0x2F
LSM303_REGISTER_ACCEL_INT1_CFG_A = 0x30
LSM303_REGISTER_ACCEL_INT1_SOURCE_A = 0x31
LSM303_REGISTER_ACCEL_INT1_THS_A = 0x32
LSM303_REGISTER_ACCEL_INT1_DURATION_A = 0x33
LSM303_REGISTER_ACCEL_INT2_CFG_A = 0x34
LSM303_REGISTER_ACCEL_INT2_SOURCE_A = 0x35
LSM303_REGISTER_ACCEL_INT2_THS_A = 0x36
LSM303_REGISTER_ACCEL_INT2_DURATION_A = 0x37
LSM303_REGISTER_ACCEL_CLICK_CFG_A = 0x38
LSM303_REGISTER_ACCEL_CLICK_SRC_A = 0x39
LSM303_REGISTER_ACCEL_CLICK_THS_A = 0x3A
LSM303_REGISTER_ACCEL_TIME_LIMIT_A = 0x3B
LSM303_REGISTER_ACCEL_TIME_LATENCY_A = 0x3C
LSM303_REGISTER_ACCEL_TIME_WINDOW_A = 0x3D

#Mag registers

LSM303_REGISTER_MAG_CRA_REG_M = 0x00
LSM303_REGISTER_MAG_CRB_REG_M = 0x01
LSM303_REGISTER_MAG_MR_REG_M = 0x02
LSM303_REGISTER_MAG_OUT_X_H_M = 0x03
LSM303_REGISTER_MAG_OUT_X_L_M = 0x04
LSM303_REGISTER_MAG_OUT_Z_H_M = 0x05
LSM303_REGISTER_MAG_OUT_Z_L_M = 0x06
LSM303_REGISTER_MAG_OUT_Y_H_M = 0x07
LSM303_REGISTER_MAG_OUT_Y_L_M = 0x08
LSM303_REGISTER_MAG_SR_REG_Mg = 0x09
LSM303_REGISTER_MAG_IRA_REG_M = 0x0A
LSM303_REGISTER_MAG_IRB_REG_M = 0x0B
LSM303_REGISTER_MAG_IRC_REG_M = 0x0C
LSM303_REGISTER_MAG_TEMP_OUT_H_M = 0x31
LSM303_REGISTER_MAG_TEMP_OUT_L_M = 0x32

#LSM303_REGISTER_MAG_CRB_REG_M (Mag Gain) values

LSM303_MAGGAIN_1_3 = 0x20,  # +/- 1.3
LSM303_MAGGAIN_1_9 = 0x40,  # +/- 1.9
LSM303_MAGGAIN_2_5 = 0x60,  # +/- 2.5
LSM303_MAGGAIN_4_0 = 0x80,  # +/- 4.0
LSM303_MAGGAIN_4_7 = 0xA0,  # +/- 4.7
LSM303_MAGGAIN_5_6 = 0xC0,  # +/- 5.6
LSM303_MAGGAIN_8_1 = 0xE0   # +/- 8.1

def WRITE_ACCEL(register,value):
        bus.write_byte_data(LSM303_ADDRESS_ACCEL, register, value)
        return -1

def WRITE_MAG(register,value):
        bus.write_byte_data(LSM303_ADDRESS_MAG, register, value)
        return -1

def accelDatax():
        gxlo = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_X_L_A)
        gxhi = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_X_H_A)
        gxtotal = ((gxhi <<8) + gxlo)
        if gxtotal >= 32768:
            gxtotal = (gxtotal ^ 65535)
            gxtotal += 1
            return int(gxtotal*-1)
        return gxtotal

def accelDatay():
        gylo = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Y_L_A)
        gyhi = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Y_H_A)
        gytotal = ((gyhi << 8) | gylo)
        if gytotal >= 32768:
            gytotal = (gytotal ^ 65535)
            gytotal += 1
            return int(gytotal*-1)
        return gytotal

def accelDataz():
        gzlo = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Z_L_A)
        gzhi = bus.read_byte_data(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_Z_H_A)
        gztotal = ((gzhi << 8) | gzlo)
        if gztotal >= 32768:
            gztotal = (gztotal ^ 65535)
            gztotal += 1
            return int(gztotal*-1)
        return gztotal

def accelDataTotal():
        gtotal = int(((accelDatax()**2)+(accelDatay()**2)+(accelDataz()**2))**0.5)
        return gtotal

def magDatax():
        hxhi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_X_H_M)
        hxlo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_X_L_M)
        hxtotal = ((hxhi << 8) + hxlo)
        if hxtotal >= 32768:
            hxtotal = (hxtotal ^ 65535)
            hxtotal += 1
            return hxtotal*-1
        return hxtotal

def magDatay():
        hyhi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Y_H_M)
        hylo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Y_L_M)
        hytotal = ((hyhi << 8) + hylo)
        if hytotal >= 32768:
            hytotal = (hytotal ^ 65535)
            hytotal += 1
            return (hytotal*-1)
        return hytotal

def magDataz():
        hzhi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Z_H_M)
        hzlo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_Z_L_M)
        hztotal = ((hzhi << 8) + hzlo)
        if hztotal >= 32768:
            hztotal = (hztotal ^ 65535)
            hztotal += 1
            return (hztotal*-1)
        return hztotal
       
def magDataTotal():
        htotal = (((magDatax()**2)+(magDatay()**2)+(magDataz()**2))**0.5)
        return htotal
       
def magDataTemp():
        thi = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_TEMP_OUT_H_M)
        tlo = bus.read_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_TEMP_OUT_L_M)
        ttotal = ((thi * 16) + (tlo / 16))
        return ttotal

WRITE_ACCEL(LSM303_REGISTER_ACCEL_CTRL_REG1_A, 0x27) #initialise the Accelerometer
WRITE_ACCEL(LSM303_REGISTER_ACCEL_CTRL_REG4_A, 0x80)

WRITE_MAG(LSM303_REGISTER_MAG_CRA_REG_M, 0x90) #initialise the Magnetometer
WRITE_MAG(LSM303_REGISTER_MAG_MR_REG_M, 0x00)

while True:
        GPIO.output(LED, True)
        print "LSM303DLHC Raw Data \nAccelerometer output: \nGx: ", accelDatax(), "\nGy: ", accelDatay(), "\nGz: ", accelDataz(), "\nGtotal: ", accelDataTotal()/16, "\n"
        print "Magnetometer output: \nHx: ", magDatax(), "\nHy: ", magDatay(), "\nHz: ", magDataz(), "\nHtotal: ", int(magDataTotal()*100), "nT", "\n\nTemp: ", (magDataTemp() - 32) * 5/9, "C"
        time.sleep(0.2)
        GPIO.output(LED, False)
        time.sleep(1.8)


produces this output:
Code: Select all
LSM303DLHC Raw Data                                                                                                                                     
Accelerometer output:                                                                                                                                   
Gx:  -1024                                                                                                                                             
Gy:  64                                                                                                                                                 
Gz:  16256                                                                                                                                             
Gtotal:  1018                                                                                                                                           
                                                                                                                                                       
Magnetometer output:                                                                                                                                   
Hx:  -84                                                                                                                                               
Hy:  -403                                                                                                                                               
Hz:  409                                                                                                                                               
Htotal:  58029 nT                                                                                                                                       
                                                                                                                                                       
Temp:  35 C


rotating the board produces positive and negative values as expected. However the mag and grav totals still fluxuate far more than I would expect. I can't rule out all mag interference from my desk, though the Htotal's should fluxuate more than a few hundred nT. I think my math or calibrations are a bit off still.

Can you have a look and see if my two's compliment to decimal conversions look right? I'd like ot end up with some code that might be useful to other's, so I still need to implement inclination, azimuth, dip and roll calcs.
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby adafruit_support_mike » Sun Feb 24, 2013 11:41 pm

Atticus wrote:it's only giving me whole integers, and seems to go up or down in 2° at a time or something.


The code I mentioned only produces an integer value. Table 86 in the datasheet says the value is an 8-LSB (Least Significant Bits) per degree reading, so you actually want to shift the high byte 4 bits to the right and the low byte 8 bits to the right:

Code: Select all
temp = (TEMP_OUT_H_M / 16) + (TEMP_OUT_L_M / 256)
When you void a product warrany, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 1379
Joined: Thu Feb 11, 2010 1:51 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby adafruit_support_mike » Mon Feb 25, 2013 12:04 am

Atticus wrote:However the mag and grav totals still fluxuate far more than I would expect.

You're probably seeing scale issues again. Section 7.2.2 has a list of sensitivity settings for the magnetometer. There's also a whole raft of minimally-explained configuration registers for the accelerometers.

Here's another datasheet that gives you more "how do I use the fershluggin' thing?" information: http://www.st.com/web/en/resource/techn ... 269797.pdf

Atticus wrote:Can you have a look and see if my two's compliment to decimal conversions look right?

They seem to be. You even caught the 'multipy by -1' that I forgot to mention, so kudos there.
When you void a product warrany, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 1379
Joined: Thu Feb 11, 2010 1:51 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Wed Feb 27, 2013 6:23 pm

Thanks a bunch for your help Mike, I will get back to this project in two weeks (After I get home from work) in the meantime I've got an ADS1015 breakout that I can study. It's also an i2c device and there is code for it already up in the WebIDE, studying it may help me out with this mag/grav board. :-D
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby aufder » Mon Mar 04, 2013 3:36 pm

Hey guys,
Looks like you are still trying to get the LSM303DLHC working? There's another post with complete code available to work with that device.
http://forums.adafruit.com/viewtopic.php?f=50&t=36212&start=0&hilit=lsm303

Starting with that code, I was able to get it to detect the altitude and azimuth my telescope points at. In effect it can give you the tilt, the compass heading, and the tilt adjusted compass heading.
It also has code to get the temperature.
I'm not sure it has the tilt adjusted compass code in the library or if I just added that to my copy.

Hope that reference helps.
aufder
 
Posts: 12
Joined: Tue Jan 15, 2013 9:07 pm

Re: LSM303DLHC in Python on the Raspberry Pi

Postby Atticus » Sat Mar 09, 2013 5:08 am

Hey aufder, thanks for the link to the previous thread. Not sure why my forum searches didn't bring that up for me before I started this thread.

I have a little time now so I'll go check it out. Cheers.
Atticus
 
Posts: 11
Joined: Sat Dec 15, 2012 10:05 pm


Return to Other Adafruit products

Who is online

Users browsing this forum: No registered users and 14 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [103]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[33]
LCDs & Displays[48]
Components & Parts[69]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[109]
 
Wireless[14]
Cables[61]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]