altb_pmic / Mbed 2 deprecated MS5611_2

Dependencies:   mbed

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?

UserRevisionLine numberNew 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