Implementing 2nd fully independent print head (5 axis)

Basic Information:

Printer Model: Custom build corexyuv
MCU / Printerboard: 2x SKR pro
klippy.log klippy.log (336 Bytes)

Our issue:

Hi, our concern is to adapt Klipper so that two print heads can print simultaneously. This should mean that both heads share the z-axis (height) but can work individually on this height. Our printer is structured as shown in the attached image:


The first idea we have to solve this problem is to allow Klipper to control a total of seven motors. We use the coreXY or for the other motor the coreUV principle, for this we need two motors each, also one for the cartesian z-axis and then one motor each for the extruder on the print heads.

The first step we are currently implementing is the implementation of a G1 command to be able to control all motors (individually). For this we followed the guide on the Klipper Code_Overview page (Code_Overview – “Adding new kinematics”). We have already adapted the kinematics Python file accordingly (snippet):

self.rails = [stepper.LookupMultiRail(config.getsection(‘stepper_’ + n)) for n in ‘xyzuv’]
for s in self.rails[1].get_steppers():
| self.rails[0].get_endstops()[0].add_stepper(s)
for s in self.rails[0].get_steppers():
| self.rails[1].get_endstops()[0][0].add_stepper(s)
for s in self.rails[4].get_steppers():
| self.rails[3].get_endstops()[0][0].add_stepper(s)
for s in self.rails[3].get_steppers():
| self.rails[4].get_endstops()[0][0].add_stepper(s)

self.rails[0].setup_itersolve(‘corexy_stepper_alloc’, b’+‘)
self.rails[1].setup_itersolve(‘corexy_stepper_alloc’, b’-‘)
self.rails[2].setup_itersolve(‘cartesian_stepper_alloc’, b’z’)
self.rails[3].setup_itersolve(‘coreuv_stepper_alloc’, b’+‘)
self.rails[4].setup_itersolve(‘coreuv_stepper_alloc’, b’-')

Our u and v axes of the second print head run basically the same as the x and y axes of the first head (where both are actually the a and b axes in coreXY / coreUV, but this is converted in the G1 command). We have therefore taken the file kin_corexy.c (in klipper/klippy/chelper) and replaced only the labels x and y by u and v. This gives us an error. First of all, two questions arise from this:

  1. Is there a way of Klipper in combination with OctoPrint on a Raspberry Pi to look at the raw error messages? Because the log is not very meaningful with this error:

Building C code module
Unable to build C code module (error=256)

  1. Are the files “kin_cureuv.c”, “itersolve.h” and “trapq.h” the only ones to be edited for the kinematics of the new printhead? Or are there other files to be considered?

Our current work status on the code (not finished yet!) can be found here: GitHub - Rapid-OOD-GmbH/klipper_corexyuv: modification for klipper to implement two individual printer heads using the same z-axis.

We appreciate any help.

For host C code errors like that, I run the code in “batch mode”, which will show the compile errors on the console. Debugging - Klipper documentation


Update: we have completed the first steps of the implementation and have now set up a system with
Klipper that allows us to address two print heads. These run partially individually. This means that we
can move both print heads individually to any position, but not independently of each other in terms
of speed.
So if both print heads are addressed at the same time, they only move at the same time and so the
faster movement is scaled down to the slower one. This means that either only one printhead moves
at the same time or both move at the same time, but never a movement of one overlaps with the
movement of the other.
In the linked video you can see how these movements look like in our case.

For our implementation we made some changes in the source code of Klipper. This is not very ideal
in our opinion, because we are relatively inflexible, if we would like to connect more print heads.

Therefore we want to try to achieve a more individual movement of the engines by running several
gcode readers in parallel, so that we can address each printhead individually and optimally even run
the unmodified Klipper side by side on several threads in the end.

Our plan for this is to include tool changes in the gcode so that tasks for the two printheads are
written one after the other. Then the two gcode readers read this in parallel and insert all serial
gcode statements per printhead into a kind of stack. These stacks are then processed (parallel). If one
printhead is done with its stack, it waits until the other one is also done with its part
(synchronization). Then this procedure starts again for the next section of the gcode file.

Therefore now our question:
Where can we find in the code the files to modify exactly this gcode reading and is it possible to run
Klipper in parallel in multiple sub-instances?

Thanks for any advice–

1 Like