Home Code Raspberry Pi and LIS3MDL magnetic field sensor example in python

Raspberry Pi and LIS3MDL magnetic field sensor example in python

by shedboy71

In this article we look at another sensor – this time its the LIS3MDL which is a 3-axis MEMS magnetic field sensor, digital output, I2C, SPI, low power mode, high performance

Sensor Information

The LIS3MDL has user-selectable full scales of ±4/±8/±12/±16 gauss.
The self-test capability allows the user to check the functioning of the sensor in the final application.
The device may be configured to generate interrupt signals for magnetic field detection.
The LIS3MDL includes an I2C serial bus interface that supports standard and fast mode (100 kHz and 400 kHz) and SPI serial standard interface.
The LIS3MDL is available in a small thin plastic land grid array package (LGA) and is guaranteed to operate over an extended temperature range of -40 °C to +85 °C.

Features

  • Wide supply voltage, 1.9 V to 3.6 V
  • Independent IO supply (1.8 V)
  • ±4/±8/±12/±16 gauss selectable magnetic full scales
  • Continuous and single-conversion modes
  • 16-bit data output
  • Interrupt generator
  • Self-test
  • I2C/SPI digital output interface
  • Power-down mode / low-power mode

Parts Required

You could use a Pi zero easily, the link below is for a Raspberry Pi 4

Also the expansion board just makes it a little easier to connect wires to but this is optional

Name Link
Raspberry Pi 4 Aliexpress product link

Amazon. com link

Ebay search

LIS3MDL Sensor AliExpress Product link

Amazon linkebay link

Connecting wire Aliexpress product link

Amazon.com link

Ebay link

Raspberry Pi 3 Expansion Board (optional) Raspberry Pi 3 Expansion Board

Schematic/Connection

Couldn’t find a good fritzing part or image to use, this is the sensor I bought

 

As an added bonus here is the schematic for one of these modules

Raspberry Pi Sensor
3.3v Vcc
Gnd Gnd
SDA SDA
SCL SCL

 

Code Example

I found this python code, I had to change the I2C address variable LIS3MDL_M_ADDRESS

I also had to enclose the output in brackets

[codesyntax lang=”python”]

''**************************************************************************/
Controleverything.com - LIS3MDL 
3-Axis Digital Magnetometer 16-Bit I2C Mini Module
A versatile motion-sensing system-in-a-chip

Firmware v1.0 - Python
Author - Amanpal Singh

3 magnetic field channels
4/8/12/16 gauss magnetic full scale
16-bit data output
SPI / I2C serial interfaces
Analog supply voltage 1.9 V to 3.6 V
Programmable interrupt generators
Embedded self-test
Embedded temperature sensor
Embedded FIFO


LIS3MDL_M_ADDRESS I2C Start Address-Magnetometer

Hardware Version - Rev A.
Platform - Raspberry Pi

/**************************************************************************/'''

#Setting Up smbus libraries
import smbus
import time
import math
bus = smbus.SMBus(1)


##############
# LIS3MDL Mag Registers #
##############
LIS3MDL_M_ADDRESS       = 0x1E
LIS3MDL_WHO_AM_I_M      = 0x0F
LIS3MDL_CTRL_REG1_M     = 0x20
LIS3MDL_CTRL_REG2_M     = 0x21
LIS3MDL_CTRL_REG3_M     = 0x22
LIS3MDL_CTRL_REG4_M     = 0x23
LIS3MDL_STATUS_REG_M        = 0x27
LIS3MDL_OUT_X_L_M       = 0x28
LIS3MDL_OUT_X_H_M       = 0x29
LIS3MDL_OUT_Y_L_M       = 0x2A
LIS3MDL_OUT_Y_H_M       = 0x2B
LIS3MDL_OUT_Z_L_M       = 0x2C
LIS3MDL_OUT_Z_H_M       = 0x2D
LIS3MDL_TEMP_OUT_L_M        = 0x2E
LIS3MDL_TEMP_OUT_H_M        = 0x2F
LIS3MDL_INT_CFG_M       = 0x30
LIS3MDL_INT_SRC_M       = 0x31
LIS3MDL_INT_THS_L_M     = 0x32
LIS3MDL_INT_THS_H_M     = 0x33

LIS3MDL_REG_CTL_1_TEMP_EN   = 0x80
LIS3MDL_REG_CTL_2_RESET     = 0x04


# mag_scale defines all possible FSR's of the magnetometer:
    
LIS3MDL_M_SCALE_4GS         = 0x20 # 00:  4Gs
LIS3MDL_M_SCALE_8GS     = 0x40 # 01:  8Gs
LIS3MDL_M_SCALE_12GS        = 0x60 # 10:  12Gs
LIS3MDL_M_SCALE_16GS        = 0x60 # 11:  16Gs
    

# mag_oder defines all possible output data rates of the magnetometer:
    
LIS3MDL_M_ODR_625       = 0x04 # 6.25 Hz 
LIS3MDL_M_ODR_125       = 0x08 # 12.5 Hz 
LIS3MDL_M_ODR_25        = 0x0C # 25 Hz 
LIS3MDL_M_ODR_5         = 0x10 # 50 
LIS3MDL_M_ODR_10        = 0x14 # 10 Hz
LIS3MDL_M_ODR_20        = 0x14 # 20 Hz
LIS3MDL_M_ODR_40        = 0x14 # 40 Hz
LIS3MDL_M_ODR_80        = 0x14 # 80 Hz 


mRes = 4.0 / 32768.0   # 4G
SENSITIVITY_OF_MIN_SCALE = 27368.0 # (4 guass scale) * (6842 LSB/guass at 4 guass scale)
Scale = 16
def initialise():
    
# initMag -- Sets up the magnetometer to begin reading.
    
    #User Register Reset Function
    bus.write_byte_data(LIS3MDL_M_ADDRESS, LIS3MDL_CTRL_REG2_M, LIS3MDL_REG_CTL_2_RESET)
    #Temperature Sensor Enabled
    bus.write_byte_data(LIS3MDL_M_ADDRESS, LIS3MDL_CTRL_REG1_M, LIS3MDL_REG_CTL_1_TEMP_EN )
    #Ultra High Performance Mode Selected for XY Axis
    bus.write_byte_data(LIS3MDL_M_ADDRESS, LIS3MDL_CTRL_REG1_M, 0x60)
    #Ultra High Performance Mode Selected for Z Axis
    bus.write_byte_data(LIS3MDL_M_ADDRESS, LIS3MDL_CTRL_REG4_M, 0x0C)
    #Output Data Rate of 80 Hz Selected
    bus.write_byte_data(LIS3MDL_M_ADDRESS, LIS3MDL_CTRL_REG1_M, 0x1C)
    #Continous Conversion Mode,4 wire interface Selected 
    bus.write_byte_data(LIS3MDL_M_ADDRESS, LIS3MDL_CTRL_REG3_M, 0x00)
    # 16 guass Full Scale 
    bus.write_byte_data(LIS3MDL_M_ADDRESS, LIS3MDL_CTRL_REG2_M, 0x60)
  

#Read the magnetometer output registers.
# This will read all six Magnetometer output registers.

# Reading the  Magnetometer X-Axis Values from the Register
def readMagx():
        Mag_l = bus.read_byte_data(LIS3MDL_M_ADDRESS,LIS3MDL_OUT_X_L_M)
        Mag_h = bus.read_byte_data(LIS3MDL_M_ADDRESS,LIS3MDL_OUT_X_H_M)
        Mag_total = (Mag_l | Mag_h <<8)
        return Mag_total  if Mag_total < 32768 else Mag_total - 65536

# Reading the  Magnetometer Y-Axis Values from the Register
def readMagy():
        Mag_l = bus.read_byte_data(LIS3MDL_M_ADDRESS,LIS3MDL_OUT_Y_L_M)
        Mag_h = bus.read_byte_data(LIS3MDL_M_ADDRESS,LIS3MDL_OUT_Y_H_M)
        Mag_total = (Mag_l | Mag_h <<8)
        return Mag_total  if Mag_total < 32768 else Mag_total - 65536

# Reading the  Magnetometer Z-Axis Values from the Register
def readMagz():
        Mag_l = bus.read_byte_data(LIS3MDL_M_ADDRESS,LIS3MDL_OUT_Z_L_M)
        Mag_h = bus.read_byte_data(LIS3MDL_M_ADDRESS,LIS3MDL_OUT_Y_H_M)
        Mag_total = (Mag_l | Mag_h <<8)
        return Mag_total  if Mag_total < 32768 else Mag_total - 65536

def MagDataTotal():
        mtotal = (((readMagx()**2)+(readMagy()**2)+(readMagz()**2))**0.5)
        return mtotal

#Magnetic Sensitivity
'''
def Mag(SensorInterface):
            
             4 : (0x00, 27368.0)# (4 guass scale) * (6842 LSB/guass at 4 guass scale)
             8 : (0x01, 27368.0)# (8 guass scale) * (3421 LSB/guass at 8 guass scale)
             12: (0x10, 27372.0)# (12 guass scale) * (2281 LSB/guass at 12 guass scale)
             16: (0x11, 27376.0)# (16 guass scale) * (1711 LSB/guass at 16 guass scale)
'''


#Initialising the Device.
initialise()

while True:
    
    #Read our Magnetometer  values
    
    Magx = readMagx()
    Magy = readMagy()
    Magz = readMagz()
    Mtotal = MagDataTotal()
    
    #Convert Magnetometer raw to Guass values
    Mtotal = Mtotal * Scale/SENSITIVITY_OF_MIN_SCALE
    

    print ("\n","Magnetometer Readings :")
    print ("Mag X-Axis :",Magx,"Mag Y-Axis :",Magy, "Mag Z-Axis :", Magz)
    print ("Magx         : " ,Magx* Scale/SENSITIVITY_OF_MIN_SCALE,"Guass")
    print ("Magy         : " ,Magy* Scale/SENSITIVITY_OF_MIN_SCALE,"Guass")
    print ("Magz         : " ,Magz* Scale/SENSITIVITY_OF_MIN_SCALE,"Guass")
    print ("Mtotal           : " ,Mtotal,"Guass")
    
    print ("****************************")
    time.sleep(0.5)

[/codesyntax]

 

 

Output

In thonny I saw this

****************************

Magnetometer Readings :
Mag X-Axis : 342 Mag Y-Axis : -390 Mag Z-Axis : -468
Magx : 0.19994153756211633 Guass
Magy : -0.228003507746273 Guass
Magz : -0.27360420929552765 Guass
Mtotal : 0.40229804239672307 Guass
****************************

Magnetometer Readings :
Mag X-Axis : 318 Mag Y-Axis : -398 Mag Z-Axis : -462
Magx : 0.185910552470038 Guass
Magy : -0.2326805027769658 Guass
Magz : -0.27009646302250806 Guass
Mtotal : 0.4020634890530666 Guass
****************************

Magnetometer Readings :
Mag X-Axis : 330 Mag Y-Axis : -398 Mag Z-Axis : -451
Magx : 0.19292604501607716 Guass
Magy : -0.2326805027769658 Guass
Magz : -0.26366559485530544 Guass
Mtotal : 0.4074412512695512 Guass
****************************

 

Links

https://www.st.com/resource/en/datasheet/lis3mdl.pdf

 

 

 

You may also like

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More