[DIY 3D Printer] 2. Klipper CAN bus 구성

[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
lsusb

Mainboard Firmware 플래시 과정이 궁금하다면 아래로

[DIY 3D Printer] 1. Klipper 설치
3D 프린터 성능이 향상되며 Marlin 같은 one-board방식은 연산 능력에 한계가 생겼다. Klipper는 성능이 뛰어난 Raspberry pi같은 SBC Host에서 복잡한 연산을 담당하고, 기존의 Marlin이 올라가던 mainboard에서는 단순한 제어만을 담당하는 방식으로 기존의 한계를 해결했다. 기존 mainsail에서는 설정 값을 바꾸러면 일일히 전체 펌웨어를 다 빌드해야 했지만, Klipper는 웹 콘솔 상에서 printer.cfg파일만 수정하면

Rpi CAN bus 구성

CANBUS - Klipper documentation

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
sudo systemctl status NetworkManager

이런식으로 active 상태이면 NetworkManager를 사용중인 것이다.

NetworkManager는 can interface구성을 지원하지 않기 때문에 systemd-networkd 데몬을 이용해 can 구성을 할 것이다.

systemd-networkd가 비활성화 되어 있는지 확인한다.

sudo systemctl status 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:can0

systemd-networkd 설정 파일 생성

CAN network 생성

sudo nano /etc/systemd/network/80-can.network

아래 내용 입력 후 저장

[Match]
Name=can0

[CAN]
BitRate=1000000

CAN 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 NetworkManager

network 구성이 제대로 되었는지 확인한다.

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.0

Transmit 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

설치

GitHub - Arksine/katapult: Configurable bootloader for Klipper
Configurable bootloader for Klipper. Contribute to Arksine/katapult development by creating an account on GitHub.

Katapult는 CAN bus를 통한 펌웨어 플래쉬를 도와주는 프로그램이다.
Katapult 펌웨어를 한번 올리면 이후에는 CAN으로 펌웨어를 올릴 수 있다.

  1. Katapult 레포지토리 clone
cd ~ && git clone https://github.com/Arksine/katapult
  1. 펌웨어 설정
cd ~/katapult
make menuconfig

menuconfig설정은 자신의 expansion board에 맞게 설정한다.

ebb36(v1.2) Katapult Configuration

마찬가지로 q -> y로 나온다.

  1. 펌웨어 컴파일
make clean
make

컴파일이 완료되면 ~/klipper/out/katapult.bin에 firmware가 생성된다.

Katapult flash

ebb36
  1. ebb36보드 표시한 부분에 점퍼를 씌워 usb로 전원을 받게 한다.
  2. 좌측 BOOT버튼과 우측 RST버튼을 동시에 누른 채로 Rpi에 연결한다.
  3. RST버튼을 먼저 뗀다.
  4. BOOT버튼을 뗀다.

위 과정으로 Rpi에 연결하면 firmware를 올릴 수 있는 DFU모드로 ebb36이 연결된다.

lsusb
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:df11lsusb에서 나온 ID에 맞춰서 수정한다.

dfu flash

Error들이 몇 개 뜨는데 중간의 File downloaded successfully만 뜨면 성공이다.

Klipper firmware build

cd ~/klipper/
make menuconfig

이번엔 CAN Expansion 보드에 사용할 펌웨어를 빌드 한다.

make menuconfig
make clean
make

마찬가지로 ~/klipper/out/klipper.bin에 펌웨어가 생성된다.

Klipper Flash via Katapult

이제 ebb36과 Rpi연결을 끊고 ebb36을 CAN bus에 연결한다.

  1. Klipper 중지
sudo systemctl stop klipper
  1. CAN device query
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0

~ : CanBoot가 떠야 정상이다.
위 Klipper는 메인보드고, CanBoot이 Katapult가 올라간 보드이다.

  1. Flash via Katapult
cd ~/katapult/scripts
python3 flashtool.py -i can0 -f ~/klipper/out/klipper.bin -u <uuid>

<uuid>부분을 CanBoot기기 uuid로 바꿔서 입력한다.

katapult klipper flash

이제 다시 CAN query를 날리면 Klipper 기기 두 대로 인식되는 것을 볼 수 있다.

~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
  1. printer.cfg 수정

Mainsail 웹 콘솔(http://[Rpi IP]:80)에 접속 한 뒤
좌측 MACHINE -> printer.cfg에 아래 부분을 추가/수정한다.

[mcu]
canbus_uuid: ffb861e8a4c8

[mcu toolhead]
canbus_uuid: 25c105b4520a

우 상단 SAVE & RESTART를 클릭하고 재시작이 되면 아래처럼 mcu들이 정상적으로 인식되는 것을 확인할 수 있다.

MCU Connect via CANbus

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

Reference :
Klipper 공식 Documentation