Browse Source

lsm303: fix types returned by module and heading formula

* getRawAccelData() & other accel functions now return int16_t
* scale is now a supported constructor parameter
* heading returns 0-360 values

Signed-off-by: Mccool, Michael <michael.mccool@intel.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
Mccool, Michael 10 years ago
parent
commit
fd54745cc0
3 changed files with 112 additions and 36 deletions
  1. 23
    4
      examples/lsm303.cxx
  2. 51
    22
      src/lsm303/lsm303.cxx
  3. 38
    10
      src/lsm303/lsm303.h

+ 23
- 4
examples/lsm303.cxx View File

@@ -32,12 +32,31 @@ main(int argc, char **argv)
32 32
 {
33 33
     upm::LSM303 *sensor = new upm::LSM303(0);
34 34
 
35
-    std::cout << sensor->getHeading() << std::endl;
35
+    sensor->getCoordinates();
36
+    int16_t* coor = sensor->getRawCoorData(); // in XZY order
37
+    std::cout << "coor: rX " << (int)coor[0]
38
+              << " - rY " << (int)coor[2]  // note: index is 2
39
+              << " - rZ " << (int)coor[1]  // note: index is 1
40
+              << std::endl;
41
+    std::cout << "coor: gX " << sensor->getCoorX()
42
+              << " - gY " << sensor->getCoorY()
43
+              << " - gZ " << sensor->getCoorZ()
44
+              << std::endl;
36 45
 
37
-    sensor->getAcceleration();
38
-    uint8_t* accel = sensor->getRawAccelData();
46
+    std::cout << "heading: "
47
+              << sensor->getHeading()
48
+              << std::endl;
39 49
 
40
-    std::cout << "X " << (int)accel[0] << " - Y " << (int)accel[1] << " - Z " << (int)accel[2] << std::endl;
50
+    sensor->getAcceleration();
51
+    int16_t* accel = sensor->getRawAccelData();
52
+    std::cout << "acc: rX " << (int)accel[0]
53
+              << " - rY " << (int)accel[1]
54
+              << " - Z " << (int)accel[2]
55
+              << std::endl;
56
+    std::cout << "acc: gX " << sensor->getAccelX()
57
+              << " - gY " << sensor->getAccelY()
58
+              << " - gZ " << sensor->getAccelZ()
59
+              << std::endl;
41 60
 
42 61
     return 0;
43 62
 }

+ 51
- 22
src/lsm303/lsm303.cxx View File

@@ -33,7 +33,7 @@
33 33
 
34 34
 using namespace upm;
35 35
 
36
-LSM303::LSM303(int bus, int addrMag, int addrAcc)
36
+LSM303::LSM303(int bus, int addrMag, int addrAcc, int accScale)
37 37
 {
38 38
     mraa_result_t ret = MRAA_SUCCESS;
39 39
 
@@ -45,8 +45,14 @@ LSM303::LSM303(int bus, int addrMag, int addrAcc)
45 45
     // 0x27 is the 'normal' mode with X/Y/Z enable
46 46
     setRegisterSafe(m_addrAcc, CTRL_REG1_A, 0x27);
47 47
 
48
-    // scale == 2, can be 4 or 8
49
-    setRegisterSafe(m_addrAcc, CTRL_REG4_A, 0x00);
48
+    // scale can be 2, 4 or 8
49
+    if (2 == accScale) {
50
+      setRegisterSafe(m_addrAcc, CTRL_REG4_A, 0x00);
51
+    } else if (4 == accScale) {
52
+      setRegisterSafe(m_addrAcc, CTRL_REG4_A, 0x10);
53
+    } else { // default; equivalent to 8g
54
+      setRegisterSafe(m_addrAcc, CTRL_REG4_A, 0x30);
55
+    }
50 56
 
51 57
     // 0x10 = minimum datarate ~15Hz output rate
52 58
     setRegisterSafe(m_addrMag, CRA_REG_M, 0x10);
@@ -71,42 +77,42 @@ LSM303::getHeading()
71 77
         return -1;
72 78
     }
73 79
 
74
-    float heading = 180 * atan2(coor[Y], coor[X])/M_PI;
80
+    float heading = 180.0 * atan2(double(coor[Y]), double(coor[X]))/M_PI;
75 81
 
76
-    if (heading < 0)
77
-        heading += 360;
82
+    if (heading < 0.0)
83
+        heading += 360.0;
78 84
 
79 85
     return heading;
80 86
 }
81 87
 
82
-uint8_t*
88
+int16_t*
83 89
 LSM303::getRawAccelData()
84 90
 {
85 91
     return &accel[0];
86 92
 }
87 93
 
88
-uint8_t*
94
+int16_t*
89 95
 LSM303::getRawCoorData()
90 96
 {
91 97
     return &coor[0];
92 98
 }
93 99
 
94
-uint8_t
95
-LSM303::getAccelY()
100
+int16_t
101
+LSM303::getAccelX()
96 102
 {
97
-  return accel[2];
103
+  return accel[X];
98 104
 }
99 105
 
100
-uint8_t
101
-LSM303::getAccelZ()
106
+int16_t
107
+LSM303::getAccelY()
102 108
 {
103
-  return accel[0];
109
+  return accel[Y];
104 110
 }
105 111
 
106
-uint8_t
107
-LSM303::getAccelX()
112
+int16_t
113
+LSM303::getAccelZ()
108 114
 {
109
-  return accel[1];
115
+  return accel[Z];
110 116
 }
111 117
 
112 118
 mraa_result_t
@@ -124,15 +130,35 @@ LSM303::getCoordinates()
124 130
     }
125 131
     // convert to coordinates
126 132
     for (int i=0; i<3; i++) {
127
-        coor[i] = (buf[2*i] << 8) | buf[(2*i)+1];
133
+        coor[i] = (int16_t(buf[2*i] << 8))
134
+                |  int16_t(buf[(2*i)+1]);
128 135
     }
129
-    // note that coor array is in XZY order
136
+    // swap elements 1 and 2 to get things in natural XYZ order
137
+    int16_t t = coor[2];
138
+    coor[2] = coor[1];
139
+    coor[1] = t;
130 140
     //printf("X=%x, Y=%x, Z=%x\n", coor[X], coor[Y], coor[Z]);
131 141
 
132 142
     return ret;
133 143
 }
134 144
 
145
+int16_t
146
+LSM303::getCoorX() {
147
+  return coor[X];
148
+}
149
+
150
+int16_t
151
+LSM303::getCoorY() {
152
+  return coor[Y];
153
+}
154
+
155
+int16_t
156
+LSM303::getCoorZ() {
157
+  return coor[Z];
158
+}
159
+
135 160
 // helper function that writes a value to the acc and then reads
161
+// FIX: shouldn't this be write-then-read?
136 162
 int
137 163
 LSM303::readThenWrite(uint8_t reg)
138 164
 {
@@ -147,9 +173,12 @@ LSM303::getAcceleration()
147 173
 {
148 174
     mraa_result_t ret = MRAA_SUCCESS;
149 175
 
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));
176
+    accel[X] = (int16_t(readThenWrite(OUT_X_H_A)) << 8)
177
+             |  int16_t(readThenWrite(OUT_X_L_A));
178
+    accel[Y] = (int16_t(readThenWrite(OUT_Y_H_A)) << 8)
179
+             |  int16_t(readThenWrite(OUT_Y_L_A));
180
+    accel[Z] = (int16_t(readThenWrite(OUT_Z_H_A)) << 8)
181
+             |  int16_t(readThenWrite(OUT_Z_L_A));
153 182
     //printf("X=%x, Y=%x, Z=%x\n", accel[X], accel[Y], accel[Z]);
154 183
 
155 184
     return ret;

+ 38
- 10
src/lsm303/lsm303.h View File

@@ -57,8 +57,8 @@ namespace upm {
57 57
 #define OUT_Z_H_A 0x2D
58 58
 
59 59
 #define X 0
60
-#define Z 1
61
-#define Y 2
60
+#define Y 1
61
+#define Z 2
62 62
 
63 63
 /**
64 64
  * @brief LSM303 accelerometer/compass library
@@ -87,7 +87,10 @@ class LSM303 {
87 87
          * @param addr magometer
88 88
      * @param addr accelerometer
89 89
          */
90
-        LSM303 (int bus, int addrMag=LSM303_MAG, int addrAcc=LSM303_ACC);
90
+        LSM303 (int bus,
91
+                int addrMag=LSM303_MAG,
92
+                int addrAcc=LSM303_ACC,
93
+                int accScale=8);
91 94
 
92 95
         /**
93 96
          * LSM303 object destructor
@@ -108,24 +111,49 @@ class LSM303 {
108 111
 
109 112
         /**
110 113
          * Get accelerometer values
114
+         * Call before calling other "get" functions for acceleration
111 115
          */
112 116
         mraa_result_t getAcceleration();
113 117
 
114 118
         /**
115 119
          * Get the raw coordinate data, this will get updated when getCoordinates() is called
116 120
          */
117
-        uint8_t* getRawCoorData();
121
+        int16_t* getRawCoorData();
118 122
 
119
-        uint8_t getAccelY();
123
+        /**
124
+         * Just get the X component of the coordinate data
125
+         */
126
+        int16_t getCoorX();
120 127
 
121
-        uint8_t getAccelZ();
128
+        /**
129
+         * Just get the Y component of the coordinate data
130
+         */
131
+        int16_t getCoorY();
122 132
 
123
-        uint8_t getAccelX();
133
+        /**
134
+         * Just get the Z component of the coordinate data
135
+         */
136
+        int16_t getCoorZ();
124 137
 
125 138
         /**
126 139
          * Get the raw accelerometer data, this will get updated when getAcceleration() is called
127 140
          */
128
-        uint8_t* getRawAccelData();
141
+        int16_t* getRawAccelData();
142
+
143
+        /**
144
+         * Just get the X component of the acceleration
145
+         */
146
+        int16_t getAccelX();
147
+
148
+        /**
149
+         * Just get the Y component of the acceleration
150
+         */
151
+        int16_t getAccelY();
152
+
153
+        /**
154
+         * Just get the Z component of the acceleration
155
+         */
156
+        int16_t getAccelZ();
129 157
 
130 158
     private:
131 159
         int readThenWrite(uint8_t reg);
@@ -135,8 +163,8 @@ class LSM303 {
135 163
         int m_addrMag;
136 164
     int m_addrAcc;
137 165
         uint8_t buf[6];
138
-        uint8_t coor[3];
139
-        uint8_t accel[3];
166
+        int16_t coor[3];
167
+        int16_t accel[3];
140 168
 };
141 169
 
142 170
 }