Paparazzi UAS  v5.15_devel-99-g2ff7410
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
battery_monitor.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2015 The Paparazzi Team
3  * 2017, Utah State University, http://aggieair.usu.edu/
4  * Michal Podhradsky, michal.podhradsky@aggiemail.usu.edu
5  *
6  * This file is part of paparazzi.
7  *
8  * paparazzi is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * paparazzi is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with paparazzi; see the file COPYING. If not, write to
20  * the Free Software Foundation, 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
29 
30 #if BATTERY_MONITOR_REV4
31 PRINT_CONFIG_MSG("Battery monitor: using older revision 4");
32 #endif /* BATTERY_MONITOR_REV4 */
33 
37 
38 // can be tuned via datalink
43 
44 #if PERIODIC_TELEMETRY
46 static void send_batmon(struct transport_tx *trans, struct link_device *dev)
47 {
48  static uint16_t power_status;
49 #if BATTERY_MONITOR_REV4
50  /* revision 4 */
51  static uint8_t version = 1;
52  power_status = 0; // no status
53 #else
54  /* revision 5 */
55  static uint8_t version = 2;
56  power_status = batmonbus.bus_tempsensors_mvolts[4]; // VIN7 has position 5 in temp map, hence index 4
57 #endif
58 
59  uint8_t batmonbus_bus_trans_status = batmonbus.bus_trans.status;
60  uint8_t batmonbal1_bus_trans_status = batmonbal1.bus_trans.status;
61  uint8_t batmonbal2_bus_trans_status = batmonbal2.bus_trans.status;
62  pprz_msg_send_BATTERY_MONITOR(trans, dev, AC_ID,
63  &version,
65  &batmonbus_bus_trans_status,
73  &batmonbal1_bus_trans_status,
76  &batmonbal2_bus_trans_status,
79  &power_status);
80 }
81 #endif
82 
92  if ((chan>8) || (chan<1)){ // sanity check
93  return 0x80;
94  }
95  static uint8_t adr[] = {0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0};
96  return adr[chan-1];
97 }
98 
103  // can be tuned via datalink
108 
109  // init Bus ADC
110  // transactions
112  batmonbus.addr = BATTERY_MONITOR_BUS_ADC_I2C_ADDR;
114  // Current readings
115  batmonbus.bus_current_mvolts = 0; // mV
116  batmonbus.bus_current = 0; // A
117  // Bus voltage readings
118  batmonbus.bus_voltage_mvolts = 0; //mV
119  // Temperature readings
120  batmonbus.bus_brd_tmp = 0; // C
122  memset(batmonbus.bus_temp, 0, sizeof(batmonbus.bus_temp));
123  batmonbus.t_idx = 0; // temp sensor index
124  batmonbus.data = 0;
125 }
126 
130 void battery_monitor_init_balance(struct BatMonBal* batmonbal){
131  batmonbal->bus_trans.status = I2CTransDone;
132  batmonbal->cell_index = 0;
133  memset(batmonbal->bat_cell_mvolts, 0, sizeof(batmonbal->bat_cell_mvolts));
134  batmonbal->data = 0;
135 }
136 
141  // bus ADC
143 
144  // balance 1 ADC
146  batmonbal1.addr = BATTERY_MONITOR_BALANCE_BAT1_ADC_I2C_ADDR;
147 
148  // balance 2 ADC
150  batmonbal2.addr = BATTERY_MONITOR_BALANCE_BAT2_ADC_I2C_ADDR;
151 
152 #if PERIODIC_TELEMETRY
153  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_BATTERY_MONITOR, send_batmon);
154 #endif
155 }
156 
165 }
166 
171  switch (t->status) {
172  case I2CTransPending:
173  // wait and do nothing
174  break;
175  case I2CTransRunning:
176  // wait and do nothing
177  break;
178  case I2CTransSuccess:
179  // set to done
180  t->status = I2CTransDone;
181  break;
182  case I2CTransFailed:
183  // set to done
184  t->status = I2CTransDone;
185  break;
186  case I2CTransDone:
187  // do nothing
188  break;
189  default:
190  break;
191  }
192 }
193 
198  batmonbus.data = 0; // erase at each iteration
199 
200  switch (batmonbus.bus_status) {
201  // reqtest BUS_CURRENT measurement
203  // set ADC to current channel
206  //set to zero so we can detect an error
208 
209  // non-blocking transaction
210  if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){
212  }
213  break;
214 
215  // read BUS_CURRENT data
218  // read data
220  // NOTE: we are not using the ALERT_FLAG at the moment,
221  // get counts
223  // shift right by 2 bits if 10-bit reads only
224  if (BATTERY_MONITOR_BIT_RES == 10){
226  }
227  // convert to mV
230  // convert to [A]
233  //update electrical subsystem
235 
236  // increment status
238  }
239  break;
240 
241  // request voltage data
243  // set ADC to voltage channel
246  //set to zero so we can detect an error
248 
249  // non-blocking transaction
250  if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){
252  }
253  break;
254 
255  // read voltage data
258  // read data
260  // NOTE: we are not using the ALERT_FLAG at the moment,
261  // get counts
263  // shift right by 2 bits if 10-bit reads only
264  if (BATTERY_MONITOR_BIT_RES == 10){
266  }
267  // convert to mV
270  // convert to actual voltage
273 
274  //update electrical subsystem
275  if (batmonbus.bus_voltage_mvolts != 0) {
276  electrical.vsupply = (float)(batmonbus.bus_voltage_mvolts) / 1000.f;
277  }
278  else {
279  electrical.vsupply = 0.f;
280  }
281 
282  // update status
284  }
285  break;
286 
287  // request temperature data
289  // set ADC to correct temperature channel
292  //set to zero so we can detect an error
294 
295  // non-blocking transaction
296  if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){
298  }
299  break;
300 
301  // read temperature data
304  // read data
306  // NOTE: we are not using the ALERT_FLAG at the moment,
307  // get counts
309  // shift right by 2 bits if 10-bit reads only
310  if (BATTERY_MONITOR_BIT_RES == 10){
313  }
314  // convert to mV
317  // convert to temperature[C]
321  // increment counter
322  batmonbus.t_idx++;
324  batmonbus.t_idx = 0;
326  }
327  }
328  break;
329  default:
330  // a recovery in case of a glitch
332  break;
333  }
334 }
335 
336 
342 }
343 
349 }
350 
355  // non-blocking transaction
356  // if transaction is done, request another measurement
357  // NOTE: optionally add startup delay, but it shouldn't be necessary
358  if (batmonbal->bus_trans.status == I2CTransDone) {
359  // read data first (worst case we get some zeros)
360  batmonbal->data = (uint16_t) (batmonbal->bus_trans.buf[0] << 8 | batmonbal->bus_trans.buf[1]);
361  // NOTE: we are not using the ALERT_FLAG at the moment,
362  // get counts
363  batmonbal->bat_cell_mvolts[batmonbal->cell_index] = batmonbal->data & 0xFFF;
364  // shift right by 2 bits if 10-bit reads only
365  if (BATTERY_MONITOR_BIT_RES == 10){
366  batmonbal->bat_cell_mvolts[batmonbal->cell_index] =
367  (batmonbal->bat_cell_mvolts[batmonbal->cell_index]) >> 2;
368  }
369  // convert to mV
370  batmonbal->bat_cell_mvolts[batmonbal->cell_index] =
371  (uint16_t)((float)batmonbal->bat_cell_mvolts[batmonbal->cell_index] * BATTERY_MONITOR_VREF_MULT);
372  // convert to actual voltage
373  // we get the multiplier from battery_monitor_cellgains array, which contains multipliers
374  // for cells 1-6(in this order) battery_monitor_cellgains[0] gives us multiplier for cell_1
375  // and so on
376  batmonbal->bat_cell_mvolts[batmonbal->cell_index] =
377  (uint16_t)((float)batmonbal->bat_cell_mvolts[batmonbal->cell_index] *
379 
380  // increment counter
381  batmonbal->cell_index++;
382  if (batmonbal->cell_index == BATTERY_CELLS_NB) {
383  batmonbal->cell_index = 0;
384  }
385 
386  // erase data
387  batmonbal->data = 0; // erase at each iteration
388 
389  //set to zero so we can detect an error
390  batmonbal->bat_cell_mvolts[batmonbal->cell_index] = 0;
391 
392  // set the right address into ADC
393  // cell_index is the number of the cell we want to probe
394  // battery_monitor_cellmap1 contains the mapping of channels for given cell number
395  // i.e. Cell_1 (cell_idx = 0) has channel 2
396  // this gets translated into hexadecimal number representing the channel internally
397  batmonbal->bus_trans.buf[0] =
399 
400  // request more data
401  i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbal->bus_trans, batmonbal->addr, 1, 2);
402  }
403 }
unsigned short uint16_t
Definition: types.h:16
#define BATTERY_MONITOR_CURRENT_SENSITIVITY
uint16_t data
void battery_monitor_check_i2c_transaction(struct i2c_transaction *t)
Complete i2c transactions once they succeed or fail.
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
float batmon_current_sensitivity
void battery_monitor_init(void)
Init variables.
transaction successfully finished by I2C driver
Definition: i2c.h:57
struct BatMonBus batmonbus
struct i2c_transaction bus_trans
Periodic telemetry system header (includes downlink utility and generated code).
struct BatMonBal batmonbal2
float bus_current
float bus_temp[TEMP_SENSORS_NB]
float batmon_temp_sensitivity
uint8_t t_idx
float vsupply
supply voltage in V
Definition: electrical.h:45
void battery_monitor_read_balance_ports(struct BatMonBal *batmonbal)
Read balance ADC.
static const float battery_monitor_cellgains[]
void battery_monitor_event(void)
Event function Check i2c transaction status for each device.
Battery monitor Bus ADC struct.
Battery monitor Balance ADC struct.
uint8_t battery_monitor_get_address(uint8_t chan)
Translates the channel number to the value for address pointer register Channels are numbered from 1 ...
uint16_t data
uint16_t bus_current_mvolts
uint16_t bus_voltage_mvolts
enum BatmonBusStatus bus_status
#define BATTERY_MONITOR_VREF_MULT
int16_t batmon_temp_offset
transaction set to done by user level
Definition: i2c.h:59
uint8_t addr
driver for ADC AD7997 on a custom made power board version 4.0 and 5.0
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
signed short int16_t
Definition: types.h:17
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
void battery_monitor_read_balance_ports_2(void)
Read Balance ADC 2.
transaction failed
Definition: i2c.h:58
struct BatMonBal batmonbal1
#define BATTERY_CELLS_NB
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition: i2c.c:328
uint16_t bat_cell_mvolts[BATTERY_CELLS_NB]
I2C transaction structure.
Definition: i2c.h:93
int16_t batmon_current_offset
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
void battery_monitor_read_balance_ports_1(void)
Read Balance ADC 1.
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:73
float bus_brd_tmp
static void send_batmon(struct transport_tx *trans, struct link_device *dev)
void battery_monitor_init_bus(void)
Initializes bus ADC.
#define BATTERY_MONITOR_TEMP_OFFSET
unsigned char uint8_t
Definition: types.h:14
uint8_t addr
#define BATTERY_MONITOR_BUS_CURRENT_CHANNEL
static const uint8_t battery_monitor_tempmap[]
#define BATTERY_MONITOR_BIT_RES
transaction is currently ongoing
Definition: i2c.h:56
static const uint8_t battery_monitor_cellmap[]
Cell map - which cell is which channel Channels are 1-indexed, ie.e.
#define BATTERY_MONITOR_CURRENT_OFFSET
#define BATTERY_MONITOR_TEMP_SENSITIVITY
#define TEMP_SENSORS_NB
void battery_monitor_init_balance(struct BatMonBal *batmonbal)
Initalizes balance ADC.
struct Electrical electrical
Definition: electrical.c:66
uint8_t cell_index
static const float BatmonVbusGain
struct i2c_transaction bus_trans
float current
current in A
Definition: electrical.h:46
#define BATTERY_MONITOR_BUS_VOLTAGE_CHANNEL
transaction is pending in queue
Definition: i2c.h:55
void battery_monitor_read_bus(void)
Read bus (current, voltage and temperature sensors)
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:46
uint16_t bus_tempsensors_mvolts[TEMP_SENSORS_NB]