LSM303D Accelerometer Magnetometer
The LSM303D from STMicroelectronics [1] is a 3D accelerometer and 3D magnetometer with SPI and I2C interfaces. It can operate from between 2.16 V and 3.6 V.
It's available on a breakout from Adafruit or Pimoroni [2]:

The I2C address is #x1d or 29.
The following routines illustrate how to use the sensor to read the earth's magnetic field.
Initialising the sensor
The following routine initialises the sensor:
(defun lsm303d-init ()
; set magnetic resolution to high, data rate = 6.25Hz
(with-i2c (str #x1d)
(write-byte #x24 str)
(write-byte #x64 str))
; set magnetic to continuous conversion mode
(with-i2c (str #x1d)
(write-byte #x26 str)
(write-byte #x00 str))
; set full scale to 2 gauss
(with-i2c (str #x1d)
(write-byte #x25 str)
(write-byte #x00 str)))
The Earth's magnetic field ranges from 0.25 to 0.65 gauss.
Printing the magnetic readings
The following routine prints the values XM, YM, and HEADING:
(defvar XM 0)
(defvar YM 0)
(defvar HEADING 0)
(defun lsm303d-read-magnetic ()
(with-i2c (str #x1d)
(write-byte #x88 str)
(restart-i2c str 4)
(setq XM (logior (read-byte str) (ash (ash (read-byte str) 24) -16)))
(princ XM)
(princ " ")
(setq YM (logior (read-byte str) (ash (ash (read-byte str) 24) -16)))
(princ YM))
(princ " ")
(setq HEADING (/ (* (atan YM XM) 180) 3.141592))
(if (minusp HEADING) (setq HEADING (+ HEADING 360)))
(princ HEADING))
The HEADING value is shown in degrees, where 0 degrees = North.
Checking the sensor
The following optional routine checks the sensor ID; it should print 73 for an LSM303D:
(defun lsm303d-whoami ()
(with-i2c (str #x1d)
(write-byte #x0f str)
(restart-i2c str 1)
(read-byte str)))
Thanks to Ronny Suy for providing these routines.
- ^ LSM303D Datasheet on Pololu.
- ^ LSM303D 6DoF Motion Sensor Breakout on Pimoroni.
