A class to fetch magnetometer and accelerometer data from the FXOS8700 on the K64F board
K64_MagAcc.cpp@0:dfd48724e473, 2014-06-18 (annotated)
- Committer:
- dr_john
- Date:
- Wed Jun 18 17:12:40 2014 +0000
- Revision:
- 0:dfd48724e473
First release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dr_john | 0:dfd48724e473 | 1 | /* Copyright (c) 2014 J Kernthaler MIT License |
dr_john | 0:dfd48724e473 | 2 | * |
dr_john | 0:dfd48724e473 | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
dr_john | 0:dfd48724e473 | 4 | * and associated documentation files (the "Software"), to deal in the Software without |
dr_john | 0:dfd48724e473 | 5 | * restriction, including without limitation the rights to use, copy, modify, merge, publish, |
dr_john | 0:dfd48724e473 | 6 | * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the |
dr_john | 0:dfd48724e473 | 7 | * Software is furnished to do so, subject to the following conditions: |
dr_john | 0:dfd48724e473 | 8 | * |
dr_john | 0:dfd48724e473 | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
dr_john | 0:dfd48724e473 | 10 | * substantial portions of the Software. |
dr_john | 0:dfd48724e473 | 11 | * |
dr_john | 0:dfd48724e473 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
dr_john | 0:dfd48724e473 | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
dr_john | 0:dfd48724e473 | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
dr_john | 0:dfd48724e473 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
dr_john | 0:dfd48724e473 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
dr_john | 0:dfd48724e473 | 17 | */ |
dr_john | 0:dfd48724e473 | 18 | |
dr_john | 0:dfd48724e473 | 19 | |
dr_john | 0:dfd48724e473 | 20 | #include "K64MagAcc.h" |
dr_john | 0:dfd48724e473 | 21 | |
dr_john | 0:dfd48724e473 | 22 | // FXOS8700CQ internal register addresses |
dr_john | 0:dfd48724e473 | 23 | #define FXOS8700Q_STATUS 0x00 |
dr_john | 0:dfd48724e473 | 24 | #define FXOS8700Q_OUT_X_MSB 0x01 |
dr_john | 0:dfd48724e473 | 25 | #define FXOS8700Q_OUT_Y_MSB 0x03 |
dr_john | 0:dfd48724e473 | 26 | #define FXOS8700Q_OUT_Z_MSB 0x05 |
dr_john | 0:dfd48724e473 | 27 | #define FXOS8700Q_M_OUT_X_MSB 0x33 |
dr_john | 0:dfd48724e473 | 28 | #define FXOS8700Q_M_OUT_Y_MSB 0x35 |
dr_john | 0:dfd48724e473 | 29 | #define FXOS8700Q_M_OUT_Z_MSB 0x37 |
dr_john | 0:dfd48724e473 | 30 | #define FXOS8700Q_WHOAMI 0x0D |
dr_john | 0:dfd48724e473 | 31 | #define FXOS8700Q_XYZ_DATA_CFG 0x0E |
dr_john | 0:dfd48724e473 | 32 | #define FXOS8700Q_CTRL_REG1 0x2A |
dr_john | 0:dfd48724e473 | 33 | #define FXOS8700Q_M_CTRL_REG1 0x5B |
dr_john | 0:dfd48724e473 | 34 | #define FXOS8700Q_M_CTRL_REG2 0x5C |
dr_john | 0:dfd48724e473 | 35 | #define FXOS8700Q_WHOAMI_VAL 0xC7 |
dr_john | 0:dfd48724e473 | 36 | |
dr_john | 0:dfd48724e473 | 37 | /* |
dr_john | 0:dfd48724e473 | 38 | Mag data is from 16 bit ADC, +/- 1200 uTesla full scale, so 1 lsb is 1200/32768 |
dr_john | 0:dfd48724e473 | 39 | Acc data is from 14 bit ADC, and conversion factor is for +/- 2g full scale |
dr_john | 0:dfd48724e473 | 40 | */ |
dr_john | 0:dfd48724e473 | 41 | const float MagScale = 0.0366; |
dr_john | 0:dfd48724e473 | 42 | const float AccScale = 0.244e-3; |
dr_john | 0:dfd48724e473 | 43 | |
dr_john | 0:dfd48724e473 | 44 | /** K64MagAcc class |
dr_john | 0:dfd48724e473 | 45 | * Used for setting up and reading data from the FXOS8700Q device on the |
dr_john | 0:dfd48724e473 | 46 | * K64F board. |
dr_john | 0:dfd48724e473 | 47 | * Usage |
dr_john | 0:dfd48724e473 | 48 | * Call the Update method to read data from the device |
dr_john | 0:dfd48724e473 | 49 | * The data is made available through two float arrays Mag and Acc |
dr_john | 0:dfd48724e473 | 50 | * @param sda Pin name of the I2C sda connection |
dr_john | 0:dfd48724e473 | 51 | * @param sdl Pin name of the sdl connection |
dr_john | 0:dfd48724e473 | 52 | * @param addr Address of the device on the I2C bus |
dr_john | 0:dfd48724e473 | 53 | * @note On the K64F board these parameters are hard wired, so you can leave them out to use the default settings |
dr_john | 0:dfd48724e473 | 54 | */ |
dr_john | 0:dfd48724e473 | 55 | K64MagAcc::K64MagAcc(PinName sda, PinName sdl, int addr):i2c(sda, sdl) |
dr_john | 0:dfd48724e473 | 56 | { |
dr_john | 0:dfd48724e473 | 57 | i2addr = addr; |
dr_john | 0:dfd48724e473 | 58 | i2c.frequency(400000); |
dr_john | 0:dfd48724e473 | 59 | writeControl(FXOS8700Q_CTRL_REG1, 0x00); // put device in standby |
dr_john | 0:dfd48724e473 | 60 | writeControl(FXOS8700Q_M_CTRL_REG1, 0x1F); |
dr_john | 0:dfd48724e473 | 61 | writeControl(FXOS8700Q_M_CTRL_REG2, 0x20); |
dr_john | 0:dfd48724e473 | 62 | writeControl(FXOS8700Q_XYZ_DATA_CFG, 0x00); // sets accelerometer to +/- 2g range or 0.244 mg per lsb |
dr_john | 0:dfd48724e473 | 63 | writeControl(FXOS8700Q_CTRL_REG1, 0x1D); // make device active |
dr_john | 0:dfd48724e473 | 64 | } |
dr_john | 0:dfd48724e473 | 65 | |
dr_john | 0:dfd48724e473 | 66 | void K64MagAcc::Update(void) |
dr_john | 0:dfd48724e473 | 67 | { |
dr_john | 0:dfd48724e473 | 68 | // read status, magnetometer and accel data |
dr_john | 0:dfd48724e473 | 69 | readRegs(FXOS8700Q_STATUS, SensorData, 13); |
dr_john | 0:dfd48724e473 | 70 | Status = SensorData[0]; |
dr_john | 0:dfd48724e473 | 71 | AccData[0] = Unpick14(1); |
dr_john | 0:dfd48724e473 | 72 | AccData[1] = Unpick14(3); |
dr_john | 0:dfd48724e473 | 73 | AccData[2] = Unpick14(5); |
dr_john | 0:dfd48724e473 | 74 | MagData[0] = Unpick(7); |
dr_john | 0:dfd48724e473 | 75 | MagData[1] = Unpick(9); |
dr_john | 0:dfd48724e473 | 76 | MagData[2] = Unpick(11); |
dr_john | 0:dfd48724e473 | 77 | Scale(MagData, Mag, MagScale); |
dr_john | 0:dfd48724e473 | 78 | Scale(AccData, Acc, AccScale); |
dr_john | 0:dfd48724e473 | 79 | } |
dr_john | 0:dfd48724e473 | 80 | |
dr_john | 0:dfd48724e473 | 81 | uint8_t K64MagAcc::WhoAmI(void) |
dr_john | 0:dfd48724e473 | 82 | { |
dr_john | 0:dfd48724e473 | 83 | uint8_t data; |
dr_john | 0:dfd48724e473 | 84 | readRegs(FXOS8700Q_WHOAMI, &data, 1); |
dr_john | 0:dfd48724e473 | 85 | return data; |
dr_john | 0:dfd48724e473 | 86 | } |
dr_john | 0:dfd48724e473 | 87 | |
dr_john | 0:dfd48724e473 | 88 | int16_t K64MagAcc::Unpick(int n) |
dr_john | 0:dfd48724e473 | 89 | { |
dr_john | 0:dfd48724e473 | 90 | return (SensorData[n] << 8) | SensorData[n+1]; |
dr_john | 0:dfd48724e473 | 91 | } |
dr_john | 0:dfd48724e473 | 92 | |
dr_john | 0:dfd48724e473 | 93 | int16_t K64MagAcc::Unpick14(int n) |
dr_john | 0:dfd48724e473 | 94 | { |
dr_john | 0:dfd48724e473 | 95 | // pulls 14 bit data from SensorData and returns it as a signed integer |
dr_john | 0:dfd48724e473 | 96 | return (int16_t)(((SensorData[n] << 8) | SensorData[n+1]))>>2; |
dr_john | 0:dfd48724e473 | 97 | } |
dr_john | 0:dfd48724e473 | 98 | |
dr_john | 0:dfd48724e473 | 99 | void K64MagAcc::Scale(int16_t * RawData, float * ScaledData, float Factor) |
dr_john | 0:dfd48724e473 | 100 | { |
dr_john | 0:dfd48724e473 | 101 | for(int i = 0; i < 3; i++) |
dr_john | 0:dfd48724e473 | 102 | *ScaledData++ = *RawData++ * Factor; |
dr_john | 0:dfd48724e473 | 103 | } |
dr_john | 0:dfd48724e473 | 104 | |
dr_john | 0:dfd48724e473 | 105 | void K64MagAcc::readRegs(int RegAddr, uint8_t * data, int len) |
dr_john | 0:dfd48724e473 | 106 | { |
dr_john | 0:dfd48724e473 | 107 | char t[1] = {RegAddr}; |
dr_john | 0:dfd48724e473 | 108 | i2c.write(i2addr, t, 1, true); |
dr_john | 0:dfd48724e473 | 109 | i2c.read(i2addr, (char *)data, len); |
dr_john | 0:dfd48724e473 | 110 | } |
dr_john | 0:dfd48724e473 | 111 | |
dr_john | 0:dfd48724e473 | 112 | void K64MagAcc::writeRegs(uint8_t * data, int len) |
dr_john | 0:dfd48724e473 | 113 | { |
dr_john | 0:dfd48724e473 | 114 | i2c.write(i2addr, (char *)data, len); |
dr_john | 0:dfd48724e473 | 115 | } |
dr_john | 0:dfd48724e473 | 116 | |
dr_john | 0:dfd48724e473 | 117 | void K64MagAcc::writeControl(uint8_t reg, uint8_t data) |
dr_john | 0:dfd48724e473 | 118 | { |
dr_john | 0:dfd48724e473 | 119 | uint8_t buffer[2]; |
dr_john | 0:dfd48724e473 | 120 | buffer[0] = reg; |
dr_john | 0:dfd48724e473 | 121 | buffer[1] = data; |
dr_john | 0:dfd48724e473 | 122 | i2c.write(i2addr, (char*) buffer, 2); |
dr_john | 0:dfd48724e473 | 123 | } |