Configuring Pre-Stall
-
I'm using a 1HCL with the Duet closed loop encoder on a Nema 23. It's working very well for with the stall condition. It runs "driver-error.g" when it stalls and I can call M112 inside that macro to kill the system.
I can't get the pre-stall condition to work though. In the config I have this line to configure pre-stall:
M569.1 P123.0 T3 E5:10 R100
But it never calls any of the following macros:
driver-stall.g
driver-warning.g
driver-prestall.gHow is the pre-stall behaviour meant to be configured? I also don't understand why stall calls driver-error.g instead of driver-stall.g
Ultimately what I want to do is try and drop the speed or acceleration of the move dynamically if it's getting close to full stall and then increase it to nominal again after it has completed the move.
Thank you.
-
@jjem See the 'Events' page for what happens in the event of a stall: https://docs.duet3d.com/User_manual/RepRapFirmware/Events
As far as I'm aware, there is no driver-prestall.g macro, and driver-warning.g is used for internal drivers, e.g. over temperature warning, or phase disconnected.
With your M569.1, driver-stall.g should be called if the error is more than 5 full steps but less than 10, and driver-error.g should be called if the error is more than 10 full steps. It may be that it's difficult to stall it between these, perhaps change them to a wider range to check driver-stall.g is working.
You can also manually raise an event using M957 to test functionality.
Ian
-
@droftarts Thanks for the clarification on which macros are called when. I think it's unclear on the events page.
I suspect my issue is that small difference between 5 and 10 steps, as you suggest. I'll test that next.I have a few general questions about closed loop behaviour, to understand the best way to make use of the prestall and stall triggers and associated macros, and where to set the thresholds:
- If a motor has missed steps will it indefinitely try to recover its position as long as its within the error threshold?
- Does it do this at as close to whatever feedrate/acceleration was asked of it in the move or is it adaptive to maximise torque?
- Will subsequent moves on other axes be allowed to be carried out even if the first axis is still working to recover position or will they wait?
Thank you,
Josh -
@jjem said in Configuring Pre-Stall:
I have a few general questions about closed loop behaviour, to understand the best way to make use of the prestall and stall triggers and associated macros, and where to set the thresholds:
- If a motor has missed steps will it indefinitely try to recover its position as long as its within the error threshold?
- Does it do this at as close to whatever feedrate/acceleration was asked of it in the move or is it adaptive to maximise torque?
- Will subsequent moves on other axes be allowed to be carried out even if the first axis is still working to recover position or will they wait?
I'm not an expert on closed loop, but as far as I understand:
- If it's within the error threshold, it will try to get to position, until it's time for the next move in the command queue. Position errors are reported in the Object Model, and can be logged. I'd guess if you have problems with this, either the motor isn't tuned well, or there is a mechanical problem.
- Yes. Motor current is increased (up to the limit set by M906), and so torque increases, until the motor position is achieved, at the desired speed/acceleration.
- No. Axis movements are, and must be, coordinated. If it fails to achieve position, to within the error amount, by the beginning of the next move, it will go on to the next move in coordination with the other axes.
It's also not just about the endpoint position of the move; an error can happen anywhere along a move. Each move has a time and position profile, to keep axes synchronised, and deviations from this will trigger an error.
Ian
-
@droftarts Thank you for the clarifications, that's useful to know.
I tried to get the pre-stall working, by changing the configuration to:
M569.1 P123.0 T3 E1:30 R100
so there should be pre-stall triggered when there is between 0.3-9mm of travel loss, and then error if there's more than 9mm of travel loss.
I then moved the axes 2mm at a time into a hard stop. It didn't trigger driver-stall.g (which contains an echo command) at all but did call driver-error.g after it had moved the 9mm. Do you know why this might be?
-
@jjem I've asked @dc42 to have a look, to see if there's something we're missing.
A full step is 0.3mm on your system? That seems quite a large step size!Please could you post your config.g, and send M122 from the console and post the response, so we can see what firmware version and hardware you are using. Please also send M122 B#, where # is the CAN address of the 1HCL.
Ian
-
@droftarts Thank you.
It's a 3mm pitch belt on a 20T pulley that's giving the 300 micron step!
The set-up is a 6XD connected to a 1XD which is connected to a 1HCL. There are clearpath servos on the 6XD and 1XD, and a nema 23 on the 1HCL which is the one we've been discussing. Here's the config:
;Configuration File 'config.g' ;General preferences for MB6XD ; G91 ;Set to Relative Positioning ;FAN CONTROL M950 F0 C"!out4+out4.tach" ;Set up fan pin/s M106 S0.4 ;Turn fan on (40%) ;LED CONTROL M950 P0 C"out6" ;Right LED pin M950 P1 C"out7" ;Left LED pin M98 P"/macros/ledfade.g" S1.0 ;Fade LEDs to set value (0-255 or 0.0-1.0) ; Turn on pi M950 P0 C"123.out0" M42 P0 S255 ;CANBUS G4 S5 ;Wait for expansion boards to boot up ;MOTOR DRIVERS M569 P1 R1 ;Y0 - Set driver 1: enable is HIGH M569 P2 R1 ;Y1 - Set driver 2: enable is HIGH M569.1 P123.0 T3 E1:30 R100 ;X - Driver 0 on board 123, Duet 3D magnetic encoder, pre-stall error when 1 step error (0.3mm), driver error when more than 30 step error (9mm). Proportional constant of 100 M569 P123.0 D4 ;X - Driver 0 on board 123, closed loop mode M569 P122.0 R1 S0 ;Z - Driver 0 on board 122, enable HIGH, direction non-default M584 X123.0 Y1:2 Z122.0 ;XYZ Set drivers M906 X2800 I30 ;X motor 2.8A (30% at idle) ;MOTION PARAMETERS M92 X53.33 Y40 Z40 ;Set axis steps per unit (steps per mm) M203 X60000 Y180000 Z160000 ;Set maximum feedrate (mm/min) 60,000mm/60s==1000mm/s==1m/s M201 X6000 Y8000 Z9000 ;Set max acceleration (mm/second^2) M205 X10 Y10 Z10 ;Set allowable instantaneous speed change (mm/s). If we go from 0 to the values set here we'll do so with infinite acceleration. Anything above that will use values set in M201 M208 X0:240 Y0:3130 Z0:1648 ;Set axis min:max travel (mm) M350 X16 I1 ;Set microstepping mode (1/n steps per rev) ;ENDSTOP AXIS M574 X1 P"!123.io0.in" S1 ;input 0 on 123 for X M574 Y1 P"!io3.in+!io2.in" S1 ;inputs 2 and 3 for Y (ORDER DEPENDENT to pair correct endstop to correct driver) M574 Z1 P"!122.io1.in" S1 ;input 1 on 122 for Z ;NETWORKING M550 P"MB6XD" ;Set name M552 P0.0.0.0 S1 ;DHCP test ;M552 P192.168.254.2 ;IP Address ;M554 P192.168.254.1 ;Gateway ;M553 P255.255.255.224 ;Netmask ;M552 S1 ;Network, GO! ;E-STOP EMERGENCY M950 J1 C"^io0.in" ;Index (J=input) 0 uses input pin 0 (pullup) - Physical ESTOP M950 J2 C"^io1.in" ;Index (J=input) 1 uses input pin 1 (pullup) - Y ERROR M950 J3 C"^122.io0.in" ;Index (J=input) 3 uses input pin 0 on 122 (pullup) - Z ERROR M581 P1 T0 S1 ;Configure index 1 to trigger T0 (emergency stop), rising edge M581 P2 T2 S1 ;Configure index 2 to trigger T2 (Y motor stall), rising edge M581 P3 T3 S1 ;Configure index 3 to trigger T3 (Z motor stall), rising edge M582 T0 ;Check if physical estop switch has been reset on bootup
And here's the result from the M122 B123:
Diagnostics for board 123: Duet EXP1HCL rev 1.0a or earlier firmware version 3.5.0-rc.2 (2023-12-14 08:55:39) Bootloader ID: SAME5x bootloader version 2.4 (2021-12-10) All averaging filters OK Never used RAM 45932, free system stack 184 words Tasks: EncCal(1,nWait,0.0%,472) Move(3,nWait,0.0%,104) CLSend(3,nWait,0.0%,150) HEAT(2,nWait,0.3%,112) CanAsync(5,nWait,0.0%,67) CanRecv(3,nWait,0.0%,46) CanClock(5,nWait,0.0%,70) TMC(4,nWait,247.1%,325) MAIN(1,running,116.9%,265) IDLE(0,ready,0.0%,30) AIN(2,nWait,12.1%,265), total 376.4% Last reset 02:09:58 ago, cause: software Last software reset data not available Driver 0: pos -14292, 53.3 steps/mm, ok, SG min n/a, mspos 8, reads 7411, writes 9788 timeouts 0, steps req 0 done 0 Moves scheduled 2, completed 2, in progress 0, hiccups 0, segs 5, step errors 0, maxLate 0 maxPrep 149, maxOverdue 0, maxInc 0, mcErrs 0, gcmErrs 0, ebfmin 0.00 max 0.00 Peak sync jitter -7/8, peak Rx sync delay 189, resyncs 0/0, no timer interrupt scheduled VIN voltage: min 48.2, current 48.2, max 48.3 V12 voltage: min 12.2, current 12.2, max 12.2 MCU temperature: min 28.5C, current 36.2C, max 36.2C Last sensors broadcast 0x00000000 found 0 24 ticks ago, 0 ordering errs, loop time 0 CAN messages queued 62416, send timeouts 0, received 38603, lost 0, errs 0, boc 0, free buffers 38, min 38, error reg 0 dup 0, oos 0/0/0/0, bm 0, wbm 0, rxMotionDelay 330, adv 37142/37199 Closed loop driver 0 mode: closed loop, pre-error threshold: 1.00, error threshold: 30.00, encoder type rotaryAS5047, position 5350 Encoder reverse polarity: yes, full rotations 0, last angle 5351, minCorrection=-8.0, maxCorrection=9.9, agc 63, mag 4730, no error Tuning mode: 0, tuning error: 0, collecting data: no Control loop runtime (us): min=2, max=64, frequency (Hz): min=8928, max=15000 Accelerometer: none I2C bus errors 12, naks 0, contentions 0, other errors 0
-
@jjem Can you do M122 for the mainboard too?
Ian
-
@droftarts M122 B0:
=== Diagnostics === RepRapFirmware for Duet 3 MB6XD version 3.5.0-rc.2 (2023-12-14 10:33:00) running on Duet 3 MB6XD v1.01 or later (standalone mode) Board ID: 0JD2M-999AL-D25SW-6J1FD-3SJ6J-T4XH3 Used output buffers: 1 of 40 (22 max) === RTOS === Static ram: 153284 Dynamic ram: 117668 of which 0 recycled Never used RAM 70056, free system stack 158 words Tasks: NETWORK(1,ready,69.8%,175) ETHERNET(5,nWait,0.0%,317) HEAT(3,nWait,0.0%,359) Move(4,nWait,0.0%,216) CanReceiv(6,nWait,0.0%,797) CanSender(5,nWait,0.0%,329) CanClock(7,delaying,0.0%,350) MAIN(1,running,30.1%,444) IDLE(0,ready,0.0%,30), total 100.0% Owned mutexes: HTTP(MAIN) === Platform === Last reset 02:59:59 ago, cause: software Last software reset at 2024-02-20 08:45, reason: User, Gcodes spinning, available RAM 66000, slot 2 Software reset code 0x0003 HFSR 0x00000000 CFSR 0x00000000 ICSR 0x00400000 BFAR 0x00000000 SP 0x00000000 Task MAIN Freestk 0 n/a Error status: 0x00 MCU temperature: min 39.9, current 41.8, max 41.9 Supply voltage: min 23.7, current 23.8, max 24.0, under voltage events: 0, over voltage events: 0, power good: yes 12V rail voltage: min 12.2, current 12.3, max 12.3, under voltage events: 0 Heap OK, handles allocated/used 99/66, heap memory allocated/used/recyclable 4096/2332/184, gc cycles 0 Events: 0 queued, 0 completed Driver 0: ok Driver 1: ok Driver 2: ok Driver 3: ok Driver 4: ok Driver 5: ok Date/time: 2024-02-20 11:45:53 Slowest loop: 44.22ms; fastest: 0.07ms === Storage === Free file entries: 20 SD card 0 detected, interface speed: 25.0MBytes/sec SD card longest read time 3.0ms, write time 0.0ms, max retries 0 === Move === DMs created 125, segments created 3, maxWait 30055ms, bed compensation in use: none, height map offset 0.000, max steps late 0, ebfmin 0.00, ebfmax 0.00 no step interrupt scheduled Moves shaped first try 0, on retry 0, too short 0, wrong shape 0, maybepossible 0 === DDARing 0 === Scheduled moves 9, completed 9, hiccups 0, stepErrors 0, LaErrors 0, Underruns [0, 0, 0], CDDA state -1 === DDARing 1 === Scheduled moves 0, completed 0, hiccups 0, stepErrors 0, LaErrors 0, Underruns [0, 0, 0], CDDA state -1 === Heat === Bed heaters -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1, chamber heaters -1 -1 -1 -1, ordering errs 0 === GCodes === Movement locks held by null, null HTTP is ready with "m122 b0" in state(s) 0 Telnet is idle in state(s) 0 File is idle in state(s) 0 USB is idle in state(s) 0 Aux is idle in state(s) 0 Trigger is idle in state(s) 0 Queue is idle in state(s) 0 LCD is idle in state(s) 0 SBC is idle in state(s) 0 Daemon is idle in state(s) 0 Aux2 is idle in state(s) 0 Autopause is idle in state(s) 0 File2 is idle in state(s) 0 Queue2 is idle in state(s) 0 Q0 segments left 0, axes/extruders owned 0x0000007 Code queue 0 is empty Q1 segments left 0, axes/extruders owned 0x0000000 Code queue 1 is empty === CAN === Messages queued 54034, received 172846, lost 0, errs 0, boc 0 Longest wait 52ms for reply type 6041, peak Tx sync delay 272, free buffers 50 (min 49), ts 53996/53995/0 Tx timeouts 0,0,0,0,0,0 === Network === Slowest loop: 5.15ms; fastest: 0.03ms Responder states: MQTT(0) HTTP(0) HTTP(0) HTTP(0) HTTP(0) HTTP(0) HTTP(0) FTP(0) Telnet(0) Telnet(0) HTTP sessions: 1 of 8 = Ethernet = Interface state: active Error counts: 0 0 0 0 0 0 Socket states: 5 5 2 2 2 0 0 0 === Multicast handler === Responder is inactive, messages received 0, responses 0
-
@jjem I think you are right: currently a pre-stall returns information in the driver status but does not appear to generate an event. I think our intention was to generate a driverWarning event, not a stall event. I will generate new 3.5.x EXP1HCL firmware to correct this.
-
@dc42 Good to know. That would be great, thank you. Do you know when that might be ready, so I can plan around it? Thanks.
-
@jjem please try the new firmware at https://www.dropbox.com/scl/fo/p0136wx04h8xf6ejwdnn9/h?rlkey=efrfwyb6o5tqid11gustz3uvy&dl=0 and let me know whether this fixes the problem. It should generate a driverWarning event but I haven't yet had time to set up a system to test it.
-
@dc42 This is working, thank you. It is now calling driver-warning.g for pre-stall, and driver-error.g for stall!
It would be useful to understand how these work better. If I have a macro which performs a sequence of moves, and one of those moves triggers a pre-stall, does the driver-warning.g code get injected after the move it's currently carrying out? And after that it will continue the macro?
When pre-stall is triggered I would like to drop the speed for the move currently being carried out. From my testing using M203 it seems this isn't possible, since it will only get dropped for the following move and not the current one which triggers the pre-stall.
Alternatively, I could stop the move and quit the macro entirely and rerun a slower version of the same macro. Again, from testing I've found I can't do this, as an M99 in driver-warning.g doesn't exit the moves macro, I wonder if it just exits the warning macro?Happy to expand upon any of the above points. Thank you.
-
@jjem maybe adding segmentation, something like
M669 S1 T1
will aid in being able to apply a speed change to the current move -
@jay_s_uk I'll give it a go, thank you. What's the downside to using high resolution segmentation? Presumably it uses more processing power?
-
@jjem it "may" affect IS but I'm not 100%. it shouldn't over power the MCU though
-
@jjem in general, moves already in the movement queue can't be altered. You can abort the later moves in the move queue by commanding a pause.
As @jay_s_uk says, you can use segmentation (see M669) to split long moves into short moves, to get faster response to movement speed changes and fast response to pause commands. To reduce movement speed temporarily I suggest you use M220 rather than M203.
-
@dc42 Thank you both.
I'm finding M220 isn't affecting speeds inside of any macros. It does work for individual moves though.
-
@jjem I think it would help if you posted an example and explained what you expect it to do and what you actually observe it doing.
-
@gloomyandy Sure, if I run M220 S100, and then G1 X50 F60000 it runs at the requested speed. If I do M220 S1 followed by G1 X50 F60000 then it runs very slowly. So the command works properly in this context.
If I run M220 S1 in DWC and then run a macro, which only contains G1 X50 F60000, it moves at full speed not at 1%. If I call M220 after that macro it confirms the speed is set at 1%