Storing current tool number across power cycle/ system restart
-
My current tool changer 3D printer forgets what the current tool is when the power is cut or the system is restarted. What I want to happen is if a job is started and tool 0 is still selected for whatever reason that it homes the xy axis, puts the tool back and then continues the homing process. I am attempting to do this as a failsafe incase the tool isn't put back for some reason because it can not home the u or z axis with any tool currently selected.
So far I've gotten it to put the tool back if I simply instruct it to home all axis without cuttng the power or triggering a restart, however if I cut the power or just trigger a system restart with the DWC it doesn't try to put the tool back because it doesn't think one is selected.
I've taken a look at https://docs.duet3d.com/en/User_manual/Tuning/Resume but it doesn't appear to cover how to store and retrieve any secondary data such as the current tool number in my case. Additionally, system files such as resume.g don't seem to trigger if no job is active when the DWC tells it to restart.
Bellow are my relevant files. (note I don't currently have a resume.g set up yet because, correct me if I'm wrong, it doesn't run when the DWC triggers as system restart)
config.g
; Configuration file for RepRapFirmware on Duet 3 Main Board 6HC ; executed by the firmware on start-up ; ; generated by RepRapFirmware Configuration Tool v3.5.0-rc.3 on Fri Mar 15 2024 11:41:50 GMT-0400 (Eastern Daylight Time) ; General M550 P"Duet 3" ; set hostname ; Accessories M575 P1 S0 B57600 ; configure PanelDue support ; Network M551 P"Knights24" ; set machine password M552 P0.0.0.0 S1 ; configure Ethernet adapter M586 P0 S1 ; configure HTTP ; Smart Drivers M569 P0.0 S1 D2 ; driver 0.0 goes forwards (X axis) M915 P0.0 S1 ; set StallGuard threshold M569 P0.1 S0 D2 ; driver 0.1 goes backwards (Y axis) M915 P0.1 S1 ; set StallGuard threshold M569 P0.2 S0 D2 ; driver 0.2 goes backwards (Z axis) M915 P0.2 S1 ; set StallGuard threshold M569 P0.3 S0 D2 ; driver 0.3 goes backwards (Z axis) M915 P0.3 S1 ; set StallGuard threshold M569 P0.4 S1 D2 ; driver 0.4 goes forwards (U axis) M915 P0.4 S2 ; set StallGuard threshold M569 P0.5 S1 D2 ; driver 0.5 goes forwards (extruder 0) ; Motor Idle Current Reduction M906 I10 ; set motor current idle factor M84 S10 ; set motor current idle timeout ; Axes M584 X0.0 Y0.1 Z0.2:0.3 U0.4 ; set axis mapping M350 U16 I0 ; configure microstepping without interpolation M350 X16 Y16 Z16 I1 ; configure microstepping with interpolation M906 X900 Y900 Z900 U400 ; set axis driver currents M92 X160 Y160 Z400 U200 ; configure steps per mm M208 X0:300 Y0:300 Z0:300 U0:270 ; set minimum and maximum axis limits M566 X900 Y900 Z12 U30 ; set maximum instantaneous speed changes (mm/min) M203 X9000 Y9000 Z180 U4000 ; set maximum speeds (mm/min) M201 X600 Y600 Z20 U50 ; set accelerations (mm/s^2) ; Extruders M584 E0.5 ; set extruder mapping M350 E16 I1 ; configure microstepping with interpolation M906 E900 ; set extruder driver currents M92 E397.5 ; configure steps per mm M566 E120 ; set maximum instantaneous speed changes (mm/min) M203 E3600 ; set maximum speeds (mm/min) M201 E250 ; set accelerations (mm/s^2) ; Kinematics M669 K1 ; configure CoreXY kinematics ; Probes M558 K0 P9 C"io4.in" H5 F120 T6000 ; configure BLTouch probe via slot #0 G31 P500 X4 Y-70 Z0.7 ; set Z probe trigger value, offset and trigger height M950 S0 C"io4.out" ; create servo #0 for BLtouch ; Endstops M574 X1 S3 ; configure X axis endstop M574 Y1 S3 ; configure Y axis endstop M574 Z1 S2 ; configure Z axis endstop M574 U1 S3 ; configure U axis endstop M915 X Y Y R0 F0 H400; manually added for sensorless homing ; Mesh Bed Compensation M557 X15:245 Y20:215 S80 ; probe from X=10 to 245, Y=10 to 245mm with a mesh spacing of 80mm ; Sensors M308 S0 P"temp0" Y"thermistor" A"Heated Bed" T100000 B4725 C7.06e-8 ; configure sensor #0 M308 S1 P"temp1" Y"thermistor" A"Nozzle" T100000 B4725 C7.06e-8 ; configure sensor #1 ; Heaters M950 H0 C"out0" T0 ; create heater #0 M143 H0 P0 T0 C0 S140 A0 ; configure heater monitor #0 for heater #0 M307 H0 R0.401 K0.333:0.000 D13.12 E1.35 S1.00 B0 ; configure model of heater #0 M950 H1 C"out1" T1 ; create heater #1 M143 H1 P0 T1 C0 S300 A0 ; configure heater monitor #0 for heater #1 M307 H1 R1.804 K0.293:0.000 D9.68 E1.35 S1.00 B0 V24.1; configure model of heater #1 ; Heated beds M140 P0 H0 ; configure heated bed #0 ; Fans M950 F0 C"out5" ; create fan #0 M106 P0 S0 L0 X1 B0.1 ; configure fan #0 M950 F1 C"out4" ; create fan #1 M106 P1 S0 B0.1 H1 T45 ; configure fan #1 ; Tools M563 P0 D0 H1 F0 ; create tool #0 G10 P0 Z-4.55 ; set custom offsets for tool #0 M568 P0 R0 S0 ; set initial tool #0 active and standby temperatures to 0C
homeall.g
;; homeall.g ; called to home all axes ; ; generated by RepRapFirmware Configuration Tool v3.5.0-rc.3 on Fri Mar 15 2024 11:41:50 GMT-0400 (Eastern Daylight Time) ; ; home Y ; M400 ; Wait for current moves to finish G91 ; relative positioning G1 H2 Z10 F12000 ; lift Z relative to current position M400 ; wait for current move to finish M913 X25 Y25 ; drop motor current to 25% M400 G1 H1 Y-400 F10000 ; move quickly to Y axis endstop and stop there (first pass) G1 H2 Y5 F12000 ; go back a few mm G1 H1 Y-400 F5000 ; move slowly to Y axis endstop once more (second pass) G90 ; absolute positioning M400 M913 X100 Y100 ; return current to 100% M400 ;home X ; M400 ; Wait for current moves to finish M913 X30 Y30 ; drop motor current to 30% M400 G1 H1 X-400 F10000 ; move quickly to X axis endstop and stop there (first pass) G1 H2 X5 F12000 ; go back a few mm G1 H1 X-400 F5000 ; move slowly to X axis endstop once more (second pass) G1 X5 ;offset so tool doesnt hit belt G92 X0 ;sets current x pos as 0 M400 ;G1 H2 Z-10 F6000 ; lower Z again M564 S0 H0 ; allows temporary movemnt outside of homed axis T-1 M564 S1 H1; ; M98 P"homeU.g" ; home U axis ; home Z var xCenter = move.compensation.probeGrid.mins[0] + (move.compensation.probeGrid.maxs[0] - move.compensation.probeGrid.mins[0]) / 2 - sensors.probes[0].offsets[0] var yCenter = move.compensation.probeGrid.mins[1] + (move.compensation.probeGrid.maxs[1] - move.compensation.probeGrid.mins[1]) / 2 - sensors.probes[0].offsets[1] G1 X{var.xCenter} Y{var.yCenter} F6000 ; go to bed centre G30 ; probe the bed ;M98 P"bed.g" ; mesh bed ;G92 Z0 ;sets current z pos as 0 ;M400 G90 ;absolute positioning
homeu.g
M400 ; Wait for current moves to finish M913 U100 ; drop motor current to 20% ;U34.5 M400 G91 ; relative positioning G1 H1 U-400 F10000 ; move quickly to X axis endstop and stop there (first pass) G1 H2 U5 F12000 ; go back a few mm G1 H1 U-400 F5000 ; move slowly to X axis endstop once more (second pass) G90 ; absolute positioning M400 M913 U100 ; return current to 100% M400
Thank you for your time and I'm happy to provide any other files or test anything.
-
@SamKudarauskas the way I solve this is to have a docking switch on each tool, so that RRF can tell if a tool is not in its dock at power up.
-
@dc42 Ok, thank you for your help. I will try that. How would I configure the switch and how would I check its status in a system file such as homeall.g?
Als, do you know if T R1 would work in my scenario? Or would it only work in a resume.g file?
-
@SamKudarauskas - DC42 has the failsafe method - an input to the Deut3D board that is triggered when a tool is in its dock. You'd also really want one on the carriage to tell you that a tool is mounted on the carriage. Then on power up, you can run a macro that asks if the switches tell you there is a tool on every dock and no tool on the carriage - normally expected state. If you found a tool on the carriage and only one dock missing a tool, you can infer where the tool goes. You run into a challenge if there is a tool on the carriage, and either more than one tool dock is empty (or none are). You should have a plan for that too.
The less-good way is to track which tool is on the carriage in a way that will survive a power cycle or emergency stop/restart. One good way to do this is to have a line at the beginning of each tpostN.g file and at the end of tfree.g that looks something like this:
echo >"0:/sys/which_tool.g" "global current_tool =", {state.currentTool}
I'm not positive the RRF fw has "-1" in State.currentTool at the end of tfree, so you should check. If it still has the "previous" tool number, then the tpre line should explicitly assign -1 to the global.
echo >"0:/sys/which_tool.g" "global current_tool =-1"
When this line runs, it creates a small macro file called "which_tool.g" in the sys directory, and overwrites any existing file. If my syntax is correct, when the which_tool.g file runs it'll create a global variable called current_tool with the last tool number in it.
Now you insert a line in your config.g
M98 P"0:/sys/which_tool.g"
At power up, the macro runs and creates the global variable. Now you can query it and know which what the last tool that was used. Of course. if the tool fell off the carriage, you won't know that unless you implement the switches above.
WHen this is