Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    M42 using variable value is slow/not working well

    Scheduled Pinned Locked Moved
    Laser Cutters
    4
    8
    380
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • usinjinundefined
      usinjin
      last edited by usinjin

      Hello all. I have a custom built pen plotter (operates very similarly to a laser cutter/engraver in practice). The mechanism to raise/lower the pen is a voice coil driven by an external controller that takes a single-wire PWM signal (51% - 100% duty cycle moves the actuator up, and 49%-0% moves the pen down). This gives me a precise way to control the pressure of the pen on paper.

      At any rate, the VCA controller is connected to OUT6 of my Duet Mini 5+. I'm using M42 commands to drive it. So after building my gcode files using Lightburn, I simply replace M3 commands with something like

      M42 P0 S0.35
      

      for example.

      This works perfectly for static values of S. But if I try and use a variable for S, like the following:

      var d = global.pressure32
      (...)
      M42 P0 S{var.d}
      

      The plotter no longer reliably moves the pen. Adding a 100msec dwell after moving the pen works better, but results in some slow/jerky motion and doesn't seem like a real fix.

      I don't know if the issue lies with the motion planner somehow or if reading the variable repeatedly is just slow.

      My config.g:

      ; Configuration file for Duet 3 Mini 5+ (firmware version 3.3)
      ; executed by the firmware on start-up
      ;
      ; generated by RepRapFirmware Configuration Tool v3.3.16 on Sat Jul 22 2023 22:18:39 GMT-0500 (Central Daylight Time)
      
      ; General preferences
      M453                                    ; CNC mode
      G90                                     ; send absolute coordinates
      M550 P"nPLT"        	                ; set printer name
      
      ; Network
      M551 P"duet"                            ; set password
      M552 P192.168.1.14 S1                   ; enable network and set IP address
      M553 P255.255.255.0                     ; set netmask
      M554 P192.168.1.1                       ; set gateway
      M586 P0 S1                              ; enable HTTP
      M586 P1 S0                              ; disable FTP
      M586 P2 S0                              ; disable Telnet
      
      ; Drives
      M569 P0.0 S0                            ; physical drive 0.0 goes forwards
      M569 P0.1 S1                            ; physical drive 0.1 goes backwards
      M569 P0.2 S1                            ; physical drive 0.2 goes forwards
      ;M569 P0.3 S1                           ; physical drive 0.3 goes forwards
      M584 Y0.0:0.1 X0.2 P2                   ; set drive mapping
      M350 X16 Y16 I1      	                ; configure microstepping with interpolation
      M92 X100 Y59.26 				   	    ; set steps per mm, shorter pulleys on X
      ;M92 X80 Y59.26 				   	    ; set steps per mm, longer pulleys on X
      M566 X500.00 Y500.00                    ; set maximum instantaneous speed changes (mm/min)
      M203 X18000.00 Y18000.00                ; set maximum speeds (mm/min)
      M201 X500.00 Y500.00                    ; set accelerations (mm/s^2)
      M906 X1800 Y1800 I30            		; set motor currents (mA) and motor idle factor in per cent
      M84 S1                                  ; Set idle timeout
      
      ; Axis Limits
      M208 X0 Y0 S1                           ; set axis minima
      M208 X290 Y290 S0                       ; set axis maxima
      
      ; Endstops
      M574 X1 S1 P"^io1.in"                  ; configure switch-type (e.g. microswitch) endstop for low end on X via pin !^io0.in
      M574 Y1 S1 P"^io0.in"                  ; configure switch-type (e.g. microswitch) endstop for low end on Y via pin !^io1.in
      
      ; Pen
      M950 P1 C"io4.out"      ; allocate GPIO port 1 for the enable/disable of the voice coil amp
      M950 P0 C"out6" Q30000	; allocate GPIO port 0 to out6 on expansion connector, 30kHz
      
      M42 P1 S0               ; disable motion of pen 
      M42 P0 S0.6				; pen up command
      M42 P1 S1               ; enable motion of pen
      G4 P500
      
      M42 P0 S0.5				; set to 50% (which is 0% output)
      M42 P1 S0               ; diable motion of pen
      
      ; Sensors
      M308 S0 P"io3.in" Y"linear-analog" A"Pen pressure" F0 B-8.5 C1160
      
      ; Variables
      global pressure_on_pause=0.5
      global pen_up_on_pause=0
      global pen_is_up=1
      global pen_is_on=0
      global pressure32=0.38
      global pressure85=0.36
      global pressure105=0.32
      
      

      And a snippet of a gcode file:

      ; Layer C02
      M42 P0 S{global.pressure85}
      G1 Y250.831
      M42 P0 S0.6
      G0 X65.497Y250.831
      M42 P0 S{global.pressure85}
      G1 Y56.831
      M42 P0 S0.6
      G0 X173.447Y56.831
      M42 P0 S{global.pressure85}
      G1 Y250.831
      

      The immediate fix I can think of simply hardcodes in all values into M42 commands before running the plot, but I wanted to see if there was a better/easier way of doing things. Thanks for any assistance.

      T3P3Tonyundefined dc42undefined 2 Replies Last reply Reply Quote 0
      • T3P3Tonyundefined
        T3P3Tony administrators @usinjin
        last edited by

        @usinjin this is one for @dc42 to confirm but adding the delay (or M400) will almost certainly not be what you want as it means the following movement commands wont be handled until the delay/M400 completes. even without the delay using M42 in between the movement commands like that is probably sub optimal. The way this is handled for Laser cutters is with a S parameter of the G1 command. If that can be made to work with your VCA controller then that may be the better solution:

        https://docs.duet3d.com/en/User_manual/Reference/Gcodes#m452-select-laser-device-mode

        you can set the same pin you are using now for M42, but instead as a laser pin. I expect you will want S1 mode of M452 so there is a continuous output and then use commands of the form:
        G1 Xxxx Yxxx Sx.xx

        What I don't know is if commands of this sort:
        G1 Xxxx Yxxx S{<variable>}

        Will work better but its worth a shot.

        www.duet3d.com

        1 Reply Last reply Reply Quote 0
        • dc42undefined
          dc42 administrators @usinjin
          last edited by

          @usinjin this is a known issue, see https://github.com/Duet3D/RepRapFirmware/issues/767. Meanwhile I suggest you either use a M400 command prior to each M42 command, or use laser mode and the G1 S parameter as @tony suggested.

          T3P3 created this issue in Duet3D/RepRapFirmware

          open M280 M42 etc. commands are executed too soon if they use any expressions e.g. involving variables #767

          Duet WiFi hardware designer and firmware engineer
          Please do not ask me for Duet support via PM or email, use the forum
          http://www.escher3d.com, https://miscsolutions.wordpress.com

          usinjinundefined 1 Reply Last reply Reply Quote 0
          • usinjinundefined
            usinjin @dc42
            last edited by

            Thanks to both for the help. I did forget to mention that I had tried M400 already, and seeing as it's the same as G4 P0 that's when I tried to increase the dwell time, neither of those work very well.

            I avoided laser mode before because as I'm controlling an actuator and not a laser, the "pen down" time is dependent on the force being applied. I want to be able to add padding with G4 in the event that I use a very low pressure so that I can make sure the pen is touching the page before moving occurs. Using M42 allowed me to separate "pen moves" and "XY" moves. Is there still a way to do this with M452?

            1 Reply Last reply Reply Quote 0
            • usinjinundefined
              usinjin
              last edited by

              Actually, could I do this with M670?

              o_lampeundefined 1 Reply Last reply Reply Quote 0
              • o_lampeundefined
                o_lampe @usinjin
                last edited by

                @usinjin Never tried it, but it seems to hit the nail for your use case. From what I gathered, it will apply the advanced timing on both moves (up+down).
                Is that a problem?

                usinjinundefined 1 Reply Last reply Reply Quote 0
                • usinjinundefined
                  usinjin @o_lampe
                  last edited by usinjin

                  @o_lampe I think it would work okay, there could be some wasted time if I set the timing to the worst-case for all pen movements. Not 100% sure.

                  I'm still not convinced that my hardware will support laser mode. I suspect the G1 commands will be fine, but the problem arises with G0 traversals when the pen needs to be "up"/"off". Won't G0 set the laser duty cycle to 0%? If so, that is actually pen "down" at full force on my hardware. Maybe I can turn the driver off first (also with M42, but hard coded value of 0 for off and 1 for on), so it won't matter what the duty cycle is?

                  I also figured out how I could turn this in my gcode files:

                  ...
                  M42 P0 S{var.pressure32}
                  ...
                  

                  Into this:

                  ...
                  M42 P0 S0.355
                  ...
                  

                  Based off another file that has had pressure variables written to it:

                  M28 pressure_values.g
                  set global.pressure32=0.355 ;calculated from a load cell input value
                  ...
                  

                  I did this with a Python program running on the host that transfers the files via FTP. It's a pretty ugly solution to basically just do a text substitution, but it does work...if anyone is interested in how I did that I can elaborate. I will also keep trying the laser mode option (which would be far nicer I think).

                  dc42undefined 1 Reply Last reply Reply Quote 0
                  • dc42undefined
                    dc42 administrators @usinjin
                    last edited by

                    @usinjin said in M42 using variable value is slow/not working well:

                    Won't G0 set the laser duty cycle to 0%? If so, that is actually pen "down" at full force on my hardware

                    You could reverse the sense so that 0 means pen up and 1 means down, by inverting the control pin name in the M452 command.

                    Duet WiFi hardware designer and firmware engineer
                    Please do not ask me for Duet support via PM or email, use the forum
                    http://www.escher3d.com, https://miscsolutions.wordpress.com

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post
                    Unless otherwise noted, all forum content is licensed under CC-BY-SA