Duet3D Logo

    Duet3D

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • Documentation
    • Order
    1. Home
    2. mikeabuilder
    • Profile
    • Following 0
    • Followers 1
    • Topics 49
    • Posts 275
    • Best 76
    • Controversial 1
    • Groups 0

    mikeabuilder

    @mikeabuilder

    Retired computer architect. Science and technology fan. Non-user of social media (it ain't "technology" and it ain't "science" - it's... I don't know what, but not technology or science"). Will almost always ask either "why was it done that way", or "why wasn't it done this way".

    101
    Reputation
    19
    Profile views
    275
    Posts
    1
    Followers
    0
    Following
    Joined Last Online
    Location Seattle, WA

    mikeabuilder Unfollow Follow

    Best posts made by mikeabuilder

    • A rudimentary array macro

      No question or issue, just sharing something.

      A thread in this forum mentioned having macros write their own macros and it occurred to me maybe this could work to make a rudimentary array. It festered in my brain like the last few words in the NY Times Sunday crossword. This morning I got it working. The code is below, but I'll describe how it works and it's shortcomings.

      A new array is initialized when a macro that needs an array calls the code below using an M98. The user supplies an array name. Then the macro below echos commands into a file with the array name. Now this newly-created macro (say my_array.g) can be called from the original macro. It supports adding new elements, changing the value of existing elements and querying the value of existing elements. When called, it puts the appropriate return value into a global variable called "global.array_response". So it only clogs memory with a single additional global variable.

      Writing it was a bit of a mind-bender because of nested echos to files and their associated escaped quote marks, the array macro appending to itself when an element is added or changed, and the need for the array macro to call itself to find it's own length so it can increment the array index when adding an element. Also, in the initialization macro, the echoed strings all needed to be kept under the length limit.

      The shortcoming of this macro is that it will allow the user to replace a value at an index that is outside the length of the array (say, replace loc[10] when the array is only three elements long). This will then add a gap in the array for future normal adds. I might work on that. This same shortcoming would also let someone use this as a data dictionary, using strings as the array index parameter.

      Now I need to find a reason to use an array in a macro...

      ; Array.g is a macro intended to be used by other macros to manage data in an array-like structure. 
      ; You call array.g once to create an array macro.  You call that macro add an element to the array, 
      ; read the value at a specified index, get the length of the array, or replace a value at an existing index. 
      
      ; This macro creates the array in a /temp sub-folder of the sys directory, but you can change the location if you want.
      ; Author: mikeabuilder
      
      ; One day, if RRF adds array support to the core RRF funstionality, this macro will no longer be needed.
      ; That will be a happy day. 
      
      var Array_location = "0:/sys/temp/"
      
      
      
      ; Typical usage
      ;  M98 P"0:/sys/array.g" S"array name"
      ;
      ;Parameter definition and usage
      ;  S"array_name"  Required parameter. This is the name of an array you want to create. If you use a name that was used previously, the old array will be overwritten.
      
      ; PARAMETER CHECK
      if !exists(param.S)
        M291 P"No macro name provided. Cancelling array build" S3 T-1
        M99
      
      var file = var.Array_location^param.S^".g"  ;create full path to the new array
      
      
      ; The following lines are all echoed into the new array file
      echo >{var.file}  "; This file was created by the macro array.g, normally located in the /sys directory."
      echo >>{var.file} "; It is used as method for creating a rudimentary array data capability for other macros."
      echo >>{var.file} "; This macro is called to add elements to the array, read values of an existing element,"
      echo >>{var.file} "; change the values of existing element, or get the number of elements in the array."
      echo >>{var.file} "; The requested data is passed back to the calling macro by putting it into a global "
      echo >>{var.file} "; variable called gloabl.macro_response."
      echo >>{var.file} "; Author: mikeabuilder"
      echo >>{var.file} "; "
      echo >>{var.file} "; TYPICAL USE"
      echo >>{var.file} "; M98 P""0:/sys/temp/"^var.file^""" V""value""  I""index"" L                "
      echo >>{var.file} "; "
      echo >>{var.file} "; PARAMETERS"
      echo >>{var.file} ";  V""value""   When used without the I parameter, the value is appended to that array as a new     "
      echo >>{var.file} ";               element. The value of global.macro_response is set to the array index of the added  "
      echo >>{var.file} ";               value.                                                                              "
      echo >>{var.file} ";  I""number""  When used without the A parameter, the value of element I[number] is returned in    "
      echo >>{var.file} ";             global.macro_response.                                                                "
      echo >>{var.file} ";             When both A and I parameters are used, the existing value of the element I[number] is "
      echo >>{var.file} ";             replaced. If there is no element I[number], a new element I[number] is created. It    "
      echo >>{var.file} ";             might get overwritten.                                                                "
      echo >>{var.file} ";  None       If no parameter is present, the length of the array is returned in                    "
      echo >>{var.file} ";             global.array_response.                                                                "
      echo >>{var.file} "; "
      echo >>{var.file} "; THEORY OF OPERATION"
      echo >>{var.file} "; When array elemenmts are added or changed, they are added to the end of this macro file. Changed  "
      echo >>{var.file} "; element values result is multiple values in this file. The valie closest to the end of the file is"
      echo >>{var.file} "; the current value. This means that a value that is changed a lot will make the file longer and    "
      echo >>{var.file} "; longer. Simple enough, eh? "
      echo >>{var.file} ""
      echo >>{var.file} ""
      echo >>{var.file} ";START OF THE REAL WORK"
      echo >>{var.file} ""
      echo >>{var.file} "; If we are appending or replacing, this is the easy part"
      echo >>{var.file} "; Set up some variables"
      echo >>{var.file} "var index = 0                                                                                       "
      echo >>{var.file} "if !exists(global.array_response)                                                                   "
      echo >>{var.file} "  global array_response = var.index                                                                 "
      echo >>{var.file} "else                                                                                                "
      echo >>{var.file} "  set global.array_response = var.index                                                             "
      
      echo >>{var.file} "var my_len = 0                                                                                      "
      echo >>{var.file} {"var file = """^var.file^""""}
      echo >>{var.file} ""
      echo >>{var.file} "; If we are adding a new element or changing the value of an existing element it happens here.      "
      echo >>{var.file} "if exists(param.V)          ; We are appending or changing                                          "
      echo >>{var.file} "  if exists(param.I)        ; An index is supplied, so we are changing a value                      "
      echo >>{var.file} "    set var.index = param.I  ; The user supplied the index for the element to be replaced           "
      echo >>{var.file} "  else                      ; We are adding a new element so we need to get the next unused index   "
      echo >>{var.file} "    M98 P"""^{var.file}^"""  ; query myself for the length of my array                              "
      echo >>{var.file} "    set var.index = global.array_response  ; The array length is the next index                     "
      echo >>{var.file} "                                                                                                    "
      echo >>{var.file} "  ; we have the index and the value to add, so lets add to our own file                             "
      echo >>{var.file} "  "
      echo >>{var.file} "  echo >>{var.file} ""       ;NEXT ARRAY ELEMENT""                                                  "
      echo >>{var.file} "  echo >>{var.file} ""if exists(param.I)  ; we are returning an existing value""                    "
      echo >>{var.file} "  echo >>{var.file} ""  if param.I = ""^var.index                                                   "
      echo >>{var.file} "  echo >>{var.file} ""  set global.array_response = """"""^param.V^""""""""                         "
      echo >>{var.file} "  echo >>{var.file} ""else""                                                                        "
      echo >>{var.file} "  echo >>{var.file} ""  set var.my_len = max(global.array_response,""^var.index+1^"")""             "
      echo >>{var.file} "  echo >>{var.file} ""  set global.array_response= var.my_len""                                     "
      echo >>{var.file} ";  "
      
      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • RE: Input shaping guidance

      Quick update - I used the sliders on the raw data to isolate on the data after the move stopped and then did the fft again. I have a sharp peak at 22.5Hz. I captured the data again after adding an M593 P"zvd" and in the resulting waveform, that frequency is gone. Super-cool. I'm off to play with a ringing tower.

      posted in Tuning and tweaking
      mikeabuilder
      mikeabuilder
    • RE: How to put a conditional question based action into a macro

      Here's my answer, but it's based on me only knowing one way to "read" a user input - the M291 command. Someone else might have a better method.

      M291 posts a message and the user has two response options, "OK" and "Cancel". According to the M291 wiki page, if the users responds "OK", execution continues, but if they respond "Cancel", it "cancels the operation in progress".

      I use the M291 in the following way:

      global response = "Cancel"   ;set the variable to the default Value.
      
      M291 P"To keep the default, select "Cancel" R"To change the default to the new value, select OK" S3  ; use the box title and the message to describe the two options. 
      
      set global. response = "OK"
      

      I put these lines in their own macro. If the user responds OK, the last line is executed and the global variable becomes the OK value. If they select Cancel, the macro exits without executing the last mine and the "Cancel value is used.

      Someone may know better what "operation in progress" means and maybe this could be written in an if statement in the code.

      A good FW wishlist item would be new M291 parameters to specify the words on the buttons, and have the response stored in the object model so you could read the response directly.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • Macro for PA testing with Prusa Slicer

      I thought I'd share this simple macro I wrote for tweaking the PA parameter while printing. I made it because I could not get the prusa slicer code provided in the PA wiki page ( https://duet3d.dozuki.com/Wiki/Pressure_advance) to work for me.

      My macro works by inserting an M98 call in the "Before Layer Change" area in the Custom G-code part of Printer Settings in PrusaSlicer. The complete line of code is:

      M98 P"0:/macros/PA_tester.g" L[layer_num]
      

      The slicer calls the macro I've named "PA_tester.g" and passes a parameter L and the layer number. This happens for every later change.

      The Macro, which I adapted from the PA wiki page looks like this:

      ; This macro changes the pressure advance setting every 25 layers so that the user can see the effect of different PA values 
      
      ; 0.2mm layer, 8 bands 5mm each, total height 40mm
      if param.L = 1 
        M572 D0 S0.0
      elif param.L== 25
        M572 D0 S0.05
      elif param.L== 50
        M572 D0 S0.10
      elif param.L== 75
        M572 D0 S0.15
      elif param.L== 100
        M572 D0 S0.20
      elif param.L== 125
        M572 D0 S0.25
      elif param.L== 150
        M572 D0 S0.30
      elif param.L== 175
        M572 D0 S0.35
      
      m99
      

      The advantage of this over the in-slicer Prusa version on the PA page (beyond that code not working), is that I can change the PA parameters and the layers they change on and reprint my test part without needing to go back to the slicer.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • time measurements

      I'm working on some macros where I want to measure time to less than 1 second resolution. I created this command to get me to msec resolution. It may be of use to others.

      mod(mod({+state.time},10000),10000) + state.msUpTime/1000
      

      It takes the time in seconds since the datum, strips off all but the last 4 digits and adds the ms portion of uptime to it. Note that the msec portion is not synched to universal time, but synched to the last board boot. Still very good for measuring and accurate duration up to 9999seconds (2.77 hours)

      Someone may have a cleaner way to do it than doing mod twice, but it gets the job done.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • RE: Fine editor for working with Duet boards

      One of my "back in my day" sayings for the new kids used to be showing them a 3.5" dual density (2.88MB - size defined to 2 decimal places) floppy disk in a hard case and tell them this was the "premium" small portable storage 30 years ago. Then I'd tell then how many it would take to store the same amount as a modern device. Today, that's a 1TB micro SD card (that us old guys can barely handle, they're so tiny). So, roughly 350,000 old-style disks. They were about 1/8 inch thick, so a stack of 350K would be over 3600 feet tall.

      Oh yeah, and we had to write to those old ones with a piece of charcoal by candle-light. After walking 5 miles to work through snowdrifts.

      And they hadn't even invented espresso.

      Harumpf.

      posted in Third-party software
      mikeabuilder
      mikeabuilder
    • RE: Filament-type visible in Object Model?

      It's buried in the move section.

      move.extruders[<#>].filament
      

      You need to give an extruder number. For the extruder on the current tool:

      move.extruders[state.currentTool].filament
      

      If you tool has multiple extruders... I'm not sure

      posted in Firmware wishlist
      mikeabuilder
      mikeabuilder
    • RE: Heightmap is completely ignored

      I had a similar issue with a printer I'm building and the root cause was that when the print head moved from one side of the bed to the other, there was a slight force on it from the wiring and filament. This force caused the printhead to tilt one way on side 1 of the bed and tile the other way on side 2. That tilting lifted the nozzle enough to cause the first layer to not adhere, or shoved the nozzle into the bed. The offset of the z-probe from the nozzle can amplify any wobbliness in the printhead.

      posted in Tuning and tweaking
      mikeabuilder
      mikeabuilder
    • RE: implementing a slicer checker

      Thanks for all the thoughtful responses. I'll work on a feature request and submit through proper channels. I think I'll ask for a named macro that runs after the print header is processed but before additional lines, and that named metadata in that header be available at that time. I can think of a few uses in addition to my use case.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • RE: Echo commands...

      DC42's method is shorter for using echo, but does not concatenate strings in general. If you want to do something like an M291 (print a message to the user interface, maybe wait for a response) vs sending the output to the console, concatenate with a caret" is needed.

      posted in Tuning and tweaking
      mikeabuilder
      mikeabuilder

    Latest posts made by mikeabuilder

    • RE: Bltouch deploy while printing.

      This is only a workaround suggestion, but you could "tape up" the BLtouch pin while the print is under way. If you don't have any homing, leveling or mesh commands in your part gcode, you could use some tape to hold up the pin before you start your print. If you do have those commands in the part gcode, you'd need to insert a pause so that you'd have an opportunity to do the taping.

      As I sad at the top, just a workaround.

      posted in Duet Hardware and wiring
      mikeabuilder
      mikeabuilder
    • RE: G10 P0 depricated in 3.5.beta1?

      @dc42 - Thanks for the advice. A couple weeks back, we were having an issue with not having a tool selected before a print, but we thought we had solved it through a check and select in our start.g file. I'll go back and look at this some more.

      posted in Beta Firmware
      mikeabuilder
      mikeabuilder
    • RE: Programming user interface

      Please read the gcode dictionary page on M291 to see the how to send a message that will display with several buttons that you can label, and also how to read the answer the user provided. There are also modes where the user gets to enter a number or a string. If you have not written macros for RRF yet, you will want to read the meta commands page to see the programming syntax.

      Also definitely get the 3.5.0.beta4 firmware for your duet board and also the latest fw for the display if you are using a PanelDue. The older RRF and PanelDue fw does not support those the newmodes.

      GOogle translation:
      Bitte lesen Sie die Gcode-Wörterbuchseite auf M291, um zu erfahren, wie Sie eine Nachricht senden, die mehrere Schaltflächen enthält, die Sie beschriften können, und wie Sie die Antwort des Benutzers lesen. Es gibt auch Modi, in denen der Benutzer eine Zahl oder eine Zeichenfolge eingeben kann. Wenn Sie noch keine Makros für RRF geschrieben haben, sollten Sie die Seite mit den Metabefehlen lesen, um die Programmiersyntax zu sehen.

      Besorgen Sie sich außerdem unbedingt die Firmware 3.5.0.beta4 für Ihr Duet-Board und auch die neueste Firmware für das Display, wenn Sie ein PanelDue verwenden. Die ältere RRF- und PanelDue-Firmware unterstützt diese neuen Modi nicht.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • G10 P0 depricated in 3.5.beta1?

      Running 3.5.0-beta.3
      on Duet2 WIFI

      My slicer (Prusaslicer 2.5.2), with my custom printer (set to Reprap fw in the Printer config), emits a G10 P0 S215 to set the temperature (and, I think, set the heater to active) followed by an M116 to wait for the heater to warm up.

      Today I noticed my printer did not wait for the heater to get to temperature. Looking at the extruder on DWC and testing by manually entering the G10 and M116 commands, I can see that the G10 P0 S215 does not cause the heater to switch to active. The tool is selected, so that's not the issue. I added an M568 A2 to the custom Gcode in the slicer, and this fixed the issue.

      My question is whether this is behavior I should expect from G10? I'm sure if there is some other Gcode that used to be used after a G10 to turn on the heater, but Prusa slicer didn't emit it as a default.

      posted in Beta Firmware
      mikeabuilder
      mikeabuilder
    • RE: Odd corner case bug with iterations

      Some additional information. I wrote the following in response to @o_lampe's suggestion, though I used a local variable and not a global.

      var loops = 0
      while var.loops < 10
        m291 S0 P{"Waiting for 10 seconds per iteration. On iteration: "^var.loops}
        g4 s10
        set var.loops = var.loops +1
      

      In this case, the symptom is a little different. The repro steps are

      1. The file is run as a print job, then paused, then cancelled. (Note it runs properly to the end if not cancelled)
      2. The file is run a second time (either Print Again button in DWC Status page, or started from the Jobs page of DWC)

      During the second run, the following error is produced:

      M32 "0:/gcodes/loop test3.gcode"
      File 0:/gcodes/loop test3.gcode selected for printing
      Error: in GCode file line 3 column 17: meta command: unknown variable 'loops'
      Cancelled printing file 0:/gcodes/loop test3.gcode, print time was 0h 0m
      

      If the file is run a third time, it runs properly. I assume that the RRF error handler properly cleared out whatever was amiss after the Pause/Cancel process.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • RE: Odd corner case bug with iterations

      Stand-alone mode.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • RE: Odd corner case bug with iterations

      Sorry for not including my RRF version. I'm on 3.5 rc4. My hw is MB6HC

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • Odd corner case bug with iterations

      I'm writing a macro to test some new code I'm putting into start.g. The macro is launched from the Jobs tab in DWC. The complete macro is this:

      while iterations <10
        m291 S0 P{"Waiting for 10 seconds per iteration. On iteration: "^iterations}
        g4 s10
      

      If I start this "print" job, I see the messages start to print.

      The bug happens when I use DWC to pause the job, then cancel the job, then start the job again. When I do this, the variable iterations is not reset when the job starts the second time. Seems like it should happen as part of the cancel process.

      posted in Gcode meta commands
      mikeabuilder
      mikeabuilder
    • RE: First foray into object model

      @jens55 - I second OwenD - just keep at it. And post questions to this forum. You'll find lots of helpful folks here.

      My contribution is that when you this of adding some meta commands (programming) to the slicer code, it's best to either stick with the Prusa programming language, or even better, just insert an M98 P"Your macro name" to call a macro you've written and stored on the duet board.

      Just think of the macro call as pausing the print-file gcode while it runs the macro you wrote. Once inside you macro, you have full access to the object model and every other G, M, and T code that can be run. The sky's thelimit.

      posted in General Discussion
      mikeabuilder
      mikeabuilder
    • RE: [Enhancement Request] - Heater toggle

      One option is to write yourself a macro to do the tasks PanelDue doesn't have a button for. You can navigate to the macros directory to launch it. And if the macro is located in root of the macros directory (and not a sub-directory), then it will appear on the Control Screen of PanelDue.

      With the 3.5beta3 RRF and 3.5 beta PanelDue fw, you could write a nice interface. When the macro launches, it could look up and display the state of the heaters, then let you select one and switch it between states. Not a perfect solution, but it can be useful. I don't have a macro for heater states, but I've written on for loading and unloading filaments.

      If you do start writing macros, I'll recommend that the first thing in each macro is an M291 message that says what the macro is, then asks the user if they really want to run it. PanelDue doe not have that question as a standard step the way DWC does, and the buttons are close enough together to touch the wrong one easily.

      posted in PanelDue
      mikeabuilder
      mikeabuilder