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