Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
MS5611/MS5611Base.h@2:4d9204790be1, 2020-05-19 (annotated)
- Committer:
- altb2
- Date:
- Tue May 19 13:13:03 2020 +0000
- Revision:
- 2:4d9204790be1
MS56 Baro-sensor with toggling Temper. and pressure overe i2c;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
altb2 | 2:4d9204790be1 | 1 | /* |
altb2 | 2:4d9204790be1 | 2 | Copyright (c) 2012, Senio Networks, Inc. |
altb2 | 2:4d9204790be1 | 3 | |
altb2 | 2:4d9204790be1 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy |
altb2 | 2:4d9204790be1 | 5 | of this software and associated documentation files (the "Software"), to deal |
altb2 | 2:4d9204790be1 | 6 | in the Software without restriction, including without limitation the rights |
altb2 | 2:4d9204790be1 | 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
altb2 | 2:4d9204790be1 | 8 | copies of the Software, and to permit persons to whom the Software is |
altb2 | 2:4d9204790be1 | 9 | furnished to do so, subject to the following conditions: |
altb2 | 2:4d9204790be1 | 10 | |
altb2 | 2:4d9204790be1 | 11 | The above copyright notice and this permission notice shall be included in |
altb2 | 2:4d9204790be1 | 12 | all copies or substantial portions of the Software. |
altb2 | 2:4d9204790be1 | 13 | |
altb2 | 2:4d9204790be1 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
altb2 | 2:4d9204790be1 | 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
altb2 | 2:4d9204790be1 | 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
altb2 | 2:4d9204790be1 | 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
altb2 | 2:4d9204790be1 | 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
altb2 | 2:4d9204790be1 | 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
altb2 | 2:4d9204790be1 | 20 | THE SOFTWARE. |
altb2 | 2:4d9204790be1 | 21 | */ |
altb2 | 2:4d9204790be1 | 22 | |
altb2 | 2:4d9204790be1 | 23 | /* MS5611 Modifications |
altb2 | 2:4d9204790be1 | 24 | Aerodyne Labs |
altb2 | 2:4d9204790be1 | 25 | Matthew Nelson - 2014 |
altb2 | 2:4d9204790be1 | 26 | This library was originally the MS5607 library. It has been modified to |
altb2 | 2:4d9204790be1 | 27 | to be used the MS5611 Pressure sensor |
altb2 | 2:4d9204790be1 | 28 | ------------ |
altb2 | 2:4d9204790be1 | 29 | IndNav: Made adaptions, even though, the original works well, problem: |
altb2 | 2:4d9204790be1 | 30 | the original has a delay of 8ms from writing to reading (see line 73 in MS5611I2c |
altb2 | 2:4d9204790be1 | 31 | Solution: seperate write and read in 2 processes (hene's hint): |
altb2 | 2:4d9204790be1 | 32 | - write at end of data_read thread, without waiting |
altb2 | 2:4d9204790be1 | 33 | - at beginning of next call, read the data |
altb2 | 2:4d9204790be1 | 34 | since there are 2 seperate reading/writings (one for pressure(altitude), one for Temperature -and we need both!) |
altb2 | 2:4d9204790be1 | 35 | toggle the 2 processes, this results, that only every 2nd pressure/altitude value is a new value! |
altb2 | 2:4d9204790be1 | 36 | |
altb2 | 2:4d9204790be1 | 37 | altb 20.2.2020 |
altb2 | 2:4d9204790be1 | 38 | */ |
altb2 | 2:4d9204790be1 | 39 | |
altb2 | 2:4d9204790be1 | 40 | #ifndef MS5611_BASE_H |
altb2 | 2:4d9204790be1 | 41 | #define MS5611_BASE_H |
altb2 | 2:4d9204790be1 | 42 | |
altb2 | 2:4d9204790be1 | 43 | class MS5611Base { |
altb2 | 2:4d9204790be1 | 44 | public: |
altb2 | 2:4d9204790be1 | 45 | void printCoefficients() { |
altb2 | 2:4d9204790be1 | 46 | printf("%d, %d, %d, %d, %d, %d \r\n", c1, c2, c3, c4, c5, c6); |
altb2 | 2:4d9204790be1 | 47 | } |
altb2 | 2:4d9204790be1 | 48 | |
altb2 | 2:4d9204790be1 | 49 | int getRawPressure() { |
altb2 | 2:4d9204790be1 | 50 | return readADC(ADC_D1 | OSR_4096); // fuer 1024: gibt das 4 |
altb2 | 2:4d9204790be1 | 51 | } |
altb2 | 2:4d9204790be1 | 52 | int getRawPressure_read() { |
altb2 | 2:4d9204790be1 | 53 | return readADC_read(ADC_D1 | OSR_4096); // fuer 1024: gibt das 4 |
altb2 | 2:4d9204790be1 | 54 | } |
altb2 | 2:4d9204790be1 | 55 | int getRawTemperature() { |
altb2 | 2:4d9204790be1 | 56 | return readADC(ADC_D2 | OSR_4096); // fuer 1024: gibt das 20 |
altb2 | 2:4d9204790be1 | 57 | } |
altb2 | 2:4d9204790be1 | 58 | int getRawTemperature_read() { |
altb2 | 2:4d9204790be1 | 59 | return readADC_read(ADC_D2 | OSR_4096); // fuer 1024: gibt das 20 |
altb2 | 2:4d9204790be1 | 60 | } |
altb2 | 2:4d9204790be1 | 61 | |
altb2 | 2:4d9204790be1 | 62 | float getTemperature() { |
altb2 | 2:4d9204790be1 | 63 | int dT = getRawTemperature() - (c5 << 8); |
altb2 | 2:4d9204790be1 | 64 | int temp = 2000 + ((dT * c6) >> 23); |
altb2 | 2:4d9204790be1 | 65 | |
altb2 | 2:4d9204790be1 | 66 | // 2nd order temperature compensation |
altb2 | 2:4d9204790be1 | 67 | if (temp < 2000) { |
altb2 | 2:4d9204790be1 | 68 | int t2 = (int64_t) dT * dT >> 31; |
altb2 | 2:4d9204790be1 | 69 | temp -= t2; |
altb2 | 2:4d9204790be1 | 70 | } |
altb2 | 2:4d9204790be1 | 71 | |
altb2 | 2:4d9204790be1 | 72 | return float(temp) / 100; |
altb2 | 2:4d9204790be1 | 73 | } |
altb2 | 2:4d9204790be1 | 74 | |
altb2 | 2:4d9204790be1 | 75 | float getPressure() { |
altb2 | 2:4d9204790be1 | 76 | int dT = getRawTemperature() - (c5 << 8); |
altb2 | 2:4d9204790be1 | 77 | int temp = 2000 + ((dT * c6) >> 23); |
altb2 | 2:4d9204790be1 | 78 | int64_t off = ((int64_t) c2 << 16) + ((int64_t) dT * c4 >> 7); |
altb2 | 2:4d9204790be1 | 79 | int64_t sens = ((int64_t) c1 << 15) + ((int64_t) dT * c3 >> 8); |
altb2 | 2:4d9204790be1 | 80 | |
altb2 | 2:4d9204790be1 | 81 | // 2nd order temperature compensation |
altb2 | 2:4d9204790be1 | 82 | if (temp < 2000) { |
altb2 | 2:4d9204790be1 | 83 | int64_t off2 = (int64_t) 5 * (temp - 2000) * (temp - 2000) >> 1; |
altb2 | 2:4d9204790be1 | 84 | int64_t sens2 = (int64_t) 5 * (temp - 2000) * (temp - 2000) >> 2; |
altb2 | 2:4d9204790be1 | 85 | if (temp < -1500) { |
altb2 | 2:4d9204790be1 | 86 | off2 += (int64_t) 7 * (temp + 1500) * (temp + 1500); |
altb2 | 2:4d9204790be1 | 87 | sens2 += (int64_t) 11 * (temp + 1500) * (temp + 1500) >> 1; |
altb2 | 2:4d9204790be1 | 88 | } |
altb2 | 2:4d9204790be1 | 89 | off -= off2; |
altb2 | 2:4d9204790be1 | 90 | sens -= sens2; |
altb2 | 2:4d9204790be1 | 91 | } |
altb2 | 2:4d9204790be1 | 92 | |
altb2 | 2:4d9204790be1 | 93 | return float((((int64_t) getRawPressure() * sens >> 21) - off) >> 15); |
altb2 | 2:4d9204790be1 | 94 | } |
altb2 | 2:4d9204790be1 | 95 | float getPressure(int dT) { |
altb2 | 2:4d9204790be1 | 96 | // int dT = getRawTemperature() - (c5 << 8); |
altb2 | 2:4d9204790be1 | 97 | int temp = 2000 + ((dT * c6) >> 23); |
altb2 | 2:4d9204790be1 | 98 | int64_t off = ((int64_t) c2 << 16) + ((int64_t) dT * c4 >> 7); |
altb2 | 2:4d9204790be1 | 99 | int64_t sens = ((int64_t) c1 << 15) + ((int64_t) dT * c3 >> 8); |
altb2 | 2:4d9204790be1 | 100 | |
altb2 | 2:4d9204790be1 | 101 | // 2nd order temperature compensation |
altb2 | 2:4d9204790be1 | 102 | if (temp < 2000) { |
altb2 | 2:4d9204790be1 | 103 | int64_t off2 = (int64_t) 5 * (temp - 2000) * (temp - 2000) >> 1; |
altb2 | 2:4d9204790be1 | 104 | int64_t sens2 = (int64_t) 5 * (temp - 2000) * (temp - 2000) >> 2; |
altb2 | 2:4d9204790be1 | 105 | if (temp < -1500) { |
altb2 | 2:4d9204790be1 | 106 | off2 += (int64_t) 7 * (temp + 1500) * (temp + 1500); |
altb2 | 2:4d9204790be1 | 107 | sens2 += (int64_t) 11 * (temp + 1500) * (temp + 1500) >> 1; |
altb2 | 2:4d9204790be1 | 108 | } |
altb2 | 2:4d9204790be1 | 109 | off -= off2; |
altb2 | 2:4d9204790be1 | 110 | sens -= sens2; |
altb2 | 2:4d9204790be1 | 111 | } |
altb2 | 2:4d9204790be1 | 112 | |
altb2 | 2:4d9204790be1 | 113 | return float((((int64_t) getRawPressure() * sens >> 21) - off) >> 15); |
altb2 | 2:4d9204790be1 | 114 | } |
altb2 | 2:4d9204790be1 | 115 | |
altb2 | 2:4d9204790be1 | 116 | float getAltitude(int presssure = 0) { |
altb2 | 2:4d9204790be1 | 117 | return toAltitude(presssure ? presssure : (int) getPressure()); |
altb2 | 2:4d9204790be1 | 118 | } |
altb2 | 2:4d9204790be1 | 119 | |
altb2 | 2:4d9204790be1 | 120 | float getAltitude_toggle_Temp_read(int presssure = 0) { |
altb2 | 2:4d9204790be1 | 121 | if(temp_toggle) |
altb2 | 2:4d9204790be1 | 122 | { |
altb2 | 2:4d9204790be1 | 123 | dT_keep = getRawTemperature_read() - (c5 << 8); |
altb2 | 2:4d9204790be1 | 124 | temp_toggle = false; |
altb2 | 2:4d9204790be1 | 125 | } |
altb2 | 2:4d9204790be1 | 126 | else |
altb2 | 2:4d9204790be1 | 127 | { |
altb2 | 2:4d9204790be1 | 128 | temp_toggle = true; |
altb2 | 2:4d9204790be1 | 129 | old_alt = toAltitude(presssure ? presssure : (int) getPressure(dT_keep)); |
altb2 | 2:4d9204790be1 | 130 | } |
altb2 | 2:4d9204790be1 | 131 | return old_alt; |
altb2 | 2:4d9204790be1 | 132 | } |
altb2 | 2:4d9204790be1 | 133 | |
altb2 | 2:4d9204790be1 | 134 | int getAltitude_toggle_Temp_write(int presssure = 0) { |
altb2 | 2:4d9204790be1 | 135 | if(temp_toggle) |
altb2 | 2:4d9204790be1 | 136 | { |
altb2 | 2:4d9204790be1 | 137 | return readADC_write(ADC_D2 | OSR_4096); |
altb2 | 2:4d9204790be1 | 138 | } |
altb2 | 2:4d9204790be1 | 139 | else |
altb2 | 2:4d9204790be1 | 140 | { |
altb2 | 2:4d9204790be1 | 141 | return readADC_write(ADC_D1 | OSR_4096); |
altb2 | 2:4d9204790be1 | 142 | } |
altb2 | 2:4d9204790be1 | 143 | } |
altb2 | 2:4d9204790be1 | 144 | int dT_keep; |
altb2 | 2:4d9204790be1 | 145 | protected: |
altb2 | 2:4d9204790be1 | 146 | int32_t c1, c2, c3, c4, c5, c6; |
altb2 | 2:4d9204790be1 | 147 | bool temp_toggle; |
altb2 | 2:4d9204790be1 | 148 | float old_alt; // get altitude only every 2nd time. |
altb2 | 2:4d9204790be1 | 149 | enum { |
altb2 | 2:4d9204790be1 | 150 | RESET = 0x1E, |
altb2 | 2:4d9204790be1 | 151 | ADC_READ = 0x00, |
altb2 | 2:4d9204790be1 | 152 | ADC_CONV = 0x40, |
altb2 | 2:4d9204790be1 | 153 | ADC_D1 = 0x00, |
altb2 | 2:4d9204790be1 | 154 | ADC_D2 = 0x10, |
altb2 | 2:4d9204790be1 | 155 | OSR_256 = 0x00, |
altb2 | 2:4d9204790be1 | 156 | OSR_512 = 0x02, |
altb2 | 2:4d9204790be1 | 157 | OSR_1024 = 0x04, |
altb2 | 2:4d9204790be1 | 158 | OSR_2048 = 0x06, |
altb2 | 2:4d9204790be1 | 159 | OSR_4096 = 0x08, |
altb2 | 2:4d9204790be1 | 160 | PROM_READ = 0xA0 |
altb2 | 2:4d9204790be1 | 161 | }; |
altb2 | 2:4d9204790be1 | 162 | |
altb2 | 2:4d9204790be1 | 163 | virtual void writeCommand(int command, int ms = 0) = 0; |
altb2 | 2:4d9204790be1 | 164 | virtual int readPROM(int address) = 0; |
altb2 | 2:4d9204790be1 | 165 | virtual int readADC(int command) = 0; |
altb2 | 2:4d9204790be1 | 166 | virtual int readADC_write(int command) = 0; |
altb2 | 2:4d9204790be1 | 167 | virtual int readADC_read(int command) = 0; |
altb2 | 2:4d9204790be1 | 168 | |
altb2 | 2:4d9204790be1 | 169 | void init() { |
altb2 | 2:4d9204790be1 | 170 | writeCommand(RESET, 3); |
altb2 | 2:4d9204790be1 | 171 | c1 = readPROM(1); |
altb2 | 2:4d9204790be1 | 172 | c2 = readPROM(2); |
altb2 | 2:4d9204790be1 | 173 | c3 = readPROM(3); |
altb2 | 2:4d9204790be1 | 174 | c4 = readPROM(4); |
altb2 | 2:4d9204790be1 | 175 | c5 = readPROM(5); |
altb2 | 2:4d9204790be1 | 176 | c6 = readPROM(6); |
altb2 | 2:4d9204790be1 | 177 | dT_keep = 2000; |
altb2 | 2:4d9204790be1 | 178 | temp_toggle = true; |
altb2 | 2:4d9204790be1 | 179 | old_alt = 0.0; |
altb2 | 2:4d9204790be1 | 180 | } |
altb2 | 2:4d9204790be1 | 181 | |
altb2 | 2:4d9204790be1 | 182 | float toAltitude(int pressure) { |
altb2 | 2:4d9204790be1 | 183 | // Ref. 29124-AltimeterAppNote1.pdf |
altb2 | 2:4d9204790be1 | 184 | const float R = 287.052; // specific gas constant R*/M0 |
altb2 | 2:4d9204790be1 | 185 | const float g = 9.80665; // standard gravity |
altb2 | 2:4d9204790be1 | 186 | const float t_grad = 0.0065; // gradient of temperature |
altb2 | 2:4d9204790be1 | 187 | const float t0 = 273.15 + 15; // temperature at 0 altitude |
altb2 | 2:4d9204790be1 | 188 | const float p0 = 101325; // pressure at 0 altitude |
altb2 | 2:4d9204790be1 | 189 | |
altb2 | 2:4d9204790be1 | 190 | return t0 / t_grad * (1 - exp((t_grad * R / g) * log(pressure / p0))); |
altb2 | 2:4d9204790be1 | 191 | } |
altb2 | 2:4d9204790be1 | 192 | }; |
altb2 | 2:4d9204790be1 | 193 | |
altb2 | 2:4d9204790be1 | 194 | #endif |