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

    Maths in G-Code for RepRap: New M930 & M931, & #Px# values

    Scheduled Pinned Locked Moved
    Firmware developers
    2
    5
    846
    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.
    • bruceundefined
      bruce
      last edited by

      In my fork (this link) off of Dave's work for the RepRap firmware, I added two new M commands for in-G-Code arithmetic and mathematical calculations. I also added a general G-Code parsing feature to enable it using the result of the real-time arithmetic calculation:

      I took a liberty to use an apparently empty bracket in M command numbers and created these two M commands to the firmware: M930 and M931

      .

      M930
      M930 performs a maths expression between curly brackets ({}) and saves the results in one on the 10 memory slots called P0 to P9. If memory slots aren’t set, their default value will be 0 (zero)

      Example 1:
      M930 { 2 * (2+1)} P0

      sets P0 to 6. The expression that is between the curly brackets is 2*(2+1) that is 2*(3) = 6. The result is 6 which will be saved in memory slot 0 because of P0 parameter given in the M930 command line

      Using X or Y or Z in the expression copies the current position in the expression and uses the position as if it was a number.

      Example 2:
      Assume X is at 5mm (or whatever unit you are running on)

      M930 {2*X} P1

      sets P1 to 10. Because X will be interpreted as 5.000 and the result of the expression 2*5.00 equals 10. This result is then saved in P1 memory slot to be used later.

      Example 3:
      M930 {X} P2 ;

      simply sets P2 to current X position 5 (assuming X is at 5, P2 value will be 5.000)

      Px (such as P0, P1, … P9) values are accessible to other G or M commands using #Px# format (such as #P0#, #P1#, … #P9#)

      Example 4:
      G0 X#P0# ;

      Remember in Example 1 P0 was set to 6. This line will be translated as G0 X6. That is value of 6 replaced the variable name P0

      Example 5:
      M930 {(X * #P0#)+2} P0 ;

      remember in Example 1 P0 was set to 6, it is now set to be (X*6)+2. For example if X is at 5, P0 would be 32

      If Px is not set, it’ll auto initialises to 0

      Example 6:
      G1 X#P1# Y#P2# F#P8#

      Assume before this line of GCode, P1 is set to be 76.23, P2 is 36.17, P8 is 400. The output of this line will be as if it was:
      G1 X76.23 Y36.17 F400;

      If you need to make any calculation to be passed to any G command you will need to do it before that G command in a separate M930 command line.

      Example 7:
      M930 {X*2} P1 ; doubles the value of the current position of X axis
      G1 X#P1# ; moves X axis to our newly calculated P1. Now the current X position is the changed to be P1
      Assume X is at 5. The first M930 line above sets P1 to 10. The second line will be G1 X10. Therefore now the current position of X is 10 (as opposed to be 5). So the next time you do this P1 will be 20 (as opposed to 10)

      Similarly you can use this format #Px# (for P0 to P9) in any other G or M commands to pass your calculation results to other commands.

      Example 8:
      M930 {25} P0 ; #P0# is 25
      M930 {100} P0 ; #P0# is now overwritten with 100 without any warning

      The second M930 overwrites P0 value to 100, without giving any warning.

      .

      M931
      M931 saves or loads all variables (P0 to P9) on SD Card in a file named: “arithmetics-memory-slots.g” that can be found under “sys” directory (/folder)
      This can be useful to inspect the values, or to load them again for a later use

      M931 has a single parameter Pxx. P0 saves variables, P1 loads them from the file

      Example 1:
      M931 P0 ; this saves all P0 to P9 values into “arithmetics-memory-slots.g”

      Example 2:
      M931 P1 ; this loads all values back to P0 to P9 when running your G-Code programme

      .

      M930 Capabilities
      M930 takes advantage of the ExprTk library that has the following capabilities:

      • Mathematical operators (+, -, *, /, %, ^)

      • Trigonometry (sin, cos, tan, acos, asin, atan, atan2, cosh, cot, csc, sec, sinh, tanh, d2r, r2d, d2g, g2d, hyp)

      • Equalities & Inequalities (=, ==, <>, !=, <, <=, >, >=)

      • Assignment (:=, +=, -=, *=, /=, %=)

      • Logical operators (and, nand, nor, not, or, xor, xnor, mand, mor)

      • Functions (min, max, avg, sum, abs, ceil, floor, round, roundn, exp, log, log10, logn, pow, root, sqrt, clamp, inrange, swap)

      • And more …

      I hope a few people find this useful for their projects as it is for mine. Please comment if you have any thoughts to improve this.

      At this stage I only did this for my own use and obviously cannot be held responsible for whatever damages that could come out of this.

      I will be pulling a request for this on GitHub to hopefully be added to an official release. I have a hard time compiling this correctly for RepRap so I hope Dave (or others) come to rescue 😊 🤞

      1 Reply Last reply Reply Quote 3
      • bruceundefined
        bruce
        last edited by

        To whoever interested:
        These 6 files are modified for this addition:

        (Under src/GCodes)

        • GCodes.h
        • GCodes.cpp
        • GCodeBuffer.h
        • GCodeBuffer.cpp
        • GCodes2.cpp
        • GCodes3.cpp

        This file (and toolkit folder) added:

        • src/toolkit/exprtk,hpp
        1 Reply Last reply Reply Quote 0
        • OwenDundefined
          OwenD
          last edited by

          Looks like you've gone to a lot of trouble.
          Kudos for that.
          Can you give some more detail about why you felt it necessary or how it might be used that isn't currentlly possible?

          Initially I thought it was largely redundant as we already have the ability to carry out mathematical equations and now that we have variables, the scope is opened even more.

          I can see a use for it as a method of using psuedo arrays which may be handy.
          Especially as these can be persistent.

          We already have min(n,n,n,n) etc, but no method of creating an array other than a series of variables.

          bruceundefined 2 Replies Last reply Reply Quote 1
          • bruceundefined
            bruce @OwenD
            last edited by

            @OwenD Thank you for your comment

            I mainly did this for the ability to create even smarter ‘Macros’. Another one is the ability to generate formula driven paths using G-Code only.

            As a use case example:
            Creating a macro to automatically set/fine tune /readjust axis steps per unit (using M92)

            Let’s say we need to fine tune steps per mm on X and Y (or automate it for every morning. For example to compensate for the room temperature changes)
            We got a cuboid probe. The exact dimensions on each side are measured and know (L x W x H) - Let’s put the exact measurements in P0, P1, P2
            We know our current step per unit in each axis from our config.g file (say X400 for the X drive and 400 steps per mm for the Y drive. Set in P3 and P4.
            Now, in our macro, we probe a corner (say bottom-left) and set them in P5 and P5. Like:
            M930 {X} P5
            M930 {Y} P6

            The macro then moves to probe the opposite corner. We now have
            M930 {X} P7
            M930 {Y} P8
            The motor/firmware ‘thinks’ that the tool has moved L mm (that is saved in P0), however, the probe shows that to reach the opposite corner we moved L+0.1 mm (+0.1 is an example error we got). So:
            Actual (Measured) Movement Distance = L + 0.1 = P7 - P5
            Desired Movement Distance = L = P0
            Therefore 400 steps (= P3) took us 0.1 short of L
            Now the macro does this and fine tunes the steps per mm for us automatically:
            M930 {#P0# * #P3# / (#P7# - #P5#)} P9
            M92 X#P9#
            Here, M930 on the above line calculates the correct and super accurate steps needed for L mm and holds it in P9
            The next M92 line sets the Steps per mm to the super accurate value

            We do similar thing for Y axis:
            M930 {#P1# * #P4# / (#P8# - #P6#)} P9
            M92 Y#P9#
            The M92 line above sets the steps per mm for the Y axis automatically

            This is just one example to show a use case in a macro. I hope I was able to make my use case example easy to follow 🙂

            1 Reply Last reply Reply Quote 1
            • bruceundefined
              bruce @OwenD
              last edited by

              @OwenD
              In the above example we can have the probe known dimensions (P0, P1, P2) and or config,g steps (P4 and P5) saved in the file and load them at the beginning of the example macro with M931 P1, and the whole fine tuning steps can happen really quickly and accurately 🙂

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