|
@@ -10,7 +10,7 @@
|
|
|
// declaring static global variables to retain their values between multiple function calls till the end of the program
|
|
// 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 BatteryChargingState charging_state= STATE_IDLE; //setting default state of the battery charging state
|
|
|
-static uint16_t cycle_count= 0;
|
|
|
|
|
|
|
+static uint16_t cycle_count=0;
|
|
|
|
|
|
|
|
//Battery Measurements Received
|
|
//Battery Measurements Received
|
|
|
static uint16_t batt_voltage;
|
|
static uint16_t batt_voltage;
|
|
@@ -35,6 +35,7 @@ void CC_CV_UpdateChargingState(uint8_t slot_id) {
|
|
|
battery->cycle_number= cycle_count;
|
|
battery->cycle_number= cycle_count;
|
|
|
// Flag for CV charging, the charging mode flips back to CC mode
|
|
// Flag for CV charging, the charging mode flips back to CC mode
|
|
|
static bool cv_charging_started = false;
|
|
static bool cv_charging_started = false;
|
|
|
|
|
+ //Battery
|
|
|
batt_voltage = battery_data[slot_id].battery_measurement.voltage;
|
|
batt_voltage = battery_data[slot_id].battery_measurement.voltage;
|
|
|
batt_current = battery_data[slot_id].battery_measurement.current;
|
|
batt_current = battery_data[slot_id].battery_measurement.current;
|
|
|
batt_min_voltage = battery_data[slot_id].min_voltage;
|
|
batt_min_voltage = battery_data[slot_id].min_voltage;
|
|
@@ -48,6 +49,7 @@ void CC_CV_UpdateChargingState(uint8_t slot_id) {
|
|
|
if(charging_state != previous_state){
|
|
if(charging_state != previous_state){
|
|
|
printf("State transition: %d -> %d\n", previous_state, charging_state);
|
|
printf("State transition: %d -> %d\n", previous_state, charging_state);
|
|
|
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
|
|
//Check if the slot is empty or if the battery limits are not set
|
|
@@ -68,56 +70,60 @@ void CC_CV_UpdateChargingState(uint8_t slot_id) {
|
|
|
//1. Pre Charge: if the battery is deeply discharged
|
|
//1. Pre Charge: if the battery is deeply discharged
|
|
|
if ((batt_voltage < batt_min_voltage)) {
|
|
if ((batt_voltage < batt_min_voltage)) {
|
|
|
charging_state = STATE_PRE_CHARGE;
|
|
charging_state = STATE_PRE_CHARGE;
|
|
|
|
|
+ printf("PRE CHARGING\n");
|
|
|
cv_charging_started = false;
|
|
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
|
|
// 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)) {
|
|
|
|
|
|
|
+ else if (!cv_charging_started && (batt_voltage >= batt_min_voltage) && (batt_voltage < batt_max_voltage - BATTERY_THRESHOLD)){
|
|
|
charging_state = STATE_CC_CHARGING;
|
|
charging_state = STATE_CC_CHARGING;
|
|
|
- }
|
|
|
|
|
|
|
+ printf("CC CHARGING\n");
|
|
|
|
|
+ cv_charging_started = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 3. CV Charging condition: Changing the cv_charging_state to True, once the CV mode is reached
|
|
// 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) {
|
|
else if (batt_voltage >= batt_max_voltage - BATTERY_THRESHOLD) {
|
|
|
charging_state = STATE_CV_CHARGING;
|
|
charging_state = STATE_CV_CHARGING;
|
|
|
cv_charging_started = true;
|
|
cv_charging_started = true;
|
|
|
|
|
+ printf("CV CHARGING\n");
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 4. Cut-off check if CV cycle started
|
|
|
|
|
|
|
|
- // 4. Cut-off check inside CV
|
|
|
|
|
-
|
|
|
|
|
- else if ((charging_state == STATE_CV_CHARGING) && (batt_current <= batt_cutoff_current + BATTERY_THRESHOLD)) {
|
|
|
|
|
|
|
+ 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:
|
|
//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(previous_cycle_number > cycle_count){
|
|
|
|
|
- cycle_count= previous_cycle_number;
|
|
|
|
|
- charging_state = STATE_DISCHARGING;
|
|
|
|
|
- }else if (cycle_count < MAX_CYCLES) {
|
|
|
|
|
|
|
+ if (cycle_count < MAX_CYCLES) {
|
|
|
charging_state = STATE_DISCHARGING;
|
|
charging_state = STATE_DISCHARGING;
|
|
|
cycle_count++;
|
|
cycle_count++;
|
|
|
|
|
+ battery->cycle_number= cycle_count;
|
|
|
|
|
+ cv_charging_started= false;
|
|
|
|
|
+ printf("DISCHARGING\n");
|
|
|
|
|
+
|
|
|
}else {
|
|
}else {
|
|
|
charging_state = STATE_FINAL_DISCHARGE;
|
|
charging_state = STATE_FINAL_DISCHARGE;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
// 5. State Discharging condition
|
|
// 5. State Discharging condition
|
|
|
-
|
|
|
|
|
- else if (charging_state == STATE_DISCHARGING &&
|
|
|
|
|
- batt_voltage <= batt_min_voltage + BATTERY_THRESHOLD) {
|
|
|
|
|
|
|
+ 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);
|
|
DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
charging_state = STATE_CC_CHARGING;
|
|
charging_state = STATE_CC_CHARGING;
|
|
|
cv_charging_started = false;
|
|
cv_charging_started = false;
|
|
|
|
|
+ printf("DISCHARGE -> CC CHARGING\n");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//6. Check if the battery is overcharged
|
|
//6. Check if the battery is overcharged
|
|
|
else if (batt_voltage > batt_max_voltage) {
|
|
else if (batt_voltage > batt_max_voltage) {
|
|
|
charging_state = STATE_ERROR;
|
|
charging_state = STATE_ERROR;
|
|
|
|
|
+ printf("ERROR\n");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ //Handling MCU reset:
|
|
|
// 8. Hold previous state if none of the condition matches (Previously,
|
|
// 8. Hold previous state if none of the condition matches (Previously,
|
|
|
// CV_STATE was jumping directly to STATE_ERROR in else statement, to handle
|
|
// CV_STATE was jumping directly to STATE_ERROR in else statement, to handle
|
|
|
// the condition better, else condition is being changed).
|
|
// the condition better, else condition is being changed).
|
|
|
else {
|
|
else {
|
|
|
- printf("[CC-CV] Current state: Voltage= %d mV, Current= %d mA\n, Current Cycle= %c\n",
|
|
|
|
|
|
|
+ printf("[CC-CV] Current state: Voltage= %d mV, Current= %d mA\n, Current Cycle= %d\n",
|
|
|
batt_voltage, batt_current, charging_state);
|
|
batt_voltage, batt_current, charging_state);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -136,7 +142,7 @@ voltage threshold is obtained.
|
|
|
void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
|
// Calling function to get all the conditional states
|
|
// Calling function to get all the conditional states
|
|
|
CC_CV_UpdateChargingState(slot_id);
|
|
CC_CV_UpdateChargingState(slot_id);
|
|
|
- int16_t charge_current= 50;
|
|
|
|
|
|
|
+ int16_t charge_current= 100;
|
|
|
batt_voltage = battery_data[slot_id].battery_measurement.voltage;
|
|
batt_voltage = battery_data[slot_id].battery_measurement.voltage;
|
|
|
batt_current= battery_data[slot_id].battery_measurement.current;
|
|
batt_current= battery_data[slot_id].battery_measurement.current;
|
|
|
batt_min_voltage= battery_data[slot_id].min_voltage;
|
|
batt_min_voltage= battery_data[slot_id].min_voltage;
|
|
@@ -155,36 +161,33 @@ void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
|
static bool chargeCurrent_initialized= false;
|
|
static bool chargeCurrent_initialized= false;
|
|
|
|
|
|
|
|
switch (charging_state) {
|
|
switch (charging_state) {
|
|
|
-
|
|
|
|
|
// PRE CHARGE STATE: Battery Voltage is lesser than 3000 mVolts
|
|
// PRE CHARGE STATE: Battery Voltage is lesser than 3000 mVolts
|
|
|
case STATE_PRE_CHARGE:
|
|
case STATE_PRE_CHARGE:
|
|
|
-
|
|
|
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
|
controller_SetCurrent(slot_id, charge_current);
|
|
controller_SetCurrent(slot_id, charge_current);
|
|
|
- if (true) {
|
|
|
|
|
- printf("PRE CHARGING: Slot %d at %d mA.\n", slot_id, charge_current);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ printf("PRE CHARGING: Slot %d at %d mA.\n", slot_id, charge_current);
|
|
|
|
|
+ chargeCurrent_initialized= false;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
// CC CHARGING STATE: Keeps on checking the condition until battery voltage
|
|
// CC CHARGING STATE: Keeps on checking the condition until battery voltage
|
|
|
- // reaches to (MAXIMUM_VOLTAGE-BATTERY_THRESHOLD)= 4150 mVolts
|
|
|
|
|
|
|
+ // reaches to (MAXIMUM_VOLTAGE(4200)-BATTERY_THRESHOLD(20))= 4180 mV
|
|
|
case STATE_CC_CHARGING:
|
|
case STATE_CC_CHARGING:
|
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
|
controller_SetCurrent(slot_id, charge_current);
|
|
controller_SetCurrent(slot_id, charge_current);
|
|
|
printf("CC CHARGING: Slot %d, Current: %d mA, Voltage: %d mV.\n", slot_id, batt_current, batt_voltage);
|
|
printf("CC CHARGING: Slot %d, Current: %d mA, Voltage: %d mV.\n", slot_id, batt_current, batt_voltage);
|
|
|
|
|
+ chargeCurrent_initialized= false;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
// CV CHARGING STATE: Keeps on checking the condition until battery current
|
|
// CV CHARGING STATE: Keeps on checking the condition until battery current
|
|
|
- // decreases till it exceeds (CUTOFF_CURRENT_MA + BATTERY_THRESHOLD)= 290 mAs
|
|
|
|
|
|
|
+ // decreases till it lowers to (CUTOFF_CURRENT_MA + BATTERY_THRESHOLD)
|
|
|
case STATE_CV_CHARGING:
|
|
case STATE_CV_CHARGING:
|
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
|
-
|
|
|
|
|
if(!chargeCurrent_initialized){
|
|
if(!chargeCurrent_initialized){
|
|
|
cvChargingPhaseCurrent= charge_current;
|
|
cvChargingPhaseCurrent= charge_current;
|
|
|
chargeCurrent_initialized= true;
|
|
chargeCurrent_initialized= true;
|
|
|
}
|
|
}
|
|
|
- //battery current > 200 for 250 cut_off_current and 50 threshold
|
|
|
|
|
- if (batt_current > batt_cutoff_current - BATTERY_THRESHOLD) {
|
|
|
|
|
|
|
+ //batt_cutoff_current: 75, BATTERY_THRESHOLD: 20
|
|
|
|
|
+ if (batt_current >= batt_cutoff_current - BATTERY_THRESHOLD) {
|
|
|
// Detect steep voltage drop:
|
|
// Detect steep voltage drop:
|
|
|
if (last_voltage != 0 && (last_voltage - batt_voltage) > 100) {
|
|
if (last_voltage != 0 && (last_voltage - batt_voltage) > 100) {
|
|
|
printf("!!! CV CHARGING: Voltage dropped too fast: %d -> %d mV.\n", last_voltage, batt_voltage);
|
|
printf("!!! CV CHARGING: Voltage dropped too fast: %d -> %d mV.\n", last_voltage, batt_voltage);
|
|
@@ -192,19 +195,23 @@ void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
cvChargingPhaseCurrent-= 5;
|
|
cvChargingPhaseCurrent-= 5;
|
|
|
|
|
+ // Lower bound so that the charge current does not go to negative
|
|
|
|
|
+ if (cvChargingPhaseCurrent < BATTERY_THRESHOLD) {
|
|
|
|
|
+ charging_state= STATE_DISCHARGING;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- last_voltage = batt_voltage;
|
|
|
|
|
controller_SetCurrent(slot_id, cvChargingPhaseCurrent);
|
|
controller_SetCurrent(slot_id, cvChargingPhaseCurrent);
|
|
|
|
|
+ last_voltage = batt_voltage;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case STATE_DISCHARGING:
|
|
case STATE_DISCHARGING:
|
|
|
DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
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);
|
|
DL_GPIO_setPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
//controller_EvaluateBatterySlotState(slot_id, BatteryMeasurement *measurement);
|
|
//controller_EvaluateBatterySlotState(slot_id, BatteryMeasurement *measurement);
|
|
|
- controller_SetCurrent(slot_id, charge_current);
|
|
|
|
|
|
|
+ controller_SetCurrent(slot_id, (-1 * charge_current));
|
|
|
printf("DISCHARGING: Slot %d at %d mA.\n", slot_id, batt_current);
|
|
printf("DISCHARGING: Slot %d at %d mA.\n", slot_id, batt_current);
|
|
|
-
|
|
|
|
|
|
|
+ chargeCurrent_initialized= false;
|
|
|
//Safety Check
|
|
//Safety Check
|
|
|
if(batt_voltage< batt_min_voltage){
|
|
if(batt_voltage< batt_min_voltage){
|
|
|
charging_state= STATE_ERROR;
|
|
charging_state= STATE_ERROR;
|
|
@@ -219,22 +226,25 @@ void CC_CV_ControlCharging(uint8_t slot_id) {
|
|
|
DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
controller_SetCurrent(slot_id, 0);
|
|
controller_SetCurrent(slot_id, 0);
|
|
|
charging_state = STATE_IDLE;
|
|
charging_state = STATE_IDLE;
|
|
|
|
|
+ chargeCurrent_initialized= false;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case STATE_ERROR:
|
|
case STATE_ERROR:
|
|
|
DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
|
DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
printf("ERROR: Slot %d.\n", slot_id);
|
|
printf("ERROR: Slot %d.\n", slot_id);
|
|
|
|
|
+ chargeCurrent_initialized= false;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case STATE_IDLE:
|
|
case STATE_IDLE:
|
|
|
DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB7_PIN);
|
|
|
DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB6_PIN);
|
|
|
//charging_state = STATE_PRE_CHARGE;
|
|
//charging_state = STATE_PRE_CHARGE;
|
|
|
|
|
+ chargeCurrent_initialized= false;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
default:
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
+}
|
|
|
// End of the file
|
|
// End of the file
|