High resolution barometer and altimeter using i2c mode. Adapted to FreeIMU interface
Dependents: FreeIMU FreeIMU_external_magnetometer FreeIMU
Fork of ms5611 by
MS561101BA.cpp@9:9f1d38b8d7c3, 2018-03-07 (annotated)
- Committer:
- tyftyftyf
- Date:
- Wed Mar 07 04:13:14 2018 +0000
- Revision:
- 9:9f1d38b8d7c3
- Parent:
- 8:f3660f819e54
- Child:
- 10:7802dc3ef0a0
test
Who changed what in which revision?
User | Revision | Line number | New 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 | 8:f3660f819e54 | 32 | #define I2C_SDA p28 |
tyftyftyf | 8:f3660f819e54 | 33 | #define I2C_SCL p27 |
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 | } |