1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

Merge branch 'amorale/OP-994_adc_cleanup' into next

This commit is contained in:
Alessio Morale 2013-07-16 12:23:25 +00:00
commit 11bc7804d0
16 changed files with 133 additions and 45 deletions

View File

@ -123,31 +123,30 @@ int32_t BatteryInitialize(void)
}
MODULE_INITCALL(BatteryInitialize, 0);
#define HAS_SENSOR(x) batterySettings.SensorType[x] == FLIGHTBATTERYSETTINGS_SENSORTYPE_ENABLED
static void onTimer(__attribute__((unused)) UAVObjEvent *ev)
{
static FlightBatteryStateData flightBatteryData;
FlightBatterySettingsData batterySettings;
static FlightBatterySettingsData batterySettings;
FlightBatterySettingsGet(&batterySettings);
static float dT = SAMPLE_PERIOD_MS / 1000.0f;
const float dT = SAMPLE_PERIOD_MS / 1000.0f;
float energyRemaining;
// calculate the battery parameters
if (voltageADCPin >= 0) {
flightBatteryData.Voltage = ((float)PIOS_ADC_PinGet(voltageADCPin)) * batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_VOLTAGEFACTOR]; // in Volts
flightBatteryData.Voltage = (PIOS_ADC_PinGetVolt(voltageADCPin) - batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_VOLTAGEZERO]) * batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_VOLTAGEFACTOR]; // in Volts
} else {
flightBatteryData.Voltage = 1234; // Dummy placeholder value. This is in case we get another source of battery current which is not from the ADC
flightBatteryData.Voltage = 0; // Dummy placeholder value. This is in case we get another source of battery current which is not from the ADC
}
if (currentADCPin >= 0) {
flightBatteryData.Current = ((float)PIOS_ADC_PinGet(currentADCPin)) * batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_CURRENTFACTOR]; // in Amps
flightBatteryData.Current = (PIOS_ADC_PinGetVolt(currentADCPin) - batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_CURRENTZERO]) * batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_CURRENTFACTOR]; // in Amps
if (flightBatteryData.Current > flightBatteryData.PeakCurrent) {
flightBatteryData.PeakCurrent = flightBatteryData.Current; // in Amps
}
} else { // If there's no current measurement, we still need to assign one. Make it negative, so it can never trigger an alarm
flightBatteryData.Current = -0.1234f; // Dummy placeholder value. This is in case we get another source of battery current which is not from the ADC
flightBatteryData.Current = -0; // Dummy placeholder value. This is in case we get another source of battery current which is not from the ADC
}
flightBatteryData.ConsumedEnergy += (flightBatteryData.Current * dT * 1000.0f / 3600.0f); // in mAh
@ -160,16 +159,11 @@ static void onTimer(__attribute__((unused)) UAVObjEvent *ev)
In short, is there any likelihood of measuring negative current? If it's a bad current reading we want to check, then
it makes sense to saturate at max and min values, because a misreading could as easily be very large, as negative. The simple
sign check doesn't catch this.*/
////sanity checks
// if (flightBatteryData.AvgCurrent<0) flightBatteryData.AvgCurrent=0.0f;
// if (flightBatteryData.PeakCurrent<0) flightBatteryData.PeakCurrent=0.0f;
// if (flightBatteryData.ConsumedEnergy<0) flightBatteryData.ConsumedEnergy=0.0f;
energyRemaining = batterySettings.Capacity - flightBatteryData.ConsumedEnergy; // in mAh
if (flightBatteryData.AvgCurrent > 0) {
if (batterySettings.Capacity > 0 && flightBatteryData.AvgCurrent > 0) {
flightBatteryData.EstimatedFlightTime = (energyRemaining / (flightBatteryData.AvgCurrent * 1000.0f)) * 3600.0f; // in Sec
} else {
flightBatteryData.EstimatedFlightTime = 9999;
flightBatteryData.EstimatedFlightTime = 0;
}
// generate alarms where needed...
@ -180,9 +174,9 @@ static void onTimer(__attribute__((unused)) UAVObjEvent *ev)
AlarmsSet(SYSTEMALARMS_ALARM_FLIGHTTIME, SYSTEMALARMS_ALARM_ERROR);
} else {
// FIXME: should make the timer alarms user configurable
if (flightBatteryData.EstimatedFlightTime < 30) {
if (batterySettings.Capacity > 0 && flightBatteryData.EstimatedFlightTime < 30) {
AlarmsSet(SYSTEMALARMS_ALARM_FLIGHTTIME, SYSTEMALARMS_ALARM_CRITICAL);
} else if (flightBatteryData.EstimatedFlightTime < 120) {
} else if (batterySettings.Capacity > 0 && flightBatteryData.EstimatedFlightTime < 120) {
AlarmsSet(SYSTEMALARMS_ALARM_FLIGHTTIME, SYSTEMALARMS_ALARM_WARNING);
} else {
AlarmsClear(SYSTEMALARMS_ALARM_FLIGHTTIME);
@ -190,9 +184,9 @@ static void onTimer(__attribute__((unused)) UAVObjEvent *ev)
// FIXME: should make the battery voltage detection dependent on battery type.
/*Not so sure. Some users will want to run their batteries harder than others, so it should be the user's choice. [KDS]*/
if (flightBatteryData.Voltage < batterySettings.VoltageThresholds[FLIGHTBATTERYSETTINGS_VOLTAGETHRESHOLDS_ALARM]) {
if (flightBatteryData.Voltage < batterySettings.CellVoltageThresholds[FLIGHTBATTERYSETTINGS_CELLVOLTAGETHRESHOLDS_ALARM] * batterySettings.NbCells) {
AlarmsSet(SYSTEMALARMS_ALARM_BATTERY, SYSTEMALARMS_ALARM_CRITICAL);
} else if (flightBatteryData.Voltage < batterySettings.VoltageThresholds[FLIGHTBATTERYSETTINGS_VOLTAGETHRESHOLDS_WARNING]) {
} else if (flightBatteryData.Voltage < batterySettings.CellVoltageThresholds[FLIGHTBATTERYSETTINGS_CELLVOLTAGETHRESHOLDS_WARNING] * batterySettings.NbCells) {
AlarmsSet(SYSTEMALARMS_ALARM_BATTERY, SYSTEMALARMS_ALARM_WARNING);
} else {
AlarmsClear(SYSTEMALARMS_ALARM_BATTERY);

View File

@ -545,19 +545,9 @@ static void updateStats()
} // else: TickCount has wrapped, do not calc now
lastTickCount = now;
idleCounterClear = 1;
#if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR)
#if defined(STM32F4XX)
float temp_voltage = 3.3f * PIOS_ADC_PinGet(3) / ((1 << 12) - 1);
const float STM32_TEMP_V25 = 0.76f; /* V */
const float STM32_TEMP_AVG_SLOPE = 2.5f; /* mV/C */
stats.CPUTemp = (temp_voltage - STM32_TEMP_V25) * 1000.0f / STM32_TEMP_AVG_SLOPE + 25.0f;
#else
float temp_voltage = 3.3f * PIOS_ADC_PinGet(0) / ((1 << 12) - 1);
const float STM32_TEMP_V25 = 1.43f; /* V */
const float STM32_TEMP_AVG_SLOPE = 4.3f; /* mV/C */
stats.CPUTemp = (temp_voltage - STM32_TEMP_V25) * 1000.0f / STM32_TEMP_AVG_SLOPE + 25.0f;
#endif
float temp_voltage = PIOS_ADC_PinGetVolt(PIOS_ADC_TEMPERATURE_PIN);
stats.CPUTemp = PIOS_CONVERT_VOLT_TO_CPU_TEMP(temp_voltage);;
#endif
SystemStatsSet(&stats);
}

View File

@ -39,6 +39,7 @@ typedef void (*ADCCallback)(float *data);
/* Public Functions */
void PIOS_ADC_Config(uint32_t oversampling);
int32_t PIOS_ADC_PinGet(uint32_t pin);
float PIOS_ADC_PinGetVolt(uint32_t pin);
int16_t *PIOS_ADC_GetRawBuffer(void);
uint8_t PIOS_ADC_GetOverSampling(void);
void PIOS_ADC_SetCallback(ADCCallback new_function);

View File

@ -81,6 +81,8 @@
#include "semphr.h"
#endif
#include <pios_architecture.h>
#ifdef PIOS_INCLUDE_TASK_MONITOR
#ifndef PIOS_INCLUDE_FREERTOS
#error PiOS Task Monitor requires PIOS_INCLUDE_FREERTOS to be defined

View File

@ -0,0 +1,39 @@
/**
******************************************************************************
*
* @file pios_architecture.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief Architecture specific macros and definitions
* --
* @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
*/
#ifndef PIOS_ARCHITECTURE_H
#define PIOS_ARCHITECTURE_H
// defines for adc
#define PIOS_ADC_VOLTAGE_SCALE 3.30f / 4096.0f
// defines for Temp measurements
#define PIOS_ADC_STM32_TEMP_V25 1.43f /* V */
#define PIOS_ADC_STM32_TEMP_AVG_SLOPE 4.3f /* mV/C */
#define PIOS_CONVERT_VOLT_TO_CPU_TEMP(x) ((PIOS_ADC_STM32_TEMP_V25 - x) * 1000.0f / PIOS_ADC_STM32_TEMP_AVG_SLOPE + 25.0f)
#endif /* PIOS_ARCHITECTURE_H */

View File

@ -20,6 +20,7 @@ ASRC += $(PIOS_DEVLIB)startup_stm32f10x_$(MODEL)$(MODEL_SUFFIX).S
# PIOS device library source and includes
SRC += $(sort $(wildcard $(PIOS_DEVLIB)*.c))
EXTRAINCDIRS += $(PIOS_DEVLIB)inc
# CMSIS for the F1
include $(PIOSCOMMON)/libraries/CMSIS/library.mk

View File

@ -57,6 +57,11 @@ struct pios_adc_dev {
enum pios_adc_dev_magic magic;
};
float PIOS_ADC_PinGetVolt(uint32_t pin)
{
return ((float)PIOS_ADC_PinGet(pin)) * PIOS_ADC_VOLTAGE_SCALE;
}
#if defined(PIOS_INCLUDE_FREERTOS)
struct pios_adc_dev *pios_adc_dev;
#endif

View File

@ -0,0 +1,39 @@
/**
******************************************************************************
*
* @file pios_architecture.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief Architecture specific macros and definitions
* --
* @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
*/
#ifndef PIOS_ARCHITECTURE_H
#define PIOS_ARCHITECTURE_H
// defines for adc
#define PIOS_ADC_VOLTAGE_SCALE 3.30f / 4096.0f
// defines for Temp measurements
#define PIOS_ADC_STM32_TEMP_V25 0.76f /* V */
#define PIOS_ADC_STM32_TEMP_AVG_SLOPE 2.5f /* mV/C */
#define PIOS_CONVERT_VOLT_TO_CPU_TEMP(x) ((x - PIOS_ADC_STM32_TEMP_V25) * 1000.0f / PIOS_ADC_STM32_TEMP_AVG_SLOPE + 25.0f)
#endif /* PIOS_ARCHITECTURE_H */

View File

@ -128,8 +128,7 @@ static void init_pins(void)
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
for (uint32_t i = 0; i < PIOS_ADC_NUM_PINS; ++i) {
if (config[i].port == NULL) {
continue;
@ -325,6 +324,11 @@ int32_t PIOS_ADC_PinGet(uint32_t pin)
return -1;
}
float PIOS_ADC_PinGetVolt(uint32_t pin)
{
return ((float)PIOS_ADC_PinGet(pin)) * PIOS_ADC_VOLTAGE_SCALE;
}
/**
* @brief Set a callback function that is executed whenever
* the ADC double buffer swaps

View File

@ -25,7 +25,6 @@
#ifndef PIOS_BOARD_H
#define PIOS_BOARD_H
// ------------------------
// Timers and Channels Used
// ------------------------
@ -213,6 +212,8 @@ extern uint32_t pios_com_hkosd_id;
#define PIOS_ADC_RATE (72.0e6f / 1.0f / 8.0f / 252.0f / (PIOS_ADC_NUM_CHANNELS >> PIOS_ADC_USE_ADC2))
#define PIOS_ADC_MAX_OVERSAMPLING 36
#define PIOS_ADC_TEMPERATURE_PIN 0
// ------------------------
// PIOS_RCVR
// See also pios_board.c

View File

@ -25,7 +25,6 @@
#ifndef PIOS_BOARD_H
#define PIOS_BOARD_H
#define ADD_ONE_ADC
// ------------------------
@ -235,6 +234,8 @@ extern uint32_t pios_ppm_out_id;
#define PIOS_ADC_RATE (72.0e6 / 1.0 / 8.0 / 252.0 / (PIOS_ADC_NUM_CHANNELS >> PIOS_ADC_USE_ADC2))
#define PIOS_ADC_MAX_OVERSAMPLING 36
#define PIOS_ADC_TEMPERATURE_PIN 0
// ------------------------
// PIOS_RCVR
// See also pios_board.c

View File

@ -223,7 +223,10 @@ extern uint32_t pios_com_telem_usb_id;
#define PIOS_ADC_NUM_CHANNELS 7
#define PIOS_ADC_MAX_OVERSAMPLING 10
#define PIOS_ADC_USE_ADC2 0
#define PIOS_ADC_USE_TEMP_SENSOR 1
#define PIOS_ADC_USE_TEMP_SENSOR
#define PIOS_ADC_TEMPERATURE_PIN 6 /* V */
// *****************************************************************
// USB

View File

@ -908,6 +908,16 @@ void PIOS_Board_Init(void)
PIOS_DEBUG_Init(pios_tim_servoport_all_pins, NELEMENTS(pios_tim_servoport_all_pins));
#endif
// Disable GPIO_A8 Pullup to prevent wrong results on battery voltage readout
GPIO_InitTypeDef gpioA8 = {
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_IN,
.GPIO_PuPd = GPIO_PuPd_NOPULL,
.GPIO_Pin = GPIO_Pin_8,
.GPIO_OType = GPIO_OType_OD,
};
GPIO_Init(GPIOA, &gpioA8);
if (PIOS_I2C_Init(&pios_i2c_mag_pressure_adapter_id, &pios_i2c_mag_pressure_adapter_cfg)) {
PIOS_DEBUG_Assert(0);
}

View File

@ -30,7 +30,6 @@
#define PIOS_BOARD_H
#include <stdbool.h>
// ------------------------
// Timers and Channels Used
// ------------------------
@ -293,8 +292,9 @@ extern uint32_t pios_packet_handler;
#define PIOS_ADC_NUM_CHANNELS 4
#define PIOS_ADC_MAX_OVERSAMPLING 2
#define PIOS_ADC_USE_ADC2 0
#define PIOS_ADC_VOLTAGE_SCALE 3.30f / 4096.0f
#define PIOS_ADC_USE_TEMP_SENSOR 1
#define PIOS_ADC_USE_TEMP_SENSOR
#define PIOS_ADC_TEMPERATURE_PIN 3
// -------------------------
// USB

View File

@ -254,8 +254,9 @@ extern uint32_t pios_com_hkosd_id;
#define PIOS_ADC_NUM_CHANNELS 4
#define PIOS_ADC_MAX_OVERSAMPLING 2
#define PIOS_ADC_USE_ADC2 0
#define PIOS_ADC_VOLTAGE_SCALE 3.30f / 4096.0f
#define PIOS_ADC_USE_TEMP_SENSOR 1
#define PIOS_ADC_USE_TEMP_SENSOR
#define PIOS_ADC_TEMPERATURE_PIN 3 /* V */
// -------------------------
// USB

View File

@ -6,11 +6,8 @@
<field name="NbCells" units="" type="uint8" elements="1" defaultvalue="3"/>
<field name="Capacity" units="mAh" type="uint32" elements="1" defaultvalue="2200"/>
<field name="VoltageThresholds" units="V" type="float" elementnames="Warning, Alarm" defaultvalue="9.8, 9.2"/>
<field name="SensorType" units="" type="enum" elementnames="BatteryCurrent,BatteryVoltage" options="Disabled,Enabled" defaultvalue="Enabled,Enabled"/>
<field name="SensorCalibrations" units="" type="float" elementnames="VoltageFactor, CurrentFactor" defaultvalue="1.0, 1.0"/>
<field name="CellVoltageThresholds" units="V" type="float" elementnames="Warning, Alarm" defaultvalue="3.4,3.1"/>
<field name="SensorCalibrations" units="" type="float" elementnames="VoltageFactor, CurrentFactor, VoltageZero, CurrentZero" defaultvalue="1.0, 1.0, 0.0, 0.0"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>