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:
Wed Apr 18 20:24:20 2018 +0000
Revision:
10:7802dc3ef0a0
Parent:
9:9f1d38b8d7c3
change to I2C 1

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 8:f3660f819e54 27 #include "rtos.h"
tyftyftyf 8:f3660f819e54 28 #include "MODI2C.h"
tyftyftyf 7:8545a1d1d1e4 29 #include "MS561101BA.h"
tyftyftyf 7:8545a1d1d1e4 30
tyftyftyf 8:f3660f819e54 31 #ifndef I2C_SDA
tyftyftyf 10:7802dc3ef0a0 32 #define I2C_SDA p9
tyftyftyf 10:7802dc3ef0a0 33 #define I2C_SCL p10
tyftyftyf 8:f3660f819e54 34 #endif
tyftyftyf 7:8545a1d1d1e4 35
tyftyftyf 9:9f1d38b8d7c3 36 MS561101BA::MS561101BA() : i2c(I2C_SDA,I2C_SCL), _thread(), sem(0){
tyftyftyf 8:f3660f819e54 37 zero = 0;
tyftyftyf 8:f3660f819e54 38 MS561101BA_RESET = 0x1E;
tyftyftyf 8:f3660f819e54 39 _OSR = NULL;
tyftyftyf 9:9f1d38b8d7c3 40 _thread.start(callback(&MS561101BA::samplingthread_stub, (void *) this));
tyftyftyf 7:8545a1d1d1e4 41 }
tyftyftyf 7:8545a1d1d1e4 42
tyftyftyf 7:8545a1d1d1e4 43 void MS561101BA::init(uint8_t address) {
tyftyftyf 8:f3660f819e54 44 lastPresConv=0;
tyftyftyf 8:f3660f819e54 45 lastTempConv=0;
tyftyftyf 9:9f1d38b8d7c3 46 t.start();
tyftyftyf 9:9f1d38b8d7c3 47 _addr = address << 1;
tyftyftyf 7:8545a1d1d1e4 48
tyftyftyf 9:9f1d38b8d7c3 49 reset(); // reset the device to populate its internal PROM registers
tyftyftyf 9:9f1d38b8d7c3 50 Thread::wait(500); // some safety time
tyftyftyf 9:9f1d38b8d7c3 51 readPROM(); // reads the PROM into object variables for later use
tyftyftyf 7:8545a1d1d1e4 52 }
tyftyftyf 7:8545a1d1d1e4 53
tyftyftyf 8:f3660f819e54 54 void MS561101BA::samplingthread_stub(void const *p) {
tyftyftyf 8:f3660f819e54 55 MS561101BA *instance = (MS561101BA*)p;
tyftyftyf 8:f3660f819e54 56 instance->samplingthread();
tyftyftyf 8:f3660f819e54 57 }
tyftyftyf 8:f3660f819e54 58
tyftyftyf 8:f3660f819e54 59 float MS561101BA::getPressure() {
tyftyftyf 7:8545a1d1d1e4 60 // see datasheet page 7 for formulas
tyftyftyf 7:8545a1d1d1e4 61
tyftyftyf 8:f3660f819e54 62 if(pressCache == NULL) {
tyftyftyf 7:8545a1d1d1e4 63 return NULL;
tyftyftyf 7:8545a1d1d1e4 64 }
tyftyftyf 7:8545a1d1d1e4 65
tyftyftyf 8:f3660f819e54 66 int32_t dT = getDeltaTemp();
tyftyftyf 7:8545a1d1d1e4 67 if(dT == NULL) {
tyftyftyf 7:8545a1d1d1e4 68 return NULL;
tyftyftyf 7:8545a1d1d1e4 69 }
tyftyftyf 7:8545a1d1d1e4 70
tyftyftyf 7:8545a1d1d1e4 71 int64_t off = ((uint32_t)_Cal[1] <<16) + (((int64_t)dT * _Cal[3]) >> 7);
tyftyftyf 7:8545a1d1d1e4 72 int64_t sens = ((uint32_t)_Cal[0] <<15) + (((int64_t)dT * _Cal[2]) >> 8);
tyftyftyf 8:f3660f819e54 73 return ((( (pressCache * sens ) >> 21) - off) >> 15) / 100.0;
tyftyftyf 7:8545a1d1d1e4 74 }
tyftyftyf 7:8545a1d1d1e4 75
tyftyftyf 8:f3660f819e54 76 float MS561101BA::getTemperature() {
tyftyftyf 7:8545a1d1d1e4 77 // see datasheet page 7 for formulas
tyftyftyf 8:f3660f819e54 78 int64_t dT = getDeltaTemp();
tyftyftyf 7:8545a1d1d1e4 79
tyftyftyf 7:8545a1d1d1e4 80 if(dT != NULL) {
tyftyftyf 7:8545a1d1d1e4 81 return (2000 + ((dT * _Cal[5]) >> 23)) / 100.0;
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 8:f3660f819e54 88 int32_t MS561101BA::getDeltaTemp() {
tyftyftyf 8:f3660f819e54 89 if(tempCache != NULL) {
tyftyftyf 8:f3660f819e54 90 return (int32_t)(tempCache - ((uint32_t)_Cal[4] << 8));
tyftyftyf 7:8545a1d1d1e4 91 }
tyftyftyf 7:8545a1d1d1e4 92 else {
tyftyftyf 7:8545a1d1d1e4 93 return NULL;
tyftyftyf 7:8545a1d1d1e4 94 }
tyftyftyf 7:8545a1d1d1e4 95 }
tyftyftyf 7:8545a1d1d1e4 96
tyftyftyf 8:f3660f819e54 97 void MS561101BA::samplingthread(){
tyftyftyf 8:f3660f819e54 98 Thread::signal_wait(0x1);
tyftyftyf 8:f3660f819e54 99 for (;;){
tyftyftyf 8:f3660f819e54 100 char command = MS561101BA_D1 + _OSR;
tyftyftyf 8:f3660f819e54 101 startConversion(&command);
tyftyftyf 8:f3660f819e54 102 Thread::wait(13);
tyftyftyf 8:f3660f819e54 103 getConversion();
tyftyftyf 8:f3660f819e54 104 sem.wait();
tyftyftyf 8:f3660f819e54 105 pressCache = conversion;
tyftyftyf 8:f3660f819e54 106 command = MS561101BA_D2 + _OSR;
tyftyftyf 8:f3660f819e54 107 startConversion(&command);
tyftyftyf 8:f3660f819e54 108 Thread::wait(13);
tyftyftyf 8:f3660f819e54 109 getConversion();
tyftyftyf 8:f3660f819e54 110 sem.wait();
tyftyftyf 8:f3660f819e54 111 tempCache = conversion;
tyftyftyf 8:f3660f819e54 112 Thread::yield();
tyftyftyf 8:f3660f819e54 113 }
tyftyftyf 8:f3660f819e54 114 }
tyftyftyf 7:8545a1d1d1e4 115
tyftyftyf 8:f3660f819e54 116 void MS561101BA::start_sampling(uint8_t OSR){
tyftyftyf 8:f3660f819e54 117 _OSR = OSR;
tyftyftyf 8:f3660f819e54 118 _thread.signal_set(0x1);
tyftyftyf 7:8545a1d1d1e4 119 }
tyftyftyf 7:8545a1d1d1e4 120
tyftyftyf 8:f3660f819e54 121 int MS561101BA::rawTemperature(){
tyftyftyf 8:f3660f819e54 122 return tempCache;
tyftyftyf 7:8545a1d1d1e4 123 }
tyftyftyf 7:8545a1d1d1e4 124
tyftyftyf 8:f3660f819e54 125 int MS561101BA::rawPressure(){
tyftyftyf 8:f3660f819e54 126 return pressCache;
tyftyftyf 8:f3660f819e54 127 }
tyftyftyf 7:8545a1d1d1e4 128
tyftyftyf 7:8545a1d1d1e4 129 // see page 11 of the datasheet
tyftyftyf 8:f3660f819e54 130 void MS561101BA::startConversion(char *command) {
tyftyftyf 7:8545a1d1d1e4 131 // initialize pressure conversion
tyftyftyf 8:f3660f819e54 132 i2c.write(_addr, (char*)command, 1);
tyftyftyf 7:8545a1d1d1e4 133 }
tyftyftyf 7:8545a1d1d1e4 134
tyftyftyf 8:f3660f819e54 135 uint32_t getConversion_fin(uint32_t param){
tyftyftyf 8:f3660f819e54 136 MS561101BA* ins = (MS561101BA*)param;
tyftyftyf 8:f3660f819e54 137 ins->conversion = (ins->cobuf[0] << 16) + (ins->cobuf[1] << 8) + ins->cobuf[2];
tyftyftyf 8:f3660f819e54 138 ins->sem.release();
tyftyftyf 8:f3660f819e54 139 return 0;
tyftyftyf 7:8545a1d1d1e4 140 }
tyftyftyf 7:8545a1d1d1e4 141
tyftyftyf 8:f3660f819e54 142 void MS561101BA::getConversion() {
tyftyftyf 8:f3660f819e54 143 i2c.write(_addr, (char*)&zero, 1);
tyftyftyf 8:f3660f819e54 144 i2c.read_nb(_addr, (char*)cobuf, MS561101BA_D1D2_SIZE, &getConversion_fin, this);
tyftyftyf 8:f3660f819e54 145 }
tyftyftyf 7:8545a1d1d1e4 146
tyftyftyf 7:8545a1d1d1e4 147 /**
tyftyftyf 7:8545a1d1d1e4 148 * Reads factory calibration and store it into object variables.
tyftyftyf 7:8545a1d1d1e4 149 */
tyftyftyf 7:8545a1d1d1e4 150 int MS561101BA::readPROM() {
tyftyftyf 7:8545a1d1d1e4 151 for (int i=0;i<MS561101BA_PROM_REG_COUNT;i++) {
tyftyftyf 8:f3660f819e54 152 char a = MS561101BA_PROM_BASE_ADDR + (i * MS561101BA_PROM_REG_SIZE);
tyftyftyf 8:f3660f819e54 153 i2c.write(_addr, &a, 1);
tyftyftyf 7:8545a1d1d1e4 154
tyftyftyf 7:8545a1d1d1e4 155 char tmp[2];
tyftyftyf 8:f3660f819e54 156 if (i2c.read(_addr, tmp, MS561101BA_PROM_REG_SIZE)!=0) return -1;
tyftyftyf 8:f3660f819e54 157 _Cal[i] = tmp[0] <<8 | tmp[1];
tyftyftyf 8:f3660f819e54 158 Thread::wait(200);
tyftyftyf 7:8545a1d1d1e4 159 }
tyftyftyf 7:8545a1d1d1e4 160 return 0;
tyftyftyf 7:8545a1d1d1e4 161 }
tyftyftyf 7:8545a1d1d1e4 162
tyftyftyf 7:8545a1d1d1e4 163
tyftyftyf 7:8545a1d1d1e4 164 /**
tyftyftyf 7:8545a1d1d1e4 165 * Send a reset command to the device. With the reset command the device
tyftyftyf 7:8545a1d1d1e4 166 * populates its internal registers with the values read from the PROM.
tyftyftyf 7:8545a1d1d1e4 167 */
tyftyftyf 7:8545a1d1d1e4 168 void MS561101BA::reset() {
tyftyftyf 8:f3660f819e54 169 i2c.write(_addr, (char*)&MS561101BA_RESET, 1);
tyftyftyf 7:8545a1d1d1e4 170 }