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