Преглед изворни кода

lsm303: add new sensor, 6-Axis Accelerometer/Compass

Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
Brendan Le Foll пре 10 година
родитељ
комит
88bf6956fe

+ 1
- 0
README.md Прегледај датотеку

@@ -32,6 +32,7 @@ Temperature Sensors:
32 32
 Compass/Gyro/Magnometer Sensors:
33 33
   * upm::Hmc5883l
34 34
   * upm::MPU9150
35
+  * upm::LSM303
35 36
 
36 37
 Atmospheric Pressure Sensors:
37 38
   * upm::GY65

+ 3
- 0
examples/CMakeLists.txt Прегледај датотеку

@@ -35,6 +35,7 @@ add_executable (mq5-example mq5-example.cxx)
35 35
 add_executable (mq9-example mq9-example.cxx)
36 36
 add_executable (tcs3414cs-example tcs3414cs-example.cxx)
37 37
 add_executable (th02-example th02-example.cxx)
38
+add_executable (lsm303-example lsm303.cxx)
38 39
 
39 40
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
40 41
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -64,6 +65,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/ecs1030)
64 65
 include_directories (${PROJECT_SOURCE_DIR}/src/gas)
65 66
 include_directories (${PROJECT_SOURCE_DIR}/src/tcs3414cs)
66 67
 include_directories (${PROJECT_SOURCE_DIR}/src/th02)
68
+include_directories (${PROJECT_SOURCE_DIR}/src/lsm303)
67 69
 
68 70
 target_link_libraries (compass hmc5883l ${CMAKE_THREAD_LIBS_INIT})
69 71
 target_link_libraries (groveled grove ${CMAKE_THREAD_LIBS_INIT})
@@ -102,3 +104,4 @@ target_link_libraries (mq5-example gas ${CMAKE_THREAD_LIBS_INIT})
102 104
 target_link_libraries (mq9-example gas ${CMAKE_THREAD_LIBS_INIT})
103 105
 target_link_libraries (tcs3414cs-example tcs3414cs ${CMAKE_THREAD_LIBS_INIT})
104 106
 target_link_libraries (th02-example th02 ${CMAKE_THREAD_LIBS_INIT})
107
+target_link_libraries (lsm303-example lsm303 ${CMAKE_THREAD_LIBS_INIT})

+ 44
- 0
examples/lsm303.cxx Прегледај датотеку

@@ -0,0 +1,44 @@
1
+/*
2
+ * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <iostream>
26
+
27
+//! [Interesting]
28
+#include "lsm303.h"
29
+
30
+int
31
+main(int argc, char **argv)
32
+{
33
+    upm::LSM303 *sensor = new upm::LSM303(0);
34
+
35
+    std::cout << sensor->getHeading() << std::endl;
36
+
37
+    sensor->getAcceleration();
38
+    uint8_t* accel = sensor->getRawAccelData();
39
+
40
+    std::cout << "X " << (int)accel[0] << " - Y " << (int)accel[1] << " - Z " << (int)accel[2] << std::endl;
41
+
42
+    return 0;
43
+}
44
+//! [Interesting]

+ 29
- 0
examples/python/lsm303.py Прегледај датотеку

@@ -0,0 +1,29 @@
1
+#!/usr/bin/env python
2
+
3
+# Author: Brendan Le Foll <brendan.le.foll@intel.com>
4
+# Copyright (c) 2014 Intel Corporation.
5
+#
6
+# Permission is hereby granted, free of charge, to any person obtaining
7
+# a copy of this software and associated documentation files (the
8
+# "Software"), to deal in the Software without restriction, including
9
+# without limitation the rights to use, copy, modify, merge, publish,
10
+# distribute, sublicense, and/or sell copies of the Software, and to
11
+# permit persons to whom the Software is furnished to do so, subject to
12
+# the following conditions:
13
+#
14
+# The above copyright notice and this permission notice shall be
15
+# included in all copies or substantial portions of the Software.
16
+#
17
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
24
+
25
+import pyupm_lsm303 as lsm303
26
+
27
+x = lsm303.LSM303(0)
28
+x.getCoordinates()
29
+x.getHeading()

+ 5
- 0
src/lsm303/CMakeLists.txt Прегледај датотеку

@@ -0,0 +1,5 @@
1
+set (libname "lsm303")
2
+set (libdescription "upm lsm303")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 8
- 0
src/lsm303/jsupm_lsm303.i Прегледај датотеку

@@ -0,0 +1,8 @@
1
+%module jsupm_lsm303
2
+%include "../upm.i"
3
+
4
+%{
5
+    #include "lsm303.h"
6
+%}
7
+
8
+%include "lsm303.h"

+ 156
- 0
src/lsm303/lsm303.cxx Прегледај датотеку

@@ -0,0 +1,156 @@
1
+/*
2
+ * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Code based on LSM303DLH sample by Jim Lindblom SparkFun Electronics
6
+ * and the CompensatedCompass.ino by Frankie Chu from SeedStudio
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+#include <iostream>
29
+#include <unistd.h>
30
+#include <stdlib.h>
31
+
32
+#include "lsm303.h"
33
+
34
+using namespace upm;
35
+
36
+LSM303::LSM303(int bus, int addrMag, int addrAcc)
37
+{
38
+    mraa_result_t ret = MRAA_SUCCESS;
39
+
40
+    m_addrMag = addrMag;
41
+    m_addrAcc = addrAcc;
42
+
43
+    m_i2c = mraa_i2c_init(bus);
44
+
45
+    buf[0] = CTRL_REG1_A;
46
+    buf[1] = 0x27;
47
+    ret = mraa_i2c_address(m_i2c, m_addrAcc);
48
+    ret = mraa_i2c_write(m_i2c, buf, 2);
49
+
50
+    // 0x27 = normal power mode, all accel axes on
51
+    buf[0] = CTRL_REG1_A;
52
+    buf[1] = 0x27;
53
+    ret = mraa_i2c_address(m_i2c, m_addrAcc);
54
+    ret = mraa_i2c_write(m_i2c, buf, 2);
55
+
56
+    // scale == 2, can be 4 or 8
57
+    buf[0] = CTRL_REG4_A;
58
+    buf[1] = 0x00;
59
+    ret = mraa_i2c_address(m_i2c, m_addrAcc);
60
+    ret = mraa_i2c_write(m_i2c, buf, 2);
61
+
62
+    // 0x14 = mag 30Hz output rate
63
+    buf[0] = CRA_REG_M;
64
+    buf[1] = 0x14;
65
+    ret = mraa_i2c_address(m_i2c, m_addrMag);
66
+    ret = mraa_i2c_write(m_i2c, buf, 2);
67
+
68
+    // magnetic scale = +/-1.3Gaussmagnetic scale = +/-1.3Gauss
69
+    buf[0] = CRB_REG_M;
70
+    buf[1] = 0x20; // MAG_SCALE_1_3;
71
+    ret = mraa_i2c_address(m_i2c, m_addrMag);
72
+    ret = mraa_i2c_write(m_i2c, buf, 2);
73
+
74
+    // 0x00 = continouous conversion mode
75
+    buf[0] = MR_REG_M;
76
+    buf[1] = 0x00;
77
+    ret = mraa_i2c_address(m_i2c, m_addrMag);
78
+    ret = mraa_i2c_write(m_i2c, buf, 2);
79
+}
80
+
81
+LSM303::~LSM303() {
82
+    mraa_i2c_stop(m_i2c);
83
+}
84
+
85
+float
86
+LSM303::getHeading()
87
+{
88
+    if (getCoordinates() != MRAA_SUCCESS) {
89
+        return -1;
90
+    }
91
+
92
+    float heading = 180 * atan2(coor[Y], coor[X])/M_PI;
93
+
94
+    if (heading < 0)
95
+        heading += 360;
96
+
97
+    return heading;
98
+}
99
+
100
+uint8_t*
101
+LSM303::getRawAccelData()
102
+{
103
+    return &accel[0];
104
+}
105
+
106
+uint8_t*
107
+LSM303::getRawCoorData()
108
+{
109
+    return &coor[0];
110
+}
111
+
112
+mraa_result_t
113
+LSM303::getCoordinates()
114
+{
115
+    mraa_result_t ret = MRAA_SUCCESS;
116
+
117
+    memset(&buf[0], 0, sizeof(uint8_t)*6);
118
+    ret = mraa_i2c_address(m_i2c, m_addrMag);
119
+    ret = mraa_i2c_write_byte(m_i2c, OUT_X_H_M);
120
+    ret = mraa_i2c_address(m_i2c, m_addrMag);
121
+    int num = mraa_i2c_read(m_i2c, buf, 6);
122
+    if (num != 6) {
123
+        return ret;
124
+    }
125
+    // convert to coordinates
126
+    for (int i=0; i<3; i++) {
127
+        coor[i] = (buf[0*i] << 8) | buf[1*i];
128
+    }
129
+    // note that coor array is in XZY order
130
+    //printf("X=%x, Y=%x, Z=%x\n", coor[X], coor[Y], coor[Z]);
131
+
132
+    return ret;
133
+}
134
+
135
+// helper function that writes a value to the acc and then reads
136
+int
137
+LSM303::readThenWrite(uint8_t reg)
138
+{
139
+    mraa_i2c_address(m_i2c, m_addrAcc);
140
+    mraa_i2c_write_byte(m_i2c, reg);
141
+    mraa_i2c_address(m_i2c, m_addrAcc);
142
+    return (int) mraa_i2c_read_byte(m_i2c);
143
+}
144
+
145
+mraa_result_t
146
+LSM303::getAcceleration()
147
+{
148
+    mraa_result_t ret = MRAA_SUCCESS;
149
+
150
+    accel[2] = (readThenWrite(OUT_X_L_A) << 8) | (readThenWrite(OUT_X_H_A));
151
+    accel[0] = (readThenWrite(OUT_Y_L_A) << 8) | (readThenWrite(OUT_Y_H_A));
152
+    accel[1] = (readThenWrite(OUT_Z_L_A) << 8) | (readThenWrite(OUT_Z_H_A));
153
+    //printf("X=%x, Y=%x, Z=%x\n", accel[X], accel[Y], accel[Z]);
154
+
155
+    return ret;
156
+}

+ 129
- 0
src/lsm303/lsm303.h Прегледај датотеку

@@ -0,0 +1,129 @@
1
+/*
2
+ * Author: Brendan Le Foll<brendan.le.foll@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Code based on LSM303DLH sample by Jim Lindblom SparkFun Electronics
6
+ * and the CompensatedCompass.ino by Frankie Chu from SeedStudio
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+#pragma once
28
+
29
+#include <string.h>
30
+#include <mraa/i2c.h>
31
+#include <math.h>
32
+
33
+namespace upm {
34
+
35
+/* LSM303 Address definitions */
36
+#define LSM303_MAG 0x1E // assuming SA0 grounded
37
+#define LSM303_ACC 0x18 // assuming SA0 grounded
38
+
39
+/* LSM303 Register definitions */
40
+#define CTRL_REG1_A 0x20
41
+#define CTRL_REG2_A 0x21
42
+#define CTRL_REG3_A 0x22
43
+#define CTRL_REG4_A 0x23
44
+#define CTRL_REG5_A 0x24
45
+
46
+#define CRA_REG_M 0x00
47
+#define CRB_REG_M 0x01
48
+
49
+#define MR_REG_M 0x02
50
+#define OUT_X_H_M 0x03
51
+
52
+#define OUT_X_L_A 0x28
53
+#define OUT_X_H_A 0x29
54
+#define OUT_Y_L_A 0x2A
55
+#define OUT_Y_H_A 0x2B
56
+#define OUT_Z_L_A 0x2C
57
+#define OUT_Z_H_A 0x2D
58
+
59
+#define X 0
60
+#define Z 1
61
+#define Y 2
62
+
63
+/**
64
+ * @brief C++ API for LSM303
65
+ *
66
+ * This file defines the LSM303DLH 3-axis magnetometer/3-axis accelerometer.
67
+ * This module was tested with the SeedStudio Grove [6-Axis Accelerometer&Compass]
68
+ * (http://www.seeedstudio.com/wiki/Grove_-_6-Axis_Accelerometer%26Compass)
69
+ * module that is used over i2c. The magnometer and acceleromter are accessed
70
+ * at two seperate i2c addresses.
71
+ *
72
+ * @snippet lsm303.cxx Interesting
73
+ * @image html lsm303.jpeg
74
+ */
75
+class LSM303 {
76
+    public:
77
+         /**
78
+         * Instanciates a LSM303 object
79
+         *
80
+         * @param i2c bus
81
+         * @param addr magometer
82
+	 * @param addr accelerometer
83
+         */
84
+        LSM303 (int bus, int addrMag=LSM303_MAG, int addrAcc=LSM303_ACC);
85
+
86
+        /**
87
+         * LSM303 object destructor
88
+         */
89
+        ~LSM303 ();
90
+
91
+        /**
92
+         * Get Current Heading, headings <0 indicate an error occured
93
+         *
94
+         * @return float
95
+         */
96
+        float getHeading();
97
+
98
+        /**
99
+         * Get the coordinates in XYZ order
100
+         */
101
+        mraa_result_t getCoordinates();
102
+
103
+        /**
104
+         * Get accelerometer values
105
+         */
106
+        mraa_result_t getAcceleration();
107
+
108
+        /**
109
+         * Get the raw coordinate data, this will get updated when getCoordinates() is called
110
+         */
111
+        uint8_t* getRawCoorData();
112
+
113
+        /**
114
+         * Get the raw accelerometer data, this will get updated when getAcceleration() is called
115
+         */
116
+        uint8_t* getRawAccelData();
117
+
118
+    private:
119
+        int readThenWrite(uint8_t reg);
120
+
121
+        mraa_i2c_context m_i2c;
122
+        int m_addrMag;
123
+	int m_addrAcc;
124
+        uint8_t buf[6];
125
+        uint8_t coor[3];
126
+        uint8_t accel[3];
127
+};
128
+
129
+}

+ 9
- 0
src/lsm303/pyupm_lsm303.i Прегледај датотеку

@@ -0,0 +1,9 @@
1
+%module pyupm_lsm303
2
+%include "../upm.i"
3
+
4
+%feature("autodoc", "3");
5
+
6
+%include "lsm303.h"
7
+%{
8
+    #include "lsm303.h"
9
+%}