Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
electrical.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010-2013 The Paparazzi Team
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
28 #include "subsystems/electrical.h"
29 
30 #include "mcu_periph/adc.h"
31 #include "subsystems/commands.h"
32 
33 #include "generated/airframe.h"
34 #include BOARD_CONFIG
35 
36 #ifdef MILLIAMP_PER_PERCENT
37 #warning "deprecated MILLIAMP_PER_PERCENT --> Please use MILLIAMP_AT_FULL_THROTTLE"
38 #endif
39 #if defined BATTERY_SENS || defined BATTERY_OFFSET
40 #warning "BATTERY_SENS and BATTERY_OFFSET are deprecated, please remove them --> if you want to change the default use VoltageOfAdc"
41 #endif
42 
43 #if defined COMMAND_THROTTLE
44 #define COMMAND_CURRENT_ESTIMATION COMMAND_THROTTLE
45 #elif defined COMMAND_THRUST
46 #define COMMAND_CURRENT_ESTIMATION COMMAND_THRUST
47 #endif
48 
49 #ifndef BAT_CHECKER_DELAY
50 #define BAT_CHECKER_DELAY 5
51 #endif
52 
53 #define ELECTRICAL_PERIODIC_FREQ 10
54 
55 #ifndef MIN_BAT_LEVEL
56 #define MIN_BAT_LEVEL 3
57 #endif
58 
62 
64 
65 #if defined ADC_CHANNEL_VSUPPLY || defined ADC_CHANNEL_CURRENT || defined MILLIAMP_AT_FULL_THROTTLE
66 static struct {
67 #ifdef ADC_CHANNEL_VSUPPLY
68  struct adc_buf vsupply_adc_buf;
69 #endif
70 #ifdef ADC_CHANNEL_CURRENT
71  struct adc_buf current_adc_buf;
72 #endif
73 #ifdef MILLIAMP_AT_FULL_THROTTLE
74  float nonlin_factor;
75 #endif
76 } electrical_priv;
77 #endif
78 
79 #ifndef VoltageOfAdc
80 #define VoltageOfAdc(adc) DefaultVoltageOfAdc(adc)
81 #endif
82 #ifndef MilliAmpereOfAdc
83 #define MilliAmpereOfAdc(adc) DefaultMilliAmpereOfAdc(adc)
84 #endif
85 
86 #ifndef CURRENT_ESTIMATION_NONLINEARITY
87 #define CURRENT_ESTIMATION_NONLINEARITY 1.2
88 #endif
89 
90 void electrical_init(void) {
91  electrical.vsupply = 0;
92  electrical.current = 0;
93  electrical.energy = 0;
94 
95  electrical.bat_low = FALSE;
96  electrical.bat_critical = FALSE;
97 
98 #if defined ADC_CHANNEL_VSUPPLY
99  adc_buf_channel(ADC_CHANNEL_VSUPPLY, &electrical_priv.vsupply_adc_buf, DEFAULT_AV_NB_SAMPLE);
100 #endif
101 
102  /* measure current if available, otherwise estimate it */
103 #if defined ADC_CHANNEL_CURRENT && !defined SITL
104  adc_buf_channel(ADC_CHANNEL_CURRENT, &electrical_priv.current_adc_buf, DEFAULT_AV_NB_SAMPLE);
105 #elif defined MILLIAMP_AT_FULL_THROTTLE
107  electrical_priv.nonlin_factor = CURRENT_ESTIMATION_NONLINEARITY;
108 #endif
109 }
110 
112  static uint32_t bat_low_counter = 0;
113  static uint32_t bat_critical_counter = 0;
114  static bool_t vsupply_check_started = FALSE;
115 
116 #if defined(ADC_CHANNEL_VSUPPLY) && !defined(SITL)
117  electrical.vsupply = 10 * VoltageOfAdc((electrical_priv.vsupply_adc_buf.sum/electrical_priv.vsupply_adc_buf.av_nb_sample));
118 #endif
119 
120 #ifdef ADC_CHANNEL_CURRENT
121 #ifndef SITL
122  int32_t current_adc = electrical_priv.current_adc_buf.sum/electrical_priv.current_adc_buf.av_nb_sample;
123  electrical.current = MilliAmpereOfAdc(current_adc);
124  /* Prevent an overflow on high current spikes when using the motor brake */
125  BoundAbs(electrical.current, 65000);
126 #endif
127 #elif defined MILLIAMP_AT_FULL_THROTTLE && defined COMMAND_CURRENT_ESTIMATION
128  /*
129  * Superellipse: abs(x/a)^n + abs(y/b)^n = 1
130  * with a = 1
131  * b = mA at full throttle
132  * n = 1.2 This defines nonlinearity (1 = linear)
133  * x = throttle
134  * y = current
135  *
136  * define CURRENT_ESTIMATION_NONLINEARITY in your airframe file to change the default nonlinearity factor of 1.2
137  */
138  float b = (float)MILLIAMP_AT_FULL_THROTTLE;
139  float x = ((float)commands[COMMAND_CURRENT_ESTIMATION]) / ((float)MAX_PPRZ);
140  /* electrical.current y = ( b^n - (b* x/a)^n )^1/n
141  * a=1, n = electrical_priv.nonlin_factor
142  */
143  electrical.current = b - pow((pow(b,electrical_priv.nonlin_factor)-pow((b*x),electrical_priv.nonlin_factor)), (1./electrical_priv.nonlin_factor));
144 #endif /* ADC_CHANNEL_CURRENT */
145 
146  // mAh = mA * dt (10Hz -> hours)
147  electrical.energy += ((float)electrical.current) / 3600.0f / ELECTRICAL_PERIODIC_FREQ;
148 
149  /*if valid voltage is seen then start checking. Set min level to 0 to always start*/
150  if (electrical.vsupply >= MIN_BAT_LEVEL * 10) {
151  vsupply_check_started = TRUE;
152  }
153 
154  if (vsupply_check_started) {
155  if (electrical.vsupply < LOW_BAT_LEVEL * 10) {
156  if (bat_low_counter > 0)
157  bat_low_counter--;
158  if (bat_low_counter == 0)
159  electrical.bat_low = TRUE;
160  }
161  else {
162  // reset battery low status and counter
163  bat_low_counter = BAT_CHECKER_DELAY * ELECTRICAL_PERIODIC_FREQ;
164  electrical.bat_low = FALSE;
165  }
166 
167  if (electrical.vsupply < CRITIC_BAT_LEVEL * 10) {
168  if (bat_critical_counter > 0)
169  bat_critical_counter--;
170  if (bat_critical_counter == 0)
171  electrical.bat_critical = TRUE;
172  }
173  else {
174  // reset battery critical status and counter
175  bat_critical_counter = BAT_CHECKER_DELAY * ELECTRICAL_PERIODIC_FREQ;
176  electrical.bat_critical = FALSE;
177  }
178  }
179 
180 }
bool_t bat_critical
battery critical status
Definition: electrical.h:53
void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
Registers a buffer to be used to store the specified converted channel Usage:
Definition: adc_arch.c:59
#define LOW_BAT_LEVEL
low battery level in Volts (for 3S LiPo)
Definition: electrical.h:36
float energy
consumed energy in mAh
Definition: electrical.h:51
uint16_t vsupply
supply voltage in decivolts
Definition: electrical.h:48
#define VoltageOfAdc(adc)
Definition: electrical.c:80
#define MIN_BAT_LEVEL
Definition: electrical.c:56
arch independent ADC (Analog to Digital Converter) API
#define ADC_CHANNEL_VSUPPLY
Definition: apogee_0.99.h:115
#define FALSE
Definition: imu_chimu.h:141
#define MilliAmpereOfAdc(adc)
Definition: electrical.c:83
void electrical_init(void)
Definition: electrical.c:90
Interface for electrical status: supply voltage, current, battery status, etc.
#define BAT_CHECKER_DELAY
Definition: electrical.c:50
#define ELECTRICAL_PERIODIC_FREQ
Definition: electrical.c:53
Generic interface for all ADC hardware drivers, independent from microcontroller architecture.
Definition: adc.h:53
unsigned long uint32_t
Definition: types.h:18
Hardware independent code for commands handling.
signed long int32_t
Definition: types.h:19
#define TRUE
Definition: imu_chimu.h:144
void electrical_periodic(void)
Definition: electrical.c:111
int32_t current
current in milliamps
Definition: electrical.h:49
pprz_t commands[COMMANDS_NB]
Storage of intermediate command values.
Definition: commands.c:30
#define CURRENT_ESTIMATION_NONLINEARITY
Definition: electrical.c:87
#define DEFAULT_AV_NB_SAMPLE
Definition: adc.h:41
struct Electrical electrical
Definition: electrical.c:63
#define MAX_PPRZ
Definition: paparazzi.h:8
#define CRITIC_BAT_LEVEL
critical battery level in Volts (for 3S LiPo)
Definition: electrical.h:42
bool_t bat_low
battery low status
Definition: electrical.h:52