High resolution barometer and altimeter using i2c mode. Adapted to FreeIMU interface

Dependents:   FreeIMU FreeIMU_external_magnetometer FreeIMU

Fork of ms5611 by Kevin Braun

Committer:
tyftyftyf
Date:
Sat Nov 02 17:23:33 2013 +0000
Revision:
7:8545a1d1d1e4
Child:
8:f3660f819e54
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tyftyftyf 7:8545a1d1d1e4 1 /*
tyftyftyf 7:8545a1d1d1e4 2 MS5611-01BA.cpp - Interfaces a Measurement Specialities MS5611-01BA with Arduino
tyftyftyf 7:8545a1d1d1e4 3 See http://www.meas-spec.com/downloads/MS5611-01BA01.pdf for the device datasheet
tyftyftyf 7:8545a1d1d1e4 4
tyftyftyf 7:8545a1d1d1e4 5 Copyright (C) 2011 Fabio Varesano <fvaresano@yahoo.it>
tyftyftyf 7:8545a1d1d1e4 6
tyftyftyf 7:8545a1d1d1e4 7 Development of this code has been supported by the Department of Computer Science,
tyftyftyf 7:8545a1d1d1e4 8 Universita' degli Studi di Torino, Italy within the Piemonte Project
tyftyftyf 7:8545a1d1d1e4 9 http://www.piemonte.di.unito.it/
tyftyftyf 7:8545a1d1d1e4 10
tyftyftyf 7:8545a1d1d1e4 11
tyftyftyf 7:8545a1d1d1e4 12 This program is free software: you can redistribute it and/or modify
tyftyftyf 7:8545a1d1d1e4 13 it under the terms of the version 3 GNU General Public License as
tyftyftyf 7:8545a1d1d1e4 14 published by the Free Software Foundation.
tyftyftyf 7:8545a1d1d1e4 15
tyftyftyf 7:8545a1d1d1e4 16 This program is distributed in the hope that it will be useful,
tyftyftyf 7:8545a1d1d1e4 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
tyftyftyf 7:8545a1d1d1e4 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
tyftyftyf 7:8545a1d1d1e4 19 GNU General Public License for more details.
tyftyftyf 7:8545a1d1d1e4 20
tyftyftyf 7:8545a1d1d1e4 21 You should have received a copy of the GNU General Public License
tyftyftyf 7:8545a1d1d1e4 22 along with this program. If not, see <http://www.gnu.org/licenses/>.
tyftyftyf 7:8545a1d1d1e4 23
tyftyftyf 7:8545a1d1d1e4 24 */
tyftyftyf 7:8545a1d1d1e4 25
tyftyftyf 7:8545a1d1d1e4 26 #include "mbed.h"
tyftyftyf 7:8545a1d1d1e4 27 #include "MS561101BA.h"
tyftyftyf 7:8545a1d1d1e4 28 #define CONVERSION_TIME 12000l // conversion time in microseconds
tyftyftyf 7:8545a1d1d1e4 29
tyftyftyf 7:8545a1d1d1e4 30 MS561101BA::MS561101BA():i2c(I2C_SDA,I2C_SCL){
tyftyftyf 7:8545a1d1d1e4 31 }
tyftyftyf 7:8545a1d1d1e4 32
tyftyftyf 7:8545a1d1d1e4 33 MS561101BA::MS561101BA(I2C _i2c):i2c(_i2c) {
tyftyftyf 7:8545a1d1d1e4 34 ;
tyftyftyf 7:8545a1d1d1e4 35 }
tyftyftyf 7:8545a1d1d1e4 36
tyftyftyf 7:8545a1d1d1e4 37 void MS561101BA::init(uint8_t address) {
tyftyftyf 7:8545a1d1d1e4 38 lastPresConv=0;
tyftyftyf 7:8545a1d1d1e4 39 lastTempConv=0;
tyftyftyf 7:8545a1d1d1e4 40 t.start();
tyftyftyf 7:8545a1d1d1e4 41 _addr = address;
tyftyftyf 7:8545a1d1d1e4 42
tyftyftyf 7:8545a1d1d1e4 43 reset(); // reset the device to populate its internal PROM registers
tyftyftyf 7:8545a1d1d1e4 44 wait_ms(500); // some safety time
tyftyftyf 7:8545a1d1d1e4 45 readPROM(); // reads the PROM into object variables for later use
tyftyftyf 7:8545a1d1d1e4 46 }
tyftyftyf 7:8545a1d1d1e4 47
tyftyftyf 7:8545a1d1d1e4 48 float MS561101BA::getPressure(uint8_t OSR) {
tyftyftyf 7:8545a1d1d1e4 49 // see datasheet page 7 for formulas
tyftyftyf 7:8545a1d1d1e4 50
tyftyftyf 7:8545a1d1d1e4 51 uint32_t rawPress = rawPressure(OSR);
tyftyftyf 7:8545a1d1d1e4 52 if(rawPress == NULL) {
tyftyftyf 7:8545a1d1d1e4 53 return NULL;
tyftyftyf 7:8545a1d1d1e4 54 }
tyftyftyf 7:8545a1d1d1e4 55
tyftyftyf 7:8545a1d1d1e4 56 int32_t dT = getDeltaTemp(OSR);
tyftyftyf 7:8545a1d1d1e4 57 if(dT == NULL) {
tyftyftyf 7:8545a1d1d1e4 58 return NULL;
tyftyftyf 7:8545a1d1d1e4 59 }
tyftyftyf 7:8545a1d1d1e4 60
tyftyftyf 7:8545a1d1d1e4 61 int64_t off = ((uint32_t)_Cal[1] <<16) + (((int64_t)dT * _Cal[3]) >> 7);
tyftyftyf 7:8545a1d1d1e4 62 int64_t sens = ((uint32_t)_Cal[0] <<15) + (((int64_t)dT * _Cal[2]) >> 8);
tyftyftyf 7:8545a1d1d1e4 63 return ((( (rawPress * sens ) >> 21) - off) >> 15) / 100.0;
tyftyftyf 7:8545a1d1d1e4 64 }
tyftyftyf 7:8545a1d1d1e4 65
tyftyftyf 7:8545a1d1d1e4 66 float MS561101BA::getTemperature(uint8_t OSR) {
tyftyftyf 7:8545a1d1d1e4 67 // see datasheet page 7 for formulas
tyftyftyf 7:8545a1d1d1e4 68 int64_t dT = getDeltaTemp(OSR);
tyftyftyf 7:8545a1d1d1e4 69
tyftyftyf 7:8545a1d1d1e4 70 if(dT != NULL) {
tyftyftyf 7:8545a1d1d1e4 71 return (2000 + ((dT * _Cal[5]) >> 23)) / 100.0;
tyftyftyf 7:8545a1d1d1e4 72 }
tyftyftyf 7:8545a1d1d1e4 73 else {
tyftyftyf 7:8545a1d1d1e4 74 return NULL;
tyftyftyf 7:8545a1d1d1e4 75 }
tyftyftyf 7:8545a1d1d1e4 76 }
tyftyftyf 7:8545a1d1d1e4 77
tyftyftyf 7:8545a1d1d1e4 78 int32_t MS561101BA::getDeltaTemp(uint8_t OSR) {
tyftyftyf 7:8545a1d1d1e4 79 uint32_t rawTemp = rawTemperature(OSR);
tyftyftyf 7:8545a1d1d1e4 80 if(rawTemp != NULL) {
tyftyftyf 7:8545a1d1d1e4 81 return (int32_t)(rawTemp - ((uint32_t)_Cal[4] << 8));
tyftyftyf 7:8545a1d1d1e4 82 }
tyftyftyf 7:8545a1d1d1e4 83 else {
tyftyftyf 7:8545a1d1d1e4 84 return NULL;
tyftyftyf 7:8545a1d1d1e4 85 }
tyftyftyf 7:8545a1d1d1e4 86 }
tyftyftyf 7:8545a1d1d1e4 87
tyftyftyf 7:8545a1d1d1e4 88 //TODO: avoid duplicated code between rawPressure and rawTemperature methods
tyftyftyf 7:8545a1d1d1e4 89 //TODO: possible race condition between readings.. serious headache doing this.. help appreciated!
tyftyftyf 7:8545a1d1d1e4 90
tyftyftyf 7:8545a1d1d1e4 91 uint32_t MS561101BA::rawPressure(uint8_t OSR) {
tyftyftyf 7:8545a1d1d1e4 92 uint32_t now = t.read_us();
tyftyftyf 7:8545a1d1d1e4 93 if(lastPresConv != 0 && (now - lastPresConv) >= CONVERSION_TIME) {
tyftyftyf 7:8545a1d1d1e4 94 lastPresConv = 0;
tyftyftyf 7:8545a1d1d1e4 95 pressCache = getConversion(MS561101BA_D1 + OSR);
tyftyftyf 7:8545a1d1d1e4 96 }
tyftyftyf 7:8545a1d1d1e4 97 else {
tyftyftyf 7:8545a1d1d1e4 98 if(lastPresConv == 0 && lastTempConv == 0) {
tyftyftyf 7:8545a1d1d1e4 99 startConversion(MS561101BA_D1 + OSR);
tyftyftyf 7:8545a1d1d1e4 100 lastPresConv = now;
tyftyftyf 7:8545a1d1d1e4 101 }
tyftyftyf 7:8545a1d1d1e4 102 }
tyftyftyf 7:8545a1d1d1e4 103 return pressCache;
tyftyftyf 7:8545a1d1d1e4 104 }
tyftyftyf 7:8545a1d1d1e4 105
tyftyftyf 7:8545a1d1d1e4 106 uint32_t MS561101BA::rawTemperature(uint8_t OSR) {
tyftyftyf 7:8545a1d1d1e4 107 unsigned long now = t.read_us();
tyftyftyf 7:8545a1d1d1e4 108 if(lastTempConv != 0 && (now - lastTempConv) >= CONVERSION_TIME) {
tyftyftyf 7:8545a1d1d1e4 109 lastTempConv = 0;
tyftyftyf 7:8545a1d1d1e4 110 tempCache = getConversion(MS561101BA_D2 + OSR);
tyftyftyf 7:8545a1d1d1e4 111 }
tyftyftyf 7:8545a1d1d1e4 112 else {
tyftyftyf 7:8545a1d1d1e4 113 if(lastTempConv == 0 && lastPresConv == 0) { // no conversions in progress
tyftyftyf 7:8545a1d1d1e4 114 startConversion(MS561101BA_D2 + OSR);
tyftyftyf 7:8545a1d1d1e4 115 lastTempConv = now;
tyftyftyf 7:8545a1d1d1e4 116 }
tyftyftyf 7:8545a1d1d1e4 117 }
tyftyftyf 7:8545a1d1d1e4 118 return tempCache;
tyftyftyf 7:8545a1d1d1e4 119 }
tyftyftyf 7:8545a1d1d1e4 120
tyftyftyf 7:8545a1d1d1e4 121
tyftyftyf 7:8545a1d1d1e4 122 // see page 11 of the datasheet
tyftyftyf 7:8545a1d1d1e4 123 void MS561101BA::startConversion(uint8_t command) {
tyftyftyf 7:8545a1d1d1e4 124 // initialize pressure conversion
tyftyftyf 7:8545a1d1d1e4 125 i2c.start();
tyftyftyf 7:8545a1d1d1e4 126 i2c.write(_addr<<1);
tyftyftyf 7:8545a1d1d1e4 127 i2c.write(command);
tyftyftyf 7:8545a1d1d1e4 128 i2c.stop();
tyftyftyf 7:8545a1d1d1e4 129 }
tyftyftyf 7:8545a1d1d1e4 130
tyftyftyf 7:8545a1d1d1e4 131 uint32_t MS561101BA::getConversion(uint8_t command) {
tyftyftyf 7:8545a1d1d1e4 132 uint32_t conversion = 0;
tyftyftyf 7:8545a1d1d1e4 133
tyftyftyf 7:8545a1d1d1e4 134 // start read sequence
tyftyftyf 7:8545a1d1d1e4 135 /*Wire.beginTransmission(_addr);
tyftyftyf 7:8545a1d1d1e4 136 Wire.write(0);
tyftyftyf 7:8545a1d1d1e4 137 Wire.endTransmission();*/
tyftyftyf 7:8545a1d1d1e4 138 i2c.start();
tyftyftyf 7:8545a1d1d1e4 139 i2c.write(_addr<<1);
tyftyftyf 7:8545a1d1d1e4 140 i2c.write(0);
tyftyftyf 7:8545a1d1d1e4 141 i2c.stop();
tyftyftyf 7:8545a1d1d1e4 142
tyftyftyf 7:8545a1d1d1e4 143 //Wire.beginTransmission(_addr);
tyftyftyf 7:8545a1d1d1e4 144 //Wire.requestFrom(_addr, (uint8_t) MS561101BA_D1D2_SIZE);
tyftyftyf 7:8545a1d1d1e4 145 char cobuf[3];
tyftyftyf 7:8545a1d1d1e4 146 if (i2c.read((_addr<<1)+1, cobuf, MS561101BA_D1D2_SIZE)!=0) {conversion=0xFFFFFFFF;}else{
tyftyftyf 7:8545a1d1d1e4 147 conversion = (cobuf[0] << 16) + (cobuf[1] << 8) + cobuf[2];
tyftyftyf 7:8545a1d1d1e4 148 }
tyftyftyf 7:8545a1d1d1e4 149 return conversion;
tyftyftyf 7:8545a1d1d1e4 150 }
tyftyftyf 7:8545a1d1d1e4 151
tyftyftyf 7:8545a1d1d1e4 152
tyftyftyf 7:8545a1d1d1e4 153 /**
tyftyftyf 7:8545a1d1d1e4 154 * Reads factory calibration and store it into object variables.
tyftyftyf 7:8545a1d1d1e4 155 */
tyftyftyf 7:8545a1d1d1e4 156 int MS561101BA::readPROM() {
tyftyftyf 7:8545a1d1d1e4 157 for (int i=0;i<MS561101BA_PROM_REG_COUNT;i++) {
tyftyftyf 7:8545a1d1d1e4 158 /*Wire.beginTransmission(_addr);
tyftyftyf 7:8545a1d1d1e4 159 Wire.write(MS561101BA_PROM_BASE_ADDR + (i * MS561101BA_PROM_REG_SIZE));
tyftyftyf 7:8545a1d1d1e4 160 Wire.endTransmission();*/
tyftyftyf 7:8545a1d1d1e4 161 i2c.start();
tyftyftyf 7:8545a1d1d1e4 162 i2c.write(_addr<<1);
tyftyftyf 7:8545a1d1d1e4 163 i2c.write(MS561101BA_PROM_BASE_ADDR + (i * MS561101BA_PROM_REG_SIZE));
tyftyftyf 7:8545a1d1d1e4 164 i2c.stop();
tyftyftyf 7:8545a1d1d1e4 165
tyftyftyf 7:8545a1d1d1e4 166 char tmp[2];
tyftyftyf 7:8545a1d1d1e4 167 if (i2c.read((_addr<<1)+1, tmp, MS561101BA_PROM_REG_SIZE)!=0) return -1;
tyftyftyf 7:8545a1d1d1e4 168 _Cal[i] = tmp[0]<<8 | tmp[1];
tyftyftyf 7:8545a1d1d1e4 169 wait_ms(200);
tyftyftyf 7:8545a1d1d1e4 170 }
tyftyftyf 7:8545a1d1d1e4 171 return 0;
tyftyftyf 7:8545a1d1d1e4 172 }
tyftyftyf 7:8545a1d1d1e4 173
tyftyftyf 7:8545a1d1d1e4 174
tyftyftyf 7:8545a1d1d1e4 175 /**
tyftyftyf 7:8545a1d1d1e4 176 * Send a reset command to the device. With the reset command the device
tyftyftyf 7:8545a1d1d1e4 177 * populates its internal registers with the values read from the PROM.
tyftyftyf 7:8545a1d1d1e4 178 */
tyftyftyf 7:8545a1d1d1e4 179 void MS561101BA::reset() {
tyftyftyf 7:8545a1d1d1e4 180 /*Wire.beginTransmission(_addr);
tyftyftyf 7:8545a1d1d1e4 181 Wire.write(MS561101BA_RESET);
tyftyftyf 7:8545a1d1d1e4 182 Wire.endTransmission();*/
tyftyftyf 7:8545a1d1d1e4 183 i2c.start();
tyftyftyf 7:8545a1d1d1e4 184 i2c.write(_addr<<1);
tyftyftyf 7:8545a1d1d1e4 185 i2c.write(MS561101BA_RESET);
tyftyftyf 7:8545a1d1d1e4 186 i2c.stop();
tyftyftyf 7:8545a1d1d1e4 187 }