/** ****************************************************************************** * @addtogroup PIOS PIOS Core hardware abstraction layer * @{ * @addtogroup PIOS_MPXV5004 MPXV5004 Functions * @brief Hardware functions to deal with the DIYDrones airspeed kit, using MPXV5004. * This is a differential sensor, so the value returned is first converted into * calibrated airspeed, using http://en.wikipedia.org/wiki/Calibrated_airspeed * @{ * * @file pios_mpxv5004.h * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. * @brief ETASV3 Airspeed Sensor Driver * @see The GNU Public License (GPL) Version 3 * ******************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Project Includes */ #include "pios.h" #if defined(PIOS_INCLUDE_MPXV5004) #include "pios_mpxv5004.h" static uint32_t calibrationSum = 0; //static? static int16_t calibrationOffset; //static? /* * Reads ADC. */ uint16_t PIOS_MPXV5004_Measure(uint8_t airspeedADCPin) { return PIOS_ADC_PinGet(airspeedADCPin); } /* *Returns zeroPoint so that the user can inspect the calibration vs. the sensor value */ uint16_t PIOS_MPXV5004_Calibrate(uint8_t airspeedADCPin, uint16_t calibrationCount){ calibrationSum += PIOS_MPXV5004_Measure(airspeedADCPin); uint16_t zeroPoint = (uint16_t)(((float)calibrationSum) / calibrationCount + 0.5f); calibrationOffset = zeroPoint - (int16_t)(1.0f/3.3f*4096.0f+0.5f); //The offset should set the zero point to 1.0V return zeroPoint; } /* * Updates the calibration when zero point is manually set by user. */ void PIOS_MPXV5004_UpdateCalibration(uint16_t zeroPoint){ calibrationOffset = zeroPoint - (int16_t)(1.0f/3.3f*4096.0f+0.5f); //The offset should set the zero point to 1.0V } /* * Reads the airspeed and returns CAS (calibrated airspeed) in the case of success. * In the case of a failed read, returns -1. */ float PIOS_MPXV5004_ReadAirspeed(uint8_t airspeedADCPin) { float sensorVal = PIOS_MPXV5004_Measure(airspeedADCPin); //Calculate dynamic pressure, as per docs float Qc = 5.0f*(((sensorVal - calibrationOffset)/4096.0f*3.3f)/VCC - 0.2f); //Saturate Qc on the lower bound, in order to make sure we don't have negative airspeeds. No need // to saturate on the upper bound, we'll handle that later with calibratedAirspeed. if (Qc < 0) { Qc=0; } //Compute calibraterd airspeed, as per http://en.wikipedia.org/wiki/Calibrated_airspeed float calibratedAirspeed = A0*sqrt(5.0f*(pow(Qc/P0+1.0f,POWER)-1.0f)); //Upper bound airspeed. No need to lower bound it, that comes from Qc if (calibratedAirspeed > 80) { //in [m/s] calibratedAirspeed=80; } return calibratedAirspeed; } #endif /* PIOS_INCLUDE_MPXV5004 */