Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login
    1. Home
    2. AndyE3D
    3. Best
    • Profile
    • Following 0
    • Followers 0
    • Topics 0
    • Posts 16
    • Best 3
    • Controversial 0
    • Groups 0

    Best posts made by AndyE3D

    • RE: Magnetic Filament Monitor for Automatic E-Step Calibration

      I created this macro to use the mfm to calibrate non linear extrusion. Have done nearly no print tests to see if it actually have a print quality improvement though so feedback would also be appreciated.

      ; Inputs
      var tool = param.T
      var maxSpeed = exists(param.S) ? param.S : 20
      var dist = exists(param.D) ? param.D : 20
      var minExtrusionThreshold = exists(param.E) ? param.E : 0.85
      
      var force = exists(param.F) ? param.F : 0   ; if > 0, will run macro without confirming with user
      
      ; Configuration
      var baseSpeed = 1
      var debug = false
      
      ; Internal variables
      var originalTool = state.currentTool
      var speeds = {1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1}
      var speedInc = var.maxSpeed / #var.speeds
      while (iterations < #var.speeds)
          set var.speeds[iterations] = var.speedInc * (iterations + 1)
      
      var drive = tools[var.tool].filamentExtruder
      var flows = var.speeds ; must be same length as var.speeds
      var eMulti = var.speeds ; must be same length as var.speeds
      var numMeasurements = 0
      
      ; Check with user
      if (var.force <= 0)
          var msg = "Would you like to calibrate non linear extrusion for T"^{var.tool}^"? Current coefficients: Base="^move.extruders[var.drive].factor * 100^"%, A="^move.extruders[var.drive].nonlinear.a^", B="^move.extruders[var.drive].nonlinear.b
          M291 S4 R{"Calibrating Extrusion: T"^var.tool} P{var.msg} K{"Yes", "No", "Reset Coefficients"}
      
          if (input == 1)
              M99                         ; exit
          if (input == 2)
              M221 D{var.drive} S100
              M592 D{var.drive} A0 B0
              M99                         ; exit
      
      ; Calibrate default extrusion percentage
      if (#var.speeds != #var.eMulti)
          abort "var.speeds must have the same length as var.eMulti"
      
      echo "Calibrating extrusion rate for T"^var.tool^" using filament \""^move.extruders[tools[var.tool].filamentExtruder].filament^"\""
      echo "Settings: distance = "^var.dist^"mm, base speed = "^var.baseSpeed^"mm/s, min extrusion threshold = "^{var.minExtrusionThreshold * 100}^"%"
      echo "Speeds: "^var.speeds^" mm/s"
      
      if (sensors.filamentMonitors[var.drive].type != "rotatingMagnet")
          abort "Must be a rotating magnet encoder"
      if (sensors.filamentMonitors[var.drive].enableMode != 2)
          abort "Encoder mode must be S2"
      if (sensors.filamentMonitors[var.drive].configured.allMoves != true)
          abort "Encoder must be active for all moves (A2)"
      
      T-1
      T{var.tool} P0      ; don't run tpre, tfree, tpost
      M703
      if (tools[var.tool].active[0] == 0)
          M568 P{var.tool} S{global.defaultFilamentTemperature}
      M116 P{var.tool}
      M220 S100                   ; reset speed
      ; M221 D{var.drive} S100      ; reset base extrusion
      M592 D{var.drive} A0 B0     ; reset non linear extrusion
      ; G1 X334 Y100 F30000
      M591 D{var.drive} S2 A1  ; set magnetic encoder to record during all moves
      M400
      G1 E{var.dist} F{var.baseSpeed * 60}
      M400
      var flow = sensors.filamentMonitors[var.drive].lastPercentage / 100
      var baseFlowModifier = {100 / var.flow}
      echo "Setting base extrusion factor override for drive "^var.drive^" = "^var.baseFlowModifier
      M221 D{var.drive} S{var.baseFlowModifier}
      
      ; Collect non linear data
      while iterations < #var.speeds
          ; clear encoder data
          M591 D{var.drive} S0
          M591 D{var.drive} S2
      
          G1 E{var.dist} F{var.speeds[iterations] * 60}
          M400
          set var.flow = sensors.filamentMonitors[var.drive].lastPercentage / 100
          set var.flows[iterations] = var.flow
          set var.eMulti[iterations] = 1 / var.flow
          echo "Flow at "^var.speeds[iterations]^"mm/s = "^{var.flow * 100}^"%, requires extrusion multiplier of "^{var.eMulti[iterations] * 100}^"%"
      
          set var.numMeasurements = iterations + 1
          if (var.flow < var.minExtrusionThreshold)
              break
      
      echo "Number of measurements = "^var.numMeasurements
      echo "Flows: "^var.flows
      echo "Required extrusion multipliers: "^var.eMulti
      
      ; Quadratic regression
      ; https://www.statisticshowto.com/quadratic-regression/
      var x = 0
      var y = 1
      var x2 = 0
      var x3 = 0
      var x4 = 0
      var xy = 0
      var x2y = 0
      
      while (iterations < var.numMeasurements)
          set var.x = var.x + var.speeds[iterations]
          set var.y = var.y + var.eMulti[iterations]
          set var.x2 = var.x2 + (var.speeds[iterations] * var.speeds[iterations])
          set var.x3 = var.x3 + (var.speeds[iterations] * var.speeds[iterations] * var.speeds[iterations])
          set var.x4 = var.x4 + (var.speeds[iterations] * var.speeds[iterations] * var.speeds[iterations] * var.speeds[iterations])
          set var.xy = var.xy + (var.speeds[iterations] * var.eMulti[iterations])
          set var.x2y = var.x2y + (var.speeds[iterations] * var.speeds[iterations] * var.eMulti[iterations])
      
      if var.debug
          echo "x = "^var.x
          echo "y = "^var.y
          echo "x2 = "^var.x2
          echo "x3 = "^var.x3
          echo "x4 = "^var.x4
          echo "xy = "^var.xy
          echo "x2y = "^var.x2y
      
      ; add 100% flow at 0 speed
      set var.numMeasurements = var.numMeasurements + 1
      
      ; a*var.x4 + b*var.x3 + c*var.x2 = var.x2y
      ; a*var.x3 + b*var.x2 + c*var.x = var.xy
      ; a*var.x2 + b*var.x + c*var.numMeasurements = var.y
      
      ; Because we have normalised the base extrusion multiplier with a slow extrusion rate
      ; c ~= 1
      var c = 1
      
      ; Therefore
      ; a*var.x4 + b*var.x3 = var.x2y - var.x2
      ; a*var.x3 + b*var.x2 = var.xy - var.x
      ; a*var.x2 + b*var.x = var.y - var.numMeasurements
      
      ; a = (var.y - var.numMeasurements - b*var.x) / var.x2
      
      ; ((var.y - var.numMeasurements - b*var.x) / var.x2)*var.x3 + b*var.x2 = var.xy - var.x
      ; ((var.y - var.numMeasurements - b*var.x)*var.x3 / var.x2) + b*var.x2 = var.xy - var.x
      
      var b = ((var.xy - var.x) - (((var.y - var.numMeasurements)*var.x3)/var.x2))/(var.x2 - ((var.x * var.x3)/var.x2))
      var a = ((var.y - var.numMeasurements) - (var.b * var.x))/var.x2
      
      if var.debug
          echo "a = "^var.a
          echo "b = "^var.b
          echo "c = "^var.c
      
      ; Note var.a and var.b are flipped because M592 uses the equation (1 + min(L, Av + Bv^2)) which has different coefficients to that uses to solve the quadratic regression
      echo "Setting non linear extrusion multiplier with: M592 D"^var.drive^" A"^var.b^" B"^var.a
      M592 D{var.drive} A{var.b} B{var.a}
      
      T-1 P0
      T{var.originalTool}
      
      ; M591 D{var.drive} S1 A1  ; only monitor filament during prints
      

      The main issue I have identified, which I don't think can easily be solved, is that it doesn't account for how much the filament expands coming out of the nozzle from die swell and foaming. So the extruder might be moving the correct quantity of filament, but the filament becomes a lower density once it leaves the nozzle which effectively produces overextrusion. I think a visual based method would be the most comprehensive way to measure this.

      posted in Filament Monitor
      AndyE3Dundefined
      AndyE3D
    • RE: 3.6.0-beta.1 Breaking Homing Sequence

      @Charlie one other thing to verify relating to you homing/motor stalling issue is the actual current that is being applied to the motors. Can you send the response from M569 P{driver_num} and M906 please. Make sure that M569 is sent soon after a move so that the current has not been reduced by the M906 idle current reduction

      posted in Beta Firmware
      AndyE3Dundefined
      AndyE3D
    • RE: 3.6.0-beta.1 Breaking Homing Sequence

      @Notepad @Charlie this is the equation that uses the acceleration & velocity constants

      float PhaseStep::CalculateCurrentFraction() noexcept
      {
      	// Driver is in assisted open loop mode
      	// In this mode the PID terms are not used and the A and V terms are independent of the loop time.
      	constexpr float scalingFactor = 100.0;
      	constexpr float scalingFactorSqr = scalingFactor * scalingFactor;
      	PIDVTerm = mParams.speed * Kv * scalingFactor;
      	PIDATerm = mParams.acceleration * Ka * scalingFactorSqr;
      	PIDControlSignal = min<float>(fabsf(PIDVTerm) + fabsf(PIDATerm), 256.0);
      
      	currentFraction = holdCurrentFraction + (1.0 - holdCurrentFraction) * min<float>(PIDControlSignal * (1.0/256.0), 1.0);
      	if (reprap.GetDebugFlags(Module::Move).IsBitSet(MoveDebugFlags::PhaseStep))
      	{
      		debugPrintf("v=%f, a=%f, cf=%f\n", (double)(mParams.speed * scalingFactor), (double)(mParams.acceleration * scalingFactorSqr), (double)currentFraction);
      	}
      	return currentFraction;
      }
      

      The units, calculation, and tuning are almost identical to assisted open loop on the 1HCL board with the main difference being it does not have the encoder to warn about skipped steps (stall detect also does not work when phase stepping), and the Kp & Kd terms are not used.

      In YAT make sure that you have enabled DTR if you are running the latest firmware as the USB code was changed recently. I don't know if there are other difference connecting to the Duet on MacOS
      815afc9a-6200-4f26-8096-3abb0b8c6f03-image.png

      posted in Beta Firmware
      AndyE3Dundefined
      AndyE3D