Browse Source

added logic for CC-CV charging

namrota ghosh 7 months ago
parent
commit
495655aef1
2 changed files with 212 additions and 0 deletions
  1. 192 0
      src/cc_cv_charging.c
  2. 20 0
      src/cc_cv_charging.h

+ 192 - 0
src/cc_cv_charging.c

@@ -0,0 +1,192 @@
+#include "cc_cv_charging.h"
+#include "src/config.h"
+#include "src/battery_data/battery.h"
+#include <stdio.h>
+#include "ti/driverlib/dl_gpio.h"
+
+static ChargingState charging_state= STATE_IDLE;
+static uint16_t cycle_count = 0;
+// declaring static global variables
+static uint16_t batt_voltage;
+static int16_t batt_current;
+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;
+// Functions for Charging and Discharging State
+
+void CC_CV_UpdateChargingState(uint8_t slot_id) {
+    // Flag for CV charging, the charging mode flips back to CC mode
+    static bool cv_charging_started = false;
+    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].battery_limits.min_voltage;
+    batt_max_voltage = battery_data[slot_id].battery_limits.max_voltage;
+    batt_cutoff_current = battery_data[slot_id].battery_limits.cut_off_current;
+    batt_capacitance = battery_data[slot_id].battery_limits.capacitance;
+    batt_charge_discharge= battery_data[slot_id].charge_discharge;
+    //Check if the slot is empty or if the battery limits are not set
+    if (battery_data[slot_id].battery_state == STATE_EMPTY || (batt_min_voltage == 0 && batt_max_voltage == 0 &&
+         batt_cutoff_current== 0 && batt_capacitance== 0)) {
+      charging_state = STATE_IDLE;
+      return;
+    }
+    
+    //Check if the battery is overcharged
+    if (batt_voltage > batt_max_voltage) {
+      charging_state = STATE_ERROR;
+      return;
+    }
+  
+    //1. Pre Charge: if the battery is deeply discharged
+    if ((batt_voltage < batt_min_voltage)) {
+      charging_state = STATE_PRE_CHARGE;
+      cv_charging_started = false;
+    }
+    // 2. Fast Charging Condition: CC Charging: cv_charging_started condition
+    // added to avoid toggling back to CC after CV state is reached
+  
+    else if (!cv_charging_started &&
+             (batt_voltage >= batt_min_voltage) &&
+             (batt_voltage < batt_max_voltage - BATTERY_THRESHOLD)) {
+      charging_state = STATE_CC_CHARGING;
+    }
+    // 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;
+    }
+  
+    // 4. Cut-off check inside CV
+  
+    else if ((charging_state == STATE_CV_CHARGING) &&
+             (batt_current <= batt_cutoff_current + BATTERY_THRESHOLD)) {
+      if (cycle_count < MAX_CYCLES) {
+        charging_state = STATE_DISCHARGING;
+        cycle_count++;
+      } 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_PB12_PIN);
+      charging_state = STATE_CC_CHARGING;
+      cv_charging_started = false;
+    }
+  
+    // 6. Hold previous state if none of the condition matches (Previously,
+    // CV_STATE was jumping directly to STATE_ERROR in else statement, to handle
+    // the condition better, else condition is being changed).
+    else {
+      printf("[CC-CV] Current state: Voltage= %d mV, Current= %d mA\n",
+             batt_voltage, batt_current);
+    }
+  }
+
+  /*
+Function for Battery Charging and Discharging:
+** Pre Charge: Once the battery is in discharged state, pre-charging
+begins. Starts charging safely with a typically low current C/10
+** Constant Current: Continues until the battery voltage has reached the "full"
+or floating voltage level
+** Constant Voltage: CV voltage starts once the maximum
+voltage threshold is obtained.
+*/
+
+void CC_CV_ControlCharging(uint8_t slot_id, int16_t charge_current) {
+    // Calling function to get all the conditional states
+    CC_CV_UpdateChargingState(slot_id);
+    
+    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].battery_limits.min_voltage;
+    batt_max_voltage= battery_data[slot_id].battery_limits.max_voltage;
+    batt_cutoff_current = battery_data[slot_id].battery_limits.cut_off_current;
+    batt_capacitance= battery_data[slot_id].battery_limits.capacitance;
+    batt_charge_discharge= battery_data[slot_id].charge_discharge;
+
+    
+    //  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;
+    //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 dac_initialized= false;
+
+    switch (charging_state) {
+  
+    // PRE CHARGE STATE: Battery Voltage is lesser than 3000 mVolts
+    case STATE_PRE_CHARGE:
+
+      DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
+      controller_SetCurrent(TARGET_ADDRESS, slot_id, charge_current);
+      if (true) {
+        printf("PRE CHARGING: Slot %d at %d mA.\n", slot_id, );
+      }
+      break;
+  
+    // CC CHARGING STATE: Keeps on checking the condition until battery voltage
+    // reaches to (MAXIMUM_VOLTAGE-BATTERY_THRESHOLD)= 4150 mVolts
+    case STATE_CC_CHARGING:
+      
+      controller_SetCurrent(TARGET_ADDRESS, slot_id, charge_current);
+      printf("CC CHARGING: Slot %d, Current: %d mA, Voltage: %d mV.\n", slot_id, batt_current, batt_voltage);
+      break;
+  
+    // CV CHARGING STATE: Keeps on checking the condition until battery current
+    // decreases till it exceeds (CUTOFF_CURRENT_MA + BATTERY_THRESHOLD)= 290 mAs
+    case STATE_CV_CHARGING:
+      if (batt_current >= batt_cutoff_current + BATTERY_THRESHOLD) {
+        // Detect steep voltage drop:
+        if (last_voltage != 0 && (last_voltage - batt_voltage) > 100) {
+          printf("!!! CV CHARGING: Voltage dropped too fast: %d -> %d mV.\n", last_voltage, batt_voltage);
+        }
+      }else {
+        charging_state = STATE_FINAL_DISCHARGE;
+        dac_initialized= false;
+      }
+      last_voltage = batt_voltage;
+      controller_SetCurrent(TARGET_ADDRESS, slot_id, charge_current);
+      break;
+  
+    case STATE_DISCHARGING:
+      DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
+      DL_GPIO_setPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB12_PIN);
+      controller_SetCurrent(TARGET_ADDRESS, slot_id, charge_current);
+      printf("DISCHARGING: Slot %d at %d mA.\n", slot_id, batt_voltage);
+      break;
+  
+    case STATE_FINAL_DISCHARGE:
+      //Once the cycle gets done, the battery state transitions to "STATE_MEASUREMENT_DONE"
+      batteries[slot_id].state= STATE_MEASUREMENT_DONE;
+      DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
+      DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB12_PIN);
+      controller_SetCurrent(TARGET_ADDRESS, slot_id, 0);
+      charging_state = STATE_IDLE;
+      break;
+  
+    case STATE_ERROR:
+      DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
+      DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB12_PIN);
+      printf("ERROR: Slot %d.\n", slot_id);
+      break;
+  
+    case STATE_IDLE:
+      DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
+      DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB12_PIN);
+      charging_state = STATE_PRE_CHARGE;
+      break;
+      
+    default:
+      break;
+    }
+  }
+// End of the file  

+ 20 - 0
src/cc_cv_charging.h

@@ -0,0 +1,20 @@
+#include <stdint.h>
+
+#ifndef CC_CV_CHARGING_H_
+#define CC_CV_CHARGING_H_
+
+typedef enum{
+    STATE_PRE_CHARGE,
+    STATE_CC_CHARGING,
+    STATE_CV_CHARGING,
+    STATE_DISCHARGING,
+    STATE_FINAL_DISCHARGE,
+    STATE_ERROR,
+    STATE_IDLE,
+}ChargingState;
+
+
+void CC_CV_UpdateChargingState(uint8_t slot_id);
+void CC_CV_ControlCharging(uint8_t slot_id);
+
+#endif