|
|
@@ -6,67 +6,53 @@
|
|
|
#include "ti_msp_dl_config.h"
|
|
|
#include "src/controller/controller.h"
|
|
|
|
|
|
-
|
|
|
-// declaring static global variables to retain their values between multiple function calls till the end of the program
|
|
|
-
|
|
|
-static BatteryChargingState charging_state= STATE_IDLE; //setting default state of the battery charging state
|
|
|
-static uint16_t cycle_count=0;
|
|
|
-
|
|
|
-//Battery Measurements Received
|
|
|
-static uint16_t batt_voltage;
|
|
|
-static int16_t batt_current;
|
|
|
-
|
|
|
-//Battery Limits Received
|
|
|
-static uint16_t batt_min_voltage;
|
|
|
-static uint16_t batt_max_voltage;
|
|
|
-static uint16_t batt_cutoff_current;
|
|
|
-static uint16_t batt_capacitance;
|
|
|
-static int16_t batt_charge_discharge;
|
|
|
-static uint8_t previous_cycle_number;
|
|
|
-
|
|
|
+static BatteryChargingState charging_state= STATE_IDLE; //Default value of the charging state
|
|
|
+static bool battery_discharge= false;
|
|
|
|
|
|
// Functions for Charging and Discharging State
|
|
|
void CC_CV_UpdateChargingState(uint8_t slot_id) {
|
|
|
- //static variable to keep a log on the transition during charging and discharging phases
|
|
|
- static BatteryChargingState previous_state= STATE_IDLE;
|
|
|
- //Storing the charging state in the BatteryInfo struct for Pi monitoring:
|
|
|
+
|
|
|
+ static bool cv_charging_started = false;
|
|
|
BatteryInfo *battery= &battery_data[slot_id];
|
|
|
+
|
|
|
+ //Battery Measurement and Limits:
|
|
|
+ uint16_t batt_voltage = battery->battery_measurement.voltage;
|
|
|
+ int16_t batt_current = battery->battery_measurement.current;
|
|
|
+ uint16_t batt_min_voltage = battery->min_voltage;
|
|
|
+ uint16_t batt_max_voltage = battery->max_voltage;
|
|
|
+ uint8_t batt_cutoff_current = battery->cut_off_current;
|
|
|
+ uint16_t batt_capacitance = battery->capacitance;
|
|
|
+ int16_t batt_charge_discharge= battery->charge_discharge;
|
|
|
+ uint8_t previous_cycle= battery->previous_cycle_number;
|
|
|
+ uint8_t *cycle_count = &battery->cycle_number;
|
|
|
battery->battery_charging_state= charging_state;
|
|
|
- battery->cycle_number= cycle_count;
|
|
|
- // Flag for CV charging, the charging mode flips back to CC mode
|
|
|
- static bool cv_charging_started = false;
|
|
|
- //Battery
|
|
|
- batt_voltage = battery_data[slot_id].battery_measurement.voltage;
|
|
|
- batt_current = battery_data[slot_id].battery_measurement.current;
|
|
|
- batt_min_voltage = battery_data[slot_id].min_voltage;
|
|
|
- batt_max_voltage = battery_data[slot_id].max_voltage;
|
|
|
- batt_cutoff_current = battery_data[slot_id].cut_off_current;
|
|
|
- batt_capacitance = battery_data[slot_id].capacitance;
|
|
|
- batt_charge_discharge= battery_data[slot_id].charge_discharge;
|
|
|
- previous_cycle_number= battery_data[slot_id].previous_cycle_number;
|
|
|
+ BatteryChargingState previous_state= charging_state;
|
|
|
|
|
|
//For logging state transitions
|
|
|
if(charging_state != previous_state){
|
|
|
printf("State transition: %d -> %d\n", previous_state, charging_state);
|
|
|
previous_state= charging_state;
|
|
|
- previous_cycle_number= cycle_count;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
//Check if the slot is empty or if the battery limits are not set
|
|
|
- if ((battery_data[slot_id].battery_state == STATE_EMPTY) || (battery_data[slot_id].batteryLimitReceived == 0)) {
|
|
|
- charging_state = STATE_IDLE;
|
|
|
+ if ((battery_data[slot_id].battery_state == STATE_EMPTY) || (battery->batteryLimitReceived == 0)) {
|
|
|
+ battery->battery_charging_state= STATE_IDLE;
|
|
|
+ cv_charging_started= false;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//Checking the condition where all the battery measurements are NULL
|
|
|
- if((battery_data[slot_id].battery_measurement.voltage == 0) && (battery_data[slot_id].battery_measurement.current == 0) && (battery_data[slot_id].battery_measurement.temperature == 0)){
|
|
|
- charging_state= STATE_IDLE;
|
|
|
+ if((batt_voltage== 0) && (batt_current == 0)){
|
|
|
+ battery->battery_charging_state= STATE_IDLE;
|
|
|
+ cv_charging_started= false;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// Once the battery limits are received then start with the charging
|
|
|
- if(battery_data[slot_id].batteryLimitReceived == 1){
|
|
|
- printf("Battery Limit Received:%d\n", battery_data[slot_id].batteryLimitReceived);
|
|
|
+ if(battery->batteryLimitReceived == 1){
|
|
|
+ printf("Battery Limit Received:%d\n", battery->batteryLimitReceived);
|
|
|
+
|
|
|
//1. Pre Charge: if the battery is deeply discharged
|
|
|
if ((batt_voltage < batt_min_voltage)) {
|
|
|
charging_state = STATE_PRE_CHARGE;
|
|
|
@@ -82,36 +68,33 @@ void CC_CV_UpdateChargingState(uint8_t slot_id) {
|
|
|
}
|
|
|
|
|
|
// 3. CV Charging condition: Changing the cv_charging_state to True, once the CV mode is reached
|
|
|
-
|
|
|
else if (batt_voltage >= batt_max_voltage - BATTERY_THRESHOLD) {
|
|
|
charging_state = STATE_CV_CHARGING;
|
|
|
cv_charging_started = true;
|
|
|
printf("CV CHARGING\n");
|
|
|
}
|
|
|
-
|
|
|
- // 4. Cut-off check if CV cycle started
|
|
|
-
|
|
|
- else if ((charging_state == STATE_CV_CHARGING) && (batt_current <= batt_cutoff_current - BATTERY_THRESHOLD)) {
|
|
|
- //since after the reset the cycle_count sets back to 0, and if the previous_cycle_number obtained from the Pi is greater then:
|
|
|
- if (cycle_count < MAX_CYCLES) {
|
|
|
- charging_state = STATE_DISCHARGING;
|
|
|
- cycle_count++;
|
|
|
- battery->cycle_number= cycle_count;
|
|
|
+
|
|
|
+ //4. When in CV state
|
|
|
+ else if(charging_state== STATE_CV_CHARGING && battery_discharge== true){
|
|
|
+ if(*cycle_count < MAX_CYCLES){
|
|
|
+ charging_state= STATE_DISCHARGING;
|
|
|
+ (*cycle_count)++;
|
|
|
cv_charging_started= false;
|
|
|
- printf("DISCHARGING\n");
|
|
|
-
|
|
|
+ printf("Transition to DISCHARGING, new cycle: %d\n", battery->cycle_number);
|
|
|
}else {
|
|
|
charging_state = STATE_FINAL_DISCHARGE;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
// 5. State Discharging condition
|
|
|
- else if (charging_state == STATE_DISCHARGING && batt_voltage <= batt_min_voltage + BATTERY_THRESHOLD) {
|
|
|
- DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
- charging_state = STATE_CC_CHARGING;
|
|
|
- cv_charging_started = false;
|
|
|
- printf("DISCHARGE -> CC CHARGING\n");
|
|
|
+ else if ((charging_state == STATE_DISCHARGING)&& (batt_voltage <= batt_min_voltage + BATTERY_THRESHOLD)){
|
|
|
+ DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
+ charging_state = STATE_CC_CHARGING;
|
|
|
+ cv_charging_started = false;
|
|
|
+ battery_discharge= false;
|
|
|
+ printf("DISCHARGE -> CC CHARGING\n");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//6. Check if the battery is overcharged
|
|
|
else if (batt_voltage > batt_max_voltage) {
|
|
|
charging_state = STATE_ERROR;
|
|
|
@@ -142,24 +125,27 @@ voltage threshold is obtained.
|
|
|
void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
|
// Calling function to get all the conditional states
|
|
|
CC_CV_UpdateChargingState(slot_id);
|
|
|
- int16_t charge_current= 100;
|
|
|
- batt_voltage = battery_data[slot_id].battery_measurement.voltage;
|
|
|
- batt_current= battery_data[slot_id].battery_measurement.current;
|
|
|
- batt_min_voltage= battery_data[slot_id].min_voltage;
|
|
|
- batt_max_voltage= battery_data[slot_id].max_voltage;
|
|
|
- batt_cutoff_current = battery_data[slot_id].cut_off_current;
|
|
|
- batt_capacitance= battery_data[slot_id].capacitance;
|
|
|
- batt_charge_discharge= battery_data[slot_id].charge_discharge;
|
|
|
|
|
|
+ int16_t charge_current= 100;
|
|
|
// DAC channel value:
|
|
|
// dac_channel_value is for CV mode where the charge current is calibrated till battery current is less than (cutoff current+threshold)
|
|
|
// Adding a variable to check the stepness in the voltage drop in CV charging
|
|
|
// mode:
|
|
|
static uint16_t last_voltage = 0;
|
|
|
- static int16_t cvChargingPhaseCurrent;
|
|
|
+ static int16_t cvChargingPhaseCurrent= 0;
|
|
|
//flag for DAC: so that the dac value is initialized only once and then can be decremented rather than resetting to the initial value
|
|
|
static bool chargeCurrent_initialized= false;
|
|
|
-
|
|
|
+
|
|
|
+ BatteryInfo *battery= &battery_data[slot_id];
|
|
|
+ //Battery Measurement and Limits:
|
|
|
+ uint16_t batt_voltage = battery->battery_measurement.voltage;
|
|
|
+ int16_t batt_current = battery->battery_measurement.current;
|
|
|
+ uint16_t batt_min_voltage = battery->min_voltage;
|
|
|
+ uint16_t batt_max_voltage = battery->max_voltage;
|
|
|
+ uint8_t batt_cutoff_current = battery->cut_off_current;
|
|
|
+ uint16_t batt_capacitance = battery->capacitance;
|
|
|
+
|
|
|
+
|
|
|
switch (charging_state) {
|
|
|
// PRE CHARGE STATE: Battery Voltage is lesser than 3000 mVolts
|
|
|
case STATE_PRE_CHARGE:
|
|
|
@@ -189,18 +175,20 @@ void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
|
//batt_cutoff_current: 75, BATTERY_THRESHOLD: 20
|
|
|
if (batt_current >= batt_cutoff_current - BATTERY_THRESHOLD) {
|
|
|
// Detect steep voltage drop:
|
|
|
- if (last_voltage != 0 && (last_voltage - batt_voltage) > 100) {
|
|
|
+ if (last_voltage != 0 && (last_voltage - batt_voltage) > 250) {
|
|
|
printf("!!! CV CHARGING: Voltage dropped too fast: %d -> %d mV.\n", last_voltage, batt_voltage);
|
|
|
charging_state= STATE_ERROR;
|
|
|
break;
|
|
|
}
|
|
|
- cvChargingPhaseCurrent-= 5;
|
|
|
- // Lower bound so that the charge current does not go to negative
|
|
|
- if (cvChargingPhaseCurrent < BATTERY_THRESHOLD) {
|
|
|
- charging_state= STATE_DISCHARGING;
|
|
|
+ if(cvChargingPhaseCurrent >= BATTERY_THRESHOLD){
|
|
|
+ cvChargingPhaseCurrent-= 5;
|
|
|
+ }else{
|
|
|
+ chargeCurrent_initialized= false;
|
|
|
+ battery_discharge= true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
controller_SetCurrent(slot_id, cvChargingPhaseCurrent);
|
|
|
last_voltage = batt_voltage;
|
|
|
break;
|
|
|
@@ -208,7 +196,6 @@ void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
|
case STATE_DISCHARGING:
|
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
|
DL_GPIO_setPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
- //controller_EvaluateBatterySlotState(slot_id, BatteryMeasurement *measurement);
|
|
|
controller_SetCurrent(slot_id, (-1 * charge_current));
|
|
|
printf("DISCHARGING: Slot %d at %d mA.\n", slot_id, batt_current);
|
|
|
chargeCurrent_initialized= false;
|