Battery Management Routines for the eXPal Prototype A. More...
#include "config.h"
#include <stdio.h>
#include "xpal_bat.h"
#include "adc.h"
#include "xpal_power.h"
#include "xpal_async32khz.h"
#include <avr/eeprom.h>
#include "../hlog/config-params.h"
Functions | |
uint8_t | hl_bat_GetBatStatus (void) |
Estimate the Battery condition and return the state for the. | |
uint16_t | hl_bat_slow (void *p) |
Slow Timer Call. | |
void | hl_InitBatMan (void) |
Init battery management system. | |
Variables | |
volatile uint8_t | BatStatus |
Battery status byte. | |
volatile uint16_t | BatVoltage |
voltage in mV | |
volatile int16_t | BatGradient |
voltage gradient in mV | |
volatile int16_t | BatGradientTimer |
Time periode where BatGradient is collected from [s]. | |
int8_t | adc_calibration = 80 |
ADC calibration value. |
Battery Management Routines for the eXPal Prototype A.
The battery voltage is measured one time per second. In parallel with this measurement, the differences compared to the previous second are accumulated. When this gradient reaches a certain value, the system is checking the time that went over to reach the limit value. The actual battery status and type is derrived from the parameters voltage and time to reach a certain voltage difference. This way, the system shows some adaptive behaviour, depending on the discharge speed.
The Power management will use the following measurement units for all calculations:
uint8_t hl_bat_GetBatStatus | ( | void | ) |
Estimate the Battery condition and return the state for the.
The battery voltage is evaluated to estimate the battery status
{ // return old value when no reevaluation event happened if((BatStatus & HL_BAT_UPDATE) == 0){ // return old value when no reevaluation event happened BatStatus &= ~(HL_BAT_NEWSTAT); }else{ // clear update state BatStatus &= ~(HL_BAT_UPDATE); // clear battery state BatStatus &= ~(HL_BAT_ST_MASK); if(BatVoltage >= HL_BAT_V_FOPMIN){ // we have enough power for full operation if (BatVoltage > HL_BAT_V_FOPMAX){ BatStatus |= HL_BAT_ST_FOPMAX; }else if(BatVoltage > HL_BAT_V_FOP4){ BatStatus |= HL_BAT_ST_FOP4; }else if(BatVoltage > HL_BAT_V_FOP3){ BatStatus |= HL_BAT_ST_FOP3; }else if(BatVoltage > HL_BAT_V_FOP2){ BatStatus |= HL_BAT_ST_FOP2; }else if(BatVoltage > HL_BAT_V_FOP1){ BatStatus |= HL_BAT_ST_FOP1; }else{ BatStatus |= HL_BAT_ST_FOPMIN; } }else{ // we are in limited op mode now if (BatVoltage > HL_BAT_V_LIM3){ BatStatus |= HL_BAT_ST_LIM3; }else if(BatVoltage > HL_BAT_V_LIM2){ BatStatus |= HL_BAT_ST_LIM2; }else if(BatVoltage > HL_BAT_V_LIM1){ BatStatus |= HL_BAT_ST_LIM1; }else if(BatVoltage > HL_BAT_V_EMPTY){ BatStatus |= HL_BAT_ST_LIM1; }else{ BatStatus |= HL_BAT_ST_EMPTY; } } // mark status as new value BatStatus |= HL_BAT_NEWSTAT; // !!!! debug printf("\n\r.%X %imV", BatStatus, BatVoltage); } // Evaluate discharge Gradient if(BatGradient < HL_BAT_MAX_VOLT_GRADIENT){ // Need to collect data on this value // useful code comming soon // !!!! debug printf(":%imV_%is \n\r", BatGradient, BatGradientTimer); BatGradientTimer = 1; BatGradient = 0; } return BatStatus; }
uint16_t hl_bat_slow | ( | void * | p | ) |
Slow Timer Call.
Do slow operations for power management:
{ if ((HL_PWR_ST_OFF & hl_pwr_GetState()) != HL_PWR_ST_OFF){ // If not in power off /* Evaluate last bat measurement */ BatGradient -= (BatVoltage & ~HL_BAT_MEASURE_ACTIVE) - (adc_calibration + hl_adc_convert(hl_adc_result ())); BatVoltage = adc_calibration + hl_adc_convert(hl_adc_result ()); // Do not count beyond max time value if (BatGradientTimer < HL_BAT_GRADIENT_COUNT_MAX){ BatGradientTimer++; } // Do only collect battery discharge for evaluation if (BatGradient > 0){ BatGradient = 0; // Battery is recovering, check for update BatStatus |= HL_BAT_UPDATE; } // Check Battery when timer is running over Zero for startup check if(BatGradientTimer == 0){ BatStatus |= HL_BAT_UPDATE; } // Check Battery when gradient exceeds threshold if (BatGradient < HL_BAT_MAX_VOLT_GRADIENT){ // Battery is recovering, check for update BatStatus |= HL_BAT_UPDATE; } /* Start new Bat voltage measurement */ hl_adc_init(); // hl_adc_select (adc_chan0); hl_adc_start (); } return 0; }
void hl_InitBatMan | ( | void | ) |
Init battery management system.
Initialize
This function needs to be called early in main(), before the 1s timer is running to ensure that there is an initial value for the battery voltage available
The init function will take some time to do the first measurement.
{ int8_t calvalue; BatVoltage = HL_BAT_VOLT_INVALID; BatGradient= 0; BatGradientTimer = HL_BAT_GRADIENT_COUNT_PON; // Start with low bat setting and activate update BatStatus = HL_BAT_ST_FOP1 & HL_BAT_UPDATE; // Start initial voltage measurement hl_adc_init(); // Do the initial measurement // This is required for the later gradient calculation hl_adc_StartNwait4conversion(); /* read calibration value from EEPROM */ calvalue = eeprom_read_byte (CFG_CALIB_BATT_VOLT); if (calvalue != 0xFF) adc_calibration = calvalue; BatVoltage = adc_calibration + hl_adc_convert(hl_adc_result ()); // register 1s timer call back hl_asyn_Register1sTimer( (&hl_bat_slow), NULL); }
int8_t adc_calibration = 80 |
ADC calibration value.
The calibration value is read from EEPROM during initialization. To get the corrected ADC output, use hl_adc_correct().
volatile int16_t BatGradientTimer |
Time periode where BatGradient is collected from [s].
BatGradient was collected over this time [s].