CAN_OBD-II2010. 1. 7. 09:30

CAN 통신을 통해 OBD-II를 구현하려면 당연한 말이지만 CAN 통신이 먼저 구현되어야 합니다.

CAN은 multi master network이며 CSMA/CD(Carrier Sense Multiple Access/Collision Detection) +
AMP(Arbitration on Message Priority)방식을 사용합니다.
CSMA/CD 는 LAN에서도 사용하는 방식이며, AMP는 충동 발생시 우선 순위에 의해 중재한다는 뜻입니다.
CAN에서 ID가 곧 우선순위이므로 결국은 충돌 발생시 ID에 의해 중재된다고 볼 수 있습니다.

CAN 통신을 위해서는 기본적으로 MicroController와 CAN tranceiver가 필요합니다.
CAN tranceiver를 직접 구현할 수도 있겠지만, 위에서 말한 SCMA/CD + AMP를 직접 구현해야 하는 일인데,
왠만하면 그냥 포기하고 전용 chip 쓰기를 권합니다.
CAN chip으로 대표적인 것이 Atmel사의 AT90CAN128 입니다.
MCU와 tranceiver가 합쳐진 chip인데, 시중에서 쉽게 구할 수 있고 관련 자료들도 인터넷에 널려 있으니 개인적인 목적으로 사용할 분들에게 추천하는 chip입니다.
단점은 좀 비싸다는 건데, 경험상 CAN 개발은 돈이 투자되는 만큼 시간이 절약되더라는 ...
그 외에도 많이 쓰는 칩으로는 CAN뿐만 아니라 PWM, ISO등 모든 통신이 지원되는 ELM327이 있는데, 이놈도 역시 비쌉니다.
우리 회사에서는 이런 비싼 chip을 쓸 수 없어 선택한 것이 Renesas사의 R8C34E.
이놈도 tranceiver가 내장되어 있는데 가격도 쌉니다.
그 대신,  ROM 32K/RAM 2.5K 정도로 메모리가 아주 작죠.


사실 Chip만 괜찮은 걸 고르면 CAN 통신 자체는 별거 아닙니다.
레지스터 몇개 세팅해 주면 대부분 통신은 뚫리는데, 중요한 건 Baud rate 입니다.
해당 차량에서 사용하는 Baud rate를 스캔해야 되는데 이게 skill이라면 skill입니다.
(대부분은 125K/250K/500K/1M 넷 중에서 하나는 맞을텐데 아닌 경우도 있을 수 있으니...)

자, 이제 CAN 통신은 뚫렸으니 우리의 원래 목적인 OBD-II로 돌아가 보겠습니다..
OBD-II 통신의 기본은 Request and Response 입니다.
무슨 말인고 하면, 내가 원하는 데이터를 요청하면 그에 대한 응답이 나한테 온다는 것이죠.
그런데 문제가 있네요. CAN으로 데이터를 요청하려면 ID를 알아야 하는데, 어떻게 알지?

위키백과를 찾아보니 이런 내용이 있습니다.
The PID query is sent to the vehicle on the CAN bus at ID 7DFh, using 8 data bytes.
(Part1에 첨부한 PID 자료의 제일 뒷부분에 나옵니다.)
ID 0x7DF로 요청을 보내면 ID 0x7E8 또는 0x7E9로 응답이 옵니다.
필터설정을 통해 위 ID들만 받아들이도록 해놓으면 나머지 ID들은 자동으로 무시하게 됩니다.

또 한가지 문제가 있습니다.
11bit ID일 경우에 대해서는 Request/Response ID가 나와 있는데, 29bit일 경우에는 어떡하나???
고민하던중 ECU Simulator와 CAN Analyser를 구매하게 됐는데, 이걸 쓰니 간단하게 해결이 되네요.
Request는 0x18DAF110, Response는 0x18DB33F1 입니다.
(돈을 투자하는 만큼 시간이 절약된다는 말을 이래서 한 것입니다).
Tool 소개는 나중에 따로 할 기회가 있을테니 생략하도록 합니다.

예를 들어서 RPM을 구하고 싶으면
Request
0x02 0x01 0x0C 0x00 0x00 0x00 0x00 0x00 (total 8 byte)을 Data frame에 넣어서 네트웤으로 쏴주면 됩니다.
첫번째 바이트는 첫 바이트를 제외한 유효 데이터의 바이트 수를 의미합니다.
Request의 경우는 Mode와 PID만 있으면 되므로 거의 0x02로 고정이라고 보면 됩니다. ("항상"은 아니고 "거의" 입니다.)

Response
0x05 0x41 0x0C 0x0A 0x03 0x00 0x00 0x00
첫번째 바이트는 역시 유효 데이터의 바이트 수를 의미합니다.
두번째 바이트는 Mode인데, Request에서 6번(7번째) 비트를 1로 만들어 주면 됩니다.
Request의 Mode가 0x01이었으므로 Response는 0x41이 된다.
PID는 0x0C로 같고, 이후의 두 바이트가 원하는 값이다. 해석은 Part 1에 첨부해 놓은 PID 문서 참조.
RPM의 경우는 (A*256+B)/4 이므로 이 경우에는 (10*256+3)/4 = 640.75 가 되죠.

참고로 문서의 Formula 필드에서 대문자 A,B,C 등은 데이터 바이트의 순서를 나타냅니다.


참고문헌
위키백과: http://en.wikipedia.org/wiki/Obd-ii#OBD-II
Posted by 못생긴나무