Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / flight / modules / Airspeed / baro_airspeed_ms4525do.c
blob6c93b07d84acb9e4cda2a30e0254942c3b4fc390
1 /**
2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
4 * @{
5 * @addtogroup AirspeedModule Airspeed Module
6 * @brief Communicate with airspeed sensors and return values
7 * @{
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
25 * for more details.
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
32 /**
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)
56 // Private types
58 // Private functions definitions
60 // Private variables
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)
66 uint16_t values[2];
68 // Read sensor
69 int8_t retVal = PIOS_MS4525DO_Read(values);
71 // check for errors
72 if (retVal != 0) {
73 airspeedSensor->SensorValue = -1;
74 airspeedSensor->SensorValueTemperature = -1;
75 airspeedSensor->SensorConnected = AIRSPEEDSENSOR_SENSORCONNECTED_FALSE;
76 airspeedSensor->CalibratedAirspeed = 0;
77 AirspeedAlarm(SYSTEMALARMS_ALARM_ERROR);
78 return;
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) {
88 calibrationCount++;
89 filter_reg = (airspeedSensor->SensorValue << FILTER_SHIFT);
90 AirspeedAlarm(SYSTEMALARMS_ALARM_WARNING);
91 return;
92 } else if (calibrationCount <= (CALIBRATION_IDLE_MS + CALIBRATION_COUNT_MS) / airspeedSettings->SamplePeriod) {
93 calibrationCount++;
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);
105 return;
109 /* Compute airspeed
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) */
137 * @}
138 * @}