2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "build/debug.h"
25 #include "common/calibration.h"
26 #include "common/log.h"
27 #include "common/maths.h"
28 #include "common/time.h"
29 #include "common/utils.h"
31 #include "config/parameter_group.h"
32 #include "config/parameter_group_ids.h"
34 #include "drivers/barometer/barometer.h"
35 #include "drivers/barometer/barometer_bmp085.h"
36 #include "drivers/barometer/barometer_bmp280.h"
37 #include "drivers/barometer/barometer_bmp388.h"
38 #include "drivers/barometer/barometer_lps25h.h"
39 #include "drivers/barometer/barometer_fake.h"
40 #include "drivers/barometer/barometer_ms56xx.h"
41 #include "drivers/barometer/barometer_spl06.h"
42 #include "drivers/barometer/barometer_dps310.h"
43 #include "drivers/barometer/barometer_2smpb_02b.h"
44 #include "drivers/barometer/barometer_msp.h"
45 #include "drivers/time.h"
47 #include "fc/runtime_config.h"
48 #include "fc/settings.h"
50 #include "sensors/barometer.h"
51 #include "sensors/sensors.h"
53 #ifdef USE_HARDWARE_REVISION_DETECTION
54 #include "hardware_revision.h"
57 baro_t baro
; // barometer access functions
61 PG_REGISTER_WITH_RESET_TEMPLATE(barometerConfig_t
, barometerConfig
, PG_BAROMETER_CONFIG
, 4);
63 PG_RESET_TEMPLATE(barometerConfig_t
, barometerConfig
,
64 .baro_hardware
= SETTING_BARO_HARDWARE_DEFAULT
,
65 .baro_calibration_tolerance
= SETTING_BARO_CAL_TOLERANCE_DEFAULT
68 static zeroCalibrationScalar_t zeroCalibration
;
69 static float baroGroundAltitude
= 0;
70 static float baroGroundPressure
= 101325.0f
; // 101325 pascal, 1 standard atmosphere
72 bool baroDetect(baroDev_t
*dev
, baroSensor_e baroHardwareToUse
)
74 // Detect what pressure sensors are available. baro->update() is set to sensor-specific update function
76 baroSensor_e baroHardware
= BARO_NONE
;
77 requestedSensors
[SENSOR_INDEX_BARO
] = baroHardwareToUse
;
79 switch (baroHardwareToUse
) {
82 #ifdef USE_BARO_BMP085
83 if (bmp085Detect(dev
)) {
84 baroHardware
= BARO_BMP085
;
88 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
89 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
95 #ifdef USE_BARO_MS5607
96 if (ms5607Detect(dev
)) {
97 baroHardware
= BARO_MS5607
;
101 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
102 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
108 #ifdef USE_BARO_MS5611
109 if (ms5611Detect(dev
)) {
110 baroHardware
= BARO_MS5611
;
114 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
115 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
121 #if defined(USE_BARO_BMP280) || defined(USE_BARO_SPI_BMP280)
122 if (bmp280Detect(dev
)) {
123 baroHardware
= BARO_BMP280
;
127 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
128 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
134 #if defined(USE_BARO_BMP388) || defined(USE_BARO_SPI_BMP388)
135 if (bmp388Detect(dev
)) {
136 baroHardware
= BARO_BMP388
;
140 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
141 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
147 #if defined(USE_BARO_SPL06) || defined(USE_BARO_SPI_SPL06)
148 if (spl06Detect(dev
)) {
149 baroHardware
= BARO_SPL06
;
153 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
154 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
160 #if defined(USE_BARO_LPS25H)
161 if (lps25hDetect(dev
)) {
162 baroHardware
= BARO_LPS25H
;
166 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
167 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
173 #if defined(USE_BARO_DPS310)
174 if (baroDPS310Detect(dev
)) {
175 baroHardware
= BARO_DPS310
;
179 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
180 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
186 #if defined(USE_BARO_B2SMPB)
187 if (baro2SMPB02BDetect(dev
)) {
188 baroHardware
= BARO_B2SMPB
;
192 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
193 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
200 // Skip autodetection for MSP baro, only allow manual config
201 if (baroHardwareToUse
!= BARO_AUTODETECT
&& mspBaroDetect(dev
)) {
202 baroHardware
= BARO_MSP
;
206 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
207 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
214 if (fakeBaroDetect(dev
)) {
215 baroHardware
= BARO_FAKE
;
219 /* If we are asked for a specific sensor - break out, otherwise - fall through and continue */
220 if (baroHardwareToUse
!= BARO_AUTODETECT
) {
226 baroHardware
= BARO_NONE
;
230 if (baroHardware
== BARO_NONE
) {
231 sensorsClear(SENSOR_BARO
);
235 detectedSensors
[SENSOR_INDEX_BARO
] = baroHardware
;
236 sensorsSet(SENSOR_BARO
);
242 if (!baroDetect(&baro
.dev
, barometerConfig()->baro_hardware
)) {
249 BAROMETER_NEEDS_SAMPLES
= 0,
250 BAROMETER_NEEDS_CALCULATION
253 uint32_t baroUpdate(void)
255 static barometerState_e state
= BAROMETER_NEEDS_SAMPLES
;
259 case BAROMETER_NEEDS_SAMPLES
:
260 if (baro
.dev
.get_ut
) {
261 baro
.dev
.get_ut(&baro
.dev
);
263 if (baro
.dev
.start_up
) {
264 baro
.dev
.start_up(&baro
.dev
);
266 state
= BAROMETER_NEEDS_CALCULATION
;
267 return baro
.dev
.up_delay
;
270 case BAROMETER_NEEDS_CALCULATION
:
271 if (baro
.dev
.get_up
) {
272 baro
.dev
.get_up(&baro
.dev
);
274 if (baro
.dev
.start_ut
) {
275 baro
.dev
.start_ut(&baro
.dev
);
278 if (!ARMING_FLAG(SIMULATOR_MODE
)) {
279 //output: baro.baroPressure, baro.baroTemperature
280 baro
.dev
.calculate(&baro
.dev
, &baro
.baroPressure
, &baro
.baroTemperature
);
283 baro
.dev
.calculate(&baro
.dev
, &baro
.baroPressure
, &baro
.baroTemperature
);
285 state
= BAROMETER_NEEDS_SAMPLES
;
286 return baro
.dev
.ut_delay
;
291 static float pressureToAltitude(const float pressure
)
293 return (1.0f
- powf(pressure
/ 101325.0f
, 0.190295f
)) * 4433000.0f
;
296 static float altitudeToPressure(const float altCm
)
298 return powf(1.0f
- (altCm
/ 4433000.0f
), 5.254999) * 101325.0f
;
301 bool baroIsCalibrationComplete(void)
303 return zeroCalibrationIsCompleteS(&zeroCalibration
) && zeroCalibrationIsSuccessfulS(&zeroCalibration
);
306 void baroStartCalibration(void)
308 const float acceptedPressureVariance
= (101325.0f
- altitudeToPressure(barometerConfig()->baro_calibration_tolerance
)); // max 30cm deviation during calibration (at sea level)
309 zeroCalibrationStartS(&zeroCalibration
, CALIBRATING_BARO_TIME_MS
, acceptedPressureVariance
, false);
312 int32_t baroCalculateAltitude(void)
314 if (!baroIsCalibrationComplete()) {
315 zeroCalibrationAddValueS(&zeroCalibration
, baro
.baroPressure
);
317 if (zeroCalibrationIsCompleteS(&zeroCalibration
)) {
318 zeroCalibrationGetZeroS(&zeroCalibration
, &baroGroundPressure
);
319 baroGroundAltitude
= pressureToAltitude(baroGroundPressure
);
320 LOG_DEBUG(BARO
, "Barometer calibration complete (%d)", (int)lrintf(baroGroundAltitude
));
326 // calculates height from ground via baro readings
327 baro
.BaroAlt
= pressureToAltitude(baro
.baroPressure
) - baroGroundAltitude
;
333 int32_t baroGetLatestAltitude(void)
338 int16_t baroGetTemperature(void)
340 return CENTIDEGREES_TO_DECIDEGREES(baro
.baroTemperature
);
343 bool baroIsHealthy(void)