본문 바로가기
아두이노

아두이노(arduino)로 자동차 ODB2를 통해 자동차 속도 표시하기 - (1부 구상편)

by 구루가 되고픈 2018. 12. 3.

아두이노(arduino)로 자동차 ODB2를 통해 자동차 속도 표시하기

(1부 구상편)

 

먼저 이글은 아두이노로 자동차 속도를 표시하는 프로젝트를 진행하면서 인터넷을 통해 상당히 많은 정보를 얻어 큰 어려움 없이 제작이 가능했어서, 나 또한 누군가에게 도움을 주어야겠다고 생각되어 소개하고자 합니다.

 

먼저 본 프로젝트를 진행하게 된 계기를 말씀드리면, 아주 오래전부터 자동차에 HUD를 달고 싶었고, 그래서 중국산 싸구려 HUD를 아주 오래전부터 장착하여 사용하였으나 품질에 만족하기 어려웠고, 이후 블루투스 ODB2 장비를 구매하여 핸드폰에 어플을 설치하여 한동안 재미있게 사용해 왔습니다.

(제가 그간 구매한 블루투스 ODB2 개수만 해도 4개나 되네요 ㅎㅎ)

 

그런데 이게 문제가 여름철에 자동차 실내 온도가 상승하면서 혹시 배터리가 터지지 않을까 하는 걱정이 많이 되었습니다.

 

그래서 이를 과감히 떼어버리고 다른 대체수단을 찾다가 직접 한번 만들어봐야겠다는 생각에 도달하여, 가능한 최대한 쉽게 구현할 수 있는 아두이노로 제작하기로 마음먹게 됩니다.

 

제작되어 동작하는 영상을 참고하세요.

 

 

 

주행속도에 따라 oled의 숫자가 변화합니다.

배선은 오렌지색이 ODB2단자에서 연결한 신호선이고, 전원선 연결한게 끝입니다.

그리고 아두이노에는 OLED하나 붙였고요.

 

화면이 깜빡거리듯 보이는 것은 숫자가 바뀌지 않더라도 실제로는 계속 화면에 속도를 숫자로 뿌리고 있기 때문에 촬영시 깜빡이는 것처럼 보입니다.

 

더구나 OLED가 화면하나를 뿌릴때 화면을 8등분하여 위에서 부터 순차적으로 뿌리는 방식을 사용하는데, 그 영향도 있는것 같습니다.

 

최초의 구상은 지금 형태가 아니라 ODB2 블루투스 아답터를 이용하는 것이었습니다.

 

1. 블루투스 ODB2 신호를 아두이노로 받는다.

2. 블루투스 신호를 분석하여 필요한 정보를 7세그먼트에 표시한다.

간단하죠~

 

구상이 나왔으니 바로 실행에 옮기기 위해 부품을 구매합니다.

 

1. 아두이노 우노 R3 호환보드

2. 블루투스 통신 모듈

3. 7세그먼트

4. 0.96인치 oled 모듈

 

 

혹시라도 실패할 수도 있기 때문에 일단 최소로 필요한 것만 구매합니다. 

 

먼저 해야하는 작업은 자동차에서 ODB2단자를 통해 차량상태에 필요한 정보를 가져오는 것이었습니다.

 

차량용 블루투스 어댑터에서 정보 가져오기 구성도

 

초기구상 - odb2 블루투스 아답터로 무선으로 전달

 

 

여기부터가 난관에 부딪힙니다.

 

인터넷을 뒤져 핸드폰과 블루투스를 연결하여 간단한 문자열 주고받기는 문제없이 되었는데, 이걸 차량용 블루투스에 붙여 정보를 가져오기가 저의 실력으로는 불가능해 보였습니다.

 

더군다나 엄청난 양의 차량정보가 쏟아져 나오는데 이걸 parsing해서 처리한다는게 생각만 해도 끔찍해 보였습니다.

 

그래서 블루투스가 아니라 유선으로 데이터를 넘겨주는 아답터를 구매할까도 생각했으나, 가격이 5만원 가까이 하고 있어 포기하였습니다.

 

 

OBD_UART_V2_1OBD_UART_V2_2

freematics사의 아두이노용 odb2 아답터 (https://freematics.com)

 

 

이 아답터를 사용하게되면 라이브러리까지 기본 제공이 되어 간단한 시리얼통신을 통해 실시간 정보를 아주 쉽게 가져올수가 있습니다.

 

그렇다보니 코드 또한 아주 간단하고, PID를 통해 상당히 많은 정보를 가져올 수가 있습니다.

 

#include <OBD2UART.h>


COBD obd;


void setup()
{
  // we'll use the debug LED as output
  pinMode(13, OUTPUT);
  // start serial communication
  obd.begin();
  // initiate OBD-II connection until success
  while (!obd.init());
}


void loop()
{
  int value;
  // save engine RPM in variable 'value', return true on success
  if (obd.readPID(PID_RPM, value)) {
    // light on LED on Arduino board when the RPM exceeds 3000
    digitalWrite(13, value > 3000 ? HIGH : LOW);
  }
}

 

 

그렇지만 이만한 가격을 주고 사면서까지 할 생각은 아니었기 때문에 이건 포기하고 다른 방법으로 구현하고자 고민하다가 생각해낸 것이, 보통 자동차의 ODB2 단자를 보면 표준에는 없지만 각 메이커들이 차속(speed) 신호를 내보내는 핀이 하나 있습니다.

 

보통 vender option으로 되어있는 핀중에 하나를 사용하게 됩니다.

 

이건 필수사항이 아니라서 전 메이커가 같은 상황인지는 모르겠으나, 제차가 현대 투싼ix 2009년식인데 현대차는 차속신호를 3번 핀에 할당하여 내보내고 있습니다.

 

 

ODB2 단자규격 (이미지 출처 : http://juke.tistory.com/255)

 

 

 

보통 저가의 HUD들이 이 단자에서 차속신호를 가져와서 속도를 표시하는 방법을 많이 사용합니다.

 

그래서 이 차속신호를 잡아서 자동차 속도값을 가져와보자는 것이었습니다.

 

차량 odb2 커넥터의 차속펄스가 나오는 핀에 신호선을 연결

 

 

신호선을 가져오기 위해 ODB2단자의 3번 핀에 선을 끼워서 연결합니다.

이 신호선은 아두이노의 핀 입력으로 들어가게 됩니다.

 

먼저 ODB2의 차속 펄스가 나오는 형태를 알아야 하는데 대충 이런식의 파형이 나온다고 보시면 됩니다.

 

차량 차속 펄스

 

 

 

정지시에는 펄스가 LOW상태이고 주행시 디지털 펄스가 발생하여 속도가 빨라질수록 주기가 빨라지게 됩니다.

 

그래서 만저 차속신호의 펄스주기(주파수)를 측정할 방법이 있어야 합니다.

 

다행히 아두이노에서는 pulsein이라는 아주 유용한 함수를 제공하고 있어서 아주 정확하진 않더라도 주파수를 측정할 수 있습니다. 

 

pulsein 함수는 파형의 HIGH와 LOW 시간을 측정하는 함수 입니다.

 

아래 그림과 같이 pusein(high)로 하는 경우 5V구간의 시간값이 마이크로세컨드(1/1000000초) 값으로 구해지고 pusein(low)로 할 경우 0V구간의 시간값이 구해집니다.

 

 

차속펄스를 아두이노 plusin함수를 통해 카운트하는 개념도

 

 

 

제가 생각한 아이디어는 high구간값과 low구간값을 더하면 1싸이클에 대한 시간이 구해지지 않을까, 이를 주파수로 계산해 보면 되지 않을까 하는 것이었습니다.

 

 

차속펄스를 아두이노 plusin함수를 통해 카운트하는 개념도

 

 

만약 high구간값이 4000uS(마이크로세컨드), low구간값이 4000uS라면 이 펄스는 1초에 몇번을 진동할 것인가로 주파수를 구할 수가 있고 계산식은 

 

주파수 = 1,000,000 / 8,000uS

 

이 될 것입니다. 이렇게 계산하니 125Hz가 나오네요.

 

주파수의 개념은 아래 그림을 참고하세요.

 

 

헤르츠에 대한 이미지 검색결과

(출처 : https://m.post.naver.com/viewer/postView.nhn?volumeNo=6719006&memberNo=36047368)

 

 

여기까지 구현에 대한 구상이었고, 그러면 실제로 이 구상대로 가능한지 아두이노 프로그램을 짜서 실제 측정을 해 보도록 하겠습니다.

 

측정부분 부터는 2부에 올리겠습니다.