Setting Up udev rules for multiple canbus interfaces

Apologies for posting in General Discussion, but I don’t seem to be able to put this in the “Knowledge Base” category with my account privs…

A multiple-instance Klipper install is when a single host is configured to serve more than one printer at once. Each instance will have one or more associated mcus. These mcus may be connected in any of the normal ways—serial, usb, or canbus. Multi-mcu instances may have a combination of any of the above connection methods, or may have multiple mcus connected via either a single or multiple canbusses. (Oh my!)

One of the least hardware intensive methods to connect multiple multi-mcu instances is probably to place an mcu into “canbus bridge mode.” This would result in each instance having its own usb-canbus adapter connected to the host. (Note, connecting an mcu via canbus bridge mode without at least one additional mcu on its canbus will be unstable and is not advisable. A single mcu should be connected via either serial or usb and addressed using its /dev/serial/by-id/ path.)

Mosts hosts will automatically name the first canbus bridge “can0,” and additional bridges as “can1,” “can2,” etc, using a system called udev. For a general introduction to the udev system, you might want to scan Writing udev Rules. However, without additional configuration, these names can change depending on the order in which the usb-can bridges are connected, making them inconsistent and unreliable for addressing by different instances.

I couldn’t find any straightforward documentation on configuring Canbus with udev for multi-instance Klipper installs, so I cobbled together the following and wanted to share in the hope it may be useful to others. In multi-instance installs, where each instance has its own canbus (aka bridge mode mcu), consistent names become necessary to ensure each instance is connected to the appropriate printer.

These instructions were written on Debian running on x86_64, but should be applicable to Armbian systems as well. For rpios, you may need to use an ifconfig command in step 6’s up directive in lieu of the ip command :man_shrugging:t2:.

Setting Up Canbus with Udev

  1. Plug your canbus device (probably an mcu in canbus bridge mode or a u2c) into an available usb port. It’s easiest to start with a single usb-can device plugged in. The system will most likely autoname this device “can0”—you can check by running ip link show.

  2. Run udevadm info -a -p $(udevadm info -q path -p /sys/class/net/can0)| grep serial| head -n 1

  3. The above command should print something like ATTRS{serial}=="490033000F50475532323820". We’ll refer to this value as YOUR_SERIAL in subsequent steps.

  4. Open /etc/udev/rules.d/z21_persistent-local.rules in your editor of choice

  5. Subtitiuting the serial number you found in step 3, add the following line. (Since your system likely automatically assigns names such as “can0,” “can1,” “can2” etc to canbus devices, use a string such as “canalpha,” “canbeta,” or “cangamma” for YOUR_CHOSEN_CANBUS_NAME):

SUBSYSTEM=="net", ACTION=="add", ATTRS{serial}=="YOUR_SERIAL", NAME="YOUR_CHOSEN_CANBUS_NAME"
  1. Open /etc/network/interfaces.d/YOUR_CHOSEN_CANBUS_NAME in your editor of choice, and insert the following text, substituting the canbus name you created in step 5:
allow-hotplug YOUR_CHOSEN_CANBUS_NAME
iface YOUR_CHOSEN_CANBUS_NAME can static
    bitrate 1000000
    up ip link set $IFACE txqueuelen 128
  1. Run sudo udevadm control --reload-rules && sudo udevadm trigger --attr-match=subsystem=net and then unplug and replug your can device

  2. Run ip -details link show YOUR_CHOSEN_CANBUS_NAME and you should see your device listed under the appropriate interface name, with the correctly configured queue length (qlen) and bitrate.

  3. You may repeat the steps 1-8 to add additional busses. It seems to work fine to have multiple lines in the udev rules file created in step 4, or if you prefer, you may split the udev rules into multiple files (all in /etc/udev/rules.d/). A reboot isn’t strictly necessary, but if you like to by all means do!

Klipper/ Katapult Config

Once the interface is properly configured as above, you can simply add a canbus_interface: YOUR_CHOSEN_CANBUS_NAME line to your [mcu] object in your printer.cfg that lists the named interface you just created.

If you use katapult, you’ll also need to use the -i YOUR_CHOSEN_CANBUS_NAME option when your run flash_can.py to set the appropriate interface.

Cheers!

Before it goes up on the Knowledge Base, could I request the following clarifications? I believe I understand what you are doing here but there are some things that I don’t find clear.

  1. Is this for multiple CAN adapters/buses or for multiple CAN devices on a single bus? I believe it’s for the former but it would help if it was explicitly spelled out.
  2. I believe “{YOUR_CHOSEN_CANBUS_NAME}” is “can0”, “can1”, etc. This goes back to the previous point.
  3. If you are doing multiple CAN adapters/buses do all 8 steps you’ve listed have to be run? Should there be a reboot on your host in between them (Actually, rereading the list, you note that in step 7. - Can I suggest you make that into a separate step so it’s more clear)?
  4. What is {serial}? On the same note, I believe “{YOUR_SERIAL}” is the value shown from the ip link show command - correct?

Sorry, I just want to make sure I’m clear on what you’re doing.

Thanks so much for the feedback as always! I made a few edits that hopefully clarify things a bit, and included a link to a good introduction to the udev system for folks as unfamiliar with it as I was.

2 Likes

That looks much better - great job!

2 Likes

Thanks for writing up this information.

Just to be clear, a Klipper mcu configured in “usb to canbus bridge mode” must be attached to a functional canbus with at least one real canbus device on it. If one were to configure Klipper in “usb to canbus bridge mode” solely to communicate with that mcu, then the connection will be unstable - it may work for a few hours, but it will be prone to sporadic (hard to debug) failures.

Cheers,
-Kevin

1 Like

Good to know… I added it as a note for clarity.

Thanks for this write up. A nice explanation on using udev for this purpose. :+1:

I was always hoping someone takes the effort to write up something on CAN in general and its different usage scenarios, e.g. when to use “usb to canbus bridge mode”, its differences, how it ties in with Katapult etc.

I do not have much experience with CAN as I do not use it, so I’m not a good source.

I’ll gladly add it to the KB. FWIW, it might seem a bit lost as the only CAN related topic there, but still good information.

Thanks Sineos!

I’ll try and write an article or two over the next few days that provide more context for the KB. MCU updates do become a little more complex with multi-mcu so I’ll try and cover that as well.

1 Like

I did a little writing—I’m sure it needs editing! Maybe this could be a start for a more extensive KB page on can.

Canbus: The Briefest of Introductions

This document provides a conversational and ambling introduction to canbus, as well as several case studies of possible canbus configurations and topologies. More technical information is available in the Klipper documentation, as well as cited throughout this text.

Klipper allows a host process to connect to a printer’s mcu. Many printers have a single mcu to which all I/O (steppers, sensors, heaters) are connected.

As one adds more peripherals to a printer, the main mcu may begin to run out of available pins. Or, perhaps one wishes to add a concentration of I/O in an area a little further from the primary mcu (generally located in the chassis), and wishes to reduce wiring (cable) clutter back to a larger main board.

A Cluttered Chassis An example of a cluttered chassis. Note the difficulty of accessing lower layers of the board and RPi GPIO due to stacked daughter board.

Klipper allows the use of multi-mcu in these cases. These additional mcus can be connected via usb or serial. But many smaller SBCs (Single Board Computer: the computers usually used to deploy Klipper, of which Raspberry Pi is probably the most popular example), especially the Zero form factor, only have two usb ports… One for power, and one for a usb device. Whereas a user with several tools which can change during a print may have four or five mcus to connect simultaneously.

What is Canbus

Canbus is a networking technology. CAN stands for Controller Area Network. We’ll use the word canbus throughout this document to refer to CAN—it works better for search results, and disambiguates from the common English word, can. Originating from the early 1980’s, canbus grew popular in the automotive industry to connect all the various pieces of a car, and for factory floor automation. Canbus runs on two wires, Can High (can_h), and Can Low (can_l). These two wires carry a differential signal, that is, the same magnitude signal where one is positive and the other negative, i.e. abs(can_l) = abs(can_h). By twisting the wires of this differential pair, greater resilience to interference is created, because the difference between the signals is still the same.

At a high level, canbus helps make I/O plastic, by adding a little or a lot just where it’s needed. This sort of fluidity can make understanding canbus topology a little more challenging at first because so many different configurations are possible.

Not every mcu is canbus capable. Many STM32 and SAM mcus implement canbus in hardware. Canbus is implemented in software (in the PIO cores) on RP2040.

An mcu doesn’t create the final can signal directly. It communicates with a device called a CAN transceiver which creates the differential signal from two pins on the mcu. Some boards have a transceiver built in, but for many older boards, you’ll need to solder and wire one yourself. If you’re building from the ground up, or shopping for new hardware to implement your canbus designs, it’s probably preferable to exclude boards without a transceiver built in.

Motive, or, Do I Need Can?

If your printer is working great, and you’re happy with it, you don’t need to add canbus. It won’t make your printer better, or faster in and of itself. It’s also worth noting that Klipper’s canbus bridge mode will NOT be stable with only a single mcu, so switching your single mcu to canbus bridge would actually be a detriment. Canbus is a useful addition for people who need to add I/O to their printer, or who like to have more readily accessible ports for testing and experimenting with hardware.

Canbus enables easy experimentation such as testing this mass dampened piezo probe on an FLSun SR

Canbus could simplify (or complicate, depending on how you think about it!) the addition of an accelerometer to a toolhead. Accelerometer data can be used with Klipper’s input shaping technology, which reduces printer vibrations for better, often quieter, prints.

Canbus is especially convenient for parts of the printer that might be further away from the primary mcu such as toolheads and multi-material units.

Wiring/Topology

As mentioned earlier, canbus is two wires: can_h and can_l. These two wires are a shared bus, and connect to each device on the canbus. Many users also route power along with the CAN wires.

Canbus is terminated at both ends by a 120Ω resistor. Proper termination helps ensure stability of the canbus line by reducing ringing.

A U2C with different plug types labeled A U2C with different plug types labeled

There isn’t a standard can plug type. Some early boards for printers used usb c pd wires to carry the can signal and power. Many end users have strong expectations about how a usb c plug should work, though, and, coupled with the physical instability of the plug some users experienced on a rapidly moving toolhead, the choice proved less than ideal. Other boards might use screw terminals, molex minifit, molex microfit, or break out the data wires to jst-xh. Some devices use an xt30(2+2) plug. You’ll probably need to be prepared to crimp cables to set up your canbus capable board, and you may need to spend some time troubleshooting the connection (for instance, rotating the plug 180 degrees to get the signal working on some devices using a coopted usb c cable).

XT30 2+2 Plug XT30 2+2

That said, wiring is where canbus shines.

The Canbus Bridge

Klipper’s host process runs on an sbc, so for it to talk to can devices, it will need to be attached to the canbus… Somehow… Most sbcs don’t have canbus onboard (RK3568, RK3588, and RK3582 based devices do, but they’ll need a transceiver), so most users add can connectivity via either SPI or a USB adapter. SPI adapters tend to require a little more work to configure, and, as a result, USB adapters have probably become more popular.

This has been especially true since Klipper introduced canbus bridge mode. This mode allows capable mcus to be configured to bridge can communications via USB.

You might have seen devices such as the BTT U2C that operate solely as canbus bridges. These are very useful for working with older mcus that don’t have can transceivers on board. They’re probably a little easier to configure than soldering your own transceiver. Many STM devices can be configured to output the canbus signal on the USB port, and these devices allow connecting those directly, avoiding searching for available pins and soldering all together.

The U2C bridge does require power, and if you’re hoping to power your sbc with it, you’ll have to get it from either your mcu’s usb port, or so other available power pins. You may need to set a jumper to connect the usb port to the 5v rail, or solder over a diode on the usb VIN line. Consult your mcu’s schematic and board drawings as necessary.

Toolhead Boards

Perhaps the most popular use of canbus in Klipper is the toolhead board. A tool tends to be an I/O dense region, usually incorporating at minimum fans, a heater, an ADC for temperature measurements, a bed probe, and a stepper driver for the extruder. All the I/O from the tool can be wired to the toolhead board, and only the 2 canbus and 2 power wires need be routed back to the primary mcu or U2C (depending on topology). Additionally, most if not all toolhead boards have their own 5v regulator, bringing a little extra breathing room to an often heavily loaded 5v rail on the main mcu, perhaps creating headroom for a few extra leds.

BTT EBB42 on Mini SB

Some printers have several tools configured and all available for use during a single print. Toolhead boards ensure the availability of ports and wiring simplicity for these tools.

Mendel Max with TapChanger used to switch between 1.75mm Sherpa and 2.85mm Orbiter

A canbus cable can also be an easy breakpoint for switching tools manually. For example, a delta printer with magballs and canbus could have an extruder and a laser mounted on separate effector plates that can be switched out by unplugging the single can cable. Or, a MendelMax could be retrofitted with a TapChanger and switch tools by simply lifting the tool off the shuttle, changing the cable, and toggling the configuration in Klipper. (It’s worth noting that canbus cables carrying power are NOT hot-swappable. Power the machine down completely before changing.) Such configurations save both costs and space by allowing sharing and reuse of a kinematic system with different tools.

Topologies

Let’s get our feet on the ground by examining a few possible canbus topologies. As we do, we’ll try to think in terms of routing the golden duo—power and data—together on a single 4 wire cable, to keep runs clean.

A CAN Distribution Board with SKR Pico in Bridge Mode A CAN Distribution Board with SKR Pico in Bridge Mode

Scenario 1: The Canbus Distribution Board with SPI Adapter

You probably wouldn’t choose to lay out your canbus system like this now, but it’s worth covering first as early systems often worked this way.

The distribution board isn’t doing any processing or switching of the can signal, it’s just connecting the wires physically, and sometimes fusing the power rail to each connected device.

This topology would demonstrate a retrofit of a printer to have multiple tools and a rotary axis. The primary tool was NOT rewired from the primary mcu, the additional toolheads and rotary stepper were simply added on. It demonstrates that it is not necessary for the primary mcu to also be on canbus, as many older mcus (Arduino Mega, for instance) don’t support it.

Scenario 2: U2C

Building on the idea of a distribution board, and consolidating the host CAN adapter into it, the U2C removed the need to install and configure the SPI bridge.

Retrofit Version

U2C Block Diagram 1

This layout is topologically similar to the first layout. It would also be possible to connect some primary mcus to the U2C board by configuring them to output a CAN signal on the usb pins. In that case, the configuration would look as follows:

U2C Block Diagram 2

Clearing the Chassis

Creating ample, unobstructed airflow in a chassis can be a challenge. Coupled with the increased difficulty that maintaining the variety of small, difficult to identify cables that run to a toolhead presents, it made sense for some people to stop using the ports for the primary toolhead on the primary pcb, and just connect them all via canbus.

U2C Block Diagram 3

The diagram doesn’t really communicate how much more open a chassis feels without the primary tool cabling. It becomes much easier to work in the chassis area without the additional clutter, and reduces the likelihood of accidentally dislodging something. It also means that the printer doesn’t have to be fully disconnected and unscrewed and flipped over to make a change to wiring at the toolhead, dramatically simplifying maintenance.

The removal of the primary tool from the primary mcu also has the advantage of putting less heat through the primary board, reducing cooling requirements in some cases.

While on the subject of thermals, it’s worth noting that canbus might not work as well for printers with enclosures that run at very high temps. For instance, the data sheet for STM32F072 states an ambient operating range of -40ºC to 85ºC, but the actual range for an early ebb board and all its components is probably lower.

Scenario 3: Canbus Bridge Mode

As interest in canbus grew, parts started to become unavailable during the chip shortage. At this time, it became a lot more valuable to integrate the canbus bridge mode that many mcus support into Klipper.

Low Cost, Readily Available Transceiver

By compiling the mcu code with bridge mode support, many users were able to eliminate the need for a U2C altogether.

Bridge Block Diagram 1

However, most primary boards did not have a transceiver on board, meaning that users needed to add one, usually SN65HVD230. Often the transceiver was packaged on a longer, kind of floppy board–not ideal for the potentially high vibration of a printer chassis. Sourcing a more square version with mounting holes proved useful. It could also be difficult to locate appropriate pins on some mcus that were near each other, as well as supply a proper voltage in order to not fry the mcu input pins.

An SKR Pico in Canbus bridge mode

Multitool

The small, loose wires going to the transceivers could also be prone to transients in the chassis. Manufacturers responded by beginning to produce primary mcus with onboard transceivers (Mellow Fly-D5, Mellow E3-V2, BTT SKR3/SKR3EZ for example). These boards served as natural bridges.

A fystec sb can th board A fystec sb can th board

For users who manually switched tools between prints, bridge mode resulted in an much streamlined layout.

Bridge Block Diagram 2

In this way, a user could switch tools, and then simply comment out an include to toggle between tools in printer.cfg, i.e.:

[include tools/extruder.cfg]
# [include tools/laser.cfg]

becomes

# [include tools/extruder.cfg]
[include tools/laser.cfg]

to change from extruder to laser.

An Flsun SR configured with canbus bridge mode. The delta arms only hold one tool at a time, but tools can be switched at the effector plate An Flsun SR configured with canbus bridge mode. The delta arms only hold one tool at a time, but tools can be switched at the effector plate. Note the U2C is only being used as a transceiver.

A Few Addition Topological Notes

For our topological scenarios, we had only a single canbus connected to the host. However, a host may have multiple canbusses connected. The host may communicate with mcus on different busses all in the context of a single Klipper device.

A host may also run multiple Klipper processes, called instances. Each instance may communicate with mcus on any of the canbusses, however, it often makes sense topologically to have a the primary mcu on each printer configured in canbus bridge mode and have all of its canbus nodes connected to it. Such a topology means that a canbus can be powered down when its instance is idle–without affecting other instances.

A multi-instance canbus topology might look like this:

We tended to build our topologies around a star shape, but canbus can be daisy chained as well. It would work perfectly well to do something like

Daisy Chain Block Diagram 1

However, most boards don’t break out ports for daisy chaining, and the cabling could end up being a little awkward. Usually mostly star works well for tools, but if the canbus needed to make a stop off on the way to tools for say a gantry mounted x axis motor and endstop, that would be just fine.

Daisy Chain Block Diagram 2

It would also be possible to have multiple hosts on the canbus, and configure multiple mcus in canbus bridge mode, however it is not recommendable as the bandwidth of the bus could quickly become saturated during a print.

A non-recommended/experimental canbus setup. Flsun QQ-S Pro with each stepper on separate mcus A non-recommended/experimental canbus setup. Flsun QQ-S Pro with each stepper on separate mcus

Flashing & Updating

In order to communicate with the host process, Klipper needs to build and install a firmware on each mcu. In order to use an mcu via canbus, this firmware needs to be built to communicate over CAN.

While it is possible to build and install the firmware over usb, it can be difficult to access mcus in remote parts of the printer such as the chassis. It would also be tedious to have to connect a usb cable to an mcu each time you wish to update it.

Katapult (Formerly CanBoot)

Using canbus means you will have more mcus to install and update software on. If you have a couple of printers, flashing and updating becomes even more cumbersome.

Luckily, other people have faced these issues as well, and come up with some brilliant solutions.

Katapult is a bootloader that allows the mcu to listen over the canbus interface, go into flashing mode, and accept and flash firmware via canbus.

Katapult needs to be installed via USB on first install, but afterwards the mcu will not need to be connected via USB again.

You can find information on installing Katapult on the Katapult page. You can also often find information on installing to your specific board by googling “Katapult” and your board name.

Klipper_canbus is a fantastic resource for flashing toolboards.

For a more thorough top-to-bottom guide to the process of installing Katapult and Klipper, Esoterical Can Bus Guide is a great read.

Automating Updates

With multiple mcus, it becomes especially cumbersome to manually configure menuconfig for each mcu on every update.

You probably used kiauh to set up Klipper, and it does have menus for building an flashing, but those don’t include the capability to flash via canbus.

update_klipper_and_mcus runs updates on mcus configured in its mcus.ini file. It only updates Klipper.

katchup is a little script that can update Klipper and Katapult on configured mcus.

Klipper is moving toward including automated updates over the course of this year, so expect changes over the coming months.

Naming Canbus interfaces on a Multi-Instance Host with udev

Mosts hosts will automatically name the first canbus bridge “can0,” and additional bridges as “can1,” “can2,” etc, using a system called udev. For a general introduction to the udev system, you might want to scan Writing udev Rules. However, without additional configuration, these names can change depending on the order in which the usb-can bridges are connected, making them inconsistent and therefore unreliable for addressing by different instances, especially if devices are powered on and off automatically. In multi-instance installs, where each instance has its own canbus (aka bridge mode mcu), consistent names become necessary to ensure each instance is connected to the appropriate printer.

These instructions were written on Debian running on x86_64, but should be applicable to Armbian systems as well. For rpiOS, you may need to use an ifconfig command in step 6’s up directive in lieu of the ip command :man_shrugging:t2:.

Consistently Naming Canbus Interfaces with udev Rules

  1. Plug your canbus device (probably an mcu in canbus bridge mode or a u2c) into an available usb port. It’s easiest to start with a single usb-can device plugged in. The system will most likely autoname this device “can0”—you can check by running ip link show.

  2. Run udevadm info -a -p $(udevadm info -q path -p /sys/class/net/can0)| grep serial| head -n 1

  3. The above command should print something like ATTRS{serial}=="490033000F50475532323820". We’ll refer to this value as YOUR_SERIAL in subsequent steps.

  4. Open /etc/udev/rules.d/z21_persistent-local.rules in your editor of choice

  5. Subtitiuting the serial number you found in step 3, add the following line. (Since your system likely automatically assigns names such as “can0,” “can1,” “can2” etc to canbus devices, use a string such as “canalpha,” “canbeta,” or “cangamma” for YOUR_CHOSEN_CANBUS_NAME):

SUBSYSTEM=="net", ACTION=="add", ATTRS{serial}=="YOUR_SERIAL", NAME="YOUR_CHOSEN_CANBUS_NAME"
  1. Open /etc/network/interfaces.d/YOUR_CHOSEN_CANBUS_NAME in your editor of choice, and insert the following text, substituting the canbus name you created in step 5:
allow-hotplug YOUR_CHOSEN_CANBUS_NAME
iface YOUR_CHOSEN_CANBUS_NAME can static
    bitrate 1000000
    up ip link set $IFACE txqueuelen 128
  1. Run sudo udevadm control --reload-rules && sudo udevadm trigger --attr-match=subsystem=net and then unplug and replug your can device

  2. Run ip -details link show YOUR_CHOSEN_CANBUS_NAME and you should see your device listed under the appropriate interface name, with the correctly configured queue length (qlen) and bitrate.

  3. You may repeat the steps 1-8 to add additional busses. It seems to work fine to have multiple lines in the udev rules file created in step 4, or if you prefer, you may split the udev rules into multiple files (all in /etc/udev/rules.d/). A reboot isn’t strictly necessary, but if you like to by all means do!

Klipper/ Katapult Config

Once the interface is properly configured as above, you can simply add a canbus_interface: YOUR_CHOSEN_CANBUS_NAME line to your [mcu] object in your printer.cfg that lists the named interface you just created.

If you use katapult, you’ll also need to use the -i YOUR_CHOSEN_CANBUS_NAME option when your run flash_can.py to set the appropriate interface.

4 Likes

For some reason, the text on the block diagrams isn’t showing on the reply. Strange, it showed in the editor when I was composing the message.

I edited the above post to show pngs of the block diagrams instead of the svgs I originally included. It seems like the discourse cdn is maybe doing something to them? If anyone has any experience on what I need to do for the svg to show, please let me know and I’ll format accordingly so things look more crisp.

The post is available at kb_can/can.md at main · willpuckett/kb_can · GitHub.

Maybe I’m misreading this, but if you disconnect an MCU Klipper will shutdown. It regularly sends sync requests to an mcu and if it doesn’t get one it throws and error and shuts everything down.

We tended to build our topologies around a star shape, but canbus can be daisy chained as well. It would work perfectly well to do something like

CAN Bus is… by it’s very name, a BUS topology. It’s never daisy chained by the CANBus standard. It requires termination at each end of the BUS to prevent signal reflection and ensure reliability. You can’t and won’t get that with a star topology.

image

Just two things I noted while scrolling through.

1 Like

Thanks for the feedback.

It definitely will. I tried to delineate between two different types of multitool in the document, but I’ll edit to clarify:

  1. All tools are connected simultaneously
  2. Tools are connected 1 at a time. The printer is shutdown and powered off, the tool is switched, and the printer is restarted. The user can then toggle the include of the first tool off (comment it out), and uncomment the second tool’s include statement.

Maybe I’m using the wrong word to describe the second type. Maybe ToolSwitch would be better?

Again, completely true. I think to many people, using a something like the Mellow CanBus Expand Board or Wagos appears as a hub, with several longer stubs running to various tools, which starts to look a lot like a star, though I agree it technically is not. It seems worthwhile to talk about longer stubs and choosing which one to terminate etc. It does seem that daisy-chaining is an appropriate term as it can also be wired say from a primary board (Mellow D5 for instance) to an EBB42, and then directly off the CAN pins of the EBB42 to say another EBB42. Yes, it’s being “daisy-chained” before passing through the transceiver so is still the bus line, but it seems like daisy chaining to me implies connecting one node sequentially after the next with very short stubs, or is that wrong in some way I’m missing?

I honestly would advise against using anything that makes people thing they can swap out tools of any kind because Toolchangers are usually hot swapable in other contexts. It’s easily misunderstood.

I would instead word it as something like “Utilizing a CAN Bus setup offers significant advantages in terms of modularity and flexibility. By reducing the amount of wiring needed it can help to make the overall setup easier to manage and modify. Allowing for such things as different toolheads to be swapped out easily and quickly managed through the configuration files.”

That implies you have to change your configuration which means a reset at a minimum.

Generally you terminate at the one at the furthest point on the bus, which is the one that’s furthest from the controller. In that sense it’s usually easiest to count by branching points. Once you’ve stopped branching off and have gotten to the “last one in the line” that’s where you terminate at. Or maybe easiest to word it as “last in the daisy-chain”.

You’re not wrong, Daisy chaining and a bus topology are technically different. In the common use case of a 3D printer they’re treated the same. At least mine are daisy chained between 7 toolhead boards and it works fine.

(If anyone reading this objects to that please say so, but I think it really comes down to semantics).

The only thing I’d suggest (and maybe you already did, I’m too lazy to scroll back up) is give an example of what “daisy-chaining” means for those who don’t know. A picture like…

Might help as a visual aid (there are probably better ones)

Call me Mr. Pedantic as I have a few points I take issue with here and I think they should be corrected to make sure that people don’t go off in the wrong direction.

A couple of things here:

  1. Stubs must be kept as short as possible. There should be no “talk about longer stubs”. If you’re wiring a node inside the ends of the CAN bus, then it needs to have two cables coming in and wired into the board/connector, one from the previous CAN device and one to the next CAN device.
  2. You don’t “generally” terminate at the ends of the bus you must terminate at the ends of the bus.

NEVER use the term “Daisy Chain” or use wiring drawings of daisy chained devices even as a reference for people when discussing CAN.

Daisy chaining actually is used to describe two network topologies (one where data is passed along a line (“open”) and the other when it forms a ring (“closed”)). CAN is a single media network or linear network topology.

The reason why I’m pushing for the correct terminology to be used when discussing CAN is that there is a certain percentage of people who take comments like the ones above and wire their devices accordingly. When that happens, it’s a bitch to figure out what’s wrong and you’re going to get pushback because the person with the problems will tell you they wired it according to some reference. I don’t want that reference to come from here.

CAN is actually quite tolerant of sloppy wiring but not of incorrect wiring.

My “if anyone reading that objects to this” comment was my shining of the “Myke Signal”. I knew you’d correct my wording on that or if I’m thinking of it wrong.

You’re absolutely right in the sense that daisy chaining can end being connected in a ring network so it’s misleading. I knew I wasn’t considering something cause I was stuck visualizing it how I have it setup.

It would be physically difficult (I’d think) for someone to daisy chain their way back around to the controller, but I wouldn’t put it past anyone to do it, so yes. It should be CLEARLY defined as a bus topology.


Agreed on both points, Again my wording was poor. It is terminated at the end of the bus, I was just trying to think of a way to make the clear for the different ways people might wire it (bear with me, I know there is only 1 right way).

In the sense of, yes stubs should be kept as short as possible, but in some circumstances a stub might become as long as the last section of the bus to the final terminal which can look like a “fork” to a user who isn’t familiar with the wiring setup. That can lead to confusion on which one should be terminated.

More visually, On paper you’d put it like this…

but in reality your wiring can end up looking like this:
image

Node 4 is still the correct termination point, but I can see people over-thinking it and thinking to themselves that node 3 and node 4 are the same distance from node 2 so what’s the difference?

Maybe I’M over thinking it though.

It should be worded as you said here:

If you’re wiring a node inside the ends of the CAN bus, then it needs to have two cables coming in and wired into the board/connector, one from the previous CAN device and one to the next CAN device

The only exception to that is the LAST device on the bus which won’t have a wire leading to the “next device” because that is the last device. THAT is the one that should be terminated.

So there is no ambiguity.

So maybe the lesson here is any guide needs to spend sufficient time on how to CORRECTLY wire a CAN bus. It’s not insanely complicated but it definitely can (and will) be messed up by people. That’s easily proven by looking at the questions in the “General Discussion” that pop up.

2 Likes

I did some editing to try and improve clarity, especially around termination. I also added termination coloring to the diagrams.

CAN bus: The Briefest of Introductions

This document provides a conversational and ambling introduction to CAN bus, as well as several case studies of possible CAN bus configurations and topologies. More technical information is available in the Klipper documentation, as well as cited throughout this text.

Klipper allows a host process to connect to a printer’s MCU. Many printers have a single MCU to which all I/O (steppers, sensors, heaters) are connected.

As one adds more peripherals to a printer, the main MCU may begin to run out of available pins. Or, perhaps one wishes to add a concentration of I/O in an area a little further from the primary MCU (generally located in the chassis), and wishes to reduce wiring (cable) clutter back to a larger main board.

A Cluttered Chassis An example of a cluttered chassis. Note the difficulty of accessing lower layers of the board and RPi GPIO due to stacked daughter board.

Klipper allows the use of multi-MCU in these cases. These additional MCUs may be connected via USB or serial. But many smaller SBCs (Single Board Computer: a small ARM based computer usually used to deploy Klipper, Raspberry Pi being the most popular example), especially the Zero form factor, only have two USB ports… One for power, and one for a USB device. Whereas a user with an MMU (multi-material unit) and several tools which can change during a print may have four or five MCUs to connect simultaneously.

What is CAN bus

CAN bus is a linear network topology. CAN stands for Controller Area Network. Originating from the early 1980’s, CAN bus grew popular in the automotive industry to connect all the various pieces of a car, and for factory floor automation. CAN bus runs on two wires, CAN High (can_h), and CAN Low (can_l). These two wires carry a differential signal, that is, the same magnitude signal where one is positive and the other negative, i.e. abs(can_l) = abs(can_h). By twisting the wires of this differential pair, greater resilience to interference is created, because the difference between the signals is still the same.

The linear topology of CAN bus means that each device on the bus communicates with every other device. This is in contrast to a star topology, where each device communicates with a central hub, and the hub communicates with each device.

CAN bus is terminated at both ends of the line. This termination helps to reduce ringing on the line, and is usually achieved by placing a 120Ω resistor between can_h and can_l. CAN bus may also be terminated in a split termination scheme, in which two 60Ω resistors are connected in series between can_h and can_l, and a capacitor connected to ground is placed between them.

At a high level, CAN bus helps make I/O plastic, by adding a little or a lot just where it’s needed. This sort of fluidity makes understanding CAN bus topology a little more challenging at first because so many different configurations are possible.

Not every MCU is CAN bus capable. Many STM32 and SAM MCUs implement CAN bus in hardware. CAN bus is implemented in software (in the PIO cores) on RP2040.

An MCU doesn’t create the final CAN signal directly. It communicates with a device called a CAN transceiver which creates the differential signal from two pins on the MCU. Some boards have a transceiver built in, but for many older boards, you’ll need to solder and/or wire one yourself. If you’re building from the ground up, or shopping for new hardware to implement your CAN bus designs, it’s probably preferable to exclude boards without a transceiver built in.

Klipper implements CAN 2.0, which has a maximum speed of 1,000,000 bits per second. The newer CAN FD (Flexible Data Rate) has a maximum speed of 8,000,000 bits per second, but is not currently supported by Klipper. CAN FD is backwards compatible with CAN 2.0. Some newer devices feature a CAN FD transceiver, which will work just fine with Klipper’s CAN 2.0 implementation.

Motive, or, Do I Need CAN?

If your printer is working great, and you’re happy with it, you don’t need to add CAN bus. It won’t make your printer better, or faster in and of itself. It’s also worth noting that Klipper’s CAN bus bridge mode will NOT be stable with only a single MCU, so switching your single MCU to CAN bus bridge would actually be a detriment. CAN bus is a useful addition for people who need to add I/O to their printer, or who like to have more readily accessible ports for testing and experimenting with hardware.

CAN bus enables easy experimentation such as testing this mass dampened piezo probe on an FLSun SR

CAN bus could simplify (or complicate, depending on how you think about it!) the addition of an accelerometer to a toolhead. Accelerometer data may be used with Klipper’s input shaping technology, which reduces printer vibrations for better, often quieter, prints.

CAN bus is especially convenient for parts of the printer that might be further away from the primary MCU such as toolheads and multi-material units.

Wiring/Topology

CAN bus is two wires: can_h and can_l. These two wires are a linear network topology, and connect to each device on the CAN bus. Many users also route power along with the CAN wires.

CAN bus is terminated at both ends by either a 120Ω resistor, or a split termination scheme. Proper termination helps ensure stability of the CAN bus line by reducing ringing.

A U2C with different plug types labeled A U2C with different plug types labeled

There isn’t a standard CAN plug type. Some early boards for printers used USB-C PD wires to carry the CAN signal and power. Many end users have strong expectations about how a USB-C plug should work, though, and, coupled with the physical instability of the plug some users experienced on a rapidly moving toolhead, the choice proved less than ideal. Other boards might use screw terminals, molex minifit, molex microfit, or break out the data wires to jst-xh. Some devices use an xt30(2+2) plug. You’ll probably need to be prepared to crimp cables to set up your CAN bus capable board, and you may need to spend some time troubleshooting the connection (for instance, rotating the plug 180º to get the signal working on some devices using a coopted USB-C cable).

XT30 2+2 Plug XT30 2+2

Non-terminating nodes may be branched from the linear CAN bus line by short connecting wires called stubs. Stubs should be kept as short as possible, and there should never be consideration of a ‘long stub.’ As a general rule of thumb, the standard recommends that a stub should be no longer than 0.3m (30 cm) when using a 1Mbps signaling rate[1].

That said, wiring is where CAN bus shines.

The CAN bus Bridge

Klipper’s host process runs on an SBC, so for it to talk to CAN devices, it will need to be attached to the CAN bus… Somehow… Most SBCs don’t have CAN bus onboard (RK3568, RK3588, and RK3582 based devices do, but they’ll need a transceiver), so most users add CAN connectivity via either SPI or a USB adapter. SPI adapters tend to require a little more work to configure, and, as a result, USB adapters have probably become more popular.

This has been especially true since Klipper introduced CAN bus bridge mode. This mode allows capable MCUs to be configured to bridge CAN communications via USB.

You might have seen devices such as the BTT U2C that operate solely as CAN bus bridges. These are very useful for working with older MCUs that don’t have CAN transceivers on board. They’re probably a little easier to configure than soldering your own transceiver. Many STM devices may be configured to output the CAN bus signal on the USB port, and these devices allow connecting those directly, avoiding searching for available pins and soldering all together.

The U2C bridge does require power, and if you’re hoping to power your SBC with it, you’ll have to get it from either your MCU’s USB port, or some other available power pins. You may need to set a jumper to connect the USB port to the 5v rail, or solder over a diode on the USB VIN line. Consult your board’s schematic as necessary.

Toolhead Boards

Perhaps the most popular use of CAN bus in Klipper is the toolhead board. A tool tends to be an I/O dense region, usually incorporating at minimum fans, a heater, an ADC for temperature measurements, a bed probe, and a stepper driver for the extruder. All the I/O from the tool can be wired to the toolhead board, and only the 2 CAN bus and 2 power wires need be routed back to the primary MCU or U2C (depending on topology). Additionally, most if not all toolhead boards have their own 5v regulator, bringing a little extra breathing room to an often heavily loaded 5v rail on the main MCU.

BTT EBB42 on Mini SB

Some printers have several tools configured and all available for use during a single print. Toolhead boards ensure the availability of ports and wiring simplicity for these multitool setups.

Utilizing a CAN Bus setup offers significant advantages in terms of modularity and flexibility. By reducing the amount of wiring needed it may help to make the overall setup easier to manage and modify, allowing for such things as different toolheads to be swapped out easily and quickly managed through the configuration files.

A fystec sb CAN th board A fystec sb CAN th board

A CAN bus cable is an easy breakpoint for modular setups, which involve switching tools manually and toggling a few lines in printer.cfg. For example, a delta printer with magballs and CAN bus could have an extruder and a laser mounted on separate effector plates that can be switched out by powering down the printer and unplugging the single CAN cable. Or, a MendelMax could be retrofitted with a TapChanger and switch tools by powering down, lifting the tool off the shuttle, changing the cable, and toggling the configuration in Klipper. (It’s worth noting that CAN bus cables carrying power are NOT hot-swappable. Power the machine down completely before changing.) Such configurations save both costs and space by allowing sharing and reuse of a kinematic system with different tools.

Mendel Max with TapChanger used to switch between 1.75mm Sherpa and 2.85mm Orbiter

Topologies

Let’s get our feet on the ground by examining a few possible CAN bus topologies. Terminating nodes in the following scenario diagrams are represented by a red border with double side edges. Non-terminated CAN elements are green, and non-CAN nodes are blue.

A CAN Distribution Board with SKR Pico in Bridge Mode A CAN Distribution Board with SKR Pico in Bridge Mode

Scenario 1: The CAN bus Distribution Board with SPI Adapter

You probably wouldn’t choose to lay out your CAN bus system like this now, but it’s worth covering first for historical context.

The distribution board isn’t doing any processing or switching of the CAN signal, it’s just connecting the wires physically, and sometimes fusing the power rail to each connected device. Even though it may look like a branching star topology, it’s still a linear network topology because all devices are communicating directly with each other on the line.

This topology would demonstrate a retrofit of a printer to have multiple tools and a rotary axis. The primary tool was NOT rewired from the primary MCU, the additional toolheads and rotary stepper were simply added on. It demonstrates that it is not necessary for the primary MCU to also be on CAN bus, as many older MCUs (Arduino Mega, for instance) don’t support it.

Some early CAN toolboards and SPI adapters had termination resistors soldered on with no jumpers, and it wasn’t always possible to create ideal schemas when adding additonal devices.

Scenario 2: U2C

Building on the idea of a distribution board, and consolidating the host CAN adapter into it, the U2C removed the need to install and configure the SPI bridge.

Retrofit Version

diagram

This layout is topologically similar to the first layout. It would also be possible to connect some primary MCUs to the U2C board by configuring them to output a CAN signal on the USB pins. In that case, the configuration would look as follows:

diagram

Clearing the Chassis

Creating ample, unobstructed airflow in a chassis can be a challenge. Coupled with the increased difficulty that maintaining the variety of small, difficult to identify cables that run to a toolhead presents, it made sense for some people to stop using the ports for the primary toolhead on the primary pcb, and just connect them all via CAN bus.

By wiring the CAN line through the secondary tool, we encorporate the maximum length of cable into the bus, and avoid a stub exceeding 0.3m.

The diagram doesn’t really communicate how much more open a chassis feels without the primary tool cabling. It becomes much easier to work in the chassis area without the additional clutter, and reduces the likelihood of accidentally dislodging something. It also means that the printer doesn’t have to be fully disconnected and unscrewed and flipped over to make a change to wiring at the toolhead, dramatically simplifying maintenance.

The removal of the primary tool from the primary MCU also has the advantage of putting less heat through the primary board, reducing cooling requirements in some cases.

While on the subject of thermals, it’s worth noting that CAN bus might not work as well for printers with enclosures that run at very high temps. For instance, the data sheet for STM32F072 states an ambient operating range of -40ºC to 85ºC, but the actual range for an early ebb board and all its components would likely be lower.

Scenario 3: CAN bus Bridge Mode

As interest in CAN bus grew in the 3DP community, parts started to become unavailable during the chip shortage. At this time, it became a lot more valuable to integrate the CAN bus bridge mode that many MCUs support into Klipper.

Low Cost, Readily Available Transceiver

By compiling the MCU code with bridge mode support, many users were able to eliminate the need for a U2C altogether.

However, most primary boards did not have a transceiver on board, meaning that users needed to add one, usually SN65HVD230. Often the transceiver was packaged on a longer, kind of floppy board–not ideal for the potentially high vibration of a printer chassis. Sourcing a more square version with mounting holes proved useful. It could also be difficult to locate appropriate pins on some MCUs that were near each other, as well as supply a proper voltage in order to not fry the MCU input pins.

An SKR Pico in CAN bus bridge mode

Modular Tool Change

The small, loose wires going to the transceivers could also be prone to transients in the chassis. Manufacturers responded by beginning to produce primary MCUs with onboard transceivers (Mellow Fly-D5, Mellow E3-V2, BTT SKR3/SKR3EZ for example). These boards served as natural bridges.

For users who manually switched tools between prints (a modular tool switch), bridge mode resulted in a much streamlined layout.

diagram

In this way, a user could switch tools, and then simply comment out an include to toggle between tools in printer.cfg, i.e.:

[include tools/extruder.cfg]
# [include tools/laser.cfg]

becomes

# [include tools/extruder.cfg]
[include tools/laser.cfg]

to change from extruder to laser.

An Flsun SR configured with CAN bus bridge mode. The delta arms only hold one tool at a time, but tools may be switched at the effector plate An Flsun SR configured with CAN bus bridge mode. The delta arms only hold one tool at a time, but tools may be modularly switched at the effector plate. Note the U2C is only being used as a transceiver.

Multi-Tool

For printers with multiple tools all connected and available simultaneously, the most correct way to wire the bus is to go from one node to the next to the next.

diagram

This ensures the greatest length of CAN bus wiring is within the linear network topology, and that the signal is not degraded by a long stub exceeding 0.3m.

A Few Addition Topological Notes

For our topological scenarios, we had only a single CAN bus connected to the host. However, a host may have multiple CAN busses connected. The host may communicate with MCUs on different busses all in the context of a single Klipper device.

A host may also run multiple Klipper processes, called instances. Each instance may communicate with MCUs on any of the CAN busses, however, it often makes sense topologically to have the primary MCU on each printer configured in CAN bus bridge mode and have all of its CAN bus nodes connected to it. Such a topology means that a CAN bus may be powered down when its instance is idle—without affecting other instances.

A multi-instance CAN bus topology might look like this:

It would also be possible to have multiple hosts on the CAN bus, and configure multiple MCUs in CAN bus bridge mode, however it is not recommendable as the bandwidth of the bus could quickly become saturated during a print.

A non-recommended/experimental CAN bus setup. Flsun QQ-S Pro with each stepper on separate MCUs A non-recommended/experimental CAN bus setup. Flsun QQ-S Pro with each stepper on separate MCUs

Flashing & Updating

In order to communicate with the host process, Klipper needs to build and install a firmware on each MCU. In order to use an MCU via CAN bus, this firmware needs to be built to communicate over CAN.

While it is possible to build and install the firmware over USB, it may be difficult to access MCUs in remote parts of the printer such as the chassis. It would also be tedious to have to connect a USB-Cable to an MCU each time you wish to update it.

Katapult (Formerly CanBoot)

Using CAN bus means you will have more MCUs to install and update software on. If you have a couple of printers, flashing and updating becomes even more cumbersome.

Luckily, other people have faced these issues as well, and come up with some brilliant solutions.

Katapult is a bootloader that allows the MCU to listen over the CAN bus interface, go into flashing mode, and accept and flash firmware via CAN bus.

Katapult needs to be installed via USB on first install, but afterwards the MCU will not need to be connected via USB again.

You can find information on installing Katapult on the Katapult page. You may also often find information on installing to your specific board by googling “Katapult” and your board name.

Klipper_canbus is a fantastic resource for flashing toolboards.

For a more thorough top-to-bottom guide to the process of installing Katapult and Klipper, Esoterical Can Bus Guide is a great read.

Automating Updates

With multiple MCUs, it becomes especially cumbersome to manually configure menuconfig for each MCU on every update.

You probably used kiauh to set up Klipper, and it does have menus for building and flashing, but those don’t include the capability to flash via CAN bus.

update_klipper_and_MCUs runs updates on MCUs configured in its MCUs.ini file. It only updates Klipper.

katchup is a little script that updates Klipper and Katapult on configured MCUs.

Klipper is moving toward including automated updates over the course of this year, so expect changes over the coming months.

Naming CAN bus interfaces on a Multi-Instance Host with udev

Mosts hosts will automatically name the first CAN bus bridge “can0,” and additional bridges as “can1,” “can2,” etc, using a system called udev. For a general introduction to the udev system, you might want to scan Writing udev Rules. However, without additional configuration, these names may change depending on the order in which the USB-can bridges are connected, making them inconsistent and therefore unreliable for addressing by different instances, especially if devices are powered on and off automatically. In multi-instance installs, where each instance has its own CAN bus (aka bridge mode MCU), consistent names become necessary to ensure each instance is connected to the appropriate printer.

These instructions were written on Debian running on x86_64, but should be applicable to Armbian systems as well. For rpiOS, you may need to use an ifconfig command in step 6’s up directive in lieu of the ip command :man_shrugging:t2:.

Consistently Naming CAN bus Interfaces with udev Rules

  1. Plug your CAN bus device (probably an MCU in CAN bus bridge mode or a u2c) into an available USB port. It’s easiest to start with a single USB-can device plugged in. The system will most likely autoname this device “can0”—you may check by running ip link show.

  2. Run udevadm info -a -p $(udevadm info -q path -p /sys/class/net/can0)| grep serial| head -n 1

  3. The above command should print something like ATTRS{serial}=="490033000F50475532323820". We’ll refer to this value as YOUR_SERIAL in subsequent steps.

  4. Open /etc/udev/rules.d/z21_persistent-local.rules in your editor of choice

  5. Substituting the serial number you found in step 3, add the following line. (Since your system likely automatically assigns names such as “can0,” “can1,” “can2” etc to CAN bus devices, use a string such as “canalpha,” “canbeta,” or “cangamma” for YOUR_CHOSEN_CANBUS_NAME):

SUBSYSTEM=="net", ACTION=="add", ATTRS{serial}=="YOUR_SERIAL", NAME="YOUR_CHOSEN_CANBUS_NAME"
  1. Open /etc/network/interfaces.d/YOUR_CHOSEN_CANBUS_NAME in your editor of choice, and insert the following text, substituting the canbus name you created in step 5:
allow-hotplug YOUR_CHOSEN_CANBUS_NAME
iface YOUR_CHOSEN_CANBUS_NAME can static
    bitrate 1000000
    up ip link set $IFACE txqueuelen 128
  1. Run sudo udevadm control --reload-rules && sudo udevadm trigger --attr-match=subsystem=net and then unplug and replug yourCAN device

  2. Run ip -details link show YOUR_CHOSEN_CANBUS_NAME and you should see your device listed under the appropriate interface name, with the correctly configured queue length (qlen) and bitrate.

  3. You may repeat the steps 1-8 to add additional busses. It seems to work fine to have multiple lines in the udev rules file created in step 4, or if you prefer, you may split the udev rules into multiple files (all in /etc/udev/rules.d/). A reboot isn’t strictly necessary, but if you like to by all means do!

Klipper/ Katapult Config

Once the interface is properly configured as above, you may simply add a canbus_interface: YOUR_CHOSEN_CANBUS_NAME line to your [MCU] object in your printer.cfg that lists the named interface you just created.

If you use Katapult, you’ll also need to use the -i YOUR_CHOSEN_CANBUS_NAME option when your run flash_can.py to set the appropriate interface.


  1. Controller Area Network Physical Layer Requirements, pg. 10 ↩︎

1 Like

Wow. You put in a lot of effort into this.

It’s looking good but there are a number of issues that need to be discussed.

I think the best way to comment is to start with the section header and then the point.

CAN bus: The Briefest of Introductions

As one adds more peripherals to a printer

Do we add “peripherals” to a printer or “devices” or “parts” or “enhancements”? “Peripheral” just doesn’t seem like the right word to me.

What is CAN bus

The linear topology of CAN bus means that each device on the bus communicates with every other device. This is in contrast to a star topology, where each device communicates with a central hub, and the hub communicates with each device.

Could I suggest adding a graphic for this?

CAN bus is terminated at both ends of the line. This termination helps to reduce ringing on the line, and is usually achieved by placing a 120Ω resistor between can_h and can_l. CAN bus may also be terminated in a split termination scheme, in which two 60Ω resistors are connected in series between can_h and can_l, and a capacitor connected to ground is placed between them.

No, the termination resistors attenuate signal reflections coming back from the end of the network.

Split termination is done to reduce pick up of high frequency noise and is tricky to get right. It is very easy to end up with your cables ringing if you don’t ground the network components correctly.

Not every MCU is CAN bus capable. Many STM32 and SAM MCUs implement CAN bus in hardware. CAN bus is implemented in software (in the PIO cores) on RP2040.

I’m debating on whether or not to suggest this paragraph be dropped. What goes in and out of a CAN transceiver is simply NRZ Serial - theoretically any MCU with a UART can communicate with a CAN transceiver but will require more software than one with dedicated hardware to provide the Data Link Layer support.

The Seeed Studio CAN Bus Transceiver:

Uses a Microchip MCP2551 Serial to CAN bus interface chip. There are also Arduino CAN shields that use the Arduino’s Serial or SPI interfaces.

Wiring/Topology

Again, I think a diagram of what the network looks like.

As a general rule of thumb, the standard recommends that a stub should be no longer than 0.3m (30 cm) when using a 1Mbps signaling rate

??? Where do you get that “general rule of thumb”? That’s an antenna that will very easily pickup fairly low frequency noise - especially in a printer with steppers. Personally, I recommend no stubs longer than 1" (2.54cm).

Many STM devices may be configured to output the CAN bus signal on the USB port, and these devices allow connecting those directly, avoiding searching for available pins and soldering all together.

This isn’t correct. USB is USB. CAN is CAN. They do NOT have the same electrical specifications and are not interchangeable.

Toolhead Boards

Can I suggest that you make the point that CAN devices are not hot swappable before you say that “allowing for such things as different toolheads to be swapped out easily and quickly”.

Topologies

Sorry, for being blunt but there are a lot of mistakes in basic understanding in this section. You really need to go through your scenarios with other people who implement CAN and understand the different scenariors.

Again, you cannot pass CAN on USB C or any other flavor of USB. Maybe you can provide a reference to a “CAN Distribution board” that you think provides this functionality. This error in understanding is repeated throughout the section.

With regards to U2C boards, can I suggest that you read through my discussion with NAPCAL last week here:

With regards to the U2C boards with “USB” connectors, I suggest that you review NAPCAL’s block diagram of them:

This is why I only recommend Canable boards because they don’t have the confusing weirdness of the BTT and other boards.

Sorry for dumping on you. What you’re doing is extremely valuable but you need to first set up a CAN bus with different devices for each of the scenarios that you present so that you have a better understanding of how CAN is wired and works.

Hey thanks for the compliments. It hasn’t been too terribly much effort—mermaid charts are pretty easy to work with, and I always enjoy trying to write about things in the practice of being more articulate.

I think responding to your commentary overall, the document has some flow issues, which seems natural as it sprawls and gets edited. I’d like to see it maybe take on specifics from what an “ideal” implementation would look like, and branch from there… More graphics (as you suggested) would of course be great. It’s starting to get a little heavy on mermaid charts and FuzzyG suggested some schematics which would be nice. I was hoping to find a markdown schematic generator similar to mermaid, but I didn’t find anything the other day in the quick search I did… So I’ll probably try to do something in kicad and export pngs, which seem to work well with the discourse cdn…

In terms of the “not every mcu is CAN bus capable” paragraph, that should be specifically addressing in the context of Klipper. So it should read, “CAN bus is supported in Klipper on the following MCUs…” something like that…

The information on where I got the general rule of thumb is from a Texas Instruments document which is footnoted in the text. It shows up as a “…” after the text, and shows the link when you hover on it. (It’s here for convenience.) The document is older, but does reference 1Mbps CAN networks, which are the maximum Klipper supports.

I also have seen some information about CAN bus being hot-pluggable, for instance, this article. The 12/24v power I agree it’s not a good idea to hot plug, and I do power things down when I change tools.

I’m curious if others have had as much difficulty using pins PA11/12 for CAN_TX/RX? It seemed pretty straightforward to me when I did it, and worked without difficulty, but I ultimately switched to PD0/1 so I didn’t have to route the cable outside the chassis, though I still use the USB A plug on the BTT U2C (with a usb A to Dupont female cable that happens to be shielded). I’ve run a lot of prints that way without hiccups, so much so I’ve never bothered to check the retransmits. I’m traveling till the end of the month, but I’ll take a look when I get home…

And please don’t apologize for being blunt! It makes the world a much easier place at least for me to navigate! Writing and gathering feedback to create a document that can speak to what many people are doing and what works for many people is a lot more valuable I think than simply a single person’s experience.

On another note, I’m experimenting with a transceiver form factor you might find interesting… It’s designed to go into a spare stepper slot on a Robin Nano v3 board…The first prototype should be in the mail for me when I get home.

It may be a miserable failure with the cap right under it, but I have been picking up PD0/1 for can from the SPI pins on the stepper (on Robin Nano v3) without problem, so I’m hopeful. :crossed_fingers:t2:

When you say, “you cannot pass CAN on USB C or any other flavor of USB” are you referring to not being able to use the cable, the housing, or some other element? I use a USB C PD cable with usb C housings on a BTT hermit crab. I know people have had a lot of difficulty with the early version of the hermitcrab, but mine works well. I also do use silicon USB C PD cables with the ends chopped off and molex crimps with my ebbs which seem to work well also. They aren’t shielded, but it hasn’t seemed to cause an issue as long as I select ones where the D+/- wires (the ones I use for CAN_L/H) are twisted. (Although I am curious to check my retransmit rates now given the issues that you’re mentioning.)

If you have topologies that you can sketch out in text with arrows, I can make a mermaid diagram of them and if there are some pictures to include, even better.

I’ll try and reorganize things a little over the next week and see if some clarity can rise out of it all…

That would make things clearer.

If you look through my previous posts, you’ll see that I’m somewhat adamant on this point. Personally, I’ve never had problems with CAN communications. A big reason for this is that I make sure that I use appropriate cables (more on this below), keep the unshielded wire lengths and stubs to an absolute minimum.

Reading your comments here and looking back over what you originally wrote, I think I understand what you’re doing but you’re not explaining yourself clearly enough. More below.

This is where you need to be a LOT more explicit in your comments. The USB A connectors on the BTT U2C board are not CAN nor are they USB. They are NRZ serial lines as I indicated in your previous comment. Nowhere do you acknowledge that and, based on your text, you imply that the USB cables can be plugged as CAN:

can-3

This is not clear in your photographs either.

Can I make the following suggestions when you write this up:

  1. Write for someone who has some high school education and the extent of their electrical skills is that they can connect an Amazon Firestick into a TV and plug them both into a wall socket. In terms of computer skills, they can follow the instructions on the screen of their car to connect their phones using Bluetooth. I’m DEFINITELY not saying people here are stupid, but many people get into the hobby later in life and just getting a 3D printer working when they get them home is a big stretch for what’s required of them technologically - adding CAN for them, unless it’s explicitly spelled out, will be a real challenge for them.
  2. Don’t be so casual with your cabling. This is less directed at the actual CAN cabling, but the serial cabling that you have running from the BTT U2C card. If you insist on running serial lines from the U2C, explain that you are using the transceiver on the BTT U2C card to convert the signals on the CAN bus to serial transmit and receive lines. Again, I’d recommend staying away from the BTT U2C Card with it’s two serial interfaces - I found them to be quite difficult to understand the different interfaces on them (and I’m an EE with many years experience) and they aren’t wired logically or seemingly correctly.
  3. Simplify your graphics and do more of them. Part of this would be starting with a basic setup with a Raspberry Pi connected via USB to a basic main controller board and a U2C board (Canable) that has a CAN connection to a toolhead controller. Next, go to something like a Manta M5P/M8P which has an integrated CAN adapter with the USB interface set up as “CAN over USB” and explain what that meants. The first graphic in your “Scenario 1” has four tools, three which are connected using “CAN via short/long USB-C cable” and one with an “umbilical cable”. If your first drawing has more than four devices on it (rPi, Main Controller, U2C & toolhead) then you’re doing it wrong.

That’s a cool idea. I hope it works for you.

See my comments above.

Let us know how your new board works!

Interesting, thanks.

I find this paragraph confusing. The CAN bus should have two 120 ohm resistors on it. Anything else is unnecessarily complex, confusing, and likely error prone.

For what it is worth, CAN bus was designed for lengths of 100+ meters. In the shorts spans we use for 3d printers (typically 2m or less), one can do just about anything with the wiring. Stubs, impedance, placement of the resistors, twisting the wires, number of twists, wire gauge, insulation, etc - all irrelevant. You could practically use cotton string for CAN_H and CAN_L. (Okay, you can’t use string, but you get my point.) I think too much is made about the wiring - almost always when problems are resolved the root cause is found to be bad crimps, completely broken wires, incorrect configuration, buggy kernel revisions, or entirely missing resistors.

If you’d like to write an introductory document on CANbus I think it would be helpful to keep it to the standard configurations, and not delve into obscure configurations that may be plausible. There are just too many obscure configurations that could work, and I fear you’ll lose your audience trying to enumerate them all.

Please don’t go there. Even mentioning CAN signalling over USB wires is an extra heaping of confusion, topped with oblique, with a side of quirky. As above, with the cable lengths we use in 3d printers, just about anything can be made to work - but for an introductory document, I fear you’ll leave your readers more confused than when they started. USB wires are great for USB signalling, and it’s pointlessly confusing to use them for something else.

Thanks again for working on this.
-Kevin

1 Like