Interface for an LIS302 accelerometer, using the SPI interface

Dependents:   LIS302_HelloWorld mbed_line_camera

Files at this revision

API Documentation at this revision

Comitter:
simon
Date:
Tue Jun 08 13:34:48 2010 +0000
Parent:
0:0785e0c655e0
Commit message:

Changed in this revision

LIS302.cpp Show annotated file Show diff for this revision Revisions of this file
LIS302.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show diff for this revision Revisions of this file
mbed.bld Show diff for this revision Revisions of this file
diff -r 0785e0c655e0 -r fe7ccd3480e6 LIS302.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS302.cpp	Tue Jun 08 13:34:48 2010 +0000
@@ -0,0 +1,174 @@
+/* mbed LIS302 Accelerometer Library
+ * Copyright (c) 2008-2010, sford, cstyles, wreynolds
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "LIS302.h"
+#include "mbed.h"
+
+#define LIS302_WHOAMI               0x0F
+#define LIS302_CTRL_REG1            0x20
+#define LIS302_CTRL_REG2            0x21
+#define LIS302_CTRL_REG3            0x22
+#define LIS302_HP_FILTER_RST        0x23
+#define LIS302_STATUS_REG           0x27
+#define LIS302_OUTX                 0x29
+#define LIS302_OUTY                 0x2B
+#define LIS302_OUTZ                 0x2D
+#define LIS302_FF_WU_CFG1           0x30
+#define LIS302_FF_WU_SRC_1          0x31
+#define LIS302_FF_WU_THS_1          0x32
+#define LIS302_FF_WU_DURATION_1     0x33
+#define LIS302_FF_WU_CFG_2          0x34
+#define LIS302_FF_WU_SRC_2          0x35
+#define LIS302_FF_WU_THS_2          0x36
+#define LIS302_FF_WU_DURATION_2     0x37
+#define LIS302_CLICK_CFG            0x38
+#define LIS302_CLICK_SRC            0x39
+#define LIS302_CLICK_THSY_X         0x3B
+#define LIS302_CLICK_THSZ           0x3C
+#define LIS302_READ                 0x80
+#define LIS302_WRITE                0x00
+
+#define LIS302_STATUS_X_AVAILABLE 0x1
+#define LIS302_STATUS_Y_AVAILABLE 0x2
+#define LIS302_STATUS_Z_AVAILABLE 0x4
+
+#define FACTOR_2g 55.6
+#define FACTOR_8g 13.9
+
+LIS302::LIS302(PinName mosi, PinName miso, PinName clk, PinName ncs)
+    : _spi(mosi, miso, clk), _ncs(ncs) {
+
+    // Make sure CS is high
+    _ncs = 1;
+
+    // Set up the spi interface
+    _spi.format(8, 3);
+    _spi.frequency(1000000);
+
+    // Write to CTRL_REG1
+    _ncs = 0;
+    _spi.write(LIS302_WRITE | LIS302_CTRL_REG1);
+    _spi.write (0x47);
+    _ncs = 1;
+
+    // Write to CTRL_REG2
+    _ncs = 0;
+    _spi.write(LIS302_WRITE | LIS302_CTRL_REG2);
+    _spi.write (0x0);  // This is default anyway
+    _ncs = 1;
+
+    // Write to CTRL_REG3
+    _ncs = 0;
+    _spi.write(LIS302_WRITE | LIS302_CTRL_REG3);
+    _spi.write (0x0);  // This is default anyway
+    _ncs = 1;
+
+    range(0);
+    calibrate();
+}
+
+float LIS302::x() {
+    // wait for a new sample
+    while(!(status() & LIS302_STATUS_X_AVAILABLE));
+
+    _ncs = 0;
+    _spi.write(LIS302_READ | LIS302_OUTX);
+    signed char raw = _spi.write(0x00);
+    _ncs = 1;
+
+    float gradient = (2.0/(_maxx-_minx));
+    return (gradient*(float)(raw)/_factor)+((-gradient*_maxx)+1);
+}
+
+float LIS302::y() {
+    // wait for a new sample
+    while(!(status() & LIS302_STATUS_Y_AVAILABLE));
+
+    _ncs = 0;
+    _spi.write(LIS302_READ | LIS302_OUTY);
+    signed char raw = _spi.write(0x00);
+    _ncs = 1;
+
+    float gradient = (2.0/(_maxy-_miny));
+    return (gradient*(float)(raw)/_factor)+((-gradient*_maxy)+1);
+}
+
+float LIS302::z() {
+    // wait for a new sample
+    while(!(status() & LIS302_STATUS_Z_AVAILABLE));
+
+    _ncs = 0;
+    _spi.write(LIS302_READ | LIS302_OUTZ);
+    signed char raw = _spi.write(0x00);
+    _ncs = 1;
+
+    float gradient = (2.0/(_maxz-_minz));
+    return (gradient*(float)(raw)/_factor)+((-gradient*_maxz)+1);
+}
+
+void LIS302::range(int g) {
+
+    // fetch the current CRTL_REG1
+    _ncs = 0;
+    _spi.write(LIS302_READ | LIS302_CTRL_REG1);
+    int value = _spi.write(0x00);
+    _ncs = 1;
+
+    // set the range bit, and the calculation factor
+    if(g) {
+        value |= 0x20; // 8g
+        _factor = FACTOR_8g;
+    } else {
+        value &= ~0x20; // 2g
+        _factor = FACTOR_2g;
+    }
+
+    _ncs = 0;
+    _spi.write(LIS302_WRITE | LIS302_CTRL_REG1);
+    _spi.write(value);
+    _ncs = 1;
+}
+
+void LIS302::calibrate(float maxx, float minx, float maxy, float miny, float maxz, float minz) {
+    _maxx = maxx;
+    _minx = minx;
+    _maxy = maxy;
+    _miny = miny;
+    _maxz = maxz;
+    _minz = minz;
+}
+
+int LIS302::whoami() {
+    _ncs = 0;
+    _spi.write(LIS302_READ | LIS302_WHOAMI);
+    int value = _spi.write(0x00);
+    _ncs = 1;
+    return value;
+}
+
+int LIS302::status() {
+    _ncs = 0;
+    _spi.write(0xA7);
+    int value = _spi.write(LIS302_READ | LIS302_STATUS_REG);
+    _ncs = 1;
+    return value;
+}
diff -r 0785e0c655e0 -r fe7ccd3480e6 LIS302.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS302.h	Tue Jun 08 13:34:48 2010 +0000
@@ -0,0 +1,105 @@
+/* mbed LIS302 Accelerometer Library
+ * Copyright (c) 2008-2010, sford, cstyles, wreynolds
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MBED_LIS302_H
+#define MBED_LIS302_H
+ 
+#include "mbed.h"
+
+/** An interface for the LIS302 triple axis SPI accelerometer
+ *
+ * @code
+ * // Print out the Z axis acceleration
+ * #include "mbed.h"
+ * #include "LIS302.h"
+ * 
+ * LIS302 acc(p5, p6, p7, p8); // mosi, miso, clk, ncs
+ * 
+ * int main() {
+ *     while(1) {
+ *         printf("Z axis acceleration = %.2f\n", acc.z());
+ *         wait(0.1);              
+ *     }
+ * }
+ * @endcode
+ */
+class LIS302  {
+public:
+
+    /** Create an LIS302 interface, connected to the specified pins
+     *
+     * @param mosi SPI data out
+     * @param miso SPI data in
+     * @param clk  SPI clock
+     * @param ncs Active low chip select (DigitalOut)
+     */
+    LIS302(PinName mosi, PinName miso, PinName clk, PinName ncs);
+
+    /** Read the X axis acceleration
+     *
+     * @return A floating-point value representing acceleration in g
+     */    
+    float x();
+
+    /** Read the Y axis acceleration
+     *
+     * @return A floating-point value representing acceleration in g
+     */    
+    float y();
+
+    /** Read the Z axis acceleration
+     *
+     * @return - A floating-point value representing acceleration in g
+     */    
+    float z();
+
+    /** Select the range of the accelerometer
+     *
+     * @param range 0 = 2g, 1 = 8g
+     */        
+    void range(int g);
+
+    /** Configure the minima and maxima for the axes to linearise the readings
+     *
+     * @param maxx float defining the maximum X value
+     * @param minx float defining the minimum X value
+     * @param maxy float defining the maximum Y value
+     * @param miny float defining the minimum Y value
+     * @param maxz float defining the maximum Z value
+     * @param minz float defining the minimum Z value
+     */        
+    void calibrate(float maxx = 1, float minx = -1, float maxy = 1, float miny = -1, float maxz = 1, float minz = -1);
+    
+private:
+    SPI _spi;
+    DigitalOut _ncs;    
+
+    int whoami();
+    int status();
+    
+    float _factor;
+    float _maxx, _minx;
+    float _maxy, _miny;
+    float _maxz, _minz;        
+};
+
+#endif
diff -r 0785e0c655e0 -r fe7ccd3480e6 main.cpp
--- a/main.cpp	Fri Nov 13 00:02:35 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-// LIS302 Hello World!
-
-#include "mbed.h"
-#include "LIS302.h"
-
-LIS302 acc(p5, p6, p7, p8); // mosi, miso, sclk, ncs
-
-int main() {
-    while(1) {
-        printf("%.3f %.3f %.3f\n", acc.x(), acc.y(), acc.z());
-        wait(0.1);
-    }
-}
diff -r 0785e0c655e0 -r fe7ccd3480e6 mbed.bld
--- a/mbed.bld	Fri Nov 13 00:02:35 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479