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 |
LIS3MDL Sensor | AliExpress Product link |
Connecting wire | Aliexpress product 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