DIY - TPMS(Tire Pressure Monitoring System) value display for RENAULT and NISSAN via CAN(Controller Area Network)





두번째 글 입니다.

이 글에서는 전체적인 모듈 구성도, Display 처리 logic 을 제외한 CAN data 처리 부분 code까지 살펴 봅니다.


먼저 모듈 구성도를 보겠습니다. code 구성 전에 회로를 구성하게 되고 회로에 맞추어 code를 구성해야 합니다. 물론 구성 전에 개별 port를 할당과 연결은 미리 고민 후 할당 해야겠습니다.

저의 경우 AT90CAN128 모듈의 포트 위치에 따라서 TPMS 표시 모듈을 먼저 구성하여 포트가 연속이지는 않지만 해당 모듈의 기판에서는 물리적으로 연속하여 배치 되어 실제 pin header 로 연결 용이성에 최우선 순위로 결정 했습니다.

추가로 처리한 Accelerator / RPM bar-graph는 남는 반대편 port에 구성 하였습니다.

실제 모습은 첫번째 글을 참고 하시면 되겠습니다.


[모듈 구성도] 


OBDII Socket 

4선을 연결 하면 됩니다. 저의 경우 고장난 충전용 5pin USB 케이블의 선재만 이용 했습니다.

+ / - / D+/ D- 를 그대로 활용하여 VCC(8) / GND(4,5) / CANH(6) / CANL(14) 와 연결 합니다.

여기서 주목 할 사항은 Renault / Nissan 차량에서 OBDII Socket의 8번 pin을 사용하면 항시 전원이 아닌 시동 전원(IGN2)에 연결하게 되는 것입니다.

혹시나 ELM327 호환 OBDII 장치에 대해 상시전원을 막으려면 16pin 연결된 전원 선을 8pin으로 옮기면 방전 걱정을 덜게 됩니다.

아! OBDII 소켓은 별로로 구입해서 선을 연결해야 됩니다. 저는 이 소켓에 regulator까지 함께 장착 했습니다.


Switching regulator 

차량 전원은 +12 ~ 14.8 V 의 고전압(TTL회로에 적합하지 않은) 입니다. 직접 AT90CAN128 Module에 연결할 수 없고, 5V 로 낮추어 공급 해야 합니다.

요즘은 OBDII Socket 내부에 넣을 정도로 작은 switching regulator 모듈을 판매하고 있습니다. 이러한 부품을 사용 합니다.

7805 같은 linear regulator 는 여러 이유로 추천 드리지 않습니다. (12V 에서는 고열로 인한 방열 문제 등등)


AT90CAN128 module 

전원 +5V 는 앞서 switching regulator와 연결하고, CAN 라인은 Socket 으로부터 직접 연결 하면 됩니다. (6, 14 번 핀)

Tire 공기압 표시를 위한 7 segment 모듈과 연결은 Port F / A / C 를 통합니다. 총 24pin 연결하도록 2열 pin header , socket 으로 기판을 직접 결합 하게 됩니다.

Port B / E 는 accelerator, RPM gauge bar graph 표현 모듈과 연결 합니다. 8bit는 공통이고 총 4개 모듈을 제어 하게 합니다. 마찬가지로 4번 각각 선택 해야 총 40개의 LED를 표현하게 됩니다.


7 segment display module 

Port F 와여 연결선은 모든 7 segment 모듈에 공통으로 연결합니다. (한 시점에 한개의 자리만 표시)

Port A, C 를 개별 7 segment 하나의 단위와 차례로 연결하여 총 15자리 수를 순차적으로 선택 하게 합니다.


HW 준비 설명은 이렇게 서둘러(!) 마무리 하겠습니다.

100% 똑같이 만들기는 곤란하기에, 핵심만 전달 드립니다. (포트 역할, 전체 결선 방법)



AT90CAN128 을 활용한 CAN data수신 

AT90CAN128 은 칩 이름만 보면 아시겠지만 CAN 통신 기능이 이미 chip 수준에 내장된 MICOM입니다. 다만 물리적인 CAN 라인과 연결한 트랜시버는 추가로 부착 하는 정도의 수고가 필요 합니다. 제가 사용한 모듈에는 이미 부착 되어 단지 차량 CANH, CANL 라인과 연결만 하면 됩니다.

하지만 CAN 통신 처리가 그냥 되지는 않고, Atmel 에서 제공하는 규약에 맞추어 register 설정, interrupt 설정 등을 통해 동작이 되어야 하는데 - Atmel 에서 제공하는 library가 - 시원찮습니다. 특히나 최신 Atmel studio 에서는 제대로 import 하는 것만 해도 일이더군요.

그래서 별도의 library를 독일의 한 community(https://www.mikrocontroller.net/topic/98697) 에서 구하여 약간의 수정으로 사용하게 되었습니다.


**별도 압축파일로 제공하는 Atmel Studio용 project파일의 can.h / can.c 파일을 참고 하시기 바랍니다.

AT90CAN_TPMS_2016-09-06_003533.7z




Main 함수

인트로 보여주기, 안내 메시지, can 초기화(InitCAN()), CAN data 받기용 interrupt 설정(set_interrupt_handler) 과정을 차례로 수행 합니다.

그리고 실제 동작은 interrupt 루틴인 canInterruptHander 함수에서 하고, main은 while (true)로 대기 상태(무한 loop) 처리가 됩니다. [MICOM은 무한 루프라고 열내거나 처리하다 죽지 않습니다^^]



CAN 초기화 - QM5/KOLEOS는 일반적인 속도인 500kbps를 사용 합니다. 

초기화를 완료 하면 segment display로 잠깐 결과를 보여 주게 됩니다(이건 나중에 별도 설명)



CAN data 수신 interrupt handler  - 모든 data를 수신 처리 합니다.

CAN data가 수신 될 경우 - 사실 mask 를 0으로 처리 해서 CAN으로 뿌려지는 모든 data가 수신 되게 됩니다. AT90CAN128은 충분한 속도와 반응으로 수신 처리를 하게 됩니다.

can_get_id() 함수를 통해서 CAN id를 받고, data는 can_get_data() 함수로 8 byte 배열에 수신된 data를 받게 됩니다.

이후는 잘 '요리'하는 일이죠!


우리의 관심 data인 TPMS 수치 값은 CAN id 0x385 를 가지며 길이는 8 입니다.

차량 속도: CAN id 0x284 

스티어링 앵글(운전석 핸들의 각도): CAN id 0x002 

Throttle(Accelerator), RPM : CAN id 0x180 

기어 중립 상태 여부 : CAN id 0x358 


** QM5/KOLEOS CAN data 별도 페이지로 안내 드릴 예정 입니다.

우선 TPMS CAN data 수신에 대한 처리 부분을 좀 더 보도록 하겠습니다.



TPMS data 수신 후 처리 - checkTPMSAndDisplay() 함수

8byte data 중 3번째~6번째 byte data가 각각 FR, FL, RR, RL 의 타이어 압력 값이며 code에서 보는 것과 같이 raw 수치에 0.25 를 곱한 값이 최종 압력 단위 psi(pound per square inch / 제곱 인치 당 파운드) 값이 됩니다. 즉 resolution이 0.25 psi가 됩니다.


* 10.0f 한 것은 7 segment display에서 3자리만 출력 되는 관계로 소수점 1자리만 유효하고 그에 대한 scale 처리를 한 것입니다. 예로서 32.25 라면 32.2 만 표현 할 수 있는 상태고, 실제 display 루틴은 정수 값만 받아 처리 하도록 두어서 *10 하여 최종 "322"를 만들어 전달 합니다.

물론 출력할 때 "." 위치를 마지막 자리 수 앞에 두어 최종 결과는 "32.2" 로 보이게 만듭니다.


이 최종 출력은 showATPMSValue 함수에서 처리를 하게 됩니다.

약간의 Magic(마법?!)이 이 함수에 포함 되어 있습니다. 

먼저 이전 값을 기억 했다가(static 변수) 수치가 변동 되는 시점에 값을 갱신함과 동시에 깜빡임 처리를 하게 됩니다. 이 깜빡임은 bit flag MultiSegmentDisplay::ATTR_BLINK 으로 표현되고, "4" 값에 의해 지속 시간이 전달 됩니다. 실제 처리는 MultiSegmentDisplay class의 timer interrupt 에서 약 4초간 깜빡이게 사전 code가 구성 되어 있습니다. (다음 글에서 이 부분을 더 자세히 볼 예정 입니다)



속도 표시 - displaySpeed() 함수

차량의 현재 속도는 CAN id 0x284 에 담겨져 오고 5번째, 6번째 byte data의 조합으로 계산 됩니다.

계산 수식은 Speed = (D5*2)+(D6/128) 로 처리 됩니다. 실제 code상에서는 소수점 2자리를 표현하기 위해 100배의 값이 두 byte로 표현 하는 것으로 아래 처럼 계산처리가 가능 한 것입니다.

  speedx100 = (data[4] << 8 | data[5]);


이곳에서도 Magic(?!) 으로 소수점 단위의 절반 값에 대해서만 값 변동을 처리하여 빈번한 속도 표시 변동을 막는 기법을 사용 하고 있습니다.

표시는 7 segment 중간에 있는 3자리 수에 표시를 하게 됩니다.



스티어링 앵글(운전석 핸들 각도) - displaySteeringAngle() 함수

이 부분은 매우 큰 관심을 받을 만한 값으로 생각 됩니다. 

이미 제 블로그에 공유 드렸던 "[DIY] 차량용 코너링 램프 컨트롤러 제작" 에서 휠각을 판단하기 위해 별도의 센서를 설치하는 고난도(?)의 DIY를 소개 드렸는데, CAN 통신을 통해서 한번에 휠각을 실시간으로 0.1 도의 정확도로 받아 올 수 있는 길이 있는 것입니다.

이번 TPMS diy를 완성 하기 까지 여전히 제 차에는 앞서 직접 DIY한 코너링 램프 컨트롤러가 동작 중입니다. 언젠가는 CAN 연결을 통한 제어로 바꿀 수도 있을 것 같습니다 (귀찮아서 언제 쯤....)



수동 기어 단수 표시, Accelerator, RPM 상태 표시 - checkEngineParameter() 함수

처음 계획은 TPMS로 부터의 개별 tire psi 값 출력이었습니다. 항상 그렇지만 하나가 되니 추가로 무언가 하고 싶더군요(실은 예전 부터 계획했고, 부품도 함께 구입 했다는).

특히 AT90CAN128의 엄청난 수의 port를 남겨 둘 수 없는 마음에 - 가속 패달(Accelerator)과 엔진 회전수(RPM)을 그럴 듯 한 Bar LED 모듈를 사용한 bar graph 로 표현하고자 하여 만든 함수 입니다.

RPM, 가속 페달 값은 아래와 같이 계산이 되는 것입니다.

    uint16_t RPM = (data[0] << 7 | data[1]) >> 2; // Engin RPM = (D1*128+D2)/4

    uint16_t throttle = (data[5] << 2) | ((data[6] & 0xC0) >> 6);


특이점으로 수동 기어 단수를 현재 RPM과 속도로 부터 유추하여 디스플레이어 가운데 부분에 보여 주는 code도 담겨져 있습니다.

자동이던 수동이던 기어비는 이미 정해 져 있습니다(무단 변속기 제외). 이 기어비 값을 현재 RPM과 속도로 부터 역으로 유추하여 보여 주는 것이죠! - 단 클러치를 밝고 있는 경우 속도와 RPM은 비례 관계가 아니므로 정확한 실제 기어 위치를 알 수는 없습니다. 하지만 충분히 실용적인 표시가 가능 하고, clutch 동작 시점에만 표시 하기에 엉뚱한 값 표시를 최대한 억제 하게 됩니다.

해당 함수는 getTransmissionInformation() 를 살펴 보면 되겠습니다.



이상 주요 함수를 돌아 보았습니다.

다음 글에서는 7 segment 15개와 bar LED 10 x 5 에 대한 driver code구성을 살펴볼 예정 입니다.


AtmelStudio 7로 작성한 project와 source 코드는 앞서 언급 드린 첨부 파일을 다운로드 받으셔서 컴파일, 실행, 확인을 하실 수 있습니다.

AtmelStudio 7 은 Atmel에서 배포하는 무료 AVR 통합 환경 입니다. Visual studio IDE를 사용하여 만들어 졌고 AVR 개발에는 매우 유용한 도구 입니다.


AT90CAN_TPMS_2016-09-06_003533.7z


**개인 사용자라면 누구나 자유롭게 사용 가능 하며 출처 표기 정도는 해 주시면 감사 하겠습니다.

  단, 상업적인 목적으로는 허용하지 않습니다.



+ Recent posts