OBD II 를 이용한 차량 정보 감시/프로그래밍

[목차(도우미)]
OBD(On Board Diagnostics) II 는 최근 차량에 거의 표준장착되어 있는 장치임에도 불구하고 일반에는 많이 알려져 있지 않고 그 응용 기술도 문헌이 많지 않다.
위키피디어 참고: http://ko.wikipedia.org/wiki/온보드진단기

OBD II에 관하여

나도 적지 않은 문헌을 찾아 조사하면서 결국에는 제조사의 공개 자료를 읽으면서 응용 시스템을 개발하게 되었는데, 간단히 원리적인 것을 기억나는 대로 메모해 두기로 한다.

  • OBD II 는 차량에서 일어나는 기계적인 상태를 컴퓨터에서 파악할 수 있는 인터페이스를 제공해 준다.
  • 차량과의 통신 수단은 USB 시리얼을 사용하는 기기도 있고 블루투스(Bluetooth, 굳이 번역하면 파란니. 왕조 이름) 통신을 제공하는 기기도 있다.
  • 물론 블루투스 기기가 사용하기에 편리하다. 단지 선이 없다는 이유로 편리하다는 것이다.
  • 블루투스용 기기의 경우 통신 속도(Baud rate)는 대개 115200 bps를 지원하는 것 같다.
  • PC에서 블루투스 통신을 하려면 가상 시리얼포트(예를 들어 COM8)를 열어서 통신하면 되고 리눅스에서 블루투스 통신을 하려면 약간 복잡하다.
  • 리눅스에서 블루투스를 쓴다는 자체가 복잡한데, BlueZ라는 오픈소스를 설치하여 해결한다. 물론 설치했다고 해서 간단히 연결되는 것은 아니다.
  • 리눅스에서는 몇몇 이유로 GNU C/C++로 프로그래밍을 하게 될텐데 모든 포트 통신을 비롯하여 통신을 파일(FILE) 이라는 개념으로 통일하여 설계되어 있다. 그래서 통신하는 경우도 fread, fwrite 함수를 자주 호출하게 된다.
  • OBD II 기기류를 Donglee라고 부르는데 이 말의 어원은 모르지만 그냥 우리말인 것처럼 "동글이"라고 부르면 무방하다.
  • OBD II 와의 통신은 결국 시리얼 통신을 수행하는 것으로 귀착되는데, GPS 기기와는 달리 대화형 통신방식이다. 다만 시리얼 통신으로 프로그램을 짜면 개행 코드를 어떻게 취급할 것인지에 대해 일일이 설정해 주어야 한다.
  • 블루투스 통신의 예제는 http://people.csail.mit.edu/albert/bluez-intro/x502.html 에서 Example 4-3. rfcomm-client.c 를 보면 응용할 만한 소스코드를 발견할 수 있다.
  • 대화형 통신 방식 외에도 비동기 통신 모드가 규격에는 존재할 지도 모른다는 소문 내지는 추측이 있으나 검색 서비스를 통해 발견되지 않았다.
  • 기본적으로 OBD II 와의 통신은 텍스트만으로 수행하고 가장 기본적인 커맨드는 " 01 01" 을 보내서 사용가능한 커맨드를 알아내는 것이다.
  • 전화 모뎀에서 처럼 AT 커맨드도 장착되어 있는데 자세한 사양은 제조사의 설명서에 의존한다. 대표적인 것으로는 ATZ E 또는 atz (기기를 초기화하는 명령)
  • OBD II 에 터미널 프로그램으로 연결하는 경우에 처음에는 에코백(Echo back)이 설정되어 있지 않기 때문에 알아보기가 어렵다. 그럴 때는 "ATL1", "ATE1"등의 커맨드를 보내서 줄바꿈 모드로 바꾸고 에코설정 모드로 바꾸면 보기 좋다.
  • 오픈소스는 아니지만 제조사가 만든 소스코드 샘플 프로그램이 있는데 그것을 잘 참고하여 활용하면 제법 쓸만한 프로그램을 개발하는데 도움이 된다. ScanTool.exe 이라는 이름의 프로그램이다. http://sourceforge.net/projects/scantool/ 에 자료가 공개되어 있다.
  • ScanTool 이라는 프로그램은 마이크로소프트 윈도에서 돌아가는 GNU C 를 사용하므로 비주얼 스튜디오를 가지고서 완벽한 컴파일은 되지 않는다. GNU C (gcc컴파일러)와 관련 라이브러리를 다운로드해서 개발환경을 구축하여야 한다.
  • 나는 리눅스에서 ScanTool을 사용하려고 했지만 관련 라이브러리의 입수가 번거로와서 컴파일을 하지 않고 단지 소스코드를 참고하기로 했다.  

컴포넌트 설계

한편 내가 항상 강조하는 재사용을 위하여 설계적 아이디어를 메모해 둔다. 소스코드를 직접 공개하지 않는 이유는 저작권에도 문제가 될 소지가 있고 또 중요한 것은 아이디어이지 구현 소스가 아니기 때문이다.
  • OBD II 클래스를 구현하려면 SerialPort 클래스를 계승하는 것이 편리하다. 블루투스를 사용하는 경우라면 블루투스 통신 예제를 참고하여 블루투스 소켓 클래스를 만드는 것이 편리하다.
  • 같은 이유로 SerialPort 클래스는 Port클래스를 구현하는 것이 편리하다.
  • 여러가지 이유가 있겠지만 경험상 통신을 사용하는 클래스는 소켓 클래스의 형태로 정의하는 것이 편리하다.
  • 그러므로 추상 클래스로 소켓을 정의하여 시리얼 소켓(SerialPort를 가리킴)을 구현(Implementation)하는 것이다.
  • 계층적으로 본다면 Socket ---> SerialSocket(또는 BluetoothSocket) ---> OBDSocket의 순으로 계승한다.
  • C++ 문법적으로 기술하자면
    class Socket {virtual ...}
    class SerialSocket (Socket) {...}
    class OBDSocket (SerialSocket) {...}
  • 다음 기회에 기술하려는 GPS에 대해서도 같은 시리얼 통신을 수행하므로 GpsSocket 도 SerialSocket 을 계승함으로 구현하면 된다.
  • 그렇다면 시리얼 소켓에서 대부분의 통신 방식을 구현해 두고 쓰면 편리하다.
  • 구현이라 해봐야 실타래(Thread, 쓰레드)와 파일 입출력을 주로 구현해주는 것이다.
  • 시리얼 통신에 관해서는 많은 예제가 있다. 예제를 참고하면 어느 정도의 소스코드를 장만할 수 있다.

오늘은 이 정도로 해두자.

관련글

[연구개발 이야기] - OBD-II PID에 관하여

by 금메달.아빠 on 2011. 6. 14. 06:00