[DIY 3D Printer] 2. Klipper CAN bus 구성
3D프린터를 만들다 보면 toolhead로 가는 배선들이 굉장히 거슬린다.
hotend heater, thermistor, probe, heater / parts fan 만 해도 기본 11가닥이고,
rgb led, input shaper를 위한 가속도 센서까지 추가되면 20가닥부터 시작은 기본이다.
이 케이블들은 서로 얽혀 유지보수를 어렵게 만들 뿐만 아니라 그 자체로 뻣뻣하여 고속 프린팅을 방해한다.
이번 포스팅에선 CAN bus를 구성해 여러 보드 간의 통신을 가능하게 함으로써 이러한 문제를 해결할 것이다.
CAN bus란?
CAN(Controller Area Network)은 원래 차량 내부의 수많은 전자 장치(ECU) 간의 통신을 위해 개발된 신뢰성 높은 차량용 네트워크 규격이다.
두 가닥의 통신선(CAN-High, CAN-Low)에 노드를 연결하는 방식으로 구성된다.
신호 안정성을 위해 차동 신호 방식을 사용하는데, 원래 차량 내부의 수많은 기기, 엔진 등 노이즈 가득한 환경에서 사용하기 위한 프로토콜이기에 3D프린터의 스텝모터, 핫엔드 등의 노이즈에도 안정성을 가질 수 있다.
사전 확인
Rpi에 mainboard를 USB로 연결한다.
이전 포스팅에서 USB to CAN bus bridge 펌웨어를 mainboard에 올려 두었기에
Rpi에서 mainboard가 CAN adapter로 인식 될 것이다
lsusb
Mainboard Firmware 플래시 과정이 궁금하다면 아래로

Rpi CAN bus 구성
Klipper CAN bus 문서의 USB to CAN bus bridge mode부분에 can interface 구성하는 방법이 나와있지만,
이 방법은 Raspbian 8 이하 버전에서 network관리 deamon이 ifupdown인 환경을 기반으로 만들어진 문서이다.
Rsapberry Pi OS 12이상, Debian 12 Bookworm이상의 최신 OS에서는 network deamon으로 NetworkManager를 사용하기 때문에 위 방식은 사용할 수 없다.
사전 확인
우선 본인의 Host가 NetworkManager를 사용중인지 확인한다.
sudo systemctl status NetworkManager
이런식으로 active 상태이면 NetworkManager를 사용중인 것이다.
NetworkManager는 can interface구성을 지원하지 않기 때문에 systemd-networkd 데몬을 이용해 can 구성을 할 것이다.
systemd-networkd가 비활성화 되어 있는지 확인한다.
sudo systemctl status systemd-networkd
NetworkManager가 can0를 무시하도록 설정
NetworkManager는 can interface를 지원하지 않기에 이미 사용되고 있는 NetworkManager가 아닌 systemd-networkd를 이용해 can interface를 구성한다.
두 deamon이 동시에 작동하기 때문에 충돌을 피하기 위해 NetworkManager에서는 can0를 무시하도록 설정 한다.
NetworkManager설정파일 생성
sudo nano /etc/NetworkManager/conf.d/99-ignore-can0.conf열린 nano 편집기를 통해 아래 내용 입력 후 ctrl + x -> y로 저장 후 종료
[keyfile]
unmanaged-devices=interface-name:can0systemd-networkd 설정 파일 생성
CAN network 생성
sudo nano /etc/systemd/network/80-can.network아래 내용 입력 후 저장
[Match]
Name=can0
[CAN]
BitRate=1000000CAN link 생성
sudo nano /etc/systemd/network/80-can.link
아래 내용 입력 후 저장
[Match]
Type=can
[Link]
TransmitQueueLength=256서비스 활성화 및 재시작
# systemd-networkd
sudo systemctl enable systemd-networkd
sudo systemctl restart systemd-networkd
# NetworkManager restart
sudo systemctl restart NetworkManagernetwork 구성이 제대로 되었는지 확인한다.
ip -details link show can0정상적으로 구성이 되었다면 아래와 같이 나타난다
can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.875
tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
gs_usb: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp-inc 1
clock 48000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 parentbus usb parentdev 1-2:1.0Transmit queue length 설정(optional)
ip -details link show can0에서 qlen이 10으로 되어있는걸 볼 수 있다.
Transmit queue 가 10밖에 되지 않으므로 갑자기 많은 패킷이 넘어간다면 이를 처리하지 못 할 것이다.
udev rule 수정
sudo nano /etc/udev/rules.d/99-canbus.rules아래 내용 입력 후 저장
SUBSYSTEM=="net", ACTION=="add|change", KERNEL=="can0" ATTR{tx_queue_len}="256"재시작
sudo reboot now재시작 후 구성을 다시 확인하면 qlen이 256으로 되어있을 것이다.
ip -details link show can0
Katapult
설치
Katapult는 CAN bus를 통한 펌웨어 플래쉬를 도와주는 프로그램이다.
Katapult 펌웨어를 한번 올리면 이후에는 CAN으로 펌웨어를 올릴 수 있다.
- Katapult 레포지토리 clone
cd ~ && git clone https://github.com/Arksine/katapult- 펌웨어 설정
cd ~/katapult
make menuconfigmenuconfig설정은 자신의 expansion board에 맞게 설정한다.

마찬가지로 q -> y로 나온다.
- 펌웨어 컴파일
make clean
make컴파일이 완료되면 ~/klipper/out/katapult.bin에 firmware가 생성된다.
Katapult flash

- ebb36보드 표시한 부분에 점퍼를 씌워 usb로 전원을 받게 한다.
- 좌측 BOOT버튼과 우측 RST버튼을 동시에 누른 채로 Rpi에 연결한다.
- RST버튼을 먼저 뗀다.
- BOOT버튼을 뗀다.
위 과정으로 Rpi에 연결하면 firmware를 올릴 수 있는 DFU모드로 ebb36이 연결된다.
lsusb
이처럼 ~ in DFU Mode로 인식되면 성공.
sudo dfu-util -a 0 -D ~/katapult/out/katapult.bin --dfuse-address 0x08000000:force:mass-erase:leave -d 0483:df11 마지막의 0483:df11는 lsusb에서 나온 ID에 맞춰서 수정한다.

Error들이 몇 개 뜨는데 중간의 File downloaded successfully만 뜨면 성공이다.
Klipper firmware build
cd ~/klipper/
make menuconfig이번엔 CAN Expansion 보드에 사용할 펌웨어를 빌드 한다.

make clean
make마찬가지로 ~/klipper/out/klipper.bin에 펌웨어가 생성된다.
Klipper Flash via Katapult
이제 ebb36과 Rpi연결을 끊고 ebb36을 CAN bus에 연결한다.
- Klipper 중지
sudo systemctl stop klipper- CAN device query
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
~ : CanBoot가 떠야 정상이다.
위 Klipper는 메인보드고, CanBoot이 Katapult가 올라간 보드이다.
- Flash via Katapult
cd ~/katapult/scripts
python3 flashtool.py -i can0 -f ~/klipper/out/klipper.bin -u <uuid><uuid>부분을 CanBoot기기 uuid로 바꿔서 입력한다.

이제 다시 CAN query를 날리면 Klipper 기기 두 대로 인식되는 것을 볼 수 있다.
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
- printer.cfg 수정
Mainsail 웹 콘솔(http://[Rpi IP]:80)에 접속 한 뒤
좌측 MACHINE -> printer.cfg에 아래 부분을 추가/수정한다.
[mcu]
canbus_uuid: ffb861e8a4c8
[mcu toolhead]
canbus_uuid: 25c105b4520a우 상단 SAVE & RESTART를 클릭하고 재시작이 되면 아래처럼 mcu들이 정상적으로 인식되는 것을 확인할 수 있다.

이렇게 CAN bus를 이용해 Rpi에 여러 MCU 연결에 성공하였다.
다음 포스팅에서는 Klipper의 꽃인 printer.cfg를 수정해 볼 것이다.
Reference :
Klipper 공식 Documentation