Controlling servo via arduino for tool changing
-
You can do it as described using M581, M582 commands in your toolchanging macros, but you could also control the servo directly.
That would allow you to write your own Tool1 babystepping macros. Although I'm not sure how accurate a servo would react on tiny moves? But there should be a way to adjust Z-height, since the servo must not run 'against the wall' or you overheat it. The play in the servogears and the deadband in their internal feedback-loop makes the endposition less exact than required.
I'm currently playing with tiny DC encoder motors, they might be better suited for a low-Torque/high accuracy usecase as yours (and mine). Unfortunatly, the external trigger inputs aren't fast enough to read the incoming encoder signal directly.I have to find a way to convince the Duet team into implementing a high-priority trigger input (like they already exist for Z-probes)
-
Thanks you @o_lampe for your reply.
I will have a look at M581 and M582.
My concerns are all about the integration and the "how" of the firmware/duet board.
Are there any examples of how to integrate it in a similar usecase?I am still pretty new to the duet familiy and dont have that much knowledge yet
The realisation regarding the hardware and accuracy is not the problem - if I can use an arduino and do "my own stuff"
-
Ok, after reading a lot and learning (hopefully), this is my idea:
in config.g
; define tool changer output pin M950 P1 C"exp.heater3" ; Create output 1, attached to exp.heater3 ; define inputs for tool changer M950 J1 C"!exp.e2stop" ; Create input 1 which uses exp.e2stop/exp.4 pin, inverted, pullup disabled M950 J2 C"!exp.e3stop" ; Create input 2 which uses exp.e3stop/exp.9 pin, inverted, pullup disabled ; make sure tool 1 (the 2nd tool) is in the lifted position while sensors.gpIn[1].value = 0 M42 P1 S1 ; set output 1 to 1 (high) to lift up the 2nd tool while sensors.gpIn[1].value = 0 HERE_CommandForWaiting ; make it blocking, preferable with an warning message after a certain time
in pre1.g:
; move the tool up if not in position yet if sensors.gpIn[2].value = 0 M42 P1 S0 ; set output 1 to 0 (low) to move 2nd tool down in printing position while sensors.gpIn[2].value = 0 HERE_CommandForWaiting ; make it blocking, preferable with an warning message after a certain time
in post1.g:
; move the tool up if not in position yet if sensors.gpIn[1].value = 0 M42 P1 S1 ; set output 1 to 1 (high) to lift up the 2nd tool ; wait until toll is in position while sensors.gpIn[1].value = 0 HERE_CommandForWaiting ; make it blocking, preferable with an warning message after a certain time
My biggest problem is, that the movement of the tool changer is not instant, so I have to wait until feedback is coming from the toolchanger (either J1 or J2 high).
How can I make it wait?
It would be good to give it a timeout like: Waiting maximum 5sec and if J1/J2 is still not triggered then give a Warning message and stop the machine to prevent the nozzle to scratch the printed part ot the bed.
Do you guys have any ideas how this can be accomplished?
My idea is to make it like this:
M291 R"Error at tool changing" P"Toolchange was not sucessfull. Continue?" S3 T0
But what will happen If the user presses "cancel"?
(I assume, that pressing "OK" will just continue with the rest. But "Cancel" is undefinied for me)Will my code have a chance or working?
Thanks to all for helping me
-
@phil333 said in Controlling servo via arduino for tool changing:
; move the tool up if not in position yet if sensors.gpIn[1].value = 0 M42 P1 S1 ; set output 1 to 1 (high) to lift up the 2nd tool ; wait until toll is in position while sensors.gpIn[1].value = 0 HERE_CommandForWaiting ; make it blocking, preferable with an warning message after a certain time
One way to do it is simply use a G4 and count the number of iterations
You could use M291 to ask the user if they want to cancel. If they cancel it will close the macro and cancel the print.Or you can use the abort command which will also close all macros in progress and cancel the print, but won't give the user the option.
It will output a definable message to the console.
link textYou must ensure that the indentation of all the lines in the "while" loop are correct and even.
Typed this on my phone, so may need adjustment.Also this won't be exact timing (you'd have to count milliseconds for that) , but should be near enough for the job at hand.
; move the tool up if not in position yet if sensors.gpIn[1].value = 0 M42 P1 S1 ; set output 1 to 1 (high) to lift up the 2nd tool ; wait until tool is in position while sensors.gpIn[1].value = 0 G4 S1 ; wait 1 second if iterations > 4 ; iterations is zero based so at least 5 seconds has passed abort "tool did not reach position in allowed time"
-
Hey,
I just started the test phase but I it looks like the software is not doing what I intended on the Duet side.
Can I assign these pins as inputs and outputs?
; define tool changer output pins M950 P1 C"exp.14" ; Create (GPIO-)output pin 1, attached to EXPANSION Pin 14 M950 P2 C"exp.16" ; Create (GPIO-)output pin 2, attached to EXPANSION Pin 16 ; define tool changer input pins M950 J0 C"!exp.18" ; Create input pin 0, attached to EXPANSION Pin 18, inverted, pullup disabled M950 J1 C"!exp.20" ; Create input pin 1, attached to EXPANSION Pin 20, inverted, pullup disabled
Do I need to define a J0 to make it work?
Because I got a "meta command: array index out of bounds" error when trying to use J1 and J2 (with no J0 definded and trying to read the sensors.gpIn[2].value.My pre0.g which should lift the 2nd tool is looking like this:
; tpre0.g ; called before tool 0 is selected if sensors.gpIn[1].value != 0 M42 P1 S0 ; set output 1 to 0 (LOW voltage level == HIGH Arduino read... maybe because of the level shifter?) to command the arduino to lift the 2nd tool echo "printhead is beeing lifted" else echo "else: gpIn[1] is 0" ; debug ; wait until tool is in position while sensors.gpIn[1].value != 0 G4 S15 ; wait in seconds if iterations > 15 ; iterations is zero based so at least 16 seconds has passed echo "Timeout on movin up" abort "Timeout: 2nd printhead is not up." ; if the printhead is in up position, unset the command to move printhead up if sensors.gpIn[1].value == 0 M42 P1 S1 ; set output 1 to 1 echo "2nd printhead is up." else echo "else: gpIn[1] is 1" ; debug
One question would be if there is a logical or semantic error.
2nd question is, if a "HIGH" (or a 1) on the Duet is also 0V and a "LOW" (or a 0) is 3.3V (inverted) in real voltage - like the Arduino. -
@phil333 firstly not all the pin names you are using are valid AFAIK see:
https://duet3d.dozuki.com/Wiki/Duet_Wiring_Diagramsand here:
https://duet3d.dozuki.com/Wiki/RepRapFirmware_3_overview#Section_Pin_names_for_Duet_2_WiFi_EthernetSo for example pin exp.14 is in the list, but exp.16 is not, thats because its a stepper motor DIR pin so not available to use as a GPIO pin. The same with exp.18 (valid) and exp.20 (invalid)
picking enstop pins as inputs and heater pins as outputs is a good plan.
-
Thanks a lot @T3P3Tony , thats it!
I set the macros (tpre1, tpost0 and tfree1) according to my needs.
Tool changing mechanism works great nowThere are only two things left to work flawlessly:
I would like to use PrusaSlicer (Slic3r) to print something with both tools.
If I want to print something with 2 tools the first thing that is problematic now is,that the 2nd tool stays completely cold until its used for the first time.
Then it needs about 1-2min to head up.
This is on one hand a bit of time wasting, but on the other hand first used tool oozes out like 20mm, because it stays hot (at the standby temp, which is good).#1:
I would like to set the 2nd tool to standby temperature on the print start.
I only found the Tnnn gcode, which selects a tool as active, but how do I set a tool to its standby temperature?Right now I have this at the Start G-code section:
T-1 ; deselect all tools (its a must do make sure the right macros being loaded and to not damage the printer) M140 S[first_layer_bed_temperature] ; set bed temp right away to save time G28 ; home all axes G1 Z2 F5000 ; lift nozzle M190 S[first_layer_bed_temperature] ; wait for bed temp G90 ; Absolute positionning G28 ; rehome after bed is hot G1 Z2 F5000 ; lift nozzle T[initial_tool] ; set the first used tool as active tool G10 P[initial_tool] S[first_layer_temperature] R195 ; set temperatures for the first tool M116 ; wait for extruder temperature to be reached
Is there something I can add to make the 2nd tool to heat up aswell?
I know I can to something likeT[next_extruder] ; set the first used tool as active tool G10 P[next_extruder] S[first_layer_temperature] R195; set temperatures for the second tool
before I call the [initial_tool], but this would also result in unnecessary tool changing. I am sure that there is something (someone) smarter than this
#2:
How can I prevent the passive extruder from oozing?
The first thing that came in mind was to do an additional small retraction on the "soon to be passive tool" at the tool change G-code section.
Something like :G91 ; use relative coordinates G1 E-2.00000 F2400 ; retract at the soon to be passive tool G91 ; use absolute coordinates
But how to de-retract after this tool is becoming active again?
Maybe someone has solved this also already.Thanks a lot four your help
-
@phil333 said in Controlling servo via arduino for tool changing:
you can send this command for a tool without selecting the tool so what you could do in you start gcode is
M568 P[initial_tool] S[first_layer_temperature] R195 A1 M568 P[next_extruder] S[first_layer_temperature] R195 A1 M116 ; wait for stand by temps to be reached T[initial_tool] ; select initial tool M116 ; wait for active temperature to be reached
Which will set both active and standby temperatures for both tools, with them set to standby. I added some examples of how you might want to wait for heatup but of course change those as you like
I used M568 instead of G10 as this is now the preferred way to control heaters in RRF from 3.3 onwards:
https://duet3d.dozuki.com/Wiki/M568 -
@phil333 for the second issue you can add the amunt of retract and unretract to your tool change macros (retract a bit more in tfree, undo that retraction in tpost. however be careful, depending on the hotend retracting to far and then letting filament sit and solidify can cause blockages.
-
Thanks @T3P3Tony I will have a look at it tomorrow and report back, but I'm not sure if its already on RRFW 3.3.
-
@T3P3Tony
I tested it, but the custom gcode doesnt work, if I only print with one tool.The line:
M568 P[next_extruder] S[first_layer_temperature] R195 A1 ; set second tool (if present) standby temp
drops this error:
G-code export to C:\Users\user\AppData\Local\Temp\.5328.gcode failed due to invalid custom G-code sections: start_gcode Parsing error at line 7: Variable does not exist M568 P[next_extruder] S[first_layer_temperature] R195 A1 ; set second tool (if present) standby temp ^ Please inspect the file C:\Users\user\AppData\Local\Temp\.5328.gcode.tmp for error messages enclosed between !!!!! Failed to process the custom G-code template ... and !!!!! End of an error report for the custom G-code template ... for all macro processing errors.
Any ideas how to make it generic?
-
@phil333 where is that error being generated? did the same examples work with G10?
-
@T3P3Tony I will recheck if G10 works on tuesday.
Its a error beeing generated by the Silyer (SuperSlicer) and it shows on a new opened error window on trying to slice.I guess its a problem on using the "[next_extruder]" varialbe on a print that uses just one tool (and there is no "next extruder".
I didnt cross check it, but I think that also Slic3r and PrusaSlicer will have the same problem.