LSM303D Accelerometer Magnetometer
The LSM303D from STMicroelectronics  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 :
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.