배터리가 거의 찰 때까지는 전류로 빠르게, 거의 다 차면 전압을 고정하고 전류를 줄여서 안전하게 배터리를 충전한다.
CC-CV 충전 방식은 2가지 단계로 구성된다.
조건: V_terminal < 미리 정해둔 전압 임계값
동작: 일정한 전류 (예: 1C)로 충전
효과: SOC가 빠르게 올라감 (0% → ~80%)
조건: V_terminal이 미리 정해둔 전압 임계값에 도달
동작: 전압을 4.2V로 고정, 전류가 자연스럽게 줄어듦
효과: SOC가 천천히 올라감 (80% → 100%)
종료: 전류가 C/20 이하로 떨어지면 충전 완료
위의 동작: 전압을 4.2V로 고정, 전류가 자연스럽게 줄어듦을 보자.
왜 이렇게될까?
전압을 고정하면, SOC가 올라갈수록 OCV도 올라가서 전압 차이(ΔV)가 줄어들고, 자연스럽게 전류가 감소하게된다.


Battery CC-CV Block을 살펴보자. 배터리에 대한 CC(정전류) CV(정전압) 충전 알고리즘을 구현하는 블럭이라고 나와있다.

또한, Vmeas 가 Vmax를 넘어가는 경우PI제어를 통해 흐르는 전류를 줄여서 -> Vmeas를 낮추어서 Vmax에 도달하도록 한다.
BMS에도 PI제어가 쓰인다는 사실을 처음 알게되었다. 재밋군 ㅎㅎ.
(실제 BMS에서 Vmeas 가 Vmax를 넘어가는 경우, PI제어 출력값이 음수가 되는 경우에 대비하여 0 ≤ Icmd ≤ Imax 의 전류 클램프를 추가한다고한다)

실제로 파라미터 설정 대화상자에 들어가면 P,I 파라미터를 설정할 수도 있다.

우선, 안전 범위안에서 충전 전류의 최대값을 15A로 설정해준다.
CC단계에서 배터리는 이 값의 전류로 충전된다.

그리고 최대 셀 전압(=PI제어의 목표 값)을 4.1V 로 설정해준다.

이후, 셀의 전압을 Battery CC-CV Block 의 CellVoltage 포트에 연결해준다.

충, 방전이 동일한 전류 크기로 일어난다고 가정하고 진행할 것이다. 방전 전류를 Gain Block을 활용해서 -15A로 설정한다.
CC-CV 알고리즘은 SOC가 안전한 사용범위의 최소값/최대값에 도달하면 충전을 시작/종료한다.
■ SOC가 안전 최소값(예: 20%)에 도달 → 충전 시작!
■ SOC가 안전 최대값(예: 90%)에 도달 → 충전 종료!
최소값, 최대값을 정해놓는 이유는 아래와 같다.
SOC 0~100% 전체를 쓰면 배터리 수명이 급격히 줄어듦
0% 20% 90% 100%
|─────|════════════════════════════════|─────|
↑ ↑ ↑ ↑
과방전 안전 최소 안전 최대 과충전
위험! (충전 시작) (충전 종료) 위험!
◄──────── 실제 사용 영역 ────────►
• 과충전 (>90~100%) → 리튬 석출, 열폭주 위험
• 과방전 (<0~20%) → 구리 용출, 비가역적 손상
보통 이런 SOC의 사용범위의
최소값,최대값은 배터리 제조사에서 제공해준다.

Relay Block은 charing enable과 charging disable 신호를 만듬으로써 이를 쉽게 구현한다.
Relay Blcok를 가져오고 위와같이 파라미터를 설정해주자.
또한 현재 사용중인 배터리팩은 여러개의 배터리 셀들로 이루어져있다. 또한 직렬 연결된 배터리 셀들이 존재하므로 모든 셀에 같은전류가 흐른다.
따라서
max block을 사용해SOC가 가장 높은 셀 기준으로 충전 종료 판단을 해야한다.

위와 같이 SOC 추정값을 max block에 넣어서 최댓값을 필터링하고 -> 이를 Relay Block에 넣어서 Charing Enable 신호로 넣어준다. -> 이제 앞서 설정한 SOC의 사용범위의 최소값,최대값 파라미터를 기반으로 charing의 시작 시점과 종료 시점이 결정된다.
이제 피드백 루프가 거의 완성되었다.
그런데 이 상태로 Battery CC-CV Block의 출력을 걷바로 전류원에 입력으로 연결하면 대수 루프 (Algebraic Loop) 문제가 발생한다.
지금까지 만든 구조:
배터리 상태(V, SOC) → CC-CV 블록 → 출력: "이만큼 전류 흘려라" (I)
↓
이 전류를 다시 배터리에 넣어야 함!
↓
Controlled Current Source → 배터리
↓
배터리 상태가 변함 (V, SOC 변화)
↓
다시 CC-CV 블록으로 입력...
→ 이게 바로 "피드백 루프(Feedback Loop)"
만약 Delay 없이 위와 같이 피드백 루프를 만들면
Simulink: "어... 이 시점의 전류를 계산하려면 이 시점의 전압이 필요하고,
이 시점의 전압을 계산하려면 이 시점의 전류가 필요한데...
뭐부터 계산하지?" → 🔴 Algebraic Loop Error!
Simulink 입장에서는 뭐 부터 계산해야할지 모르게된다. (사람은 알지만)

그래서 위와같이 Unit Delay 블럭을 넣어줘야한다.
결과를 확인해보자.


위에서부터 순서대로 배터리 양단 전압, SOC 추정 값, Battery CC-CV Block의 PI제어기 출력 이다.
배터리 양단 전압이 4.1V(이전에 설정한 배터리 최대 전압 임계값) 에 도달하는 순간 PI제어기 출력이 감소하고 -> 전류가 감소하니 SOC 증가 속도도 감소한다 -> 그러다가 SOC가 이전에 설정해둔 최대 사용 지점값인 0.918에 도달하면 Charging Enable이 0이되고 -> 15A로 방전이 일어나게된다-> 방전이 계속 일어나다가 SOC 추정값이 최소 사용 지점값인 0.3에 도달하면 다시 CC-CV 로직으로 충전이 반복된다.
핵심만 다시 말하자면 약 1.2s 쯤에 배터리 양단 전압이 4.1V에 도달하므로 -> PI제어기의 출력이 감소 -> 충전 전류가 감소 -> SOC 추정값의 증가 속도가 확연하게 감소 -> 배터리 양단 전압이 목표 전압인 4.1V를 유지하게 되는 것이다.
(참고로 SOC 추정값이 가파르게 상승하는 구간이 CC구간 동작의 결과이고, SOC 추정값이 거의 일정하게 유지되는 구간이 CV구간 동작의 결과이다)
현재 CC-CV 알고리즘의 구조:
입력: SOC, V_cell
출력: 충전 전류 (I)
→ 온도(Temperature)를 전혀 보지 않음! ❌
CC-CV 충전 로직은 온도를 고려하지 않는다.
■ CC 구간에서의 발열:
P_heat = I² × R_internal
I = 15A, R_internal = 0.01Ω 일 때:
P_heat = 15² × 0.01 = 2.25W (셀 내부 발열)
■ 상온(25°C)에서는:
배터리 온도: 25°C → 30°C → 35°C (감당 가능 ✅)
■ 고온 환경(예: 한여름 40°C)에서는:
배터리 온도: 40°C → 45°C → 50°C → 55°C → 60°C! 🔥
↑
안전 한계 초과! ⚠️
왜? 시작 온도가 이미 높은데,
CC 모드에서 15A를 그대로 넣으니까
내부 발열(I²R)이 추가되어 온도가 위험 수준까지 올라감!
이렇듯 배터리 사용시 온도를 꼭 고려해야한다.
예를들어
┌──────────────┬─────────────┬──────────────────────┐
│ 환경 온도 │ CC 전류 │ 이유 │
├──────────────┼─────────────┼──────────────────────┤
│ 0°C 이하 │ 매우 낮게 │ 리튬 석출 위험 │
│ 10~25°C │ 15A (정상) │ 최적 충전 조건 │
│ 25~35°C │ 15A (정상) │ 아직 괜찮음 │
│ 35~45°C │ 10A로 감소 │ 과열 방지 필요 │
│ 45°C 이상 │ 충전 중단! │ 열폭주 위험 🔥 │
└──────────────┴─────────────┴──────────────────────┘
위와 같이 온도별 충전 전략을 다르게 해야한다는 것이다.
배터리 온도 상승 = 내부 발열 + 외부 환경
│ │
│ 1. 내부 발열 (Internal Heat) ← CC-CV가 고려함 ✅ │
│ → CV 모드로 전환해서 전류 줄임 │
│ → P = I²R 감소 │
│ │
│ 2. 외부 환경 (Ambient Temperature) ← 고려 안 함 ❌ │
│ → 한여름 40°C에서도 15A 그대로 넣음 │
│ → 내부 발열 + 외부 고온 = 과열! 🔥 │
│ │
└────────────────────────────────────────────────────┘
다음 글에서는 온도인식 CC-CV 충전 방법(Temperature-Aware CC-CV)에 대해 알아볼 것이다.