-
can2ado - CAN to Analog/ Digital Output카테고리 없음 2025. 9. 12. 10:38
시작하기 전에
- 디지털/ 아날로그 신호를 CAN 신호와 함께 측정하기 - ADI2CAN :: hsl's tsmaster 사용기에서 adi2an (Analog/ Digital Input to CAN) 장치를 만든 배경, 과정, 결과물에 관하여 설명하였다.
- can2ado는 adi2can의 상대 장치라고 할 수 있다. CAN 신호를 받아서 아날로그, 디지털 출력을 한다.
- 나는 (2025년) 10월 22일부터 24일까지 열리는 DIFA (Daegu International Future Auto & Mobility Expo 대구 국제 미래 모빌리티 엑스포 포럼 2025 대한민국 미래모빌리티엑스포 컨퍼런스 )에서 TSMaster를 전시할 때 데모를 만드는 중이다.
- 데모는 무선 조정 자동차(무조차)를 이용한다. 무선 대신 CAN 통신을 사용한다. CAN 통신과 제어 로직 개발에 TSMaster를 이용한다. (제어 로직 개발은 SDV (Software Defined Vehicle)를 구성하는 주요 요소들 중에 하나다.)
- 무조차의 모터 구동은 ESC(Electronic Speed Control. 내 블로그에 자주 출현하는 Electronic Stability Control이라는 브레이크 시스템과 약어는 같지만 전혀 다르다.)라고 불리는 속도 조절 장치가 한다. ESC는 무선 수신기가 전송한 PWM 신호에 따라 전/후진 및 속도 조절을 한다.
- 무조차의 조향은 서보 모터로 한다. 서보 모터는 PWM 신호에 따라 시계/반시계 방향으로 회전한다.
- TSMaster가 직접 PWM 신호를 생성할 수 없다. TSMaster의 CAN 신호를 PWM으로 변환하는 장치가 필요하다. 실제 데모에서는 토선사의 TIO (추측하자면, Tosun Input Output. https://tosunai.kr/hardware/category/tio-series/) 장치를 이용할 것이다. 중간 단계로 간단하게 can2ado를 만들었다.
- 아래 비디오는 TSMaster와 can2ado를 이용하여 무조차를 작동하는 모습이다. 화면에 정현파 그래프가 조향과 구동 요청 신호이다. 이 신호들은 TSMaster에서 (차에 가려져 안 보인다) can2ado로 전송된다. can2ado는 이 신호들을 PWM으로 변환하여 무조차로 전달한다. 무조차는 PWM 신호들에 따라 조향과 구동을 한다.
CAN 신호에 따라 앞바퀴가 좌우로 회전하는 것과 네 바퀴가 앞뒤로 회전하는 것을 볼 수 있다. - 요기까지 방법을 설명한다. (전체 데모 개발 스토리는 더 길다. 한 번에 모든 설명을 하자니 내 말재주로 벅차다.)
개요
- 데모 구상
- CAN dbc 작성
- ado2can 개발
- 동작 확인
구상
- 데모 시스템은 제어 알고리즘이 동작하는 TSMaster, 운전자의 조향 방향을 알 수 있는 조향각 센서, 차량 자세 측정에 사용되는 요 레이트 & 횡가속도 센서, TSMaster의 CAN 신호를 PWM 신호로 변환하는 can2ado 장치, PWM으로 조정되는 조향 서보 모터와 구동 모터를 갖춘 무조차로 구성된다.
- 조향각 센서는 현대자동차에 들어가는 부품을 사용하기로 했다. CAN 통신을 하기 때문이다. TSMaster로 입력 신호를 받아 소프트웨어를 개발하기에 편리하다. CAN 통신 데모의 취지에도 맞는다. 나는 알리익스프레스에서 각도 속도 센서, 보레고 모하비 08-15 소울 09-13 아제라 엘란트라 제네시스 산타페 세도나 포르테 소울용, 934803L002 3R000 - AliExpress 34을 주문했다. 아직 기다리는 중이다.
- 2000년대에 에어백 제어기와 요-레이트 & 횡가속도 센서를 통합하는 프로젝트에 참여한 적이 있다. 그때 사용했던 요-레이트 & 횡가속도 센서를 사용한다. (이걸 다시 만지게 될 줄 몰랐다. 이것이 내집 다락에 있는 걸 이번 주에 알았다. 잘 작동하는 것에 놀랐다.)
- can2ado는 adi2can을 만들 때와 같이 아두이노 (arduino), 아두이노 CAN 쉴드를 사용한다.
- 무조차는 2010년대에 잠시 가지고 놀던 것을 사용한다. (내집 다락에 있을 것 같았는데, 진짜 있어서 반가웠다. 잘 작동하는 것에 놀랐다.) 무조차의 조향과 구동 제어를 PWM으로 하는 것을 claude.ai와의 대화로 알았다. 그리고 이 데모의 구상은 이때부터 형태를 띄게 되었다.
CAN dbc 작성
조향각 센서의 dbc
- 알리익스프레스에서 구매한 조향각 센서는 현대자동차용 센서이다. 나는 opendbc/opendbc/dbc at master · commaai/opendbc 에서 발견한 현대자동차 dbc를 사용할 것이다. 익숙하다. 맞을 것으로 기대한다. 부품이 배달되면 알 수 있을 것이다.
opendbc에서 발견한 현대자동차의 조향각 센서 CAN 매트릭스 요 레이트 & 횡가속도 센서의 dbc
- 에어백과 요 레이트 & 횡가속도 센서 통합 프로젝트 당시에, 요 레이트 & 횡가속도 센서는 (일반 CAN 버스가 아닌) ESC(Electronic Brake System)와 전용 CAN 버스로 연결되었다. 내가 갖고 있는 센서는 전용 CAN 버스의 매트릭스가 적용된 것이다. 나는 이 매트릭스를 갖고 있다. :-)
요 레이트 & 횡가속도 센서의 CAN 매트릭스 can2ado의 dbc
- can2ado의 CAN 매트릭스는 adi2can의 매트릭스와 유사하게 만들었다. 나는 claude.ai에게 아래 요청으로 can2ado 개발을 시작했다.
첨부는 아두이노 코드입니다. 아날로그, 디지털 신호를 받아서 CAN 메시지로 전송합니다. 전송하는 CAN 메시지의 아이디와 전송 주기를 설정용 CAN 메시지로 변경할 수 있습니다. 설정은 비휘발성 메모리에 저장됩니다. 그래서 adi2can 이라고 부릅니다.
나는 이번에는 반대의 장치를 만들고 싶습니다. CAN 메시지를 받아서, 아두이노의 아날로그, 디지털, PWM 출력을 제어하고 싶습니다. can2ado라고 부르겠습니다. 설계를 어떻게 하면 좋을까요? 제안을 부탁합니다.
코드 작성은 우리 둘이 요구 조건에 관해서 충분히 논의를 하고 같은 이해를 하고 있는 것을 확인한 후에 요청하겠습니다.- 위 요청을 시작으로 claude.ai와 대화를 하면서 can2ado 설계를 개선해 나갔다. 설계가 충분히 잘 되었다고 생각했을 때, 코드 작성을 요청했다. (내 경험으로 위 요청의 마지막 문장이 중요하다. 그렇지 않으면 클로드는 수시로 코드를 작성한다. 그러면 설계에 집중하기가 (그리고 클로드를 설계에 집중시키기가) 어렵다. 중간중간에 현재까지 정의된 요구 조건을 정리해 달라고 요청하는 것도 중요하다. 나는 대화가 길어져서 클로드가 과거 대화 내용을 잘 기억하지 못한다고 생각할 때, 새로 대화를 시작한다. 이때 파일로 저장한 정리된 내용을 클로드에게 주고 이를 바탕으로 대화를 시작하자고 한다. 이때 요긴하다.)
- 위와 같이 만든 코드는 즉시 실행 가능하지 않았다. 1차적으로 컴파일 에러가 발생한다. 에러 메시지를 클로드에게 주고 새 코드를 받아서 컴파일하고, 에러가 발생하면 다시 클로드에게 주고 ... 이 과정을 반복하여 컴파일 에러를 없앴다. 2차적으로 기능 에러가 발생한다. 내가 의도한대로 코딩이 안 된 경우가 있다. 내 설계가 미흡한 경우는 더 많다. 수정 요청과 기능 확인을 반복한다.
- 나는 처음에 직접 dbc를 작성할 생각을 했다. 그래서 can2ado 코드에 있는 SMsg(Status request Message)의 구조를 그림으로 그려달라고 했다. 메시지 안에 어느 위치에 어떤 신호가 얼마 길이로 들어가 있는지 시각적으로 확인하면 CANdb++로 신호와 메시지를 만드는데 도움이 되기 때문이다.
나: SMsg의 메시지 레이아웃을 그림으로 그려주세요.
클로드: [메시지 레이아웃 그림을 그려주었다. 0번 비트부터 63번 비트까지 가로로 길게 한 줄로 있는 그림이다. 과하게 svg로 그려준다.]
나: 메시지 레이아웃은 주로 8 x 8 그리드로 그립니다. 그렇게 부탁합니다. 텍스트로 그려도 됩니다.
클로드: [아래와 같이 그려주었다. 내가 기대한 한 눈에 이해하기 좋은 방식은 아니다.]Bit: 7 6 5 4 3 2 1 0 Byte 0: RSV RSV RSV DBG FLT SFE WDG RDY Byte 1: RSV RSV PRQ DRQ ARQ PWM DIG ANA Byte 2: ┌─────────── ERROR_CODE[15:8] ────────────┐ Byte 3: └─────────── ERROR_CODE[7:0] ─────────────┘ Byte 4: ┌────────── MSG_COUNTER[7:0] ─────────────┐ Byte 5: ┌───────── ERROR_CHANNEL[7:0] ────────────┐ Byte 6: ┌─────────── ERROR_VALUE[15:8] ───────────┐ Byte 7: └─────────── ERROR_VALUE[7:0] ────────────┘
- 이때 dbc가 텍스트 문서이고, 클로드가 dbc 문법을 잘 알 것 같다는 생각이 들었다. 아래와 같이 요청해 보았다.
dbc 파일을 만들 수도 있습니까?
- 클로드는 dbc 파일을 만들어 주었다. CANdb++에서 열려고 하니 에러가 발생하였다. 에러 내용을 확인하고, 정상적으로 잘 열리는 dbc 파일과 비교하여, 차이점을 클로드에게 알려주었다.
나: Vector 사의 CANdb++로 dbc 파일을 여니 Line 151: Syntax Error라고 경고창이 뜨고 파일이 열리지 않습니다.
정상적으로 열리는 dbc 파일과 비교하니 VAL_ 라벨이 BADEF 라벨 이후에 나옵니다. 이런 것이 관련이 있을까요?
클로드: 정확한 지적입니다! DBC 파일에는 섹션 순서가 중요합니다. Vector CANdb++는 특정 순서를 요구하며, VAL_ 섹션이 BA_DEF_ 섹션보다 앞에 와야 합니다.- 이후 2~3 차례 (GetMsgCycleTime) 에러 수정을 반복하였다.
- 첨부는 위 과정으로 작성한 dbc 파일이다.
- 정확성에 관해서 평가하자면 ... 파일 이름 마지막에 4가 암시하는 것처럼 클로드가 작성한 dbc가 한 번에 완벽하게 동작하지는 않았다. 사실 내가 작성하는 dbc도 대부분 한 번에 완벽하게 동작하지는 않는다. 신호와 메시지가 많을 때는 더욱 그렇다. 다른 사람은 모르겠지만, 나보다 못하지 않다.
- 효율성에 관해서 평가하자면 ... 내가 직접 dbc를 만들었다면, 시간이 수십 배 더 들었을 것이다. 다른 사람은 모르겠지만, 나보다는 훨씬 매우 빠르다.
ado2can 개발
하드웨어
- 아래 그림과 같이 구성하였다
- adi2can과 같은 컨셉의 구조이다. 아두이노 프로토 쉴드에 커넥터 연결을 위한 핀들을 납땜하였다.
아두이노, CAN 쉴드, 프로토 쉴드로 can2ado의 하드웨어를 구성하였다. 소프트웨어
- 클로드가 작성한 코드를 컴파일하여 에러를 찾고, 에러를 클로드에게 전달하고, 수정을 요청하고, 개선된 코드를 컴파일하고 ... 이 과정을 반복한다.
- 전에는 이 과정을 아두이노 IDE에서 했다. 수정을 할 때마다 아두이노 IDE와 클로드 사이에서 코드와 에러 메시지를 복붙했다. 불편했다. 파이썬 코드처럼 vs code에서 작성하면서 ai의 지원을 받으면 좋겠다. PlatformIO IDE라는 vs code 익스텐션을 찾았다.
- Platform IDE에서 코드 작성, 아두이노로 다운로드가 가능하다. ai의 지원을 받으며 코딩을 하니 생산성이 획기적으로 증가했다. 복붙의 불편함이 없어지니 짜증도 없어졌다. 새로운 기능에 관한 아이디어가 생각나는 경우, 귀찮아서 시도도 안 하고 마는 경우가 퍽 줄었다.
- 코드는 첨부와 같다.
can2ado 소스 코드
- 코드가 잘 작동하는 것을 확인하였다. 코드가 길었다. vs code 화면을 위 아래로 옮겨 가면서 보기가 불편했다. 여러 파일들로 분리하면 불편을 줄일 수 있을 것 같았다. 클로드에게 코드를 보기 좋게 여러 파일들로 분리할 수 있는지 물었다. 아두이노 IDE가 아니라 vs code 인지라, 클로드가 새 디렉토리와 파일들을 만들 수 있다. 새 디렉토리와 파일들이 만들어졌다. 이 거대한 변경은 아직은 임시 상태다. vs code는 변경을 keep 할 지를 물었다. (ignore 옵션도 있었는데) 나는 코드가 잘 작동해서 만들어진 성취감과 기쁨의 정신 상태에서 keep을 선택한 것 같다. 그 후로 몇 시간 동안 수 많은 컴파일 에러들을 하나씩 둘씩 처리해야 했다. 나는 (다시) 배웠다. Be careful what you wish for.
동작
- 동작 확인을 위해 TSMaster에서 정현파 모양의 조향과 구동 신호들을 실은 메시지를 반복해서 전송한다. 무조차의 앞바퀴가 좌우로 조향되고 구동 바퀴들이 전후로 구동한다.
- dbc 파일들을 드래그&드롭하여 TSMaster에 임포트한다.
드래그&드롭으로 dbc 파일들을 TSMaster에 임포트한다. - 메인 메뉴/ (1) Analysis/ (2) Transmit 버튼을 클릭하여 (3) CAN / CAN FD Transmit 창을 연다.
- (4) 데이터베이스 버튼을 클릭하면 아래 그림의 CAN Database 화면이 뜬다. PWM 요청 신호가 있는 PReq 메시지를 선택한다. Transmit 창에 PReq 메시지가 추가된다.
- (5) PReq 메시지를 선택하면 Transmit 창 하단에 PReq 메시지에 포함된 신호들이 표시된다.
- (6) steering_angle_req를 선택한다.
- (7) Generator에서 Sine을 선택한다.
- (8) 설정 버튼을 클릭한다. 아래 그림과 같이 Signal Definition 창이 뜬다. Amplitude, Period, Phase, Offset 등을 설정한다.
조향 요청값으로 사용한 정현파 신호를 정의한다. - drive_speed_req 신호에 대해서도 같은 방식으로 신호를 정의한다.
- (9) PReq 메시지의 Trigger를 클릭한다. Periodic으로 스위치를 옮기고, 메시지 전송 주기를 입력한다. 삼각형의 Play 버튼을 클릭하면 메시지 전송이 시작된다.
- (10) steering_angle_req와 drive_speed_req 신호의 삼각형 Play 버튼들을 클릭하면 해당 신호들에 정현파의 값들이 실려 PReq 메시지가 전송된다.
- "시작하기 전에"에 있는 비디오에 보이는 것처럼, 앞 바퀴가 좌우로 조향된다. 네 바퀴가 전후로 구동된다.
결론
- CAN 메시지의 신호에 따라 PWM 신호를 출력하는 can2ado 장치를 만들었다.
- can2ado의 코드는 기존 adi2can 코드를 바탕으로 클로드와 협업해서 작성했다.
- can2ado의 dbc도 can2ado의 코드를 바탕으로 클로드와 협업해서 작성했다.
- can2ado의 PWM 출력 신호를 무조차의 서보 모터와 ESC (Electronic Speed Control)에 연결하여, 조향과 구동을 제어하였다.
- 조향과 구동을 위한 CAN 신호는 TSMaster의 Transmit 창에서 설정을 통해서 만들었다.
- 새로운 기능에 관한 아이디어가 있다면, TSMaster의 미니프로그램으로 구현할 수 있다. <-- 데모 개발 과정을 설명하여 여기까지 가는 것이 어렵지 않다는 것을 보이고자 한다.