2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
5 * @addtogroup AirspeedModule Airspeed Module
6 * @brief Communicate with airspeed sensors and return values
9 * @file baro_airspeed_ms4525do.c
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
11 * @brief Airspeed module, handles temperature and pressure readings from MS4525DO
13 * @see The GNU Public License (GPL) Version 3
15 *****************************************************************************/
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 * Output object: BaroAirspeed
35 * This module will periodically update the value of the BaroAirspeed object.
39 #include "openpilot.h"
40 #include "hwsettings.h"
41 #include "airspeedsettings.h"
42 #include "airspeedsensor.h" // object that will be updated by the module
43 #include "airspeedalarm.h"
45 #if defined(PIOS_INCLUDE_MS4525DO)
47 #define CALIBRATION_IDLE_MS 0 // Time to wait before calibrating, in [ms]
48 #define CALIBRATION_COUNT_MS 4000 // Time to spend calibrating, in [ms]
49 #define FILTER_SHIFT 5 // Barry Dorr filter parameter k
51 #define P0 101325.0f // standard pressure
52 #define CCEXPONENT 0.2857142857f // exponent of compressibility correction 2/7
53 #define CASFACTOR 760.8802669f // sqrt(5) * speed of sound at standard
54 #define TASFACTOR 0.05891022589f // 1/sqrt(T0)
58 // Private functions definitions
61 static uint16_t calibrationCount
= 0;
62 static uint32_t filter_reg
= 0; // Barry Dorr filter register
64 void baro_airspeedGetMS4525DO(AirspeedSensorData
*airspeedSensor
, AirspeedSettingsData
*airspeedSettings
)
69 int8_t retVal
= PIOS_MS4525DO_Read(values
);
73 airspeedSensor
->SensorValue
= -1;
74 airspeedSensor
->SensorValueTemperature
= -1;
75 airspeedSensor
->SensorConnected
= AIRSPEEDSENSOR_SENSORCONNECTED_FALSE
;
76 airspeedSensor
->CalibratedAirspeed
= 0;
77 AirspeedAlarm(SYSTEMALARMS_ALARM_ERROR
);
81 airspeedSensor
->SensorValue
= values
[0];
82 airspeedSensor
->SensorValueTemperature
= values
[1];
84 // only calibrate if no stored calibration is available
85 if (!airspeedSettings
->ZeroPoint
) {
86 // Calibrate sensor by averaging zero point value
87 if (calibrationCount
<= CALIBRATION_IDLE_MS
/ airspeedSettings
->SamplePeriod
) {
89 filter_reg
= (airspeedSensor
->SensorValue
<< FILTER_SHIFT
);
90 AirspeedAlarm(SYSTEMALARMS_ALARM_WARNING
);
92 } else if (calibrationCount
<= (CALIBRATION_IDLE_MS
+ CALIBRATION_COUNT_MS
) / airspeedSettings
->SamplePeriod
) {
94 // update filter register
95 filter_reg
= filter_reg
- (filter_reg
>> FILTER_SHIFT
) + airspeedSensor
->SensorValue
;
97 if (calibrationCount
> (CALIBRATION_IDLE_MS
+ CALIBRATION_COUNT_MS
) / airspeedSettings
->SamplePeriod
) {
98 // Scale output for unity gain.
99 airspeedSettings
->ZeroPoint
= (uint16_t)(filter_reg
>> FILTER_SHIFT
);
101 AirspeedSettingsZeroPointSet(&airspeedSettings
->ZeroPoint
);
102 calibrationCount
= 0;
104 AirspeedAlarm(SYSTEMALARMS_ALARM_WARNING
);
110 assume sensor is A Type and has a range of 1 psi, i.e. Pmin=-1.0 psi and Pmax=1.0 psi
111 Datasheet pressure: output = 0.8 * 16383 / (Pmax-Pmin) * (P - Pmin) + 0.1 * 16383
112 Inversion: P = (10*output - 81915)/65532 in psi
113 1 psi = 6894,757293168 Pa
114 P = (10*output - 81915)*0.1052120688 in Pa
115 Datasheet temperature: output = (T+50)*2047 / 200
116 Inversion: T = (200*out - 102350)/2047 in C
117 T = (200*out - 102350)/2047 + 273.15 in K
119 const float dP
= (10 * (int32_t)(airspeedSensor
->SensorValue
- airspeedSettings
->ZeroPoint
)) * 0.1052120688f
;
120 const float T
= (float)(200 * (int32_t)airspeedSensor
->SensorValueTemperature
- 102350) / 2047 + 273.15f
;
122 airspeedSensor
->DifferentialPressure
= dP
;
123 airspeedSensor
->Temperature
= T
;
124 // CAS = Csound * sqrt( 5 *( (dP/P0 +1)^(2/7) - 1) )
125 // TAS = Csound * sqrt( 5 T/T0 *( (dP/P0 +1)^(2/7) - 1) )
126 // where Csound = 340.276 m/s at standard condition T0=288.15 K and P0 = 101315 Pa
127 airspeedSensor
->CalibratedAirspeed
= airspeedSettings
->Scale
* CASFACTOR
* sqrtf(powf(fabsf(dP
) / P0
+ 1.0f
, CCEXPONENT
) - 1.0f
);
128 airspeedSensor
->TrueAirspeed
= airspeedSensor
->CalibratedAirspeed
* TASFACTOR
* sqrtf(T
);
129 airspeedSensor
->SensorConnected
= AIRSPEEDSENSOR_SENSORCONNECTED_TRUE
;
130 // everything is fine so set ALARM_OK
131 AirspeedAlarm(SYSTEMALARMS_ALARM_OK
);
134 #endif /* if defined(PIOS_INCLUDE_MS4525DO) */