Extra Klippy so it can also work with a dispenser instead of an extruder

Basic Information:

Printer Model: Ratrig Vcore 3.1
MCU / Printerboard: RaspberryPi 4/ BTT OCTOPUS V1.1

Hi everyone,

I’m Sam, a mechanical engineering student. I am currently converting a RatRig vcore 3.1 printer for a uni project such that it can print liquid metal. This is for flexible electronics.

So for this application, I am not using a standard extruder but rather a pump/dispenser that can deposit precise amounts of liquid metal.

I would like to control this pump using my Raspberry Pi on which I am currently already running Klipper. Is it possible to write an additional Klippy that controls GPIO pins of the Pi when normal extruding should be done by the extruder? So this Klippy should be able to analyse when printing is done at what speed and then pass it on via the GPIO pins. I want to keep the full flexibility of Klipper.

Can anyone support/help me in this? I myself am very inexperienced with 3D printers and even less with coding.

Many thanks!!!

Desperate student

Good start for such a project, but one grows with the challenges.

@naikymen or @Tony1 might be able to help you.

1 Like

Thank you for your quick response. @naikymen or @Tony1, if you have any ideas and would like to help me with this I would love to hear from you :slight_smile:

Reporting for duty, glad to lend a hand.

  1. What kind of pump is it?
  2. Do you need the pump to be synchronized in some way with the XYZ motion? Or is it just on/off or constant speed?
  3. Are you able to share an image of your setup?

Sincerely,
Desperate PhD Student

1 Like

Just FYI, one of the features I hacked into klippy is the ability to home extruders, just like the remaining axes. This is useful for syringe-like extruders (e.g. as in liquid handling robots, or other cold-goop-extruders).

1 Like

Hii

Thank you so much for your response, I have been struggling with this problem for a while now…

The pump that I’m using is this one:

The idea was for these to be controlled using the RS232 protocol with a written python code. For the first version the pump doesn’t need to be synchronized with the XYZ (I think is never gonna be necesery). So the main thing is just turning the pump on and off at a constant speed defined in the G-Code.

If the RS232 protocol is to diffucult to handel I would transfer the data of when to extrude and at what speed to a computer (using the Pi). Then I would control the syringe with LabVIEW.

The main goal is to read out about when to print at what speed so that I can then use the Pi for the syringe.

This is the current set-up without the Syringe:

Thank god.

So just to make sure i got it, you need:

  1. An XYZ CNC machine that moves a dispenser tool to a spot.
  2. To know when the machine has arrived at the spot.
  3. To command the dispenser to dispense.
  4. To know when the dispenser is done dispensing.
  5. To command the CNC to move to the next spot.
  6. Repeat.

Is all that correct?

I’m not sure I got what this means for the Klipper part. I’m not familiar with LabVIEW.

If you want to run your program just from GCODE, this would essentially mean that Klipper will be coordinating everything. You can write an extras module that talks to external stuff, waits for things to happen, etc.

But this road will lead you to months of spelunking uncommented code, with lots of undocumented behaviours (other stuff is really well documented), and potentially intense suffering if you are in a hurry.

From my understanding so far, it would be best if you avoided this, and instead treat the motion system and the syringe as completely different units, which you coordinate from outside Klipper.

In that last case:

  • You would interact with klipper through its UDS socket interface (or through moonraker) with a small python program, that also talks to your dispenser/labview.
  • You can use the G4 command (dwell) and wait for a response. The response indicates that the machine has stopped moving, and thus that you may dispense. I have not tested this very thoroughly.
  • I’d sugget not using Klipper at all. It is comparatively difficult to use it like this (e.g. lots of delays while waiting for more gcode before moving, complicated (web)socket stuff, etc.) and offers no advantage to the use case you described so far.

How does that sound?

1 Like

@Sineos do I get candy for being crowdsourced? :stuck_out_tongue:

Indeed, we want to have the functionality of a 3D printer but instead of fillament, print liquid metal.

There is one more thing that comes to mind: 🔬🧪 Science Jubilee ⚡⚙️ — science_jubilee 0.1 documentation

image

The folks at the Machine Agency lab at UW are really great. They have written a python framework to drive their Jubilee printer and coordinate its movements with other hardware (e.g. cameras).

I think it would be great if you got in touch with them. They are looking for poeple with use cases like yours to integrate more tools.

1 Like

Indeed, my idea initially was to “just” read out (0 or 1) when to dispense, transmit this signal over a GPIO pin so that the pump can be activated. But this is not so simple apparently?

Ah okay, I understand. Another question, is it possible that when extruding/dispensing, another (unused) GPIO pin on the motherboard is triggered (from, say, an unused fan). I could then use this pin to drive the dispenser…

Is this easy to implement in Klipper’s current code?

I will definitely arrange you candy if our problem gets solved somehow :wink:

I’ll share my candies with you :smiley: :candy:

Ohhh now I get it!

Yes that will work with stock klipper by configuring an [output_pin] section as described here: Configuration reference - Klipper documentation

I bet you can trigger a dispense in that way if you are able to read the pin’s state.

I wonder if there is a way for you to get a signal back… maybe a [gcode_button] section: Configuration reference - Klipper documentation

How do I best programme that a particular GPIO pin on the motherboard goes high when the extruder is working? This may be basic but with my limited knowledge of programming and clipper not at all easy… Can anyone perhaps help me with this on how exactly I best approach it?

This is probably going to be the easiest solution to our current problem.

Thank you so much already for all the help!

Greetings
Sam

So you do need the CNC movements to be in sync with the dispenser. Or maybe I’m not really understanding the case.

Anyway, as of recently, you can probably use [pwm_tool] to sync another thing to the 3D printer: Configuration reference - Klipper documentation

That feature is meant to sync lasers or spindles to a CNC machine, for engraving or milling. You can surely sync a dispenser to it by changing the PWM duty cycle from Klipper just before a move, reading its output on a GPIO on the Pi, then telling labview to tell the dispenser to dispense, and hope that the sum of all of the introduced latencies is not terrible.

Have you read the dispensers manual? I’m far from knowledgeable, but after a fast read it seems that you could bypass labview and RS232 by setting the “steady mode” and feeding the output of the Klipper pin directly to one of the I/O pins on the dispenser: https://nc-p-001.sitecorecontenthub.cloud/api/public/content/ad6ce7f8a8c34b72bd5295efa895fc74

I think this is as far as I can dive into your application at the moment. Perhaps someone with better ideas can jump in.

By “when the extruder is working”, I mean when normally the extruder’s stepper motor is driven. This without having to change the G-Code from a slicer…

Hi Sam

I use the Klipper on my desktop 3 axis dispensing robot to dispense liquids like UV adhesives, silicones or sealants. I can give you my settings and examples of applications. Maybe it’ll help you.

Here’s my setup:

As you can see, I’m using the same MCU as you :slight_smile:. I’m using a similar dispenser to yours. To switch the dispenser I use the foot pedal input and this is controlled via a relay module that is connected to the fan outputs. Here is code from my printer.cfg:

[output_pin Relay1]
pin: PA8
pwm: False

[output_pin Relay2]
pin: PE5
pwm: False

[output_pin Relay3]
pin: PD12
pwm: False

[output_pin Relay4]
pin: PD13
pwm: False

[output_pin PowerRelayModule]
pin: PD14
pwm: False
static_value: 1

Pin PD14 is used to power the relay module and is always on. I’m only using 2 outputs at the moment. One to control the dispenser and the other to control the shut off valve to prevent fluid leakage when the machine is not running.

I also use a physical button to fill the nozzle with liquid before running the code itself. Here is code from my macro.cfg:

[gcode_button PURGE] 
pin: !PG15 
press_gcode: 
 SET_PIN PIN=Relay1 VALUE=1
 SET_PIN PIN=Relay2 VALUE=1
release_gcode: 
 SET_PIN PIN=Relay1 VALUE=0
 SET_PIN PIN=Relay2 VALUE=0

So this is what my setup looks like. And here are sample G codes for dispensing:

-point dispensing

G0 X111.25 Y209.2 
G0 Z15.5
G1 Z11.5 F5000
SET_PIN PIN=Relay1 VALUE=1
G4 P800
SET_PIN PIN=Relay1 VALUE=0
G1 Z15.5
G0 Y200.2
G1 Z11.5 F5000
SET_PIN PIN=Relay1 VALUE=1
G4 P800
SET_PIN PIN=Relay1 VALUE=0

-continuous (shape) dispensing

G1  Z95.0
G1  Z88.2 F2000
SET_PIN PIN=Relay1 VALUE=1 
G4  P150
G1  X170.816 Y146.958 F900
G1  X170.513 Y147.554
G1  X170.142 Y148.11
G1  X169.709 Y148.62
G1  X169.22 Y149.076
G1  X168.682 Y149.472
G1  X168.101 Y149.803
G1  X167.485 Y150.065
G1  X166.843 Y150.253
G1  X166.184 Y150.365
G1  X165.517 Y150.4
G1  X164.849 Y150.357
G1  X164.191 Y150.237
G1  X163.552 Y150.042
G1  X162.94 Y149.773
G1  X162.362 Y149.436
G1  X161.828 Y149.033
SET_PIN PIN=Relay1 VALUE=0
G0  Z95.4
G1  X171.049 F5000

If you have any questions, feel free to ask.

T.

Thank you very much for your response. We are going to try to solve it this way. We ourselves were still thinking of writing a python script and linking it to our slicer so that the G-Code from the slicer is immediately uploadable to our liquid metal printer. We will still share the final result.

Thanks!