OP-1900 added deceleration check to autotakeoff failsafe
[librepilot.git] / flight / modules / Airspeed / baro_airspeed_ms4525do.c
blob181f07c472ab2065f3a18c02366ed078fbf54b58
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"
44 #include "taskinfo.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)
57 // Private types
59 // Private functions definitions
61 // Private variables
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)
67 uint16_t values[2];
69 // Read sensor
70 int8_t retVal = PIOS_MS4525DO_Read(values);
72 // check for errors
73 if (retVal != 0) {
74 airspeedSensor->SensorValue = -1;
75 airspeedSensor->SensorValueTemperature = -1;
76 airspeedSensor->SensorConnected = AIRSPEEDSENSOR_SENSORCONNECTED_FALSE;
77 airspeedSensor->CalibratedAirspeed = 0;
78 AirspeedAlarm(SYSTEMALARMS_ALARM_ERROR);
79 return;
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) {
89 calibrationCount++;
90 filter_reg = (airspeedSensor->SensorValue << FILTER_SHIFT);
91 AirspeedAlarm(SYSTEMALARMS_ALARM_WARNING);
92 return;
93 } else if (calibrationCount <= (CALIBRATION_IDLE_MS + CALIBRATION_COUNT_MS) / airspeedSettings->SamplePeriod) {
94 calibrationCount++;
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);
106 return;
110 /* Compute airspeed
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) */
138 * @}
139 * @}