Prerequisite
24. 04.30. 라즈베리파이4B+, MCP2515(with VD1050),
테스트 장비 : PEAK Systems IPEH-004022(F/W Ver. 3.2.0 Driver Ver.4.4.2), PCAN-View 사용
Linux st 6.6.20+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.20-1+rpt1 (2024-03-07) aarch64 GNU/Linux
*SPI 통신을 지원하는 환경이라면 모두 비슷한 방식으로 동작할 것으로 예상되나, 커널 버전과 보드에 따라 다를 수 있습니다.
Introduction
차량 CAN 데이터를 얻어오기 위해서는 CAN transceiver가 필요합니다. 요즘은 차량에 flexRay CAN-FD 등등을 사용하여, 전용 transceiver를 사용해야 하는 경우가 있습니다만 특정 목적에서는 여전히 전용 tranceiver를 통해 데이터를 얻어올 수 있습니다. 특히 CAN 버스를 활용한 자동차 진단 단자 OBD-II 규격의 데이터를 원한다면, 아주 적은 비용으로 CAN 데이터를 수신할 수 있습니다. 아래 알리익스프레스에서 판매하는 물건이 그 예시입니다. CAN 통신 칩을 통해 raw 데이터를 수신 후 이를 블루투스 / 와이파이로 보내는 제품이 2만원정도에 판매되고 있습니다.
Wiring
TJA1050 vs. VD1050
(이 글을 보시는 여러분처럼) 라즈베리파이를 통해 can데이터를 읽으려는경우 MCP2515를 사용할 것입니다. 아래 글과 같은 개조를 통해 라즈베리파이에 mcp2515를 연결해 라즈베리파이로 can 통신을 수행할 수 있습니다. 개조하는 방법은 너무나 널려 있으니 여기서 굳이 다루지는 않겠습니다. 다만 한 가지 언급할 게 있다면, MCP2515라는 이름으로 판매되는 모모듈에는 MCP2515 뿐 아니라 TJA1050 can tranceiver가 있고, 이때문에 개조를 수행합니다. 그러나 최근 유통되는 칩은 TJA1050 대신 VD1050이라는 모델명이 작게 각인된 모듈을 만나보실 수 있습니다. 데이터시트를 보시면 TJA1050의 개선품임을 확인할 수 있습니다. 따라서 기존의 널리 알려진 방식 그대로 개조를 해도 무방하겠습니다.
개조는 아래와 같이 진행하시면 되고...
라즈베리의 device tree까지 수정후 재부팅해주시면 MCP2515를 정상적으로 인식한 걸 확인하실 수 있습니다. 조금 더 직접적인 결과를 보고 싶으시다면, ls /sys/class/net 혹은 ifconfig -a 을 통해 확인하실 수 있습니다.
CAN 설정 마지막 확인
일단 다음의 명령어를 통해 can0을 활성화시켜봅시다. 여기서는 bitrate=500kbps 사용하겠습니다.
sudo ip link set can0 up type can bitrate 500000 restart-ms 100
이미 can0이 활성화된상태에서는 bitrate 설정이 안됩니다. 아마 resource busy 명령어같은게 뜰텐데,
sudo /sbin/ip link set can0 down 을 통해 can0을 비활성화 한 후 다시 설정해주시면 되겠습니다.
그럼 dmesg에 이렇게 까지 나오는것을 볼 수 있습니다. 내부를 자세히 분석해보지는 않았으나, 이쯤 되면 하드웨어 및 can 사용을 위한 네트워크 레이어 세팅까지 완료되었음을 확인할 수 있습니다. 여기서 PF_CAN은 리눅스에서 CAN을 네트워크 스택으로 활용하기 위한 내부 추상화 방법 중 하나라고 생각하면 되겠습니다. CAN 데이터를 socket형태로 송수신할 수 있도록 하는 모양입니다.
CAN 장치와 통신 시도해보기
*MCP2515의 J1 헤더를 헤더핀 등으로 쇼트시켜 120 Ω 종단저항을 활성화해야 합니다!
sudo apt install can-utils -y
candump can0 # CAN 데이터 수신
sudo cansend can0 123#1122334455667788 # CAN 데이터 송신
위의 내용을 참조하여 통신을 테스트해보면 다음과 같이 PCAN-View에서 정상적으로 수신되는 것을 확인할 수 있습니다. 앞서 언급했듯 종단저항을 활성화시키지 않으면 CAN Bus의 상태는 Error-Passive와 같이 표시되니 종단저항과 기타 통신상태를 다시 확인하길 바랍니다.
이 때의 PCAN-View 연결은 위와 같으며, 경험상 Mode는 CAN, CAN(SJA1000) 모두 정상 작동했고, Database Entry 역시 bitrate만 맞으면 우선은 이상 없었습니다.
Python
GPT로 간단히 해결할 수 있을테니 여기서 언급할 가치는 없겠지만...
import can
if __name__ == "__main__":
can_interface = 'can0'
bus = can.Bus(can_interface, bustype='socketcan')
# 메시지 수신 대기
while True:
message = bus.recv()
if message is not None:
print(f'{message}')
이렇게도 접근하실 수 있습니다.
Useful commands for CAN
# can 네트워크 확인 및 점검
ip addr | grep can
dmesg | grep mcp
ip -details -statistic link show can0
# can 네트워크 활성화 / 비활성화
sudo ip link set can0 up type can bitrate 500000 restart-ms 100
sudo /sbin/ip link set can0 down
# 데이터 송수신
candump can0
cansend can0 123#1122334455667788
FYI
한 가지 팁 아닌 팁을 드리자면 CAN을 개발 및 테스트용으로 연결할 때는 보통 RS-232 등에 쓰의는 DB9 커넥터에 노이즈 감소를 위해 신호선이 꼬아진 형태의 (Twisted Pair) 선을 사용합니다. DB9 커넥터구입은 그렇다 쳐도 페어선 구하는데서 약간 고민을 하게 됩니다.
1. 페어선 직접 구입 : 막상 구입하려 보면 10m 단위로 팔거나 12P짜리를 팔아서 테스트용으로 구입하기는 좀 그렇습니다.
2. UTP 케이블 사용: 급한대로 쓰기 좋지만 너무 얇고 강선이라 끊어질 우려가 있습니다.
저는 일반 AWG 전선을 손으로 꼬아서 간단하게 페어선을 만드는 것을 추천드립니다. 생각보다 금방 만들고 잘 풀리지도 않습니다. 게다가 가격이나 접근성 면에서 이 편이 월등합니다. 끝부분을 종단저항 놓듯이 수축튜브로 처리해주면 풀릴 걱정을 하지 않아도 좋습니다.
Done!
종단저항때문에 한 30분 날려먹었는데 처음 경험해보는 통신치고는 상당히 깔끔하네요. 다음에 뭘 할지 기대해주세요.
긴 글 읽어주셔서 감사합니다. ❤️와 광고 클릭으로 고마움을 간단히 표현할 수 있습니다.
개발 환경(Desktop) | Ryzen 5900X, RTX3080
개발 환경(Laptop) | M2 Macbook Pro
AI, IoT 제품 개발 및 기타 문의 | dokixote@wklabs.io