diff --git a/README.md b/README.md index 042d984..f3ec56d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ Power controller for solar powered personal cloud ================================================= -This firmware is intended to control the charging of a battery bank that -powers a small computer cluster running a private cloud system. The -idea is to try to keep the battery within a small range of voltages, -charging from solar or mains based chargers as necessary to top the -battery back up. +This firmware is intended to control the charging of a battery bank that powers +a small computer cluster running a private cloud system. The system has two +charging sources: mains power and solar power. + +The chargers are assumed to have a logic-level signal which, when pulled low, +shuts down the relevant charger. Circuit description ------------------- @@ -13,20 +14,22 @@ Circuit description An ATTiny24A microcontroller runs from a 5V rail derived from the battery. It uses its internal RC oscillator running at 1MHz. -Connected to PB0 and PB1 are the two MOSFETs that turn on the input -sources, one for solar (PB1), the other for a mains charger (PB0). +Connected to PB0 and PB1 are the two transistors that turn on the input +sources, one for solar (PB1), the other for a mains charger (PB0). These are +NPN bi-polar junction transistors. When the base is turned on via PB0 or PB1, +this allows current to flow from the collector to ground, effectively pulling +the relevant logic level output low. -The source pins of these connect to the battery positive input, so when -the FET is on, power may flow from that source to the battery. - -A third MOSFET connects to PB2, this is PWM-controlled to manage some -cooling fans. The internal temperature sensor is used to decide whether -the fans should be on or off, and at what speed. +Connected to PB2 is a third NPN transistor which is wired to a P-channel +MOSFET, such that turning the transistor on also turns on that MOSFET. This +is PWM-controlled to manage some cooling fans. The internal temperature +sensor is used to decide whether the fans should be on or off, and at what +speed. Connecting to each input, and to the battery, are separate voltage dividers, comprising of a 1.5kOhm and 100Ohm resistors. These divide the input voltage by 16, and the divided voltage is fed into the ADC -pins PA0 (mains), PA1 (solar) and PA2 (battery). +pins PA1 (solar) and PA2 (battery). LEDs connect to PA7, PA6, PA5, PA4 and PA3 to 0v. ICSP is shared with the LEDs. @@ -34,18 +37,17 @@ LEDs. GPIOs ----- - PB0: Mains MOSFET (active HIGH) - PB1: Solar MOSFET (active HIGH) + PB0: Mains enable (active LOW) + PB1: Solar enable (active LOW) PB2: Fan MOSFET (active HIGH) PB3: nRESET PA7: Temperature Low LED (active HIGH) PA6: Temperature High LED (active HIGH) + ICSP MOSI - PA5: Battery Voltage High LED (active HIGH) + ICSP MISO - PA4: Warning LED (active high) + ICSP SCK + Debug Tx + PA5: Mains Floating LED (active HIGH) + ICSP MISO + PA4: Mains Charging LED (active high) + ICSP SCK + Debug Tx PA3: Battery Voltage Good LED (active HIGH) PA2: Analogue Input: Battery voltage PA1: Analogue Input: Solar voltage - PA0: Analogue Input: Mains voltage Firmware description -------------------- @@ -64,48 +66,60 @@ loop. If DEBUG is enabled, "INIT xx" will be displayed, where xx is the value of the MCUSR register. Two counters are decremented by the Timer 1 overflow interrupt. -`led_timeout` causes the main loop to update the state of the LEDs when -it hits zero, and `adc_timeout` triggers a new ADC capture run when it -reaches zero. +`t_second` causes the main loop to decrement each one-second timer, `t_adc` +causes the ADC state machine to advance one tick and checkt the state of the +channels. -The three analogue inputs and temperature sensor are scanned when -`adc_timeout` reaches zero, then the state analysed. The battery -voltage is compared to the previous reading to dissern if the battery is -charging, discharging or holding steady. +The two analogue inputs and temperature sensor are scanned when +`t_adc` reaches zero, then the state analysed. -If this state has not changed, a battery state counter increments, -otherwise it is reset. +The charger is in one of four states: +* initialisation +* solar +* charging from mains +* floating on mains -The current state of the FETs is checked. Three states are valid: -- Idle state: all FETs off -- Mains charge: MAINS FET turned on -- Solar charge: SOLAR FET turned on +On power up, we enter the initialisation state. In this state, we wait for +the first ADC readings to arrive before deciding on whether we run from mains +power or solar. During this time, all power inputs are inhibited. -IF statements at this point compare the battery voltage to the -thresholds, and decide whether to switch voltage or not. +If either the battery or solar input are below minimum thresholds, the mains +charger is turned on and we enter the "charging from mains" state. +Otherwise the solar input is used and we enter the "solar" state. + +In the "solar" state, we monitor the battery voltage. If it drops below the +minimum voltage, we switch to the "charging from mains" state. + +In the "charging from mains" state, we monitor the battery charging progress. +Upon reaching the high voltage threshold, we switch to the "floating on mains" +state. + +In the "floating on mains" state, we wait a minimum of one hour for the +mains charger to finish its cycle. If the battery drops below the +high-voltage threshold, we move back to the "charging from mains" state. + +Once an hour has elapsed in the floating state, if the solar input is above +the minimum threshold, we turn off the mains charger and switch to the "solar" +state. LED indications --------------- The LEDs have the following meanings: -Warning LED (PA4; DEBUG undefined): -- Off: No warning condition -- Flashing: Battery below critical threshold or temperature above - maximum threshold -- On: Not used - -When in DEBUG mode, this LED may flicker with serial activity, and will -remain ON when idle. - Temperature LEDs (PA6, PA7): -- PA7 On, PA6 Off: Temperature below minimum threshold -- PA7 Flashing, PA6 Off: Temperature above minimum threshold -- PA7 Off, PA6 Flashing: Temperature above maximum threshold -- Other states: not used +- PA7 Off, PA6 Off: Temperature below minimum threshold +- PA7 On, PA6 Off: Temperature between thresholds +- PA7 Off, PA6 On: Temperature above maximum threshold -Battery LEDs (PA5, PA3): -- PA3 Flashing, PA5 Off: Battery below low threshold -- PA3 Off, PA5 Flashing: Battery above high threshold -- PA3 On, PA5 Off: Battery is in "good" range (between low and high) -- Other states: not used +Battery State LED (PA3): +- PA3 Off: Battery is below minimum voltage +- PA3 On: Battery is above minimum voltage + +Mains Charger State LEDs (PA4, PA5): +- PA4 Off, PA5 Off: Mains supply is off +- PA4 On, PA5 Off: Mains supply is charging the battery +- PA4 Off, PA5 On: Mains supply is floating the battery + +Note that in debug mode, PA4 instead becomes the serial TX line, and so will +remain on in the idle state, and will flicker with serial activity. diff --git a/board.h b/board.h index 1768574..5444954 100644 --- a/board.h +++ b/board.h @@ -22,15 +22,15 @@ /* LEDs */ #define LED_TEMP_LOW (1 << 7) #define LED_TEMP_HIGH (1 << 6) -#define LED_BATT_HIGH (1 << 5) -#define LED_WARNING (1 << 4) +#define LED_BATT_FLT (1 << 5) +#define LED_BATT_CHG (1 << 4) #define LED_BATT_GOOD (1 << 3) #define LED_PORT PORTA #define LED_PORT_DDR_REG DDRA #define LED_PORT_DDR_VAL ( LED_TEMP_LOW \ | LED_TEMP_HIGH \ - | LED_BATT_HIGH \ - | LED_WARNING \ + | LED_BATT_FLT \ + | LED_BATT_CHG \ | LED_BATT_GOOD ) /* MOSFETs */ diff --git a/powerctl.c b/powerctl.c index 9689938..ddbef80 100644 --- a/powerctl.c +++ b/powerctl.c @@ -38,36 +38,22 @@ ) /* --- Thresholds --- */ -#define V_CH_ADC ADC_READ(V_CH_MV) #define V_H_ADC ADC_READ(V_H_MV) #define V_L_ADC ADC_READ(V_L_MV) -#define V_CL_ADC ADC_READ(V_CL_MV) -#define V_DELTA_ADC ADC_READ(V_DELTA_MV) +#define V_SOL_MIN_ADC ADC_READ(V_SOL_MIN_MV) /* --- Timeouts --- */ -#define T_LED_TICKS TIMER_TICKS(T_LED_MS) #define T_ADC_TICKS TIMER_TICKS(T_ADC_MS) -#define STATE_DIS_CHECK (0) /*!< Check voltage in discharge state */ -#define STATE_DIS_WAIT (1) /*!< Wait in discharge state */ -#define STATE_CHG_CHECK (2) /*!< Check voltage in charging state */ -#define STATE_CHG_WAIT (3) /*!< Wait in charging state */ +#define STATE_INIT (0) /*!< Initial start-up state */ +#define STATE_SOLAR (1) /*!< Running from solar */ +#define STATE_MAINS_CHG (2) /*!< Charging from mains */ +#define STATE_MAINS_FLT (3) /*!< Floating on mains */ + /*! * Charger state machine state. We have four states we can be in. */ -static volatile uint8_t charger_state = STATE_DIS_CHECK; - -#define SRC_NONE (0) /*!< Turn off all chargers */ -#define SRC_SOLAR (1) /*!< Turn on solar charger */ -#define SRC_MAINS (2) /*!< Turn on mains charger */ -#define SRC_ALT (3) /*!< Alternate to *other* source, - * valid for select_src only. - */ - -/*! - * Charging source. - */ -static volatile uint8_t charge_source = SRC_NONE; +static volatile uint8_t charger_state = STATE_INIT; /*! * For state machine, the last state of the ADC MUX so we know whether @@ -76,16 +62,15 @@ static volatile uint8_t charge_source = SRC_NONE; */ static volatile uint8_t last_admux = 0; -/*! - * For state machine, determines what the battery was one sample ago so - * we know if it's charging, discharging, or remaining static. ADC units. - */ -static volatile uint16_t v_bl_adc = 0; - /*! * Current reading of the battery voltage in ADC units. */ -static volatile uint16_t v_bn_adc = 0; +static volatile uint16_t v_bat_adc = 0; + +/*! + * Current reading of the solar voltage in ADC units. + */ +static volatile uint16_t v_sol_adc = 0; /*! * Current reading of the internal temperature sensor in ADC units. @@ -103,9 +88,9 @@ static volatile uint16_t t_second = 0; static volatile uint16_t t_adc = 0; /*! - * How long before we change LED states? + * Float timeout */ -static volatile uint16_t t_led = 0; +static volatile uint16_t t_float = 0; /*! * Fan kick-start timeout @@ -113,19 +98,9 @@ static volatile uint16_t t_led = 0; static volatile uint8_t t_fan = 0; /*! - * Charger timeout + * ADC readings taken? */ -static volatile uint8_t t_charger = T_LF_S; - -/*! - * Charger warning timeout - */ -static volatile uint8_t t_cwarn = 0; - -/*! - * Are we presently in a warning state? - */ -static volatile uint8_t charger_warning = 0; +static volatile uint8_t adc_checked = 0; /* Debug messages */ #ifdef DEBUG @@ -162,190 +137,99 @@ static inline void uart_tx_bool(const char* msg, uint8_t val) { #endif /*! - * Enter charger warning state. This indicates that the battery - * *should* be charging, but isn't due to insufficient input current from - * the charger. + * Switch to charging from mains power. */ -static inline void enter_warning() { - if (charger_warning) - LED_PORT |= LED_WARNING; - else - charger_warning = 1; +static void enter_mains_chg(void) { + /* Enable mains power */ + FET_PORT &= ~FET_MAINS; - /* Reset our timer */ - t_cwarn = T_CWARN_S; + /* Indicate via LEDs */ + LED_PORT |= LED_BATT_CHG; + LED_PORT &= ~LED_BATT_FLT; + + /* Enter state */ + charger_state = STATE_MAINS_CHG; } /*! - * Leave the charger warning state. This indicates the charger has left - * the charging state or the battery has begun charging. + * Switch to floating on mains power. */ -static inline void exit_warning() { - charger_warning = 0; - t_cwarn = 0; - LED_PORT &= ~LED_WARNING; +static void enter_mains_float(void) { + /* Reset timer */ + t_float = T_FLOAT_S; + + /* Indicate via LEDs */ + LED_PORT &= ~LED_BATT_CHG; + LED_PORT |= LED_BATT_FLT; + + /* Enter state */ + charger_state = STATE_MAINS_FLT; } /*! - * Switch between chargers. This is does a "break-before-make" switchover - * of charging sources to switch from mains to solar, solar to mains, or to - * switch from charging to discharging mode. It expressly forbids turning - * both chargers on simultaneously. - * - * Added is the ability to just alternate between sources. + * Switch to running on solar. */ -static void select_src(uint8_t src) { - if (src == SRC_ALT) { - if (charge_source == SRC_SOLAR) - src = SRC_MAINS; - else - src = SRC_SOLAR; - } -#ifdef DEBUG - uart_tx_str(STR_SELECT_SRC); -#endif - switch(src) { - case SRC_SOLAR: - FET_PORT &= ~FET_MAINS; - FET_PORT |= FET_SOLAR; - charge_source = SRC_SOLAR; -#ifdef DEBUG - uart_tx_str(STR_SRC_SOLAR); -#endif - break; - case SRC_MAINS: - FET_PORT &= ~FET_SOLAR; - FET_PORT |= FET_MAINS; - charge_source = SRC_MAINS; -#ifdef DEBUG - uart_tx_str(STR_SRC_MAINS); -#endif - break; - case SRC_NONE: - default: - FET_PORT &= ~FET_SRC_MASK; - charge_source = SRC_NONE; -#ifdef DEBUG - uart_tx_str(STR_SRC_NONE); -#endif - break; - } -#ifdef DEBUG - uart_tx_str(STR_NL); -#endif +static void enter_solar(void) { + /* Inhibit mains */ + FET_PORT |= FET_MAINS; + + /* Indicate via LEDs */ + LED_PORT &= ~(LED_BATT_FLT | LED_BATT_CHG); + + /* Enter state */ + charger_state = STATE_SOLAR; } -static void discharge_check() { - /* Decide when we should do our next check */ -#ifdef DEBUG - uart_tx_str(STR_DIS); uart_tx_str(STR_CHK); - uart_tx_bool(STR_V_BN_GE_V_H, v_bn_adc >= V_H_ADC); -#endif - if (v_bn_adc >= V_H_ADC) - t_charger = T_LF_S; - else - t_charger = T_HF_S; +/*! + * Checks at start-up + */ +static void init_check(void) { + /* Wait until we have our first readings from the ADC */ + if (!adc_checked) + return; - /* Snapshot the current battery voltage */ - v_bl_adc = v_bn_adc; - - /* Exit state */ -#ifdef DEBUG - uart_tx_bool(STR_V_BN_GT_V_L, v_bn_adc > V_L_ADC); -#endif - if (v_bn_adc > V_L_ADC) - charger_state = STATE_DIS_WAIT; + if ((v_bat_adc < V_L_ADC) || (v_sol_adc < V_SOL_MIN_ADC)) + /* Battery/solar is low, begin charging */ + enter_mains_chg(); else - charger_state = STATE_CHG_CHECK; + /* Run from solar */ + enter_solar(); } -static void discharge_wait() { -#ifdef DEBUG - uart_tx_str(STR_DIS); uart_tx_str(STR_WAIT); - uart_tx_bool(STR_V_BN_LE_V_CL, v_bn_adc <= V_CL_ADC); -#endif - if (v_bn_adc <= V_CL_ADC) - /* Expire timer */ - t_charger = 0; - - /* Exit state if timer is expired */ -#ifdef DEBUG - uart_tx_bool(STR_T_CHARGER, !t_charger); -#endif - if (!t_charger) - charger_state = STATE_DIS_CHECK; -} - -static void charge_check() { -#ifdef DEBUG - uart_tx_str(STR_CHG); uart_tx_str(STR_CHK); - uart_tx_bool(STR_V_BN_LE_V_CL, v_bn_adc <= V_CL_ADC); -#endif - /* Still need to charge, when should we next check? */ - if (v_bn_adc <= V_CL_ADC) - t_charger = T_HF_S; - else - t_charger = T_LF_S; - - /* Critically high voltage check */ - if (v_bn_adc >= V_CH_ADC) { - /* We must stop now! */ - select_src(SRC_NONE); - charger_state = STATE_DIS_CHECK; - charger_warning = 0; - t_cwarn = 0; +/*! + * Checks whilst running on solar + */ +static void solar_check(void) { + if (v_bat_adc < V_L_ADC) { + /* Move to mains power */ + enter_mains_chg(); return; } - - if (charge_source == SRC_NONE) { - /* Not yet charging, switch to primary source */ - select_src(SRC_SOLAR); - /* As we have just started charging, reset warning timer */ - exit_warning(); - } else if (v_bn_adc <= (v_bl_adc + V_DELTA_ADC)) { - /* Check for high voltage threshold, are we there yet? */ -#ifdef DEBUG - uart_tx_bool(STR_V_BN_GE_V_H, v_bn_adc >= V_H_ADC); -#endif - if (v_bn_adc >= V_H_ADC) { - /* We are done now */ - select_src(SRC_NONE); - exit_warning(); - return; - } else if (!t_cwarn) { - if (charger_warning) { - /* - * Situation still not improving, - * switch sources. - */ - select_src(SRC_ALT); - } - /* Reset our warning timer */ - enter_warning(); - } - } else if (!t_cwarn) { - /* Things are improving, reset warning if set. */ - exit_warning(); - } - - v_bl_adc = v_bn_adc; - charger_state = STATE_CHG_WAIT; } -static void charge_wait() { -#ifdef DEBUG - uart_tx_str(STR_CHG); uart_tx_str(STR_WAIT); - uart_tx_bool(STR_V_BN_GE_V_CH, v_bn_adc >= V_CH_ADC); -#endif - if (v_bn_adc >= V_CH_ADC) - /* Expire timer */ - t_charger = 0; +/*! + * Checks whilst charging from mains + */ +static void mains_chg_check(void) { + if (v_bat_adc >= V_H_ADC) { + /* We've reached the float voltage */ + enter_mains_float(); + return; + } +} -#ifdef DEBUG - uart_tx_bool(STR_T_CHARGER, !t_charger); -#endif - if (!t_charger) - charger_state = STATE_CHG_CHECK; +/*! + * Checks whilst floating on mains + */ +static void mains_float_check(void) { + if (v_bat_adc < V_H_ADC) { + /* We've regressed, go back to charging state! */ + enter_mains_chg(); + return; + } else if ((!t_float) && (v_sol_adc >= V_SOL_MIN_ADC)) { + /* Solar can take it from here */ + enter_solar(); + } } /*! @@ -358,7 +242,7 @@ int main(void) { /* Configure MOSFETs */ FET_PORT_DDR_REG = FET_PORT_DDR_VAL; - FET_PORT = 0; + FET_PORT = FET_MAINS | FET_SOLAR; /* Turn on ADC and timers */ PRR &= ~((1 << PRTIM0) | (1 << PRTIM1) | (1 << PRADC)); @@ -400,49 +284,8 @@ int main(void) { /* One second passed, tick down the 1-second timers. */ if (!t_second) { t_second = TIMER_FREQ; - if (t_charger) - t_charger--; - if (t_cwarn) - t_cwarn--; - } - - if (t_adc) - t_adc--; - - if (!t_led) { - if (v_bn_adc <= V_CL_ADC) { - /* Battery is critically low */ - LED_PORT &= ~LED_BATT_HIGH; - LED_PORT ^= LED_BATT_GOOD; - } else if (v_bn_adc <= V_L_ADC) { - /* Battery is low */ - LED_PORT &= ~(LED_BATT_HIGH|LED_BATT_GOOD); - } else if (v_bn_adc <= V_H_ADC) { - /* Battery is in "good" range */ - LED_PORT &= ~LED_BATT_HIGH; - LED_PORT |= LED_BATT_GOOD; - } else if (v_bn_adc <= V_CH_ADC) { - /* Battery is above "high" threshold */ - LED_PORT |= LED_BATT_HIGH; - LED_PORT &= ~LED_BATT_GOOD; - } else { - /* Battery is critically high */ - LED_PORT ^= LED_BATT_HIGH; - LED_PORT &= ~LED_BATT_GOOD; - } - - if (temp_adc < TEMP_MIN) { - LED_PORT |= LED_TEMP_LOW; - LED_PORT &= ~LED_TEMP_HIGH; - } else if (temp_adc < TEMP_MAX) { - LED_PORT ^= LED_TEMP_LOW; - LED_PORT &= ~LED_TEMP_HIGH; - } else { - LED_PORT &= ~LED_TEMP_LOW; - LED_PORT ^= LED_TEMP_HIGH; - } - - t_led = T_LED_TICKS; + if (t_float) + t_float--; } if (!t_adc) { @@ -451,6 +294,28 @@ int main(void) { while(ADCSRA & (1 << ADEN)); + /* Temperature LED control */ + if (temp_adc < TEMP_MIN) { + LED_PORT |= LED_TEMP_LOW; + LED_PORT &= ~LED_TEMP_HIGH; + } else if (temp_adc < TEMP_MAX) { + LED_PORT |= (LED_TEMP_LOW | LED_TEMP_HIGH); + } else { + LED_PORT &= ~LED_TEMP_LOW; + LED_PORT |= LED_TEMP_HIGH; + } + + /* + * The "SOLAR" FET is no longer fitted, so this is more + * an indication of whether we consider solar to be + * "good enough". In short, it's just controlling the + * LED where the MOSFET was now. + */ + if (v_sol_adc < V_SOL_MIN_ADC) + FET_PORT |= FET_SOLAR; + else + FET_PORT &= ~FET_SOLAR; + /* Fan control */ if (t_fan) { /* Kick-start mode */ @@ -475,22 +340,29 @@ int main(void) { OCR0A = 0; } + /* Battery state LED control */ + if (v_bat_adc <= V_L_ADC) { + LED_PORT &= ~LED_BATT_GOOD; + } else { + LED_PORT |= LED_BATT_GOOD; + } + /* Charger control */ switch (charger_state) { - case STATE_DIS_CHECK: - discharge_check(); + case STATE_INIT: + init_check(); break; - case STATE_DIS_WAIT: - discharge_wait(); + case STATE_SOLAR: + solar_check(); break; - case STATE_CHG_CHECK: - charge_check(); + case STATE_MAINS_CHG: + mains_chg_check(); break; - case STATE_CHG_WAIT: - charge_wait(); + case STATE_MAINS_FLT: + mains_float_check(); break; default: - charger_state = STATE_DIS_CHECK; + charger_state = STATE_INIT; } } } @@ -505,8 +377,8 @@ ISR(TIM1_COMPA_vect) { if (t_second) t_second--; - if (t_led) - t_led--; + if (t_adc) + t_adc--; } ISR(ADC_vect) { @@ -519,20 +391,14 @@ ISR(ADC_vect) { ADCSRA |= (1 << ADSC); break; case ADC_MUX_BATT: - v_bn_adc = adc; -#if 0 - /* Not being used for now */ + v_bat_adc = adc; ADMUX = ADC_MUX_SOLAR; ADCSRA |= (1 << ADSC); break; case ADC_MUX_SOLAR: - adc_solar = adc; - ADMUX = ADC_MUX_MAINS; - ADCSRA |= (1 << ADSC); - break; - case ADC_MUX_MAINS: - adc_mains = adc; -#endif + v_sol_adc = adc; + /* Once we get here, we've done a full cycle */ + adc_checked = 1; default: ADMUX = ADC_MUX_TEMP; ADCSRA &= ~(1 << ADEN); diff --git a/setpoints.h.dist b/setpoints.h.dist index 14119f2..ac94a92 100644 --- a/setpoints.h.dist +++ b/setpoints.h.dist @@ -28,11 +28,6 @@ */ #define T_ADC_MS (250) -/*! - * How long before we change LED states? Milliseconds. - */ -#define T_LED_MS (150) - /* * Temperature ranges and fan PWM settings */ @@ -57,53 +52,29 @@ /* --- Thresholds --- */ -/*! - * Critically high battery voltage. Exceeding this voltage could damage - * the battery or the equipment downstream of it. - */ -#define V_CH_MV (15500) - /*! * High battery voltage. If we reach this voltage and the charger * stops, just switch to discharge mode, consider the job done. */ -#define V_H_MV (14000) +#define V_H_MV (14400) /*! * Low battery voltage. If the voltage dips to or below this level, we * should turn the charger on. */ -#define V_L_MV (13800) +#define V_L_MV (12400) /*! - * Critically low battery voltage. If we reach this level, we need to - * urgently turn the charger on and need to be ready to switch sources - * in a hurry if the chosen source isn't charging. + * Solar minimum voltage. If the solar is below this threshold, we + * consider it too low to reliably charge the system. */ -#define V_CL_MV (11800) - -/*! - * Battery minimum charge step. This is the amount of charge we expect - * the battery to have increased by before we consider flagging a - * warning. - */ -#define V_DELTA_MV (50) +#define V_SOL_MIN_MV (18000) /* --- Timeouts --- */ /*! - * High frequency polling period in seconds. + * How long do we remain on the mains charger after reaching V_H_MV? */ -#define T_HF_S (15) - -/*! - * Low frequency polling period in seconds. - */ -#define T_LF_S (60) - -/*! - * How long before we consider a lack of voltage increase a warning? - */ -#define T_CWARN_S (10) +#define T_FLOAT_S (3600) #endif