hitl_tester.test_cases.bms.test_2590_live

See: MIL-PRF-32383 (2590)

This file contains tests to confirm a minimum viable product, as laid out in Issue 158 of the HITL repository.

Used in these test plans:

  • live_2590_b_test ⠀⠀⠀(bms/live_2590_b_test.plan)
  • live_2590_a_test ⠀⠀⠀(bms/live_2590_a_test.plan)

Example Command (warning: test plan may run other test cases):

  • ./hitl_tester.py live_2590_b_test -DDISCHARGE_VOLTAGE=10 -DREST_TIME=10800 -DSAMPLE_INTERVAL=10 -DDISCHARGE_5_PERCENT_TIME=1300 -DCHARGE_5_PERCENT_TIME=1300 -DPLATESET=<hitl_tester.modules.bms.plateset.Plateset object at 0x7f34798a3ce0>
  1"""
  2See: MIL-PRF-32383 (2590)
  3
  4This file contains tests to confirm a minimum viable product, as laid out in Issue 158 of the HITL repository.
  5"""
  6
  7from __future__ import annotations
  8
  9import time
 10
 11import pytest
 12
 13from hitl_tester.modules.bms.bms_hw import BMSHardware
 14from hitl_tester.modules.bms.plateset import Plateset
 15from hitl_tester.modules.bms_types import TimeoutExceededError, DischargeType
 16from hitl_tester.modules.logger import logger
 17
 18DISCHARGE_VOLTAGE = 10
 19REST_TIME = 3 * 3600
 20SAMPLE_INTERVAL = 10
 21DISCHARGE_5_PERCENT_TIME = 1300
 22CHARGE_5_PERCENT_TIME = 1300
 23
 24bms_hardware = BMSHardware(pytest.flags)  # type: ignore[arg-type]
 25bms_hardware.init()
 26
 27PLATESET = Plateset()
 28
 29
 30# Capacity Discharge
 31
 32
 33def standard_charge(
 34    charge_current: float = 3,
 35    max_time: float = 3 * 3600,
 36    sample_interval: float = 10,
 37    ov_protection: float | None = None,
 38    termination_current: float = 0.100,
 39):
 40    """
 41    Charge batteries in accordance with 4.3.1 for not greater than three hours.
 42    4.3.1 = 23 ± 5°C (73.4°F) ambient pressure/relative humidity, with 2+ hours between charge and discharge.
 43    """
 44    bms_hardware.voltage = 16.8
 45    bms_hardware.ov_protection = ov_protection or (bms_hardware.voltage + 0.050)  # 50mV above the charging voltage
 46    bms_hardware.current = charge_current
 47    bms_hardware.termination_current = termination_current
 48    bms_hardware.max_time = max_time
 49    bms_hardware.sample_interval = sample_interval
 50    bms_hardware.minimum_readings = 3
 51
 52    # Run the Charge cycle
 53    bms_hardware.run_li_charge_cycle()
 54
 55
 56def standard_discharge(
 57    discharge_current: float = 2, max_time: float = 8 * 3600, sample_interval: float = 10, discharge_voltage: float = 10
 58):
 59    """Discharge at 2A until 10V."""
 60    bms_hardware.voltage = discharge_voltage
 61    bms_hardware.uv_protection = bms_hardware.voltage - 0.050  # 50mV below voltage cutoff
 62    bms_hardware.current = discharge_current
 63    bms_hardware.discharge_type = DischargeType.CONSTANT_CURRENT
 64    bms_hardware.max_time = max_time
 65    bms_hardware.sample_interval = sample_interval
 66
 67    # Run the discharge cycle, returning the capacity
 68    capacity = bms_hardware.run_discharge_cycle()
 69    logger.write_info_to_report(f"Discharge complete, capacity was {capacity * 1000.0} mAh")
 70    return capacity
 71
 72
 73def standard_rest(seconds: int = 0, sample_interval: int = 0):
 74    """Stabilize the batteries for 2+ hours."""
 75    bms_hardware.max_time = seconds or REST_TIME
 76    bms_hardware.sample_interval = sample_interval or SAMPLE_INTERVAL
 77    bms_hardware.run_resting_cycle()
 78
 79
 80def test_activate_faults():
 81    """Short discharge to activate faults in 206."""
 82    old_cycle_function = bms_hardware.csv.cycle
 83    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
 84    bms_hardware.csv.cycle.create_file()
 85    # PLATESET.ce_switch = True  # Allows current charging in excess of 400 mA
 86    # try:
 87    #    standard_charge(max_time=2 * 3600, sample_interval=10)
 88    # except TimeoutExceededError:
 89    #    bms_hardware.charger.disable()
 90    # PLATESET.ce_switch = False
 91    try:
 92        standard_discharge(max_time=2 * 60, sample_interval=10, discharge_current=0.200)
 93    except TimeoutExceededError:
 94        bms_hardware.load.disable()
 95    bms_hardware.csv.cycle = old_cycle_function
 96
 97
 98def test_capacity_discharge():
 99    """
100    Discharge at 2A (per Mil-prf/5) and capture voltage, coulomb, temp, (normal full test) as well as SMBus.
101    Ping SMBus a total of 1800 times over the 5 hour test (i.e. every 10 seconds).
102    """
103    old_cycle_function = bms_hardware.csv.cycle
104    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
105    bms_hardware.csv.cycle.create_file()
106    PLATESET.ce_switch = True  # Allows current charging in excess of 400 mA
107    standard_charge(max_time=8 * 3600, sample_interval=1)
108    PLATESET.ce_switch = False
109    standard_discharge(sample_interval=1, discharge_voltage=DISCHARGE_VOLTAGE)
110    bms_hardware.csv.cycle = old_cycle_function
111
112
113def test_resting(max_time: int = 30 * 60, sample_interval=10):
114    """Record SMBus data while at rest."""
115    old_cycle_function = bms_hardware.csv.cycle
116    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
117    bms_hardware.csv.cycle.create_file()
118    start_time = time.perf_counter()
119    while time.perf_counter() - start_time <= max_time:
120        bms_hardware.csv.cycle.record(time.perf_counter() - start_time, 0.0)
121        time.sleep(sample_interval)
122    bms_hardware.csv.cycle = old_cycle_function
123
124
125# Extensive Battery Charging and Discharging (https://github.com/turnaroundfactor/battery-benchtop-rev1/issues/197)
126
127
128def test_extensive_discharge_1():
129    """
130    Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
131    then discharge under the excited threshold hold for 3 hours, and then rest.
132    """
133    old_cycle_function = bms_hardware.csv.cycle
134    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
135    bms_hardware.csv.cycle.create_file()
136
137    try:
138        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
139    except TimeoutExceededError:
140        bms_hardware.load.disable()
141    try:
142        standard_discharge(max_time=3 * 60 * 60, sample_interval=10, discharge_current=0.050)
143    except TimeoutExceededError:
144        bms_hardware.load.disable()
145    test_resting(max_time=30 * 60)
146
147    bms_hardware.csv.cycle = old_cycle_function
148
149
150def test_extensive_discharge_2():
151    """
152    Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
153    discharge under the threshold for LESS than 3 hours (30 minutes is probably fine), then discharge excited for at
154    least another 5%.
155    """
156    old_cycle_function = bms_hardware.csv.cycle
157    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
158    bms_hardware.csv.cycle.create_file()
159
160    try:
161        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
162    except TimeoutExceededError:
163        bms_hardware.load.disable()
164    try:
165        standard_discharge(max_time=30 * 60, sample_interval=10, discharge_current=0.050)
166    except TimeoutExceededError:
167        bms_hardware.load.disable()
168    try:
169        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
170    except TimeoutExceededError:
171        bms_hardware.load.disable()
172    test_resting(max_time=30 * 60)
173
174    bms_hardware.csv.cycle = old_cycle_function
175
176
177def test_extensive_discharge_3():
178    """
179    Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
180    and then rest with no current being discharged for 3 hours.
181    """
182    old_cycle_function = bms_hardware.csv.cycle
183    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
184    bms_hardware.csv.cycle.create_file()
185
186    try:
187        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
188    except TimeoutExceededError:
189        bms_hardware.load.disable()
190    test_resting(max_time=3 * 60 * 60)
191
192    bms_hardware.csv.cycle = old_cycle_function
193
194
195def test_extensive_charge_1():
196    """
197    Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
198    then charge under the excited threshold hold for 3 hours, and then rest.
199    """
200    old_cycle_function = bms_hardware.csv.cycle
201    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
202    bms_hardware.csv.cycle.create_file()
203
204    PLATESET.ce_switch = True
205    try:
206        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
207    except TimeoutExceededError:
208        bms_hardware.charger.disable()
209    try:
210        standard_charge(max_time=3 * 60 * 60, sample_interval=10, charge_current=0.010, termination_current=0)
211    except TimeoutExceededError:
212        bms_hardware.charger.disable()
213    PLATESET.ce_switch = False
214    test_resting(max_time=30 * 60)
215
216    bms_hardware.csv.cycle = old_cycle_function
217
218
219def test_watchdog_reset():
220    """
221    A test designed to trigger the watchdog reset.
222    """
223    old_cycle_function = bms_hardware.csv.cycle
224    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
225    bms_hardware.csv.cycle.create_file()
226
227    PLATESET.ce_switch = True
228    try:
229        standard_charge(max_time=60, sample_interval=0.001)
230    except TimeoutExceededError:
231        bms_hardware.charger.disable()
232    try:
233        standard_charge(max_time=30 * 60, sample_interval=0.001, charge_current=0.010, termination_current=0.001)
234    except TimeoutExceededError:
235        bms_hardware.charger.disable()
236    try:
237        standard_charge(max_time=60, sample_interval=0.001)
238    except TimeoutExceededError:
239        bms_hardware.charger.disable()
240    PLATESET.ce_switch = False
241    test_resting(max_time=30 * 60)
242
243    bms_hardware.csv.cycle = old_cycle_function
244
245
246def test_extensive_charge_2():
247    """
248    Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
249    charge under the threshold for LESS than 3 hours (30 minutes is probably fine), then charge excited for at
250    least another 5%.
251    """
252    old_cycle_function = bms_hardware.csv.cycle
253    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
254    bms_hardware.csv.cycle.create_file()
255
256    PLATESET.ce_switch = True
257    try:
258        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
259    except TimeoutExceededError:
260        bms_hardware.charger.disable()
261    try:
262        standard_charge(max_time=30 * 60, sample_interval=10, charge_current=0.010, termination_current=0.001)
263    except TimeoutExceededError:
264        bms_hardware.charger.disable()
265    try:
266        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
267    except TimeoutExceededError:
268        bms_hardware.charger.disable()
269    PLATESET.ce_switch = False
270
271    bms_hardware.csv.cycle = old_cycle_function
272
273
274def test_extensive_charge_3():
275    """
276    Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
277    and then rest with no current being charged for 3 hours.
278    """
279    old_cycle_function = bms_hardware.csv.cycle
280    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
281    bms_hardware.csv.cycle.create_file()
282
283    PLATESET.ce_switch = True
284    try:
285        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
286    except TimeoutExceededError:
287        bms_hardware.charger.disable()
288    PLATESET.ce_switch = False
289    test_resting(max_time=3 * 60 * 60)
290
291    bms_hardware.csv.cycle = old_cycle_function
292
293
294def test_standard_rest():
295    """Stabilize the batteries for some time."""
296    old_cycle_function = bms_hardware.csv.cycle
297    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
298    standard_rest()
299    bms_hardware.csv.cycle = old_cycle_function
300
301
302def test_relaxed_soc():
303    """
304    | Requirement          | Test relaxed SOC |
305    | :------------------- | :---------------------------------- |
306    | GitHub Issue         | #309 (BMS)                          |
307    | Instructions         | 1. Rest for 30 seconds </br>\
308                             2. Charge at 3A, for 2 hours </br>\
309                             3. Rest for 3 hours & 6 minutes |
310    | Pass / Fail Criteria | SOC is measured correctly |
311    """
312    old_cycle_function = bms_hardware.csv.cycle
313    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
314    bms_hardware.csv.cycle.create_file()
315
316    standard_rest(30, 10)
317    PLATESET.ce_switch = True
318    try:
319        standard_charge(max_time=2 * 3600, sample_interval=10)
320    except TimeoutExceededError:
321        bms_hardware.charger.disable()
322    PLATESET.ce_switch = False
323    standard_rest(3 * 3600 + 6 * 60, 10)
324
325    bms_hardware.csv.cycle = old_cycle_function
DISCHARGE_VOLTAGE = 10
REST_TIME = 10800
SAMPLE_INTERVAL = 10
DISCHARGE_5_PERCENT_TIME = 1300
CHARGE_5_PERCENT_TIME = 1300
def standard_charge( charge_current: float = 3, max_time: float = 10800, sample_interval: float = 10, ov_protection: float | None = None, termination_current: float = 0.1):
34def standard_charge(
35    charge_current: float = 3,
36    max_time: float = 3 * 3600,
37    sample_interval: float = 10,
38    ov_protection: float | None = None,
39    termination_current: float = 0.100,
40):
41    """
42    Charge batteries in accordance with 4.3.1 for not greater than three hours.
43    4.3.1 = 23 ± 5°C (73.4°F) ambient pressure/relative humidity, with 2+ hours between charge and discharge.
44    """
45    bms_hardware.voltage = 16.8
46    bms_hardware.ov_protection = ov_protection or (bms_hardware.voltage + 0.050)  # 50mV above the charging voltage
47    bms_hardware.current = charge_current
48    bms_hardware.termination_current = termination_current
49    bms_hardware.max_time = max_time
50    bms_hardware.sample_interval = sample_interval
51    bms_hardware.minimum_readings = 3
52
53    # Run the Charge cycle
54    bms_hardware.run_li_charge_cycle()

Charge batteries in accordance with 4.3.1 for not greater than three hours. 4.3.1 = 23 ± 5°C (73.4°F) ambient pressure/relative humidity, with 2+ hours between charge and discharge.

def standard_discharge( discharge_current: float = 2, max_time: float = 28800, sample_interval: float = 10, discharge_voltage: float = 10):
57def standard_discharge(
58    discharge_current: float = 2, max_time: float = 8 * 3600, sample_interval: float = 10, discharge_voltage: float = 10
59):
60    """Discharge at 2A until 10V."""
61    bms_hardware.voltage = discharge_voltage
62    bms_hardware.uv_protection = bms_hardware.voltage - 0.050  # 50mV below voltage cutoff
63    bms_hardware.current = discharge_current
64    bms_hardware.discharge_type = DischargeType.CONSTANT_CURRENT
65    bms_hardware.max_time = max_time
66    bms_hardware.sample_interval = sample_interval
67
68    # Run the discharge cycle, returning the capacity
69    capacity = bms_hardware.run_discharge_cycle()
70    logger.write_info_to_report(f"Discharge complete, capacity was {capacity * 1000.0} mAh")
71    return capacity

Discharge at 2A until 10V.

def standard_rest(seconds: int = 0, sample_interval: int = 0):
74def standard_rest(seconds: int = 0, sample_interval: int = 0):
75    """Stabilize the batteries for 2+ hours."""
76    bms_hardware.max_time = seconds or REST_TIME
77    bms_hardware.sample_interval = sample_interval or SAMPLE_INTERVAL
78    bms_hardware.run_resting_cycle()

Stabilize the batteries for 2+ hours.

def test_activate_faults():
81def test_activate_faults():
82    """Short discharge to activate faults in 206."""
83    old_cycle_function = bms_hardware.csv.cycle
84    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
85    bms_hardware.csv.cycle.create_file()
86    # PLATESET.ce_switch = True  # Allows current charging in excess of 400 mA
87    # try:
88    #    standard_charge(max_time=2 * 3600, sample_interval=10)
89    # except TimeoutExceededError:
90    #    bms_hardware.charger.disable()
91    # PLATESET.ce_switch = False
92    try:
93        standard_discharge(max_time=2 * 60, sample_interval=10, discharge_current=0.200)
94    except TimeoutExceededError:
95        bms_hardware.load.disable()
96    bms_hardware.csv.cycle = old_cycle_function

Short discharge to activate faults in 206.

def test_capacity_discharge():
 99def test_capacity_discharge():
100    """
101    Discharge at 2A (per Mil-prf/5) and capture voltage, coulomb, temp, (normal full test) as well as SMBus.
102    Ping SMBus a total of 1800 times over the 5 hour test (i.e. every 10 seconds).
103    """
104    old_cycle_function = bms_hardware.csv.cycle
105    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
106    bms_hardware.csv.cycle.create_file()
107    PLATESET.ce_switch = True  # Allows current charging in excess of 400 mA
108    standard_charge(max_time=8 * 3600, sample_interval=1)
109    PLATESET.ce_switch = False
110    standard_discharge(sample_interval=1, discharge_voltage=DISCHARGE_VOLTAGE)
111    bms_hardware.csv.cycle = old_cycle_function

Discharge at 2A (per Mil-prf/5) and capture voltage, coulomb, temp, (normal full test) as well as SMBus. Ping SMBus a total of 1800 times over the 5 hour test (i.e. every 10 seconds).

def test_resting(max_time: int = 1800, sample_interval=10):
114def test_resting(max_time: int = 30 * 60, sample_interval=10):
115    """Record SMBus data while at rest."""
116    old_cycle_function = bms_hardware.csv.cycle
117    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
118    bms_hardware.csv.cycle.create_file()
119    start_time = time.perf_counter()
120    while time.perf_counter() - start_time <= max_time:
121        bms_hardware.csv.cycle.record(time.perf_counter() - start_time, 0.0)
122        time.sleep(sample_interval)
123    bms_hardware.csv.cycle = old_cycle_function

Record SMBus data while at rest.

def test_extensive_discharge_1():
129def test_extensive_discharge_1():
130    """
131    Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
132    then discharge under the excited threshold hold for 3 hours, and then rest.
133    """
134    old_cycle_function = bms_hardware.csv.cycle
135    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
136    bms_hardware.csv.cycle.create_file()
137
138    try:
139        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
140    except TimeoutExceededError:
141        bms_hardware.load.disable()
142    try:
143        standard_discharge(max_time=3 * 60 * 60, sample_interval=10, discharge_current=0.050)
144    except TimeoutExceededError:
145        bms_hardware.load.disable()
146    test_resting(max_time=30 * 60)
147
148    bms_hardware.csv.cycle = old_cycle_function

Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited, then discharge under the excited threshold hold for 3 hours, and then rest.

def test_extensive_discharge_2():
151def test_extensive_discharge_2():
152    """
153    Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
154    discharge under the threshold for LESS than 3 hours (30 minutes is probably fine), then discharge excited for at
155    least another 5%.
156    """
157    old_cycle_function = bms_hardware.csv.cycle
158    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
159    bms_hardware.csv.cycle.create_file()
160
161    try:
162        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
163    except TimeoutExceededError:
164        bms_hardware.load.disable()
165    try:
166        standard_discharge(max_time=30 * 60, sample_interval=10, discharge_current=0.050)
167    except TimeoutExceededError:
168        bms_hardware.load.disable()
169    try:
170        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
171    except TimeoutExceededError:
172        bms_hardware.load.disable()
173    test_resting(max_time=30 * 60)
174
175    bms_hardware.csv.cycle = old_cycle_function

Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited, discharge under the threshold for LESS than 3 hours (30 minutes is probably fine), then discharge excited for at least another 5%.

def test_extensive_discharge_3():
178def test_extensive_discharge_3():
179    """
180    Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
181    and then rest with no current being discharged for 3 hours.
182    """
183    old_cycle_function = bms_hardware.csv.cycle
184    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
185    bms_hardware.csv.cycle.create_file()
186
187    try:
188        standard_discharge(max_time=DISCHARGE_5_PERCENT_TIME, sample_interval=10)
189    except TimeoutExceededError:
190        bms_hardware.load.disable()
191    test_resting(max_time=3 * 60 * 60)
192
193    bms_hardware.csv.cycle = old_cycle_function

Discharge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited, and then rest with no current being discharged for 3 hours.

def test_extensive_charge_1():
196def test_extensive_charge_1():
197    """
198    Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
199    then charge under the excited threshold hold for 3 hours, and then rest.
200    """
201    old_cycle_function = bms_hardware.csv.cycle
202    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
203    bms_hardware.csv.cycle.create_file()
204
205    PLATESET.ce_switch = True
206    try:
207        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
208    except TimeoutExceededError:
209        bms_hardware.charger.disable()
210    try:
211        standard_charge(max_time=3 * 60 * 60, sample_interval=10, charge_current=0.010, termination_current=0)
212    except TimeoutExceededError:
213        bms_hardware.charger.disable()
214    PLATESET.ce_switch = False
215    test_resting(max_time=30 * 60)
216
217    bms_hardware.csv.cycle = old_cycle_function

Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited, then charge under the excited threshold hold for 3 hours, and then rest.

def test_watchdog_reset():
220def test_watchdog_reset():
221    """
222    A test designed to trigger the watchdog reset.
223    """
224    old_cycle_function = bms_hardware.csv.cycle
225    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
226    bms_hardware.csv.cycle.create_file()
227
228    PLATESET.ce_switch = True
229    try:
230        standard_charge(max_time=60, sample_interval=0.001)
231    except TimeoutExceededError:
232        bms_hardware.charger.disable()
233    try:
234        standard_charge(max_time=30 * 60, sample_interval=0.001, charge_current=0.010, termination_current=0.001)
235    except TimeoutExceededError:
236        bms_hardware.charger.disable()
237    try:
238        standard_charge(max_time=60, sample_interval=0.001)
239    except TimeoutExceededError:
240        bms_hardware.charger.disable()
241    PLATESET.ce_switch = False
242    test_resting(max_time=30 * 60)
243
244    bms_hardware.csv.cycle = old_cycle_function

A test designed to trigger the watchdog reset.

def test_extensive_charge_2():
247def test_extensive_charge_2():
248    """
249    Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
250    charge under the threshold for LESS than 3 hours (30 minutes is probably fine), then charge excited for at
251    least another 5%.
252    """
253    old_cycle_function = bms_hardware.csv.cycle
254    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
255    bms_hardware.csv.cycle.create_file()
256
257    PLATESET.ce_switch = True
258    try:
259        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
260    except TimeoutExceededError:
261        bms_hardware.charger.disable()
262    try:
263        standard_charge(max_time=30 * 60, sample_interval=10, charge_current=0.010, termination_current=0.001)
264    except TimeoutExceededError:
265        bms_hardware.charger.disable()
266    try:
267        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
268    except TimeoutExceededError:
269        bms_hardware.charger.disable()
270    PLATESET.ce_switch = False
271
272    bms_hardware.csv.cycle = old_cycle_function

Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited, charge under the threshold for LESS than 3 hours (30 minutes is probably fine), then charge excited for at least another 5%.

def test_extensive_charge_3():
275def test_extensive_charge_3():
276    """
277    Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited,
278    and then rest with no current being charged for 3 hours.
279    """
280    old_cycle_function = bms_hardware.csv.cycle
281    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
282    bms_hardware.csv.cycle.create_file()
283
284    PLATESET.ce_switch = True
285    try:
286        standard_charge(max_time=CHARGE_5_PERCENT_TIME, sample_interval=10)
287    except TimeoutExceededError:
288        bms_hardware.charger.disable()
289    PLATESET.ce_switch = False
290    test_resting(max_time=3 * 60 * 60)
291
292    bms_hardware.csv.cycle = old_cycle_function

Charge for at least 5% capacity (amount needed to calculate a new qmax) at a high enough current to be excited, and then rest with no current being charged for 3 hours.

def test_standard_rest():
295def test_standard_rest():
296    """Stabilize the batteries for some time."""
297    old_cycle_function = bms_hardware.csv.cycle
298    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
299    standard_rest()
300    bms_hardware.csv.cycle = old_cycle_function

Stabilize the batteries for some time.

def test_relaxed_soc():
303def test_relaxed_soc():
304    """
305    | Requirement          | Test relaxed SOC |
306    | :------------------- | :---------------------------------- |
307    | GitHub Issue         | #309 (BMS)                          |
308    | Instructions         | 1. Rest for 30 seconds </br>\
309                             2. Charge at 3A, for 2 hours </br>\
310                             3. Rest for 3 hours & 6 minutes |
311    | Pass / Fail Criteria | SOC is measured correctly |
312    """
313    old_cycle_function = bms_hardware.csv.cycle
314    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
315    bms_hardware.csv.cycle.create_file()
316
317    standard_rest(30, 10)
318    PLATESET.ce_switch = True
319    try:
320        standard_charge(max_time=2 * 3600, sample_interval=10)
321    except TimeoutExceededError:
322        bms_hardware.charger.disable()
323    PLATESET.ce_switch = False
324    standard_rest(3 * 3600 + 6 * 60, 10)
325
326    bms_hardware.csv.cycle = old_cycle_function
Requirement Test relaxed SOC
GitHub Issue #309 (BMS)
Instructions 1. Rest for 30 seconds
2. Charge at 3A, for 2 hours
3. Rest for 3 hours & 6 minutes
Pass / Fail Criteria SOC is measured correctly