테마
04. CAN DB와 시그널 인코딩
학습 목표
- CAN 메시지와 Signal의 관계를 설명할 수 있다.
- CAN DB에 메시지와 Signal 정보가 왜 필요한지 이해할 수 있다.
- Start Bit, Length로 데이터 영역 안의 Signal 위치를 해석할 수 있다.
- Factor와 Offset으로 물리값을 정수 데이터에 매핑하는 이유를 설명할 수 있다.
- 송신 ECU와 수신 ECU가 같은 DB를 기준으로 동작해야 하는 이유를 이해할 수 있다.
전체 구조
1. CAN 메시지는 데이터 컨테이너다
CAN 메시지를 보낼 때 실제 값은 데이터 영역에 들어간다.
High Speed CAN 기준으로 데이터 영역은 최대 8바이트다.
하지만 "데이터 영역 8바이트"라고만 하면 의미가 없다.
그 안에 어떤 값이 어떤 위치에 들어가는지 정해야 한다.
예를 들어 BatteryStatus 메시지에 다음 값을 넣고 싶다고 하자.
- 배터리 전압
- 배터리 충전량
- 최대 허용 전류
이 값 하나하나를 CAN DB에서는 보통 Signal이라고 부른다.
2. 메시지와 Signal은 계층적으로 정의된다
CAN DB는 메시지와 Signal을 계층적으로 정의한다.
메시지 단위에는 보통 다음 정보가 붙는다.
| 항목 | 예시 |
|---|---|
| Message ID | 0x123 |
| Message Name | BatteryStatus |
| Sender | BMS |
| Receivers | Cluster, Airbag |
| DLC | 4byte |
| Cycle Time | 10ms |
Signal 단위에는 다음 정보가 붙는다.
| 항목 | 예시 |
|---|---|
| Signal Name | BatteryVoltage |
| Start Bit | 0 |
| Length | 12bit |
| Factor | 0.1 |
| Offset | 0 |
| Unit | V |
| Min/Max | 0 ~ 409.5 |
3. Start Bit과 Length는 Signal의 위치를 정한다
CAN 메시지의 데이터 영역은 바이트와 비트로 구성된다.
Signal이 어디서 시작하고 몇 비트를 차지하는지를 알아야 송신 ECU와 수신 ECU가 같은 값을 해석할 수 있다.
예를 들어 4바이트 데이터 영역 안에 다음처럼 Signal을 배치할 수 있다.
| Signal | Start Bit | Length | 의미 |
|---|---|---|---|
| BatteryVoltage | 0 | 12 | 배터리 전압 |
| StateOfCharge | 12 | 8 | 충전량 |
| MaxCurrent | 20 | 12 | 최대 허용 전류 |
이 정보가 없으면 수신 ECU는 데이터 바이트를 받아도 어떤 비트가 어떤 값인지 알 수 없다.
실제 비트 순서와 엔디언 처리 방식은 DB 형식과 프로젝트 규칙을 정확히 따라야 한다.
여기서는 "위치와 길이를 DB로 합의한다"는 개념을 먼저 잡는 것이 중요하다.
4. 왜 실수값을 그대로 보내지 않을까?
배터리 전압이 12.4V라고 해보자.
컴퓨터에서 실수값을 그대로 표현하려면 보통 float 같은 형식이 필요하고, 데이터 크기도 커진다.
CAN 메시지의 데이터 영역은 작다.
그래서 실무에서는 물리값을 정수로 변환해서 보내고, 수신자가 다시 물리값으로 복원하는 방식을 자주 사용한다.
이때 쓰는 것이 Factor와 Offset이다.
기본 관계는 다음과 같이 이해하면 된다.
text
physical value = raw value * factor + offset
raw value = (physical value - offset) / factor5. Factor는 표현 단위를 정한다
배터리 전압 12.4V를 보내고 싶고 Factor가 0.1이라고 하자.
송신 측은 다음처럼 계산한다.
text
raw = 12.4 / 0.1 = 124CAN 메시지에는 124라는 정수값을 담는다.
수신 측은 DB에 적힌 Factor를 보고 다시 계산한다.
text
physical = 124 * 0.1 = 12.4VFactor가 작을수록 더 정밀하게 표현할 수 있지만, 같은 비트 수로 표현 가능한 최대 범위는 줄어든다.
| Factor | 표현 간격 | 장점 | 주의점 |
|---|---|---|---|
| 1 | 1 단위 | 범위가 넓다 | 소수 표현 불가 |
| 0.1 | 0.1 단위 | 소수 1자리 표현 | 범위가 줄어든다 |
| 0.01 | 0.01 단위 | 더 정밀 | 더 큰 raw 값 필요 |
6. Offset은 음수나 기준 이동에 유용하다
온도처럼 음수 범위가 필요한 값은 Offset을 자주 사용한다.
예를 들어 물리값 범위가 -30도부터 97도까지라고 하자.
Factor가 1, Offset이 -30이면:
text
physical = raw * 1 + (-30)송신자가 -15도를 보내려면:
text
raw = (-15 - (-30)) / 1 = 15메시지에는 음수가 아니라 15라는 정수를 넣는다.
수신자는 15 + (-30)으로 다시 -15도를 얻는다.
이 방식은 작은 비트 수로도 음수와 특정 범위 값을 표현하기 좋다.
7. 송신과 수신은 같은 DB를 보고 있어야 한다
CAN DB가 송신 측과 수신 측에서 다르면 같은 메시지를 다르게 해석하게 된다.
DB가 맞지 않으면 다음 문제가 생긴다.
- 수신 ECU가 다른 비트를 읽는다
- Factor나 Offset이 달라 물리값이 틀어진다
- 송신 ECU가 보내지 않는 Signal을 수신 ECU가 기대한다
- 메시지 주기나 ID 충돌이 발생한다
그래서 CAN DB는 단순 문서가 아니라, 여러 조직이 같은 통신 언어를 쓰게 하는 계약에 가깝다.
8. CAN DB에 없는 ID를 보내면 어떻게 될까?
CAN 프로토콜 자체는 어떤 ID를 반드시 CAN DB에 등록해야만 보낼 수 있다고 강제하지 않는다.
ECU가 특정 ID로 메시지를 보낼 수는 있다.
하지만 프로젝트 관점에서는 문제가 된다.
- 다른 ECU가 그 메시지의 의미를 모른다
- 동일 ID를 다른 ECU가 이미 쓰고 있을 수 있다
- 검증 장비와 로깅 도구가 해석하지 못한다
- OEM 사양 위반이 될 수 있다
따라서 실무에서는 "기술적으로 보낼 수 있음"과 "프로젝트에서 허용됨"을 구분해야 한다.
핵심 정리
- CAN 메시지는 ID와 데이터 영역을 가진 컨테이너이고, 데이터 영역 안의 개별 값이 Signal이다.
- CAN DB는 메시지 ID, 송신 ECU, 주기, 데이터 길이, Signal 위치, Factor/Offset 같은 정보를 정의한다.
- Start Bit과 Length는 Signal이 데이터 영역 어디에 들어가는지 알려준다.
- Factor와 Offset은 작은 정수 데이터로 실수, 큰 범위, 음수 값을 표현하기 위한 변환 규칙이다.
- 송신 ECU와 수신 ECU는 같은 CAN DB를 기준으로 구현되어야 한다.
확인 질문
- CAN 메시지와 Signal은 어떤 관계인가?
- Factor가
0.1일 때 물리값12.4는 어떤 raw 값으로 전송되는가? - Offset을 음수로 두면 어떤 종류의 값을 표현하기 쉬워지는가?
- CAN DB에 없는 메시지를 임의로 보내면 프로젝트 관점에서 어떤 문제가 생길 수 있는가?