Syringe Pumps / Depositing Viscous Materials
-
Thanks.
I'm thinking about a pair of syringes with end stop switches and isolation valves. Selection of the latter may prove tricky, but would be isolated from the duet as far as possible. I believe an end stop triggered macro would suffice to change over active syringe.
Where I begin to come a little unstuck would be after I have isolated the empty syringe how would I carry out a retract (sucking in new gunk through a non-return) concurrently to the machine carrying on printing? One of the discussed benefits of RRF2 & 3 was supposed to be concurrent actions right?
-
@DocTrucker said in Syringe Pumps / Depositing Viscous Materials:
Where I begin to come a little unstuck would be after I have isolated the empty syringe how would I carry out a retract (sucking in new gunk through a non-return) concurrently to the machine carrying on printing? One of the discussed benefits of RRF2 & 3 was supposed to be concurrent actions right?
I'm not sure that's possible yet.
-
@tom_lauerman posted quite a bit about clay printing and is a real expert.
Multiple concurrent gcode streams (what you are referring to here) is not yet implemented so you would need to pause the print to run the macro that refilled the syringe or possibly post process the gcode to run that inline (but not sure if that would work well - would depend on what needed to happen concurrently).
-
Thanks guys, I will search for the user at my leisure. Not working on clay as it happens, but it's a close enouch topic to be relevant.
-
@DocTrucker Hello all, and thanks to @T3P3Tony for the shout out. I'm doing clay printing just about every day, using a dual syringe printer. However, my refilling process is quite straightforward compared to what is proposed here. I pause the print, retract the syringe, insert a fresh tube of clay, extrude a bit to prime the nozzle, and return to printing. If I do this quickly it doesn't show in the print. If I get distracted and make the switch slowly, the object being printed shrinks a little and the first fresh layer stands a bit proud of the others.
In these pandemic times I have been documenting what I do more vis video rather than in the classroom (I'm a teacher (of Art)). So if anyone cares to see some clay printing fairly up close with the occasional explanation of process/material/art etc. have a look here: https://www.youtube.com/channel/UCeyNCJtCUtwsq2dWv26BmRA -
@tom_lauerman Morning Tom, Great thanks. Apologies for the slow response the notification got buried in responses to another thread I dropped one post on!
With regards the redundant syringes I will be proposing this as a potential solution. Its a little mucky in terms of how well thought through it is but I would hope to be able to add have the syringe depleting trigger change of active extruder onto a full syringe and the re-assignement of the empty one to a spare axis so that retraction moves could be injected into to g-code in G1 moves that would not cause any stutters in the original code. It's a bit Heath Robinson, but hopefully parallel gcode streams may be possible at a later date,
Meanwhile I will take a look at your video. I suspect it is exactly the sort of example I was after!
@T3P3Tony do you know where in the list of priorities parallel gcode streams are? Six months or more like two years after a load of other dependencies?
-
@dc42 @T3P3Tony @droftarts do you know where in the list of priorities parallel gcode streams are? Six months or more like two years after a load of other dependencies?
-
@DocTrucker said in Syringe Pumps / Depositing Viscous Materials:
@dc42 @T3P3Tony @droftarts do you know where in the list of priorities parallel gcode streams are? Six months or more like two years after a load of other dependencies?
It's hard to say. We have one other user wanting parallel GCode streams at present. The low-level support is already implemented, but we need to decide on the mechanisms that will control the second stream. Many use cases would be served by a single GCode print file containing commands for both streams, with an additional command that forces whatever stream is ahead to wait for the other to catch up. That wouldn't work for your use case, which needs to send commands to the second stream from a separate file such as a trigger macro.
-
Currently my only option appears to be:
- Trigger a macro on the syringe approaching end of travel.
- [Macro] trigger a change of tool (or swap drives for active tool) to the spare syringe and drive.
- Resume print.
- Use the raspberry pi based live g-code parsing to inject moved into vfollowing G1 commands that would not delay the overall G1 move, but would allow the slow, incremental refill of the syringe.
With concurrent moves this would look something like:
- Macro triggered by limit switch on syringe.
- [Macro] Wait for moves on currently inactive (unlikely to be any moves underway) syringe to complete.
- [Macro] change of tool (or swap drives for active tool) to the spare syringe and drive.
- [Macro] Run a G1 command that runs in parallel to the other g code commands that refills the syringe.
- Resume print.
- [Syringe comfortably refills in the time taken to deplete the second syringe]
- Macro triggered by limit switch on syringe.
- [Macro] Wait for moves on currently inactive (unlikely to be any moves underway) syringe to complete.
- [Macro] change of tool (or swap drives for active tool) to the full syringe and drive.
- [Macro] Run a G1 command that runs in parallel to the other g code commands that refills the syringe.
- etc...
More bullet points in the second list but it is far easier (for me) to implement!
-
Let's suppose that we provide the following mechanisms:
-
A mechanism to assign each axis to one or other movement queue. So in M584 you would specify which movement queue any new axes you create would be assigned to. That assignment would probably be fixed.
-
A mechanism for wait for both movement queues to empty (probably M400 with an extra parameter).
-
Movement commands involving axes assigned to one movement queue would be permitted to happen concurrently with movement commands involving axes assigned to the other movement queue.
Would that be sufficient for your use case? If you think it would, can you write the macros that would be needed?
-
-
@dc42 I will have a look at that and respond shortly. Just cleared some other work from my desk to leave me able to tackle this.
-
@dc42 How's this looking (need to double check pin labelling for expansion card)...
Config file snippets:
M584 X0 Y1:3 Z2 E5 A4 B6 ; Apply drive mapping to axes - E on expansion card. ; A4 = Physical rotational axis connected to main board. ; E5 = Primary Syringe Extruder connected to expansion board. ; B6 = Secondary Syringe Extruder connected to expansion board. ; M92, M350, M566, M203, M201, M906 all as expected, B settings mirror E. M574 B2 S1 P"e5stop" ; Set active low endstops on Z via pin e5stop for secondary syringe pump. ; Define inputs ; e4stop = Primary syringe extruder empty (on expansion board) ; e6stop = Secondary syringe extruder empty (on expansion board) M950 J0 C"^e4stop" ; Input 0 uses e3Stop pin, pullup enabled M950 J1 C"^e6stop" ; Input 1 uses e4Stop pin, pullup enabled ; Define triggers M581 T2 P0 S0 R0 ; Run sys/trigger2.g on falling edge on input 0 at any time. M581 T3 P1 S0 R0 ; Run sys/trigger3.g on falling edge on input 1 at any time. M98 P"trigger2.g"
trigger2.g
; This is used to: ; Map the secondary syringe extruder drive to B. ; Map the primary syringe extruder drive to E. ; Drive the B axis to it's limit. ; Carry on with pint while B retracts & refills. M400 [magic argument to wait for parallel moves to complete] M584 E5 B6 ; Apply drive mapping to axes - E on expansion card. ; E5 = This syringe extruder. ; B6 = other syringe extruder. ; e3stop = Primary syringe extruder full (on expansion board) ; e5stop = Secondary syringe extruder full (on expansion board) M574 B2 S1 P"e5stop" ; Set active low endstops on Z via pin e5stop G1 [magic argument to make this move parallel] B-100 H1 ; Print process continues
trigger3.g
; This is used to: ; Map the primary syringe extruder drive to B. ; Map the secondary syringe extruder drive to E. ; Start driving the B axis to it's limit. ; Carry on with pint while B retracts & refills. M400 [magic argument to wait for parallel moves to complete] M584 E6 B5 ; Apply drive mapping to axes - E on expansion card. ; E6 = This syringe extruder. ; B5 = other syringe extruder. ; e3stop = Primary syringe extruder full (on expansion board) ; e5stop = Secondary syringe extruder full (on expansion board) M574 B2 S1 P"e3stop" ; Set active low endstops on Z via pin e3stop G1 [magic argument to make this move parallel] B-100 H1 ; Print process continues
Thankfully I should be able to test most of this aside from having moves running in parallel.
-
Making progress! Test rig assembled for dual syringing, just need to work on the fitting the two switches per axis and get on with testing the non-parallel move parts of the macros...
Looking at the pause on flow (although this is driving at a higher rate than I would need) I think I may need to do a stages switch over for the syringes where I use mix ratios to go from 100% one syringe to 100% the other in a number of steps, rather than one step.
@dc42 would it be neater than what I proposed a couple of posts ago to change mixing ratios on the fly and have some way of excluding an extruder drive from lock in with the others for the retract?
-
...some of that pause is due to the hysteresis introduced by the slight shifting of the syringe in the holder, and in the part that holds the plunger handle.
-
More testing. Two switches are wired up to the e0 and e1 inputs. The e0 switch calls trigger2.g and e1 is wired up as the limit for axis B. (Need to test whether you can drive to home switch on E axis)
This video shows the basic function. Empty switch is pressed which calls for a drive to home. The home limit is then triggered when the cylinder is full.
The following video simulates what would happen if the axis were triggered in the middle of a move. You can clearly see the trigger is a lower priority than the G1 command. The G1 move is started, the cylinder move is started, the empty switch pressed and the G1 move completes before executing the trigger macro:
Can this be changed so that the trigger is a higher priority than G1?
If so is there a guide to how I could store the position of the axis before the home drive and then re-apply it after the home drive to save it doing some strange things? This may also be useful if swapping from one drive to the other as the active extruder.
If the trigger priority can't be changed it has obvious implications on the positioning of the switches, and forces a requirement to parse the g-code. There must be spare space after the switch trigger, and the gcode must be parse to ensure no extruder move is long enough to travel further than that distance.
Edit: Confirmed drive to limit does not behave the same on the extrusion axis as the other axis. There doesn't appear to be a H parameter that means the G1 will terminate on a specific input.
-
There's no real way to interrupt a long G1 move at the moment. Breaking the single long move up into smaller shorter moves would allow an interrupt to get in between.
-
Could perhaps remap endstops instead of triggers?
-
Currently working on using the trigger to signal the syringe is nearly empty and swapping the drives around with M584 between E and B so I can do a home drive in the B axis and carry on with the other axis as E, which can't do home drives.
Very nearly working as it should do - but obviously no parrallel motion without gcode parsing. To be fair since the syringes are fixed volume the switches could all be precoded in the build file.
Some oddness that smells like a bug but need to do some more work on that before raising it.
Edit:
Bug1: https://forum.duet3d.com/topic/22292/bug-rrf-3-3beta2-g92-b0-changes-e-axis-position
Bug2: https://forum.duet3d.com/topic/22295/bug-2-rrf-3-3beta2-axis-hanging-after-m584-re-assignemnt/10 -
Some more tests on this system.
To be clear this is not the only approach for achieving the end goal of minimal down time for the syringe extruder. Hard coding the syringe retractions and changeovers into the build files would be a way of achieving this. This work as presented currently would also be better suited to a single syringe system as the change over has no benefit as presented. But it has help uncover a few peculiarities in the firmware, so not lost effort.
In the following tests there are two trigger routines associated with switches that will be used to tell the system a syringe is running low on material. These triggers switch the currently active syringe which is running low to the B axis and the other syringe back to the E axis from the B axis. After the drives are switched a drive to home is commanded on the B axis to refill the empty syringe.
The build file that is used is a simple octagon with 1mm drive on the syringes for each 1mm of head travel. This may not be a fit ratio for the final build but works well for tests. I've a python script that walks around the perimeter of the octagon and outputs G1 commands for every 1mm of head displacement.
Test 1 - Basic command line test with extruder drive switch over.
In this test the only commands I and sending from the console is G1 E25 F500 and I trigger the switches to simulate the syringe running empty and hitting its limit after drawing back to the home position.
Test 2 - Using the above functionality in a live print that only comprises of G1 moves of the X, Y, and E axis.
Here the challenges start to come to light.
- A considerable delay between the trigger of the empty switch and the stopping of the system.
- The full syringe begins to move before the empty syringe retracts. The retract command is called from the same trigger file as the swap of drives. Therefore the machine appears to see the trigger, change the drives, do a bit more from the main gcode
- Retract executes after the full extruder has moved a bit.
- A pause while the machine does nothing for a few seconds.
- Normal service then resumes.
Test 3 - Basic command line test with extruder drive switch over, but with M300 peeps either side of the trigger files.
Running the "G1 E25 F500" command from the Duet Web Control again and manually triggering the limit switches to simulate the syringes running empty. In this test everything runs as expected.
Test 4 - Using the triggers from test 3 with beeps in a print as per test 2.
The addition of the M300 peeps exaggerate the interleaving of commands from the trigger file and the main gcode stream. A change over no looks like:
- Empty switch triggered.
- Machine carries on a bit
- X/Y motion pauses.
- Machine peeps
- X/Y motion resumes with the other syringe driving.
- X/Y motion pauses.
- Empty syringe completes a home drive.
- Machine sits idle for a few seconds
- X/Y motion resumes and build process continues.
This looks exaggerated with the two syringes but the switch has probably saved the system from raising some strange errors. If I hadn't carried out the atomic command changing over the drives and was working on a single extruder what would have happened when the machine tried to carry on with a few more lines of gcode with no E drive assigned?
Test 5 - Adding pause commands to the triggers just inside the M300 commands that bookend the trigger files.
Yeah, so this highlighted the fact that the M25/M24 commands call the pause and resume macros. This would have been messy if I were working with fluid as on each pause the head jumps back to the middle before returning after. That said everything else happens as expected aside from the initial peep being missing completely, and the final peep occurring some moves after the resume as it both were outside of the M25/M24 commands.
I'll add the final macros at some point today. Changing between computers to do the tests so don't have them to hand right now.
-
As promised here are the trigger files and other macros. More much neater looking videos to follow shortly including single syringe mode.
For Running Two Syringes
trigger2.g
M25 M300 M98 P"set_secondary_syringe.g" G91 G1 H1 B-100 F400 ; Drive empty syringe to limit. G90 M300 M24
trigger3.g
M25 M300 M98 P"set_primary_syringe.g" G91 G1 H1 B-100 F400 ; Drive empty syringe to limit. G90 M300 M24
set_primary_syringe.g
M584 E3 B4 ; Set primary syringe to active M574 B1 S1 P"ystop" ; Set limit switch M84 E0 ; A needed bodge!
set_secondary_syringe.g
M584 E4 B3 ; Swap drives M574 B1 S1 P"xstop" ; Set limit M84 E0 ; A needed bodge!
For Running One Syringe
trigger2.g
M25 M300 M98 P"set_secondary_syringe.g" G91 G1 H1 B-100 F400 ; Drive empty syringe to limit. G90 M98 P"set_primary_syringe.g" M300 M24