11. 데이터로깅과 CAN 통신

11. 데이터로깅과 CAN 통신

E-포뮬러 제작기: 데이터로깅

안내

본문은 포럼의 11. 데이터로깅과 CAN 통신 에서 읽으실 수 있습니다.

자작차 만들면서 다른 여러 팀의 학생분들과 익명 채팅방에서 큰 도움을 받았습니다. 귀중한 정보들이 일회성 답변으로 사라지는 것이 안타까워 모두가 정보를 공유하고 쉽게 검색해 찾아볼 수 있도록 익명 자작차 포럼을 만들었습니다.

포럼이 활성화되기를 바라는 차원에서 게시글을 전부 포럼으로 이동시켜 두었습니다. 읽고 나서 자유롭게 궁금한 점은 질문하시고, 아는 것은 공유해 주시면 앞으로 후배들에게 큰 도움이 될 것 같습니다. 감사합니다.

자작자동차포럼

한국 대학생 자작자동차 포럼
펼치기 ### 목차
## 개요 차를 다 완성해도 사실 우리는 우리가 만든 차에 대해 잘 알지 못한다. 데이터로깅의 필요성은 굳이 언급하지 않아도 차가 굴러가기 시작하면 모두가 느낄 수 있을 것이다. 대부분의 차량용 장비는 CAN으로 자신의 정보를 출력한다. 우리 팀의 Orion BMS 2와 PM100DX 컨트롤러도 마찬가지다. 차량에서 정보를 수집하고 싶다면 CAN 통신을 읽을 수 있어야 한다. 그러나 CAN 통신을 잘못 이해하고 사용하는 경우를 많이 보았다. 통신을 하려면 일단 그 통신이 어떤 것인지 대충은 알아야 한다. 적어도 종단 저항과 차동 신호에 대해서는 이해하는 것이 좋다. 그러니 일단 CAN에 대해 조금 알아보자. ## Controller Area Network, CAN CAN은 1986년에 Bosch가 공개한 통신 프로토콜(약속)이다. 여러분이 쓰는 드릴 만드는 그 보쉬 맞다. 1991년부터 완성차에 탑재되기 시작했다. 현재 CAN 2.0이 자동차 외에도 여러 산업에서 널리 쓰이고 있다. OBD-II에도 사용된다. CAN 통신은 차동 신호 버스를 이용하는 1:N 통신이다. 모든 노드(통신 장비)는 CAN-H와 CAN-L로 이루어진 두 가닥의 통신 버스에 자기 다리를 내려 연결된다.
이런 식이다. CAN 버스는 가로로 긴 CAN-H, CAN-L 전선을 말한다. CAN 통신 속도는 250kbps, 500kbps, 1Mbps가 많이 사용된다. 통신 속도가 느려질수록 버스의 길이 제한이 늘어난다. 500kbps에서 CAN 버스는 100m까지도 길어질 수 있다. 한편, 각 유닛이 이 버스에 내리는 다리는 stub라고 부른다. 이 거리는 상대적으로 짧아서 50cm 이상 길어지면 통신에 문제가 생길 수 있다. ### 종단 저항
그림에서처럼 버스의 양 끝단 CAN-H, CAN-L는 120Ω 저항으로 연결되어 있다. 이를 종단 저항이라고 부르며, 임피던스 매칭을 위해 사용된다고 하는데 이런건 몰라도 된다. 다만 종단 저항은 꼭 있어야 한다. 정상적으로 구성된 CAN 버스는 양 끝에 120Ω 저항이 병렬로 달려 있기 때문에 멀티미터로 CAN-H, CAN-L 사이의 저항을 재면 60Ω이 측정된다. 대부분 장비는 종단 저항을 설정할 수 있다. 우리 BMS는 CAN 버스가 2개라서 종단 저항이 내장된 버스와 없는 버스가 하나씩 존재한다. 컨트롤러는 EEPROM으로 종단 저항을 사용할지 여부를 설정할 수 있다. 이러한 장비들과 데이터로깅에 사용할 CAN 트랜시버의 종단 저항을 확인해서 종단 저항이 있는 2개의 장비가 CAN 버스의 양 끝에 오도록 연결해야 한다. 꼭 멀티미터로 직접 측정해 보자. ### 차동 신호 RS232나 여러분이 아두이노에서 한번쯤 써 보았을 UART 시리얼 통신은 모두 GND를 기준으로 신호를 주고받는다. 신호선이 GND를 기준으로 0V면 LOW, 5V면 HIGH 이런 식이다. 반면 CAN 통신에는 GND가 없다. 대신 CAN-H와 CAN-L 사이의 전압차가 신호를 만든다.
두 선 사이에 전압차가 없으면 HIGH, 있으면 LOW이다. 이렇게 하면 노이즈 저항성이 높아진다. 사실 그러려면 CAN 버스의 두 선을 꼬아 주어야 효과가 극대화되지만, 우리의 CAN 버스는 과하게 길거나 트래픽이 많지 않으니 여유가 없다면 생략해도 좋다. ### 통신 규칙 CAN에는 통신을 통제하는 마스터 노드가 없다. 누구든 떠들고 싶으면 버스에 대고 조잘거리면 된다. 물론 두 노드가 동시에 떠들면 충돌이 일어나지만 이런 상황은 장비들이 알아서 잘 프로토콜에 정해진 대로 대처한다. CAN 트랜시버를 만들 게 아니라면 몰라도 된다. CAN 통신은 메시지 단위로 이루어진다. CAN 메시지는 이렇게 생겼다.
다른 거 다 몰라도 된다. 메시지마다 11bit짜리 ID가 있고 데이터는 최대 64bit(8Byte)까지 담을 수 있다는 것만 알면 된다. 데이터가 몇 바이트 길이인지에 대한 정보도 control 섹션에 담겨 있어서 알 수 있다. CAN 2.0B는 ID를 29bit까지 쓸 수 있는데, 이런 부가적인 것은 필요하면 그 때 찾아보면 된다. 대부분의 장비는 CAN ID별로 내보내는 정보를 정해 놓고, 같은 메시지를 주기적으로 버스에 브로드캐스팅한다.
이런 식이다. ID가 0x0A0인 메시지의 2, 3번 바이트는 B상 IGBT 모듈의 온도 정보를 담고 있다는 뜻이다. 이런걸 한가득 미리 정해서 매뉴얼에 적어 놓고, 이 메시지를 일정한 주기(100ms 등)로 실시간 정보를 담아 CAN 버스에 뿌린다. ## CAN 통신 읽기 이러한 CAN 메시지 중에서도 우리가 진짜 궁금한 것들은 소모 전류나 토크처럼 주행중에 나오는 정보들이다. 하지만 주행 데이터를 보겠다고 차에다 노트북을 달아 놓고 달릴 수는 없는 노릇 아닌가? 우리에게는 노트북 대신 CAN 버스에 어떤 데이터들이 날라다녔는지 보여줄 작은 컴퓨터가 필요하다. 하지만 아두이노나 STM32 같은 대부분의 MCU는 CAN의 차동 신호를 처리할 수 있는 기능 자체가 없다. 이러한 MCU가 CAN 통신을 하려면 트랜시버를 사용해야 한다.
CAN 트랜시버는 차동 신호를 MCU가 알아먹을 수 있는 디지털 신호로 바꿔준다. 제일 흔하게 사용하는 것은 MCP2515이다. 이 칩이 들어간 CAN 트랜시버 모듈을 통해 MCU를 CAN 버스에 연결해야만 MCU가 CAN 신호를 이해할 수 있다. 이렇듯 CAN은 시리얼이나 I2C 등과는 아예 다른, 새로운 통신 프로토콜이다. 대회를 준비하면서 CAN 버스를 아두이노의 시리얼 통신 핀인 TX, RX에 연결했는데 데이터가 불안정하다거나, 컨트롤러에서 나오는 CAN 버스를 MCU와 연결했더니 IMD가 FAULT를 띄웠다는 등의 이야기를 들었다. 아마 다 트랜시버를 잘못 사용해서 발생하는 문제가 아닐까 싶다. CAN 버스가 HV랑 그라운드를 공유할 리는 없으니 말이다. CAN 트랜시버를 사용해서 CAN 메시지를 읽는 예제 코드같은 것은 이 글에서 설명하지 않는다. 아두이노로 CAN 통신하는 예제야 인터넷에 충분히 많고, STM32를 다룰 정도라면 HAL 라이브러리 헤더를 보고 충분히 직접 짤 수 있을 것이다. ## 데이터로거 그런데 사실 데이터로거를 실제로 쓸만하게 직접 만드려면 손이 정말 많이 간다. 1. 처음에는 대충 CAN 트래픽 정도만 기록해보고 싶다. 아두이노로 적당히 만들어 보니 그럴싸하게 동작한다. 1. 그런데 이렇게 만든 CAN 로거는 데이터를 '읽을' 수는 있지만 '기록'할 수는 없다. 차가 달리는 와중에 노트북 연결해서 시리얼 모니터 띄워놓고 나중에 복사할 것인가? 그럴거면 그냥 BMS나 인버터에 딸려오는 USB 어댑터로 바로 노트북에 연결하는게 낫다. 전원이 꺼져도 예쁘게 기록돼서 나중에 열어보려면 SD카드에 저장해야 한다. SD카드 모듈을 추가한다. 1. 다 달리고 돌아와서 나중에 데이터 열어보면 뭐가 뭔지 하나도 알 수가 없다. 적어도 시간은 알아야 데이터가 기록된 상황이 좀 보인다. 그런데 MCU는 전원이 꺼지면 초기화되기 때문에 실제 시간을 알아낼 방법이 없다. 시간을 알아내기 위해 RTC 모듈을 추가한다. 1. GPS 위치 정보 정도는 있어야 데이터의 맥락이 보인다. 시간 정보만 있으면 달릴 때 동영상을 찍어 일일히 대조해봐야 어떤 상황이었는지 알 수 있다. GPS 모듈을 추가한다. 1. 이 때 섀시 친구들이 얘기한다. 주행 중 가속도 변화, 서스펜션 길이 변화, 바퀴 네짝 휠 스피드 데이터도 좀 기록해달라고 한다. BMS, IMD FAULT도 기록되면 좋을 것 같다. 가속도 센서는 I2C, 서스펜션 리니어 센서는 ADC, 휠 스피드는 Timer input capture, FAULT 신호는 GPIO... 써야 할 peripheral(주변 장치)이 점점 늘어난다. 1. 이쯤 되면 아두이노로 이 모든 것을 하기에는 성능이 모자랄 것이다. STM32나 ESP32 정도 되는 MCU를 권장한다. * 우노는 16 MHz, STM32F4는 168 MHz로 동작한다. 단순 계산해봐도 10배 빠르다. * 우노는 8-bit 컴퓨터다. 제일 기본적인 32-bit 정수 연산도 한 번에 할 수 없고 10개 이상의 명령어가 필요하다. 클럭까지 생각하면 최소 수십 배 느려진다. * 우노의 메모리, SRAM은 2KB이다. 버퍼 하나도 제대로 만들기 어렵다. STM32F407은 192KB 정도를 가지고 있다. * 아두이노는 인터럽트 모드도 DMA도 제대로 지원하지 않는다. 온갖 peripheral에서 쏟아지는 신호를 전부 제대로 기록하려면 인터럽트 기능은 필수다. 그 와중에 SD 카드에 데이터를 안 밀리고 쓰려면 DMA도 써야 한다. 1. 데이터를 까보려면 차가 다 달리고 돌아와서 SD카드를 뽑아서 컴퓨터에 꽂아야 한다. 어느 세월에? 그리고 배터리 잔량이나 실시간 전류 소모는 나중에 알아봐야 그렇구나 할 뿐이다. 실시간으로 알아야 쓸모가 있다. 무선 통신용 MCU를 추가하고, 수집한 데이터를 SD카드에 쓰는 동시에 무선 통신으로 전송한다. 스마트폰 핫스팟을 통한 인터넷 접속이 가장 쉽다. 그러려면 웹 서버도 하나 만들어야 한다. 1. 이제 차가 달리는 와중에 데이터가 실시간으로 들어온다. 그런데 데이터는 그냥 숫자 무더기다. 여기서 각 센서를 구분하고, 센서별 데이터를 일일히 해석하고 그래프로 그린다. GPS 데이터는 지도 위에 그린다. ### 이걸 언제 다 하나 한 줄씩 적었지만 직접 개발하려면 하나하나가 몇 주씩 걸리는 기능들이다. 태반이 기계과인 자작차 동네에서 자동차 멀쩡히 굴러가게 만들기도 바쁜데, 별로 안 친한 회로랑 코딩이랑 놀 시간이 없다는 것을 잘 알고 있다. 이런 건 컴퓨터쟁이가 해야 하지 않겠는가? 그래서 다 개발해 놓았다.
CAN 버스 트래픽, 디지털 및 아날로그 입력 신호, 휠 스피드 센서, 3축 가속도, GPS 위치, LV 전원 전압 등을 측정할 수 있다. SD카드에 데이터를 저장하는 동시에 무선으로 실시간 모니터링도 가능하다. 나중에 SD카드 컴퓨터에 꽂아서 웹사이트에 업로드하면 종류별로 다 그래프 그려주고 지도에 선도 그어 준다. 그리고 누구나 직접 만들어 쓸 수 있도록 필요한 부품 목록과 회로도, 제작 방법, 소프트웨어를 모두 오픈소스로 공개해 두었다. 필요하면 직접 수정해 사용하면 된다. 조금 더 자세한 설명은 [다음 글](https://luftaquila.io/blog/e-formula/monolith-telemetry-datalogger/)에 이어진다. ### 목차