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"
46 #if defined(PIOS_INCLUDE_MS4525DO)
48 #define CALIBRATION_IDLE_MS 0 // Time to wait before calibrating, in [ms]
49 #define CALIBRATION_COUNT_MS 4000 // Time to spend calibrating, in [ms]
50 #define FILTER_SHIFT 5 // Barry Dorr filter parameter k
52 #define P0 101325.0f // standard pressure
53 #define CCEXPONENT 0.2857142857f // exponent of compressibility correction 2/7
54 #define CASFACTOR 760.8802669f // sqrt(5) * speed of sound at standard
55 #define TASFACTOR 0.05891022589f // 1/sqrt(T0)
59 // Private functions definitions
62 static uint16_t calibrationCount
= 0;
63 static uint32_t filter_reg
= 0; // Barry Dorr filter register
65 void baro_airspeedGetMS4525DO(AirspeedSensorData
*airspeedSensor
, AirspeedSettingsData
*airspeedSettings
)
70 int8_t retVal
= PIOS_MS4525DO_Read(values
);
74 airspeedSensor
->SensorValue
= -1;
75 airspeedSensor
->SensorValueTemperature
= -1;
76 airspeedSensor
->SensorConnected
= AIRSPEEDSENSOR_SENSORCONNECTED_FALSE
;
77 airspeedSensor
->CalibratedAirspeed
= 0;
78 AirspeedAlarm(SYSTEMALARMS_ALARM_ERROR
);
82 airspeedSensor
->SensorValue
= values
[0];
83 airspeedSensor
->SensorValueTemperature
= values
[1];
85 // only calibrate if no stored calibration is available
86 if (!airspeedSettings
->ZeroPoint
) {
87 // Calibrate sensor by averaging zero point value
88 if (calibrationCount
<= CALIBRATION_IDLE_MS
/ airspeedSettings
->SamplePeriod
) {
90 filter_reg
= (airspeedSensor
->SensorValue
<< FILTER_SHIFT
);
91 AirspeedAlarm(SYSTEMALARMS_ALARM_WARNING
);
93 } else if (calibrationCount
<= (CALIBRATION_IDLE_MS
+ CALIBRATION_COUNT_MS
) / airspeedSettings
->SamplePeriod
) {
95 // update filter register
96 filter_reg
= filter_reg
- (filter_reg
>> FILTER_SHIFT
) + airspeedSensor
->SensorValue
;
98 if (calibrationCount
> (CALIBRATION_IDLE_MS
+ CALIBRATION_COUNT_MS
) / airspeedSettings
->SamplePeriod
) {
99 // Scale output for unity gain.
100 airspeedSettings
->ZeroPoint
= (uint16_t)(filter_reg
>> FILTER_SHIFT
);
102 AirspeedSettingsZeroPointSet(&airspeedSettings
->ZeroPoint
);
103 calibrationCount
= 0;
105 AirspeedAlarm(SYSTEMALARMS_ALARM_WARNING
);
111 assume sensor is A Type and has a range of 1 psi, i.e. Pmin=-1.0 psi and Pmax=1.0 psi
112 Datasheet pressure: output = 0.8 * 16383 / (Pmax-Pmin) * (P - Pmin) + 0.1 * 16383
113 Inversion: P = (10*output - 81915)/65532 in psi
114 1 psi = 6894,757293168 Pa
115 P = (10*output - 81915)*0.1052120688 in Pa
116 Datasheet temperature: output = (T+50)*2047 / 200
117 Inversion: T = (200*out - 102350)/2047 in C
118 T = (200*out - 102350)/2047 + 273.15 in K
120 const float dP
= (10 * (int32_t)(airspeedSensor
->SensorValue
- airspeedSettings
->ZeroPoint
)) * 0.1052120688f
;
121 const float T
= (float)(200 * (int32_t)airspeedSensor
->SensorValueTemperature
- 102350) / 2047 + 273.15f
;
123 airspeedSensor
->DifferentialPressure
= dP
;
124 airspeedSensor
->Temperature
= T
;
125 // CAS = Csound * sqrt( 5 *( (dP/P0 +1)^(2/7) - 1) )
126 // TAS = Csound * sqrt( 5 T/T0 *( (dP/P0 +1)^(2/7) - 1) )
127 // where Csound = 340.276 m/s at standard condition T0=288.15 K and P0 = 101315 Pa
128 airspeedSensor
->CalibratedAirspeed
= airspeedSettings
->Scale
* CASFACTOR
* sqrtf(powf(fabsf(dP
) / P0
+ 1.0f
, CCEXPONENT
) - 1.0f
);
129 airspeedSensor
->TrueAirspeed
= airspeedSensor
->CalibratedAirspeed
* TASFACTOR
* sqrtf(T
);
130 airspeedSensor
->SensorConnected
= AIRSPEEDSENSOR_SENSORCONNECTED_TRUE
;
131 // everything is fine so set ALARM_OK
132 AirspeedAlarm(SYSTEMALARMS_ALARM_OK
);
135 #endif /* if defined(PIOS_INCLUDE_MS4525DO) */