DHT

Dependencies:   SDFileSystem

Committer:
david8251
Date:
Thu Jul 20 09:05:08 2017 +0000
Revision:
0:97c2d4128ff3
DHT

Who changed what in which revision?

UserRevisionLine numberNew contents of line
david8251 0:97c2d4128ff3 1 /******************************************************************************
david8251 0:97c2d4128ff3 2 * Includes
david8251 0:97c2d4128ff3 3 *****************************************************************************/
david8251 0:97c2d4128ff3 4
david8251 0:97c2d4128ff3 5 #include "mbed.h"
david8251 0:97c2d4128ff3 6 #include "mbed_debug.h"
david8251 0:97c2d4128ff3 7
david8251 0:97c2d4128ff3 8 #include "MMA7455.h"
david8251 0:97c2d4128ff3 9
david8251 0:97c2d4128ff3 10 /******************************************************************************
david8251 0:97c2d4128ff3 11 * Defines and typedefs
david8251 0:97c2d4128ff3 12 *****************************************************************************/
david8251 0:97c2d4128ff3 13
david8251 0:97c2d4128ff3 14 #define MMA7455_I2C_ADDR (0x1D << 1)
david8251 0:97c2d4128ff3 15
david8251 0:97c2d4128ff3 16 #define MMA7455_ADDR_XOUTL 0x00
david8251 0:97c2d4128ff3 17 #define MMA7455_ADDR_XOUTH 0x01
david8251 0:97c2d4128ff3 18 #define MMA7455_ADDR_YOUTL 0x02
david8251 0:97c2d4128ff3 19 #define MMA7455_ADDR_YOUTH 0x03
david8251 0:97c2d4128ff3 20 #define MMA7455_ADDR_ZOUTL 0x04
david8251 0:97c2d4128ff3 21 #define MMA7455_ADDR_ZOUTH 0x05
david8251 0:97c2d4128ff3 22 #define MMA7455_ADDR_XOUT8 0x06
david8251 0:97c2d4128ff3 23 #define MMA7455_ADDR_YOUT8 0x07
david8251 0:97c2d4128ff3 24 #define MMA7455_ADDR_ZOUT8 0x08
david8251 0:97c2d4128ff3 25 #define MMA7455_ADDR_STATUS 0x09
david8251 0:97c2d4128ff3 26 #define MMA7455_ADDR_DETSRC 0x0A
david8251 0:97c2d4128ff3 27 #define MMA7455_ADDR_TOUT 0x0B
david8251 0:97c2d4128ff3 28 #define MMA7455_ADDR_I2CAD 0x0D
david8251 0:97c2d4128ff3 29 #define MMA7455_ADDR_USRINF 0x0E
david8251 0:97c2d4128ff3 30 #define MMA7455_ADDR_WHOAMI 0x0F
david8251 0:97c2d4128ff3 31 #define MMA7455_ADDR_XOFFL 0x10
david8251 0:97c2d4128ff3 32 #define MMA7455_ADDR_XOFFH 0x11
david8251 0:97c2d4128ff3 33 #define MMA7455_ADDR_YOFFL 0x12
david8251 0:97c2d4128ff3 34 #define MMA7455_ADDR_YOFFH 0x13
david8251 0:97c2d4128ff3 35 #define MMA7455_ADDR_ZOFFL 0x14
david8251 0:97c2d4128ff3 36 #define MMA7455_ADDR_ZOFFH 0x15
david8251 0:97c2d4128ff3 37 #define MMA7455_ADDR_MCTL 0x16
david8251 0:97c2d4128ff3 38 #define MMA7455_ADDR_INTRST 0x17
david8251 0:97c2d4128ff3 39 #define MMA7455_ADDR_CTL1 0x18
david8251 0:97c2d4128ff3 40 #define MMA7455_ADDR_CTL2 0x19
david8251 0:97c2d4128ff3 41 #define MMA7455_ADDR_LDTH 0x1A
david8251 0:97c2d4128ff3 42 #define MMA7455_ADDR_PDTH 0x1B
david8251 0:97c2d4128ff3 43 #define MMA7455_ADDR_PW 0x1C
david8251 0:97c2d4128ff3 44 #define MMA7455_ADDR_LT 0x1D
david8251 0:97c2d4128ff3 45 #define MMA7455_ADDR_TW 0x1E
david8251 0:97c2d4128ff3 46
david8251 0:97c2d4128ff3 47 #define MMA7455_MCTL_MODE(m) ((m) << 0)
david8251 0:97c2d4128ff3 48 #define MMA7455_MCTL_GLVL(g) ((g) << 2)
david8251 0:97c2d4128ff3 49
david8251 0:97c2d4128ff3 50 #define MMA7455_STATUS_DRDY (1 << 0)
david8251 0:97c2d4128ff3 51 #define MMA7455_STATUS_DOVR (1 << 1)
david8251 0:97c2d4128ff3 52 #define MMA7455_STATUS_PERR (1 << 2)
david8251 0:97c2d4128ff3 53
david8251 0:97c2d4128ff3 54
david8251 0:97c2d4128ff3 55 MMA7455::MMA7455(PinName sda, PinName scl) : _i2c(sda, scl)
david8251 0:97c2d4128ff3 56 {
david8251 0:97c2d4128ff3 57 _mode = ModeStandby;
david8251 0:97c2d4128ff3 58 _range = Range_8g;
david8251 0:97c2d4128ff3 59
david8251 0:97c2d4128ff3 60 _xOff = 0;
david8251 0:97c2d4128ff3 61 _yOff = 0;
david8251 0:97c2d4128ff3 62 _zOff = 0;
david8251 0:97c2d4128ff3 63 }
david8251 0:97c2d4128ff3 64
david8251 0:97c2d4128ff3 65 bool MMA7455::setMode(Mode mode) {
david8251 0:97c2d4128ff3 66 bool result = false;
david8251 0:97c2d4128ff3 67 int mCtrl = 0;
david8251 0:97c2d4128ff3 68
david8251 0:97c2d4128ff3 69 do {
david8251 0:97c2d4128ff3 70 mCtrl = getModeControl();
david8251 0:97c2d4128ff3 71 if (mCtrl < 0) break;
david8251 0:97c2d4128ff3 72
david8251 0:97c2d4128ff3 73 mCtrl &= ~(0x03 << 0);
david8251 0:97c2d4128ff3 74 mCtrl |= MMA7455_MCTL_MODE(mode);
david8251 0:97c2d4128ff3 75
david8251 0:97c2d4128ff3 76 if (setModeControl((uint8_t)mCtrl) < 0) {
david8251 0:97c2d4128ff3 77 break;
david8251 0:97c2d4128ff3 78 }
david8251 0:97c2d4128ff3 79
david8251 0:97c2d4128ff3 80 _mode = mode;
david8251 0:97c2d4128ff3 81 result = true;
david8251 0:97c2d4128ff3 82 } while(0);
david8251 0:97c2d4128ff3 83
david8251 0:97c2d4128ff3 84
david8251 0:97c2d4128ff3 85
david8251 0:97c2d4128ff3 86 return result;
david8251 0:97c2d4128ff3 87 }
david8251 0:97c2d4128ff3 88
david8251 0:97c2d4128ff3 89 bool MMA7455::setRange(Range range) {
david8251 0:97c2d4128ff3 90 bool result = false;
david8251 0:97c2d4128ff3 91 int mCtrl = 0;
david8251 0:97c2d4128ff3 92
david8251 0:97c2d4128ff3 93 do {
david8251 0:97c2d4128ff3 94 mCtrl = getModeControl();
david8251 0:97c2d4128ff3 95 if (mCtrl < 0) break;
david8251 0:97c2d4128ff3 96
david8251 0:97c2d4128ff3 97 mCtrl &= ~(0x03 << 2);
david8251 0:97c2d4128ff3 98 mCtrl |= MMA7455_MCTL_GLVL(range);
david8251 0:97c2d4128ff3 99
david8251 0:97c2d4128ff3 100 if (setModeControl((uint8_t)mCtrl) < 0) {
david8251 0:97c2d4128ff3 101 break;
david8251 0:97c2d4128ff3 102 }
david8251 0:97c2d4128ff3 103
david8251 0:97c2d4128ff3 104 _range = range;
david8251 0:97c2d4128ff3 105 result = true;
david8251 0:97c2d4128ff3 106 } while(0);
david8251 0:97c2d4128ff3 107
david8251 0:97c2d4128ff3 108
david8251 0:97c2d4128ff3 109
david8251 0:97c2d4128ff3 110 return result;
david8251 0:97c2d4128ff3 111
david8251 0:97c2d4128ff3 112 }
david8251 0:97c2d4128ff3 113
david8251 0:97c2d4128ff3 114 bool MMA7455::read(int32_t& x, int32_t& y, int32_t& z) {
david8251 0:97c2d4128ff3 115 bool result = false;
david8251 0:97c2d4128ff3 116
david8251 0:97c2d4128ff3 117
david8251 0:97c2d4128ff3 118 // nothing to read in standby mode
david8251 0:97c2d4128ff3 119 if (_mode == ModeStandby) return false;
david8251 0:97c2d4128ff3 120
david8251 0:97c2d4128ff3 121 // wait for ready flag
david8251 0:97c2d4128ff3 122 int status = 0;
david8251 0:97c2d4128ff3 123 do {
david8251 0:97c2d4128ff3 124 status = getStatus();
david8251 0:97c2d4128ff3 125 } while (status >= 0 && (status & MMA7455_STATUS_DRDY) == 0);
david8251 0:97c2d4128ff3 126
david8251 0:97c2d4128ff3 127
david8251 0:97c2d4128ff3 128 do {
david8251 0:97c2d4128ff3 129 if (status < 0) break;
david8251 0:97c2d4128ff3 130
david8251 0:97c2d4128ff3 131
david8251 0:97c2d4128ff3 132 char buf[6];
david8251 0:97c2d4128ff3 133 buf[0] = MMA7455_ADDR_XOUTL;
david8251 0:97c2d4128ff3 134 if (_i2c.write(MMA7455_I2C_ADDR, buf, 1) != 0) break;
david8251 0:97c2d4128ff3 135 if (_i2c.read(MMA7455_I2C_ADDR, buf, 6) != 0) break;
david8251 0:97c2d4128ff3 136
david8251 0:97c2d4128ff3 137 // check if second bit is set in high byte -> negative value
david8251 0:97c2d4128ff3 138 // expand negative value to full byte
david8251 0:97c2d4128ff3 139 if (buf[1] & 0x02) buf[1] |= 0xFC;
david8251 0:97c2d4128ff3 140 if (buf[3] & 0x02) buf[3] |= 0xFC;
david8251 0:97c2d4128ff3 141 if (buf[5] & 0x02) buf[5] |= 0xFC;
david8251 0:97c2d4128ff3 142
david8251 0:97c2d4128ff3 143 x = (int16_t)((buf[1] << 8) | buf[0]) + _xOff;
david8251 0:97c2d4128ff3 144 y = (int16_t)((buf[3] << 8) | buf[2]) + _yOff;
david8251 0:97c2d4128ff3 145 z = (int16_t)((buf[5] << 8) | buf[4]) + _zOff;
david8251 0:97c2d4128ff3 146
david8251 0:97c2d4128ff3 147
david8251 0:97c2d4128ff3 148 result = true;
david8251 0:97c2d4128ff3 149
david8251 0:97c2d4128ff3 150 } while(0);
david8251 0:97c2d4128ff3 151
david8251 0:97c2d4128ff3 152
david8251 0:97c2d4128ff3 153 return result;
david8251 0:97c2d4128ff3 154 }
david8251 0:97c2d4128ff3 155
david8251 0:97c2d4128ff3 156 bool MMA7455::calibrate() {
david8251 0:97c2d4128ff3 157 bool result = false;
david8251 0:97c2d4128ff3 158 bool failed = false;
david8251 0:97c2d4128ff3 159
david8251 0:97c2d4128ff3 160 int32_t x = 0;
david8251 0:97c2d4128ff3 161 int32_t y = 0;
david8251 0:97c2d4128ff3 162 int32_t z = 0;
david8251 0:97c2d4128ff3 163
david8251 0:97c2d4128ff3 164 int32_t xr = 0;
david8251 0:97c2d4128ff3 165 int32_t yr = 0;
david8251 0:97c2d4128ff3 166 int32_t zr = 0;
david8251 0:97c2d4128ff3 167
david8251 0:97c2d4128ff3 168 int xOff = 0;
david8251 0:97c2d4128ff3 169 int yOff = 0;
david8251 0:97c2d4128ff3 170 int zOff = 16;
david8251 0:97c2d4128ff3 171 if (_range == Range_2g) {
david8251 0:97c2d4128ff3 172 zOff = 64;
david8251 0:97c2d4128ff3 173 }
david8251 0:97c2d4128ff3 174 if (_range == Range_4g) {
david8251 0:97c2d4128ff3 175 zOff = 32;
david8251 0:97c2d4128ff3 176 }
david8251 0:97c2d4128ff3 177
david8251 0:97c2d4128ff3 178 do {
david8251 0:97c2d4128ff3 179
david8251 0:97c2d4128ff3 180 // get an average of 6 values
david8251 0:97c2d4128ff3 181 for (int i = 0; i < 6; i++) {
david8251 0:97c2d4128ff3 182 if (!read(xr, yr, zr)) {
david8251 0:97c2d4128ff3 183 failed = true;
david8251 0:97c2d4128ff3 184 break;
david8251 0:97c2d4128ff3 185 }
david8251 0:97c2d4128ff3 186 x += xr;
david8251 0:97c2d4128ff3 187 y += yr;
david8251 0:97c2d4128ff3 188 z += zr;
david8251 0:97c2d4128ff3 189
david8251 0:97c2d4128ff3 190 wait_ms(100);
david8251 0:97c2d4128ff3 191 }
david8251 0:97c2d4128ff3 192
david8251 0:97c2d4128ff3 193 if (failed) break;
david8251 0:97c2d4128ff3 194 x /= 6;
david8251 0:97c2d4128ff3 195 y /= 6;
david8251 0:97c2d4128ff3 196 z /= 6;
david8251 0:97c2d4128ff3 197
david8251 0:97c2d4128ff3 198 xOff -= x;
david8251 0:97c2d4128ff3 199 yOff -= y;
david8251 0:97c2d4128ff3 200 zOff -= z;
david8251 0:97c2d4128ff3 201
david8251 0:97c2d4128ff3 202 /*
david8251 0:97c2d4128ff3 203 * For some reason we have not got correct/reliable calibration
david8251 0:97c2d4128ff3 204 * by using the offset drift registers. Instead we are
david8251 0:97c2d4128ff3 205 * calculating the offsets and store them in member variables.
david8251 0:97c2d4128ff3 206 *
david8251 0:97c2d4128ff3 207 * These member variables are then used in the read() method
david8251 0:97c2d4128ff3 208 */
david8251 0:97c2d4128ff3 209
david8251 0:97c2d4128ff3 210 _xOff = xOff;
david8251 0:97c2d4128ff3 211 _yOff = yOff;
david8251 0:97c2d4128ff3 212 _zOff = zOff;
david8251 0:97c2d4128ff3 213
david8251 0:97c2d4128ff3 214
david8251 0:97c2d4128ff3 215 result = true;
david8251 0:97c2d4128ff3 216
david8251 0:97c2d4128ff3 217 } while (0);
david8251 0:97c2d4128ff3 218
david8251 0:97c2d4128ff3 219
david8251 0:97c2d4128ff3 220
david8251 0:97c2d4128ff3 221 return result;
david8251 0:97c2d4128ff3 222 }
david8251 0:97c2d4128ff3 223
david8251 0:97c2d4128ff3 224 bool MMA7455::setCalibrationOffsets(int32_t xOff, int32_t yOff, int32_t zOff) {
david8251 0:97c2d4128ff3 225 _xOff = xOff;
david8251 0:97c2d4128ff3 226 _yOff = yOff;
david8251 0:97c2d4128ff3 227 _zOff = zOff;
david8251 0:97c2d4128ff3 228
david8251 0:97c2d4128ff3 229 return true;
david8251 0:97c2d4128ff3 230 }
david8251 0:97c2d4128ff3 231
david8251 0:97c2d4128ff3 232 bool MMA7455::getCalibrationOffsets(int32_t& xOff, int32_t& yOff, int32_t& zOff) {
david8251 0:97c2d4128ff3 233 xOff = _xOff;
david8251 0:97c2d4128ff3 234 yOff = _yOff;
david8251 0:97c2d4128ff3 235 zOff = _zOff;
david8251 0:97c2d4128ff3 236
david8251 0:97c2d4128ff3 237 return true;
david8251 0:97c2d4128ff3 238 }
david8251 0:97c2d4128ff3 239
david8251 0:97c2d4128ff3 240 int MMA7455::getStatus() {
david8251 0:97c2d4128ff3 241 int result = -1;
david8251 0:97c2d4128ff3 242 char data[1];
david8251 0:97c2d4128ff3 243
david8251 0:97c2d4128ff3 244 do {
david8251 0:97c2d4128ff3 245 data[0] = MMA7455_ADDR_STATUS;
david8251 0:97c2d4128ff3 246 if (_i2c.write(MMA7455_I2C_ADDR, data, 1) != 0) break;
david8251 0:97c2d4128ff3 247
david8251 0:97c2d4128ff3 248 if (_i2c.read(MMA7455_I2C_ADDR, data, 1) != 0) break;
david8251 0:97c2d4128ff3 249
david8251 0:97c2d4128ff3 250 result = data[0];
david8251 0:97c2d4128ff3 251
david8251 0:97c2d4128ff3 252 } while (0);
david8251 0:97c2d4128ff3 253
david8251 0:97c2d4128ff3 254
david8251 0:97c2d4128ff3 255
david8251 0:97c2d4128ff3 256 return result;
david8251 0:97c2d4128ff3 257 }
david8251 0:97c2d4128ff3 258
david8251 0:97c2d4128ff3 259 int MMA7455::getModeControl() {
david8251 0:97c2d4128ff3 260
david8251 0:97c2d4128ff3 261 int result = -1;
david8251 0:97c2d4128ff3 262 char data[1];
david8251 0:97c2d4128ff3 263
david8251 0:97c2d4128ff3 264 do {
david8251 0:97c2d4128ff3 265 data[0] = MMA7455_ADDR_MCTL;
david8251 0:97c2d4128ff3 266 if (_i2c.write(MMA7455_I2C_ADDR, data, 1) != 0) break;
david8251 0:97c2d4128ff3 267
david8251 0:97c2d4128ff3 268 if (_i2c.read(MMA7455_I2C_ADDR, data, 1) != 0) break;
david8251 0:97c2d4128ff3 269
david8251 0:97c2d4128ff3 270 result = data[0];
david8251 0:97c2d4128ff3 271
david8251 0:97c2d4128ff3 272 } while (0);
david8251 0:97c2d4128ff3 273
david8251 0:97c2d4128ff3 274
david8251 0:97c2d4128ff3 275
david8251 0:97c2d4128ff3 276 return result;
david8251 0:97c2d4128ff3 277 }
david8251 0:97c2d4128ff3 278
david8251 0:97c2d4128ff3 279 int MMA7455::setModeControl(uint8_t mctl) {
david8251 0:97c2d4128ff3 280 int result = -1;
david8251 0:97c2d4128ff3 281 char data[2];
david8251 0:97c2d4128ff3 282
david8251 0:97c2d4128ff3 283 do {
david8251 0:97c2d4128ff3 284 data[0] = MMA7455_ADDR_MCTL;
david8251 0:97c2d4128ff3 285 data[1] = (char)mctl;
david8251 0:97c2d4128ff3 286 if (_i2c.write(MMA7455_I2C_ADDR, data, 2) != 0) break;
david8251 0:97c2d4128ff3 287
david8251 0:97c2d4128ff3 288 result = 0;
david8251 0:97c2d4128ff3 289
david8251 0:97c2d4128ff3 290 } while (0);
david8251 0:97c2d4128ff3 291
david8251 0:97c2d4128ff3 292
david8251 0:97c2d4128ff3 293
david8251 0:97c2d4128ff3 294 return result;
david8251 0:97c2d4128ff3 295 }