Update Acett v05 BMS support app to version 18
authorNathael Pajani <nathael.pajani@ed3l.fr>
Wed, 18 Aug 2021 08:20:24 +0000 (10:20 +0200)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Wed, 18 Aug 2021 08:20:24 +0000 (10:20 +0200)
Change protection levels
Prevent from emptying the battery before a long storage without charge

apps/acett/v05/main.c
apps/acett/v05/version.h

index f201e13..08d7985 100644 (file)
@@ -220,12 +220,12 @@ void bms_config(void)
        }
 
        /* Configure battery limits :
-        * - Cell uvlo : 2600mV
+        * - Cell uvlo : 2700mV
         * - Cell ovp : 3650mV
         * - scd is 22mV (0x00) : 22mV / 5mOhms = 4.4 Amps
         * - ocd is 14mV (0x02) : 14mV / 5mOhms = 2.8 Amps
         */
-       uvlo16 = ((2600 - bms.adc_offset) * 1000) / bms.adc_gain_uV;
+       uvlo16 = ((2700 - bms.adc_offset) * 1000) / bms.adc_gain_uV;
        uvlo = ((uvlo16 >> 4) & 0xFF);
        ovp16 = ((3650 - bms.adc_offset) * 1000) / bms.adc_gain_uV;
        ovp = ((ovp16 >> 4) & 0xFF);
@@ -233,7 +233,7 @@ void bms_config(void)
        if (ret != 0) {
                debug_uprintf("BMS limit configuration error: %d (%d)!\n", ret, bms.probe_ok);
        } else {
-               debug_uprintf("Limits set. \n UVLO: 2.6V (0x%02x), OVP: 3.65V (0x%02x)\n",      uvlo, ovp);
+               debug_uprintf("Limits set. \n UVLO: 2.7V (0x%02x), OVP: 3.65V (0x%02x)\n",      uvlo, ovp);
                debug_uprintf(" SCD: 4.4A (22mV), OCD: 2.8A (14mV)\n");
        }
 
@@ -265,6 +265,7 @@ void bms_config(void)
 
 
 
+#define BATT_ABSOLUTE_MAX_THEORY   (320 * 1000 * 1000)  /* 85Wh * 3600s * 1000 in order to get "mW * s" */
 /*
  * Power computation is the following :
  * E = P * t = U * I * t = Ut * Um / R * t
@@ -390,9 +391,12 @@ int periodic_check(void)
                                charge = 0;
                                vbat_charge_hysteresis = VBAT_HYSTERESIS;
                                debug_uprintf("BMS detected over charge for cell %d, charge turned OFF\n", cnt);
+                               /* Fix for end of charge detection, limited discharge and fuel gauge compatibility */
+                               debug_uprintf("Battery reaching full charge.\n");
+                               batt_power = BATT_ABSOLUTE_MAX_THEORY;
                        }
-                       if (v < 2650) {
-                               /* Do not discharge below 2.65 Volt */
+                       if (v < 2850) {
+                               /* Do not discharge below 2.85 Volt */
                                discharge = 0;
                                vbat_discharge_hysteresis = VBAT_HYSTERESIS;
                                debug_uprintf("BMS detected over discharge for cell %d, discharge turned OFF\n", cnt);
@@ -416,13 +420,37 @@ int periodic_check(void)
                                vcells_max = v;
                        }
                }
-               /* Also turn off discharge if voltage is below 11.2V */
-#define VBATT_MIN_DISCHARGE_OK  11200
+               /* Also turn off discharge if voltage is below 11.8V */
+#define VBATT_MIN_DISCHARGE_OK  11800
                if (vbatt < (VBATT_MIN_DISCHARGE_OK)) {
                        discharge = 0;
                        vbat_discharge_hysteresis = VBAT_HYSTERESIS;
                }
                debug_uprintf("Battery voltage : %d (mV)\n", vbatt);
+
+               /* If charged to max voltage, set energy to max therorical level.
+                * This allows reaching full charge indicator while starting at unknown battery charge, and is made
+                *  necessary by the low energy cut-off to prevent full discharge.
+                */
+#if 0
+#define VBATT_CHARGE_OK  13800
+#define VCELL_CHARGE_MIN  3200
+               if (vbatt > VBATT_CHARGE_OK) {
+                       int ch_ok = 1;
+                       for (i = 0, cnt = 0; i < BMS_NB_CELLS; i++) {
+                               /* Real number of cells is 4, so skip cell number 3 */
+                               if (i == 3) { continue; }
+                               if (bdata.vcells[cnt++] < VCELL_CHARGE_MIN) {
+                                       ch_ok = 0;
+                               }
+                       }
+                       if (ch_ok == 1) {
+                               debug_uprintf("Battery reaching full charge.\n");
+                               batt_power = BATT_ABSOLUTE_MAX_THEORY;
+                       }
+               }
+#endif
+
        }
        if (vbat_charge_hysteresis > 0) {
                vbat_charge_hysteresis--;
@@ -461,7 +489,7 @@ int periodic_check(void)
 
                        /* Compute power */
                        cycle_power = ((vbatt * tmp) / (20 * 1000)); /* vbatt is in mV */
-                       debug_uprintf("Power: %d (mWs)\n", cycle_power);
+                       debug_uprintf("Cycle power: %d (mWs)\n", cycle_power);
                        if ((cycle_power > 0) || (batt_power > abs(cycle_power))) {
                                /* Self discharge is OK, but not "self charge" */
                                if (abs(cycle_power) < 20) {
@@ -490,7 +518,6 @@ int periodic_check(void)
 
                        /* Update max battery power, but not above the theorical limit.
                         * This has been added to compensate coulomb counter inaccuracy. */
-#define BATT_ABSOLUTE_MAX_THEORY   (320 * 1000 * 1000)  /* 85Wh * 3600s * 1000 in order to get "mW * s" */
                        if (batt_power > BATT_ABSOLUTE_MAX_THEORY) {
                                batt_power = BATT_ABSOLUTE_MAX_THEORY;
                        }
@@ -505,7 +532,7 @@ int periodic_check(void)
                                }
                        }
                        /* Shift by 10 is equivalent to divide by approx 10^3 (1024) */
-                       debug_uprintf("Battery remaining power : %d/%d (Ws)\n", (batt_power >> 10), (batt_power_max >> 10)); /* divide by 1024 */
+                       debug_uprintf("Battery power : %d/%d (Ws)\n", (batt_power >> 10), (batt_power_max >> 10)); /* divide by 1024 */
 
                        /* Count 1 cycle for each battery event */
                        cycles++;
@@ -527,6 +554,15 @@ int periodic_check(void)
                discharge = 0;
        }
 
+       /* Prevent from emptying the battery before a long storage without charge */
+#define BATT_MIN_STORAGE_RESERVE (4 * 1000 * 1000)
+       if (batt_power < BATT_MIN_STORAGE_RESERVE) {
+               if (milli_amps < 30) {
+                       discharge = 0;
+                       debug_uprintf("Discharge turned off for battery protection\n");
+               }
+       }
+
        /* Update battery state based on errors and old state immediately */
        if ((charge != charge_state) || (discharge != discharge_state)) {
                msleep(2);
@@ -581,7 +617,15 @@ int periodic_check(void)
                        cksum += data[i];
                }
 
-               debug_uprintf("Tick : %d - State C: %d, D: %d\n", systick_get_tick_count(), charge_state, discharge_state);
+               debug_uprintf("Tick : %d - State C: %d, D: %d, HVC: %d, HVD: %d, HTC: %d, HTD: %d, HIC: %d, HID: %d\n",
+                                                               systick_get_tick_count(),
+                                                               charge_state, discharge_state,
+                                                               vbat_charge_hysteresis,
+                                                               vbat_discharge_hysteresis,
+                                                               thermistor_charge_hysteresis,
+                                                               thermistor_discharge_hysteresis,
+                                                               icharge_hysteresis,
+                                                               idischarge_hysteresis);
 
                bdata.checksum = (uint8_t)(256 - cksum);
                serial_write(UART1, (char*)(&bdata), sizeof(struct bms_data));
index 119431f..5bf0f8a 100644 (file)
@@ -1,3 +1,3 @@
 #define MODULE_VERSION_STR  "v0.5"
-#define SOFT_VERSION_STR  "CEM"
-#define COMPILE_VERSION "17"
+#define SOFT_VERSION_STR  "SAM BMS"
+#define COMPILE_VERSION "18"