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.

  1. ^ LSM303D Datasheet on Pololu.
  2. ^ LSM303D 6DoF Motion Sensor Breakout on Pimoroni.