Browse Source

Initial split-up of G-code handlers by category

Scott Lahteine 7 years ago
parent
commit
4231faf779
100 changed files with 7674 additions and 316 deletions
  1. 8
    218
      Marlin/src/Marlin.cpp
  2. 0
    2
      Marlin/src/Marlin.h
  3. 3
    0
      Marlin/src/core/macros.h
  4. 0
    11
      Marlin/src/feature/I2CPositionEncoder.h
  5. 0
    2
      Marlin/src/feature/tmc2130.cpp
  6. 8
    0
      Marlin/src/feature/tmc2130.h
  7. 27
    0
      Marlin/src/gcode/calibrate/G26.h
  8. 324
    0
      Marlin/src/gcode/calibrate/G28.h
  9. 946
    0
      Marlin/src/gcode/calibrate/G29-abl.h
  10. 200
    0
      Marlin/src/gcode/calibrate/G29-mbl.h
  11. 27
    0
      Marlin/src/gcode/calibrate/G29-ubl.h
  12. 65
    0
      Marlin/src/gcode/calibrate/G29.h
  13. 451
    0
      Marlin/src/gcode/calibrate/G33.h
  14. 72
    83
      Marlin/src/gcode/calibrate/M100.h
  15. 121
    0
      Marlin/src/gcode/calibrate/M420.h
  16. 51
    0
      Marlin/src/gcode/calibrate/M421-abl.h
  17. 49
    0
      Marlin/src/gcode/calibrate/M421-mbl.h
  18. 56
    0
      Marlin/src/gcode/calibrate/M421-ubl.h
  19. 273
    0
      Marlin/src/gcode/calibrate/M48.h
  20. 27
    0
      Marlin/src/gcode/calibrate/M49.h
  21. 93
    0
      Marlin/src/gcode/calibrate/M665.h
  22. 66
    0
      Marlin/src/gcode/calibrate/M666.h
  23. 81
    0
      Marlin/src/gcode/calibrate/common.h
  24. 46
    0
      Marlin/src/gcode/config/M200.h
  25. 40
    0
      Marlin/src/gcode/config/M201.h
  26. 37
    0
      Marlin/src/gcode/config/M203.h
  27. 49
    0
      Marlin/src/gcode/config/M204.h
  28. 42
    0
      Marlin/src/gcode/config/M205.h
  29. 54
    0
      Marlin/src/gcode/config/M218.h
  30. 28
    0
      Marlin/src/gcode/config/M220.h
  31. 30
    0
      Marlin/src/gcode/config/M221.h
  32. 69
    0
      Marlin/src/gcode/config/M301.h
  33. 54
    0
      Marlin/src/gcode/config/M302.h
  34. 34
    0
      Marlin/src/gcode/config/M304.h
  35. 311
    0
      Marlin/src/gcode/config/M43.h
  36. 28
    0
      Marlin/src/gcode/config/M540.h
  37. 51
    0
      Marlin/src/gcode/config/M92.h
  38. 30
    0
      Marlin/src/gcode/control/M108.h
  39. 61
    0
      Marlin/src/gcode/control/M111.h
  40. 30
    0
      Marlin/src/gcode/control/M112.h
  41. 39
    0
      Marlin/src/gcode/control/M120_M121.h
  42. 29
    0
      Marlin/src/gcode/control/M17.h
  43. 53
    0
      Marlin/src/gcode/control/M18_M84.h
  44. 46
    0
      Marlin/src/gcode/control/M211.h
  45. 54
    0
      Marlin/src/gcode/control/M226.h
  46. 43
    0
      Marlin/src/gcode/control/M280.h
  47. 127
    0
      Marlin/src/gcode/control/M3-M5.h
  48. 33
    0
      Marlin/src/gcode/control/M350.h
  49. 39
    0
      Marlin/src/gcode/control/M351.h
  50. 93
    0
      Marlin/src/gcode/control/M380_M381.h
  51. 30
    0
      Marlin/src/gcode/control/M400.h
  52. 33
    0
      Marlin/src/gcode/control/M410.h
  53. 59
    0
      Marlin/src/gcode/control/M42.h
  54. 76
    0
      Marlin/src/gcode/control/M605.h
  55. 56
    0
      Marlin/src/gcode/control/M80.h
  56. 53
    0
      Marlin/src/gcode/control/M81.h
  57. 31
    0
      Marlin/src/gcode/control/M85.h
  58. 41
    0
      Marlin/src/gcode/control/M999.h
  59. 62
    0
      Marlin/src/gcode/control/T.h
  60. 28
    0
      Marlin/src/gcode/eeprom/M500.h
  61. 28
    0
      Marlin/src/gcode/eeprom/M501.h
  62. 28
    0
      Marlin/src/gcode/eeprom/M502.h
  63. 28
    0
      Marlin/src/gcode/eeprom/M503.h
  64. 52
    0
      Marlin/src/gcode/feature/advance/M900.h
  65. 30
    0
      Marlin/src/gcode/feature/baricuda/M126.h
  66. 30
    0
      Marlin/src/gcode/feature/baricuda/M127.h
  67. 30
    0
      Marlin/src/gcode/feature/baricuda/M128.h
  68. 30
    0
      Marlin/src/gcode/feature/baricuda/M129.h
  69. 53
    0
      Marlin/src/gcode/feature/camera/M240.h
  70. 77
    0
      Marlin/src/gcode/feature/caselight/M355.h
  71. 36
    0
      Marlin/src/gcode/feature/clean/G12.h
  72. 61
    0
      Marlin/src/gcode/feature/digipot/M907.h
  73. 39
    0
      Marlin/src/gcode/feature/digipot/M908.h
  74. 27
    0
      Marlin/src/gcode/feature/digipot/M909.h
  75. 27
    0
      Marlin/src/gcode/feature/digipot/M910.h
  76. 41
    0
      Marlin/src/gcode/feature/fwretract/G10_G11.h
  77. 36
    0
      Marlin/src/gcode/feature/fwretract/M207.h
  78. 36
    0
      Marlin/src/gcode/feature/fwretract/M208.h
  79. 35
    0
      Marlin/src/gcode/feature/fwretract/M209.h
  80. 70
    0
      Marlin/src/gcode/feature/i2c/M260_M261.h
  81. 46
    0
      Marlin/src/gcode/feature/leds/M150.h
  82. 38
    0
      Marlin/src/gcode/feature/mixing/M163.h
  83. 36
    0
      Marlin/src/gcode/feature/mixing/M164.h
  84. 36
    0
      Marlin/src/gcode/feature/mixing/M165.h
  85. 30
    0
      Marlin/src/gcode/feature/pause/G27.h
  86. 89
    0
      Marlin/src/gcode/feature/pause/M125.h
  87. 103
    0
      Marlin/src/gcode/feature/pause/M600.h
  88. 335
    0
      Marlin/src/gcode/feature/pause/common.h
  89. 50
    0
      Marlin/src/gcode/feature/snmm/M702.h
  90. 65
    0
      Marlin/src/gcode/feature/trinamic/M906.h
  91. 49
    0
      Marlin/src/gcode/feature/trinamic/M911.h
  92. 47
    0
      Marlin/src/gcode/feature/trinamic/M912.h
  93. 57
    0
      Marlin/src/gcode/feature/trinamic/M913.h
  94. 45
    0
      Marlin/src/gcode/feature/trinamic/M914.h
  95. 682
    0
      Marlin/src/gcode/gcode.h
  96. 36
    0
      Marlin/src/gcode/geometry/G17-G19.h
  97. 66
    0
      Marlin/src/gcode/geometry/G92.h
  98. 42
    0
      Marlin/src/gcode/geometry/M206.h
  99. 61
    0
      Marlin/src/gcode/geometry/M428.h
  100. 0
    0
      Marlin/src/gcode/host/M110.h

+ 8
- 218
Marlin/src/Marlin.cpp View File

@@ -25,220 +25,7 @@
25 25
  *
26 26
  * This firmware is a mashup between Sprinter and grbl.
27 27
  *  - https://github.com/kliment/Sprinter
28
- *  - https://github.com/simen/grbl/tree
29
- */
30
-
31
-/**
32
- * -----------------
33
- * G-Codes in Marlin
34
- * -----------------
35
- *
36
- * Helpful G-code references:
37
- *  - http://linuxcnc.org/handbook/gcode/g-code.html
38
- *  - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
39
- *
40
- * Help to document Marlin's G-codes online:
41
- *  - http://reprap.org/wiki/G-code
42
- *  - https://github.com/MarlinFirmware/MarlinDocumentation
43
- *
44
- * -----------------
45
- *
46
- * "G" Codes
47
- *
48
- * G0   -> G1
49
- * G1   - Coordinated Movement X Y Z E
50
- * G2   - CW ARC
51
- * G3   - CCW ARC
52
- * G4   - Dwell S<seconds> or P<milliseconds>
53
- * G5   - Cubic B-spline with XYZE destination and IJPQ offsets
54
- * G10  - Retract filament according to settings of M207 (Requires FWRETRACT)
55
- * G11  - Retract recover filament according to settings of M208 (Requires FWRETRACT)
56
- * G12  - Clean tool (Requires NOZZLE_CLEAN_FEATURE)
57
- * G17  - Select Plane XY (Requires CNC_WORKSPACE_PLANES)
58
- * G18  - Select Plane ZX (Requires CNC_WORKSPACE_PLANES)
59
- * G19  - Select Plane YZ (Requires CNC_WORKSPACE_PLANES)
60
- * G20  - Set input units to inches (Requires INCH_MODE_SUPPORT)
61
- * G21  - Set input units to millimeters (Requires INCH_MODE_SUPPORT)
62
- * G26  - Mesh Validation Pattern (Requires UBL_G26_MESH_VALIDATION)
63
- * G27  - Park Nozzle (Requires NOZZLE_PARK_FEATURE)
64
- * G28  - Home one or more axes
65
- * G29  - Start or continue the bed leveling probe procedure (Requires bed leveling)
66
- * G30  - Single Z probe, probes bed at X Y location (defaults to current XY location)
67
- * G31  - Dock sled (Z_PROBE_SLED only)
68
- * G32  - Undock sled (Z_PROBE_SLED only)
69
- * G33  - Delta Auto-Calibration (Requires DELTA_AUTO_CALIBRATION)
70
- * G38  - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET)
71
- * G42  - Coordinated move to a mesh point (Requires AUTO_BED_LEVELING_UBL)
72
- * G90  - Use Absolute Coordinates
73
- * G91  - Use Relative Coordinates
74
- * G92  - Set current position to coordinates given
75
- *
76
- * "M" Codes
77
- *
78
- * M0   - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled)
79
- * M1   -> M0
80
- * M3   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to clockwise
81
- * M4   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to counter-clockwise
82
- * M5   - Turn laser/spindle off
83
- * M17  - Enable/Power all stepper motors
84
- * M18  - Disable all stepper motors; same as M84
85
- * M20  - List SD card. (Requires SDSUPPORT)
86
- * M21  - Init SD card. (Requires SDSUPPORT)
87
- * M22  - Release SD card. (Requires SDSUPPORT)
88
- * M23  - Select SD file: "M23 /path/file.gco". (Requires SDSUPPORT)
89
- * M24  - Start/resume SD print. (Requires SDSUPPORT)
90
- * M25  - Pause SD print. (Requires SDSUPPORT)
91
- * M26  - Set SD position in bytes: "M26 S12345". (Requires SDSUPPORT)
92
- * M27  - Report SD print status. (Requires SDSUPPORT)
93
- * M28  - Start SD write: "M28 /path/file.gco". (Requires SDSUPPORT)
94
- * M29  - Stop SD write. (Requires SDSUPPORT)
95
- * M30  - Delete file from SD: "M30 /path/file.gco"
96
- * M31  - Report time since last M109 or SD card start to serial.
97
- * M32  - Select file and start SD print: "M32 [S<bytepos>] !/path/file.gco#". (Requires SDSUPPORT)
98
- *        Use P to run other files as sub-programs: "M32 P !filename#"
99
- *        The '#' is necessary when calling from within sd files, as it stops buffer prereading
100
- * M33  - Get the longname version of a path. (Requires LONG_FILENAME_HOST_SUPPORT)
101
- * M34  - Set SD Card sorting options. (Requires SDCARD_SORT_ALPHA)
102
- * M42  - Change pin status via gcode: M42 P<pin> S<value>. LED pin assumed if P is omitted.
103
- * M43  - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
104
- * M48  - Measure Z Probe repeatability: M48 P<points> X<pos> Y<pos> V<level> E<engage> L<legs>. (Requires Z_MIN_PROBE_REPEATABILITY_TEST)
105
- * M75  - Start the print job timer.
106
- * M76  - Pause the print job timer.
107
- * M77  - Stop the print job timer.
108
- * M78  - Show statistical information about the print jobs. (Requires PRINTCOUNTER)
109
- * M80  - Turn on Power Supply. (Requires POWER_SUPPLY > 0)
110
- * M81  - Turn off Power Supply. (Requires POWER_SUPPLY > 0)
111
- * M82  - Set E codes absolute (default).
112
- * M83  - Set E codes relative while in Absolute (G90) mode.
113
- * M84  - Disable steppers until next move, or use S<seconds> to specify an idle
114
- *        duration after which steppers should turn off. S0 disables the timeout.
115
- * M85  - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
116
- * M92  - Set planner.axis_steps_per_mm for one or more axes.
117
- * M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER)
118
- * M104 - Set extruder target temp.
119
- * M105 - Report current temperatures.
120
- * M106 - Fan on.
121
- * M107 - Fan off.
122
- * M108 - Break out of heating loops (M109, M190, M303). With no controller, breaks out of M0/M1. (Requires EMERGENCY_PARSER)
123
- * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
124
- *        Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
125
- *        If AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
126
- * M110 - Set the current line number. (Used by host printing)
127
- * M111 - Set debug flags: "M111 S<flagbits>". See flag bits defined in enum.h.
128
- * M112 - Emergency stop.
129
- * M113 - Get or set the timeout interval for Host Keepalive "busy" messages. (Requires HOST_KEEPALIVE_FEATURE)
130
- * M114 - Report current position.
131
- * M115 - Report capabilities. (Extended capabilities requires EXTENDED_CAPABILITIES_REPORT)
132
- * M117 - Display a message on the controller screen. (Requires an LCD)
133
- * M118 - Display a message in the host console.
134
- * M119 - Report endstops status.
135
- * M120 - Enable endstops detection.
136
- * M121 - Disable endstops detection.
137
- * M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE)
138
- * M126 - Solenoid Air Valve Open. (Requires BARICUDA)
139
- * M127 - Solenoid Air Valve Closed. (Requires BARICUDA)
140
- * M128 - EtoP Open. (Requires BARICUDA)
141
- * M129 - EtoP Closed. (Requires BARICUDA)
142
- * M140 - Set bed target temp. S<temp>
143
- * M145 - Set heatup values for materials on the LCD. H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS)
144
- * M149 - Set temperature units. (Requires TEMPERATURE_UNITS_SUPPORT)
145
- * M150 - Set Status LED Color as R<red> U<green> B<blue>. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, or PCA9632)
146
- * M155 - Auto-report temperatures with interval of S<seconds>. (Requires AUTO_REPORT_TEMPERATURES)
147
- * M163 - Set a single proportion for a mixing extruder. (Requires MIXING_EXTRUDER)
148
- * M164 - Save the mix as a virtual extruder. (Requires MIXING_EXTRUDER and MIXING_VIRTUAL_TOOLS)
149
- * M165 - Set the proportions for a mixing extruder. Use parameters ABCDHI to set the mixing factors. (Requires MIXING_EXTRUDER)
150
- * M190 - Sxxx Wait for bed current temp to reach target temp. ** Waits only when heating! **
151
- *        Rxxx Wait for bed current temp to reach target temp. ** Waits for heating or cooling. **
152
- * M200 - Set filament diameter, D<diameter>, setting E axis units to cubic. (Use S0 to revert to linear units.)
153
- * M201 - Set max acceleration in units/s^2 for print moves: "M201 X<accel> Y<accel> Z<accel> E<accel>"
154
- * M202 - Set max acceleration in units/s^2 for travel moves: "M202 X<accel> Y<accel> Z<accel> E<accel>" ** UNUSED IN MARLIN! **
155
- * M203 - Set maximum feedrate: "M203 X<fr> Y<fr> Z<fr> E<fr>" in units/sec.
156
- * M204 - Set default acceleration in units/sec^2: P<printing> R<extruder_only> T<travel>
157
- * M205 - Set advanced settings. Current units apply:
158
-            S<print> T<travel> minimum speeds
159
-            B<minimum segment time>
160
-            X<max X jerk>, Y<max Y jerk>, Z<max Z jerk>, E<max E jerk>
161
- * M206 - Set additional homing offset. (Disabled by NO_WORKSPACE_OFFSETS or DELTA)
162
- * M207 - Set Retract Length: S<length>, Feedrate: F<units/min>, and Z lift: Z<distance>. (Requires FWRETRACT)
163
- * M208 - Set Recover (unretract) Additional (!) Length: S<length> and Feedrate: F<units/min>. (Requires FWRETRACT)
164
- * M209 - Turn Automatic Retract Detection on/off: S<0|1> (For slicers that don't support G10/11). (Requires FWRETRACT)
165
-          Every normal extrude-only move will be classified as retract depending on the direction.
166
- * M211 - Enable, Disable, and/or Report software endstops: S<0|1> (Requires MIN_SOFTWARE_ENDSTOPS or MAX_SOFTWARE_ENDSTOPS)
167
- * M218 - Set a tool offset: "M218 T<index> X<offset> Y<offset>". (Requires 2 or more extruders)
168
- * M220 - Set Feedrate Percentage: "M220 S<percent>" (i.e., "FR" on the LCD)
169
- * M221 - Set Flow Percentage: "M221 S<percent>"
170
- * M226 - Wait until a pin is in a given state: "M226 P<pin> S<state>"
171
- * M240 - Trigger a camera to take a photograph. (Requires CHDK or PHOTOGRAPH_PIN)
172
- * M250 - Set LCD contrast: "M250 C<contrast>" (0-63). (Requires LCD support)
173
- * M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS)
174
- * M261 - i2c Request Data (Requires EXPERIMENTAL_I2CBUS)
175
- * M280 - Set servo position absolute: "M280 P<index> S<angle|µs>". (Requires servos)
176
- * M300 - Play beep sound S<frequency Hz> P<duration ms>
177
- * M301 - Set PID parameters P I and D. (Requires PIDTEMP)
178
- * M302 - Allow cold extrudes, or set the minimum extrude S<temperature>. (Requires PREVENT_COLD_EXTRUSION)
179
- * M303 - PID relay autotune S<temperature> sets the target temperature. Default 150C. (Requires PIDTEMP)
180
- * M304 - Set bed PID parameters P I and D. (Requires PIDTEMPBED)
181
- * M350 - Set microstepping mode. (Requires digital microstepping pins.)
182
- * M351 - Toggle MS1 MS2 pins directly. (Requires digital microstepping pins.)
183
- * M355 - Set Case Light on/off and set brightness. (Requires CASE_LIGHT_PIN)
184
- * M380 - Activate solenoid on active extruder. (Requires EXT_SOLENOID)
185
- * M381 - Disable all solenoids. (Requires EXT_SOLENOID)
186
- * M400 - Finish all moves.
187
- * M401 - Lower Z probe. (Requires a probe)
188
- * M402 - Raise Z probe. (Requires a probe)
189
- * M404 - Display or set the Nominal Filament Width: "W<diameter>". (Requires FILAMENT_WIDTH_SENSOR)
190
- * M405 - Enable Filament Sensor flow control. "M405 D<delay_cm>". (Requires FILAMENT_WIDTH_SENSOR)
191
- * M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR)
192
- * M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR)
193
- * M410 - Quickstop. Abort all planned moves.
194
- * M420 - Enable/Disable Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING or ABL)
195
- * M421 - Set a single Z coordinate in the Mesh Leveling grid. X<units> Y<units> Z<units> (Requires MESH_BED_LEVELING or AUTO_BED_LEVELING_UBL)
196
- * M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA)
197
- * M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS)
198
- * M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS)
199
- * M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
200
- * M503 - Print the current settings (in memory): "M503 S<verbose>". S0 specifies compact output.
201
- * M540 - Enable/disable SD card abort on endstop hit: "M540 S<state>". (Requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
202
- * M600 - Pause for filament change: "M600 X<pos> Y<pos> Z<raise> E<first_retract> L<later_retract>". (Requires ADVANCED_PAUSE_FEATURE)
203
- * M665 - Set delta configurations: "M665 L<diagonal rod> R<delta radius> S<segments/s> A<rod A trim mm> B<rod B trim mm> C<rod C trim mm> I<tower A trim angle> J<tower B trim angle> K<tower C trim angle>" (Requires DELTA)
204
- * M666 - Set delta endstop adjustment. (Requires DELTA)
205
- * M605 - Set dual x-carriage movement mode: "M605 S<mode> [X<x_offset>] [R<temp_offset>]". (Requires DUAL_X_CARRIAGE)
206
- * M851 - Set Z probe's Z offset in current units. (Negative = below the nozzle.)
207
- * M860 - Report the position of position encoder modules.
208
- * M861 - Report the status of position encoder modules.
209
- * M862 - Perform an axis continuity test for position encoder modules.
210
- * M863 - Perform steps-per-mm calibration for position encoder modules.
211
- * M864 - Change position encoder module I2C address.
212
- * M865 - Check position encoder module firmware version.
213
- * M866 - Report or reset position encoder module error count.
214
- * M867 - Enable/disable or toggle error correction for position encoder modules.
215
- * M868 - Report or set position encoder module error correction threshold.
216
- * M869 - Report position encoder module error.
217
- * M900 - Get and/or Set advance K factor and WH/D ratio. (Requires LIN_ADVANCE)
218
- * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires HAVE_TMC2130)
219
- * M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots)
220
- * M908 - Control digital trimpot directly. (Requires DAC_STEPPER_CURRENT or DIGIPOTSS_PIN)
221
- * M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT)
222
- * M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT)
223
- * M911 - Report stepper driver overtemperature pre-warn condition. (Requires HAVE_TMC2130)
224
- * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires HAVE_TMC2130)
225
- * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD)
226
- * M914 - Set SENSORLESS_HOMING sensitivity. (Requires SENSORLESS_HOMING)
227
- *
228
- * M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
229
- * M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
230
- * M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration)
231
- * M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
232
- * M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position)
233
- *
234
- * ************ Custom codes - This can change to suit future G-code regulations
235
- * M928 - Start SD logging: "M928 filename.gco". Stop with M29. (Requires SDSUPPORT)
236
- * M999 - Restart after being stopped by error
237
- *
238
- * "T" Codes
239
- *
240
- * T0-T3 - Select an extruder (tool) by index: "T<n> F<units/min>"
241
- *
28
+ *  - https://github.com/simen/grbl
242 29
  */
243 30
 
244 31
 #include "Marlin.h"
@@ -316,7 +103,6 @@
316 103
 #endif
317 104
 
318 105
 #if ENABLED(M100_FREE_MEMORY_WATCHER)
319
-  void gcode_M100();
320 106
   void M100_dump_routine(const char * const title, const char *start, const char *end);
321 107
 #endif
322 108
 
@@ -344,6 +130,10 @@
344 130
                            || isnan(ubl.z_values[0][0]))
345 131
 #endif
346 132
 
133
+#if ENABLED(SENSORLESS_HOMING)
134
+  #include "feature/tmc2130.h"
135
+#endif
136
+
347 137
 bool Running = true;
348 138
 
349 139
 /**
@@ -3328,7 +3118,7 @@ void dwell(millis_t time) {
3328 3118
 #endif
3329 3119
 
3330 3120
 #if ENABLED(CNC_WORKSPACE_PLANES)
3331
-  #include "gcode/feature/clean/G17-G19.h"
3121
+  #include "gcode/geometry/G17-G19.h"
3332 3122
 #endif
3333 3123
 
3334 3124
 #if ENABLED(INCH_MODE_SUPPORT)
@@ -3732,11 +3522,11 @@ void report_current_position() {
3732 3522
 #endif
3733 3523
 
3734 3524
 #if defined(CHDK) || HAS_PHOTOGRAPH
3735
-  #include "gcode/control/M240.h"
3525
+  #include "gcode/feature/camera/M240.h"
3736 3526
 #endif
3737 3527
 
3738 3528
 #if HAS_LCD_CONTRAST
3739
-  #include "gcode/control/M250.h"
3529
+  #include "gcode/lcd/M250.h"
3740 3530
 #endif
3741 3531
 
3742 3532
 #if ENABLED(PREVENT_COLD_EXTRUSION)

+ 0
- 2
Marlin/src/Marlin.h View File

@@ -194,8 +194,6 @@ inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
194 194
  */
195 195
 extern int16_t feedrate_percentage;
196 196
 
197
-#define MMM_TO_MMS(MM_M) ((MM_M)/60.0)
198
-#define MMS_TO_MMM(MM_S) ((MM_S)*60.0)
199 197
 #define MMS_SCALED(MM_S) ((MM_S)*feedrate_percentage*0.01)
200 198
 
201 199
 extern bool axis_relative_modes[];

+ 3
- 0
Marlin/src/core/macros.h View File

@@ -172,6 +172,9 @@
172 172
 #define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0)
173 173
 #define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
174 174
 
175
+#define MMM_TO_MMS(MM_M) ((MM_M)/60.0)
176
+#define MMS_TO_MMM(MM_S) ((MM_S)*60.0)
177
+
175 178
 #define NOOP do{} while(0)
176 179
 
177 180
 #define CEILING(x,y) (((x) + (y) - 1) / (y))

+ 0
- 11
Marlin/src/feature/I2CPositionEncoder.h View File

@@ -341,15 +341,4 @@ class I2CPositionEncodersMgr {
341 341
 
342 342
 extern I2CPositionEncodersMgr I2CPEM;
343 343
 
344
-FORCE_INLINE static void gcode_M860() { I2CPEM.M860(); }
345
-FORCE_INLINE static void gcode_M861() { I2CPEM.M861(); }
346
-FORCE_INLINE static void gcode_M862() { I2CPEM.M862(); }
347
-FORCE_INLINE static void gcode_M863() { I2CPEM.M863(); }
348
-FORCE_INLINE static void gcode_M864() { I2CPEM.M864(); }
349
-FORCE_INLINE static void gcode_M865() { I2CPEM.M865(); }
350
-FORCE_INLINE static void gcode_M866() { I2CPEM.M866(); }
351
-FORCE_INLINE static void gcode_M867() { I2CPEM.M867(); }
352
-FORCE_INLINE static void gcode_M868() { I2CPEM.M868(); }
353
-FORCE_INLINE static void gcode_M869() { I2CPEM.M869(); }
354
-
355 344
 #endif //I2CPOSENC_H

+ 0
- 2
Marlin/src/feature/tmc2130.cpp View File

@@ -30,8 +30,6 @@
30 30
 #include "../libs/duration_t.h"
31 31
 #include "../module/stepper_indirection.h"
32 32
 
33
-#include <TMC2130Stepper.h>
34
-
35 33
 #ifdef AUTOMATIC_CURRENT_CONTROL
36 34
   bool auto_current_control = 0;
37 35
 #endif

+ 8
- 0
Marlin/src/feature/tmc2130.h View File

@@ -23,8 +23,16 @@
23 23
 #ifndef _TMC2130_H_
24 24
 #define _TMC2130_H_
25 25
 
26
+#include <TMC2130Stepper.h>
27
+
28
+#include "../inc/MarlinConfig.h"
29
+
26 30
 extern bool auto_current_control;
27 31
 
28 32
 void tmc2130_checkOverTemp(void);
29 33
 
34
+#if ENABLED(SENSORLESS_HOMING)
35
+  void tmc2130_sensorless_homing(TMC2130Stepper &st, bool enable=true);
36
+#endif
37
+
30 38
 #endif // _TMC2130_H_

+ 27
- 0
Marlin/src/gcode/calibrate/G26.h View File

@@ -0,0 +1,27 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+void gcode_G26() {
24
+
25
+  ubl.G26();
26
+
27
+}

+ 324
- 0
Marlin/src/gcode/calibrate/G28.h View File

@@ -0,0 +1,324 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "common.h"
24
+
25
+#if HOTENDS > 1
26
+  #include "../control/tool_change.h"
27
+#endif
28
+
29
+#if ENABLED(QUICK_HOME)
30
+
31
+  static void quick_home_xy() {
32
+
33
+    // Pretend the current position is 0,0
34
+    current_position[X_AXIS] = current_position[Y_AXIS] = 0.0;
35
+    sync_plan_position();
36
+
37
+    const int x_axis_home_dir =
38
+      #if ENABLED(DUAL_X_CARRIAGE)
39
+        x_home_dir(active_extruder)
40
+      #else
41
+        home_dir(X_AXIS)
42
+      #endif
43
+    ;
44
+
45
+    const float mlx = max_length(X_AXIS),
46
+                mly = max_length(Y_AXIS),
47
+                mlratio = mlx > mly ? mly / mlx : mlx / mly,
48
+                fr_mm_s = min(homing_feedrate(X_AXIS), homing_feedrate(Y_AXIS)) * SQRT(sq(mlratio) + 1.0);
49
+
50
+    do_blocking_move_to_xy(1.5 * mlx * x_axis_home_dir, 1.5 * mly * home_dir(Y_AXIS), fr_mm_s);
51
+    endstops.hit_on_purpose(); // clear endstop hit flags
52
+    current_position[X_AXIS] = current_position[Y_AXIS] = 0.0;
53
+  }
54
+
55
+#endif // QUICK_HOME
56
+
57
+#if ENABLED(Z_SAFE_HOMING)
58
+
59
+  inline void home_z_safely() {
60
+
61
+    // Disallow Z homing if X or Y are unknown
62
+    if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
63
+      LCD_MESSAGEPGM(MSG_ERR_Z_HOMING);
64
+      SERIAL_ECHO_START();
65
+      SERIAL_ECHOLNPGM(MSG_ERR_Z_HOMING);
66
+      return;
67
+    }
68
+
69
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
70
+      if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Z_SAFE_HOMING >>>");
71
+    #endif
72
+
73
+    SYNC_PLAN_POSITION_KINEMATIC();
74
+
75
+    /**
76
+     * Move the Z probe (or just the nozzle) to the safe homing point
77
+     */
78
+    destination[X_AXIS] = LOGICAL_X_POSITION(Z_SAFE_HOMING_X_POINT);
79
+    destination[Y_AXIS] = LOGICAL_Y_POSITION(Z_SAFE_HOMING_Y_POINT);
80
+    destination[Z_AXIS] = current_position[Z_AXIS]; // Z is already at the right height
81
+
82
+    #if HOMING_Z_WITH_PROBE
83
+      destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER;
84
+      destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER;
85
+    #endif
86
+
87
+    if (position_is_reachable_xy(destination[X_AXIS], destination[Y_AXIS])) {
88
+
89
+      #if ENABLED(DEBUG_LEVELING_FEATURE)
90
+        if (DEBUGGING(LEVELING)) DEBUG_POS("Z_SAFE_HOMING", destination);
91
+      #endif
92
+
93
+      // This causes the carriage on Dual X to unpark
94
+      #if ENABLED(DUAL_X_CARRIAGE)
95
+        active_extruder_parked = false;
96
+      #endif
97
+
98
+      do_blocking_move_to_xy(destination[X_AXIS], destination[Y_AXIS]);
99
+      HOMEAXIS(Z);
100
+    }
101
+    else {
102
+      LCD_MESSAGEPGM(MSG_ZPROBE_OUT);
103
+      SERIAL_ECHO_START();
104
+      SERIAL_ECHOLNPGM(MSG_ZPROBE_OUT);
105
+    }
106
+
107
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
108
+      if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< Z_SAFE_HOMING");
109
+    #endif
110
+  }
111
+
112
+#endif // Z_SAFE_HOMING
113
+
114
+/**
115
+ * G28: Home all axes according to settings
116
+ *
117
+ * Parameters
118
+ *
119
+ *  None  Home to all axes with no parameters.
120
+ *        With QUICK_HOME enabled XY will home together, then Z.
121
+ *
122
+ * Cartesian parameters
123
+ *
124
+ *  X   Home to the X endstop
125
+ *  Y   Home to the Y endstop
126
+ *  Z   Home to the Z endstop
127
+ *
128
+ */
129
+void gcode_G28(const bool always_home_all) {
130
+
131
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
132
+    if (DEBUGGING(LEVELING)) {
133
+      SERIAL_ECHOLNPGM(">>> gcode_G28");
134
+      log_machine_info();
135
+    }
136
+  #endif
137
+
138
+  // Wait for planner moves to finish!
139
+  stepper.synchronize();
140
+
141
+  // Cancel the active G29 session
142
+  #if ENABLED(PROBE_MANUALLY)
143
+    g29_in_progress = false;
144
+  #endif
145
+
146
+  // Disable the leveling matrix before homing
147
+  #if HAS_LEVELING
148
+    #if ENABLED(AUTO_BED_LEVELING_UBL)
149
+      const bool ubl_state_at_entry = leveling_is_active();
150
+    #endif
151
+    set_bed_leveling_enabled(false);
152
+  #endif
153
+
154
+  #if ENABLED(CNC_WORKSPACE_PLANES)
155
+    workspace_plane = PLANE_XY;
156
+  #endif
157
+
158
+  // Always home with tool 0 active
159
+  #if HOTENDS > 1
160
+    const uint8_t old_tool_index = active_extruder;
161
+    tool_change(0, 0, true);
162
+  #endif
163
+
164
+  #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
165
+    extruder_duplication_enabled = false;
166
+  #endif
167
+
168
+  setup_for_endstop_or_probe_move();
169
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
170
+    if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> endstops.enable(true)");
171
+  #endif
172
+  endstops.enable(true); // Enable endstops for next homing move
173
+
174
+  #if ENABLED(DELTA)
175
+
176
+    home_delta();
177
+    UNUSED(always_home_all);
178
+
179
+  #else // NOT DELTA
180
+
181
+    const bool homeX = always_home_all || parser.seen('X'),
182
+               homeY = always_home_all || parser.seen('Y'),
183
+               homeZ = always_home_all || parser.seen('Z'),
184
+               home_all = (!homeX && !homeY && !homeZ) || (homeX && homeY && homeZ);
185
+
186
+    set_destination_to_current();
187
+
188
+    #if Z_HOME_DIR > 0  // If homing away from BED do Z first
189
+
190
+      if (home_all || homeZ) {
191
+        HOMEAXIS(Z);
192
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
193
+          if (DEBUGGING(LEVELING)) DEBUG_POS("> HOMEAXIS(Z)", current_position);
194
+        #endif
195
+      }
196
+
197
+    #else
198
+
199
+      if (home_all || homeX || homeY) {
200
+        // Raise Z before homing any other axes and z is not already high enough (never lower z)
201
+        destination[Z_AXIS] = LOGICAL_Z_POSITION(Z_HOMING_HEIGHT);
202
+        if (destination[Z_AXIS] > current_position[Z_AXIS]) {
203
+
204
+          #if ENABLED(DEBUG_LEVELING_FEATURE)
205
+            if (DEBUGGING(LEVELING))
206
+              SERIAL_ECHOLNPAIR("Raise Z (before homing) to ", destination[Z_AXIS]);
207
+          #endif
208
+
209
+          do_blocking_move_to_z(destination[Z_AXIS]);
210
+        }
211
+      }
212
+
213
+    #endif
214
+
215
+    #if ENABLED(QUICK_HOME)
216
+
217
+      if (home_all || (homeX && homeY)) quick_home_xy();
218
+
219
+    #endif
220
+
221
+    #if ENABLED(HOME_Y_BEFORE_X)
222
+
223
+      // Home Y
224
+      if (home_all || homeY) {
225
+        HOMEAXIS(Y);
226
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
227
+          if (DEBUGGING(LEVELING)) DEBUG_POS("> homeY", current_position);
228
+        #endif
229
+      }
230
+
231
+    #endif
232
+
233
+    // Home X
234
+    if (home_all || homeX) {
235
+
236
+      #if ENABLED(DUAL_X_CARRIAGE)
237
+
238
+        // Always home the 2nd (right) extruder first
239
+        active_extruder = 1;
240
+        HOMEAXIS(X);
241
+
242
+        // Remember this extruder's position for later tool change
243
+        inactive_extruder_x_pos = RAW_X_POSITION(current_position[X_AXIS]);
244
+
245
+        // Home the 1st (left) extruder
246
+        active_extruder = 0;
247
+        HOMEAXIS(X);
248
+
249
+        // Consider the active extruder to be parked
250
+        COPY(raised_parked_position, current_position);
251
+        delayed_move_time = 0;
252
+        active_extruder_parked = true;
253
+
254
+      #else
255
+
256
+        HOMEAXIS(X);
257
+
258
+      #endif
259
+
260
+      #if ENABLED(DEBUG_LEVELING_FEATURE)
261
+        if (DEBUGGING(LEVELING)) DEBUG_POS("> homeX", current_position);
262
+      #endif
263
+    }
264
+
265
+    #if DISABLED(HOME_Y_BEFORE_X)
266
+      // Home Y
267
+      if (home_all || homeY) {
268
+        HOMEAXIS(Y);
269
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
270
+          if (DEBUGGING(LEVELING)) DEBUG_POS("> homeY", current_position);
271
+        #endif
272
+      }
273
+    #endif
274
+
275
+    // Home Z last if homing towards the bed
276
+    #if Z_HOME_DIR < 0
277
+      if (home_all || homeZ) {
278
+        #if ENABLED(Z_SAFE_HOMING)
279
+          home_z_safely();
280
+        #else
281
+          HOMEAXIS(Z);
282
+        #endif
283
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
284
+          if (DEBUGGING(LEVELING)) DEBUG_POS("> (home_all || homeZ) > final", current_position);
285
+        #endif
286
+      } // home_all || homeZ
287
+    #endif // Z_HOME_DIR < 0
288
+
289
+    SYNC_PLAN_POSITION_KINEMATIC();
290
+
291
+  #endif // !DELTA (gcode_G28)
292
+
293
+  endstops.not_homing();
294
+
295
+  #if ENABLED(DELTA) && ENABLED(DELTA_HOME_TO_SAFE_ZONE)
296
+    // move to a height where we can use the full xy-area
297
+    do_blocking_move_to_z(delta_clip_start_height);
298
+  #endif
299
+
300
+  #if ENABLED(AUTO_BED_LEVELING_UBL)
301
+    set_bed_leveling_enabled(ubl_state_at_entry);
302
+  #endif
303
+
304
+  clean_up_after_endstop_or_probe_move();
305
+
306
+  // Restore the active tool after homing
307
+  #if HOTENDS > 1
308
+    tool_change(old_tool_index, 0,
309
+      #if ENABLED(PARKING_EXTRUDER)
310
+        false // fetch the previous toolhead
311
+      #else
312
+        true
313
+      #endif
314
+    );
315
+  #endif
316
+
317
+  lcd_refresh();
318
+
319
+  report_current_position();
320
+
321
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
322
+    if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< gcode_G28");
323
+  #endif
324
+}

+ 946
- 0
Marlin/src/gcode/calibrate/G29-abl.h View File

@@ -0,0 +1,946 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if ABL_GRID
24
+  #if ENABLED(PROBE_Y_FIRST)
25
+    #define PR_OUTER_VAR xCount
26
+    #define PR_OUTER_END abl_grid_points_x
27
+    #define PR_INNER_VAR yCount
28
+    #define PR_INNER_END abl_grid_points_y
29
+  #else
30
+    #define PR_OUTER_VAR yCount
31
+    #define PR_OUTER_END abl_grid_points_y
32
+    #define PR_INNER_VAR xCount
33
+    #define PR_INNER_END abl_grid_points_x
34
+  #endif
35
+#endif
36
+
37
+/**
38
+ * G29: Detailed Z probe, probes the bed at 3 or more points.
39
+ *      Will fail if the printer has not been homed with G28.
40
+ *
41
+ * Enhanced G29 Auto Bed Leveling Probe Routine
42
+ *
43
+ *  D  Dry-Run mode. Just evaluate the bed Topology - Don't apply
44
+ *     or alter the bed level data. Useful to check the topology
45
+ *     after a first run of G29.
46
+ *
47
+ *  J  Jettison current bed leveling data
48
+ *
49
+ *  V  Set the verbose level (0-4). Example: "G29 V3"
50
+ *
51
+ * Parameters With LINEAR leveling only:
52
+ *
53
+ *  P  Set the size of the grid that will be probed (P x P points).
54
+ *     Example: "G29 P4"
55
+ *
56
+ *  X  Set the X size of the grid that will be probed (X x Y points).
57
+ *     Example: "G29 X7 Y5"
58
+ *
59
+ *  Y  Set the Y size of the grid that will be probed (X x Y points).
60
+ *
61
+ *  T  Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report.
62
+ *     This is useful for manual bed leveling and finding flaws in the bed (to
63
+ *     assist with part placement).
64
+ *     Not supported by non-linear delta printer bed leveling.
65
+ *
66
+ * Parameters With LINEAR and BILINEAR leveling only:
67
+ *
68
+ *  S  Set the XY travel speed between probe points (in units/min)
69
+ *
70
+ *  F  Set the Front limit of the probing grid
71
+ *  B  Set the Back limit of the probing grid
72
+ *  L  Set the Left limit of the probing grid
73
+ *  R  Set the Right limit of the probing grid
74
+ *
75
+ * Parameters with DEBUG_LEVELING_FEATURE only:
76
+ *
77
+ *  C  Make a totally fake grid with no actual probing.
78
+ *     For use in testing when no probing is possible.
79
+ *
80
+ * Parameters with BILINEAR leveling only:
81
+ *
82
+ *  Z  Supply an additional Z probe offset
83
+ *
84
+ * Extra parameters with PROBE_MANUALLY:
85
+ *
86
+ *  To do manual probing simply repeat G29 until the procedure is complete.
87
+ *  The first G29 accepts parameters. 'G29 Q' for status, 'G29 A' to abort.
88
+ *
89
+ *  Q  Query leveling and G29 state
90
+ *
91
+ *  A  Abort current leveling procedure
92
+ *
93
+ * Extra parameters with BILINEAR only:
94
+ *
95
+ *  W  Write a mesh point. (If G29 is idle.)
96
+ *  I  X index for mesh point
97
+ *  J  Y index for mesh point
98
+ *  X  X for mesh point, overrides I
99
+ *  Y  Y for mesh point, overrides J
100
+ *  Z  Z for mesh point. Otherwise, raw current Z.
101
+ *
102
+ * Without PROBE_MANUALLY:
103
+ *
104
+ *  E  By default G29 will engage the Z probe, test the bed, then disengage.
105
+ *     Include "E" to engage/disengage the Z probe for each sample.
106
+ *     There's no extra effect if you have a fixed Z probe.
107
+ *
108
+ */
109
+void gcode_G29() {
110
+
111
+  // G29 Q is also available if debugging
112
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
113
+    const bool query = parser.seen('Q');
114
+    const uint8_t old_debug_flags = marlin_debug_flags;
115
+    if (query) marlin_debug_flags |= DEBUG_LEVELING;
116
+    if (DEBUGGING(LEVELING)) {
117
+      DEBUG_POS(">>> gcode_G29", current_position);
118
+      log_machine_info();
119
+    }
120
+    marlin_debug_flags = old_debug_flags;
121
+    #if DISABLED(PROBE_MANUALLY)
122
+      if (query) return;
123
+    #endif
124
+  #endif
125
+
126
+  #if ENABLED(PROBE_MANUALLY)
127
+    const bool seenA = parser.seen('A'), seenQ = parser.seen('Q'), no_action = seenA || seenQ;
128
+  #endif
129
+
130
+  #if ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY)
131
+    const bool faux = parser.boolval('C');
132
+  #elif ENABLED(PROBE_MANUALLY)
133
+    const bool faux = no_action;
134
+  #else
135
+    bool constexpr faux = false;
136
+  #endif
137
+
138
+  // Don't allow auto-leveling without homing first
139
+  if (axis_unhomed_error()) return;
140
+
141
+  // Define local vars 'static' for manual probing, 'auto' otherwise
142
+  #if ENABLED(PROBE_MANUALLY)
143
+    #define ABL_VAR static
144
+  #else
145
+    #define ABL_VAR
146
+  #endif
147
+
148
+  ABL_VAR int verbose_level;
149
+  ABL_VAR float xProbe, yProbe, measured_z;
150
+  ABL_VAR bool dryrun, abl_should_enable;
151
+
152
+  #if ENABLED(PROBE_MANUALLY) || ENABLED(AUTO_BED_LEVELING_LINEAR)
153
+    ABL_VAR int abl_probe_index;
154
+  #endif
155
+
156
+  #if HAS_SOFTWARE_ENDSTOPS && ENABLED(PROBE_MANUALLY)
157
+    ABL_VAR bool enable_soft_endstops = true;
158
+  #endif
159
+
160
+  #if ABL_GRID
161
+
162
+    #if ENABLED(PROBE_MANUALLY)
163
+      ABL_VAR uint8_t PR_OUTER_VAR;
164
+      ABL_VAR  int8_t PR_INNER_VAR;
165
+    #endif
166
+
167
+    ABL_VAR int left_probe_bed_position, right_probe_bed_position, front_probe_bed_position, back_probe_bed_position;
168
+    ABL_VAR float xGridSpacing = 0, yGridSpacing = 0;
169
+
170
+    #if ENABLED(AUTO_BED_LEVELING_LINEAR)
171
+      ABL_VAR uint8_t abl_grid_points_x = GRID_MAX_POINTS_X,
172
+                      abl_grid_points_y = GRID_MAX_POINTS_Y;
173
+      ABL_VAR bool do_topography_map;
174
+    #else // Bilinear
175
+      uint8_t constexpr abl_grid_points_x = GRID_MAX_POINTS_X,
176
+                        abl_grid_points_y = GRID_MAX_POINTS_Y;
177
+    #endif
178
+
179
+    #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(PROBE_MANUALLY)
180
+      #if ENABLED(AUTO_BED_LEVELING_LINEAR)
181
+        ABL_VAR int abl2;
182
+      #else // Bilinear
183
+        int constexpr abl2 = GRID_MAX_POINTS;
184
+      #endif
185
+    #endif
186
+
187
+    #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
188
+
189
+      ABL_VAR float zoffset;
190
+
191
+    #elif ENABLED(AUTO_BED_LEVELING_LINEAR)
192
+
193
+      ABL_VAR int indexIntoAB[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
194
+
195
+      ABL_VAR float eqnAMatrix[GRID_MAX_POINTS * 3], // "A" matrix of the linear system of equations
196
+                    eqnBVector[GRID_MAX_POINTS],     // "B" vector of Z points
197
+                    mean;
198
+    #endif
199
+
200
+  #elif ENABLED(AUTO_BED_LEVELING_3POINT)
201
+
202
+    int constexpr abl2 = 3;
203
+
204
+    // Probe at 3 arbitrary points
205
+    ABL_VAR vector_3 points[3] = {
206
+      vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, 0),
207
+      vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, 0),
208
+      vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, 0)
209
+    };
210
+
211
+  #endif // AUTO_BED_LEVELING_3POINT
212
+
213
+  #if ENABLED(AUTO_BED_LEVELING_LINEAR)
214
+    struct linear_fit_data lsf_results;
215
+    incremental_LSF_reset(&lsf_results);
216
+  #endif
217
+
218
+  /**
219
+   * On the initial G29 fetch command parameters.
220
+   */
221
+  if (!g29_in_progress) {
222
+
223
+    #if ENABLED(PROBE_MANUALLY) || ENABLED(AUTO_BED_LEVELING_LINEAR)
224
+      abl_probe_index = -1;
225
+    #endif
226
+
227
+    abl_should_enable = leveling_is_active();
228
+
229
+    #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
230
+
231
+      if (parser.seen('W')) {
232
+        if (!leveling_is_valid()) {
233
+          SERIAL_ERROR_START();
234
+          SERIAL_ERRORLNPGM("No bilinear grid");
235
+          return;
236
+        }
237
+
238
+        const float z = parser.floatval('Z', RAW_CURRENT_POSITION(Z));
239
+        if (!WITHIN(z, -10, 10)) {
240
+          SERIAL_ERROR_START();
241
+          SERIAL_ERRORLNPGM("Bad Z value");
242
+          return;
243
+        }
244
+
245
+        const float x = parser.floatval('X', NAN),
246
+                    y = parser.floatval('Y', NAN);
247
+        int8_t i = parser.byteval('I', -1),
248
+               j = parser.byteval('J', -1);
249
+
250
+        if (!isnan(x) && !isnan(y)) {
251
+          // Get nearest i / j from x / y
252
+          i = (x - LOGICAL_X_POSITION(bilinear_start[X_AXIS]) + 0.5 * xGridSpacing) / xGridSpacing;
253
+          j = (y - LOGICAL_Y_POSITION(bilinear_start[Y_AXIS]) + 0.5 * yGridSpacing) / yGridSpacing;
254
+          i = constrain(i, 0, GRID_MAX_POINTS_X - 1);
255
+          j = constrain(j, 0, GRID_MAX_POINTS_Y - 1);
256
+        }
257
+        if (WITHIN(i, 0, GRID_MAX_POINTS_X - 1) && WITHIN(j, 0, GRID_MAX_POINTS_Y)) {
258
+          set_bed_leveling_enabled(false);
259
+          z_values[i][j] = z;
260
+          #if ENABLED(ABL_BILINEAR_SUBDIVISION)
261
+            bed_level_virt_interpolate();
262
+          #endif
263
+          set_bed_leveling_enabled(abl_should_enable);
264
+        }
265
+        return;
266
+      } // parser.seen('W')
267
+
268
+    #endif
269
+
270
+    #if HAS_LEVELING
271
+
272
+      // Jettison bed leveling data
273
+      if (parser.seen('J')) {
274
+        reset_bed_level();
275
+        return;
276
+      }
277
+
278
+    #endif
279
+
280
+    verbose_level = parser.intval('V');
281
+    if (!WITHIN(verbose_level, 0, 4)) {
282
+      SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4).");
283
+      return;
284
+    }
285
+
286
+    dryrun = parser.boolval('D')
287
+      #if ENABLED(PROBE_MANUALLY)
288
+        || no_action
289
+      #endif
290
+    ;
291
+
292
+    #if ENABLED(AUTO_BED_LEVELING_LINEAR)
293
+
294
+      do_topography_map = verbose_level > 2 || parser.boolval('T');
295
+
296
+      // X and Y specify points in each direction, overriding the default
297
+      // These values may be saved with the completed mesh
298
+      abl_grid_points_x = parser.intval('X', GRID_MAX_POINTS_X);
299
+      abl_grid_points_y = parser.intval('Y', GRID_MAX_POINTS_Y);
300
+      if (parser.seenval('P')) abl_grid_points_x = abl_grid_points_y = parser.value_int();
301
+
302
+      if (abl_grid_points_x < 2 || abl_grid_points_y < 2) {
303
+        SERIAL_PROTOCOLLNPGM("?Number of probe points is implausible (2 minimum).");
304
+        return;
305
+      }
306
+
307
+      abl2 = abl_grid_points_x * abl_grid_points_y;
308
+      mean = 0;
309
+
310
+    #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
311
+
312
+      zoffset = parser.linearval('Z');
313
+
314
+    #endif
315
+
316
+    #if ABL_GRID
317
+
318
+      xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_SPEED));
319
+
320
+      left_probe_bed_position = (int)parser.linearval('L', LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION));
321
+      right_probe_bed_position = (int)parser.linearval('R', LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION));
322
+      front_probe_bed_position = (int)parser.linearval('F', LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION));
323
+      back_probe_bed_position = (int)parser.linearval('B', LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION));
324
+
325
+      const bool left_out_l = left_probe_bed_position < LOGICAL_X_POSITION(MIN_PROBE_X),
326
+                 left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE),
327
+                 right_out_r = right_probe_bed_position > LOGICAL_X_POSITION(MAX_PROBE_X),
328
+                 right_out = right_out_r || right_probe_bed_position < left_probe_bed_position + MIN_PROBE_EDGE,
329
+                 front_out_f = front_probe_bed_position < LOGICAL_Y_POSITION(MIN_PROBE_Y),
330
+                 front_out = front_out_f || front_probe_bed_position > back_probe_bed_position - (MIN_PROBE_EDGE),
331
+                 back_out_b = back_probe_bed_position > LOGICAL_Y_POSITION(MAX_PROBE_Y),
332
+                 back_out = back_out_b || back_probe_bed_position < front_probe_bed_position + MIN_PROBE_EDGE;
333
+
334
+      if (left_out || right_out || front_out || back_out) {
335
+        if (left_out) {
336
+          out_of_range_error(PSTR("(L)eft"));
337
+          left_probe_bed_position = left_out_l ? LOGICAL_X_POSITION(MIN_PROBE_X) : right_probe_bed_position - (MIN_PROBE_EDGE);
338
+        }
339
+        if (right_out) {
340
+          out_of_range_error(PSTR("(R)ight"));
341
+          right_probe_bed_position = right_out_r ? LOGICAL_Y_POSITION(MAX_PROBE_X) : left_probe_bed_position + MIN_PROBE_EDGE;
342
+        }
343
+        if (front_out) {
344
+          out_of_range_error(PSTR("(F)ront"));
345
+          front_probe_bed_position = front_out_f ? LOGICAL_Y_POSITION(MIN_PROBE_Y) : back_probe_bed_position - (MIN_PROBE_EDGE);
346
+        }
347
+        if (back_out) {
348
+          out_of_range_error(PSTR("(B)ack"));
349
+          back_probe_bed_position = back_out_b ? LOGICAL_Y_POSITION(MAX_PROBE_Y) : front_probe_bed_position + MIN_PROBE_EDGE;
350
+        }
351
+        return;
352
+      }
353
+
354
+      // probe at the points of a lattice grid
355
+      xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (abl_grid_points_x - 1);
356
+      yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (abl_grid_points_y - 1);
357
+
358
+    #endif // ABL_GRID
359
+
360
+    if (verbose_level > 0) {
361
+      SERIAL_PROTOCOLLNPGM("G29 Auto Bed Leveling");
362
+      if (dryrun) SERIAL_PROTOCOLLNPGM("Running in DRY-RUN mode");
363
+    }
364
+
365
+    stepper.synchronize();
366
+
367
+    // Disable auto bed leveling during G29
368
+    planner.abl_enabled = false;
369
+
370
+    if (!dryrun) {
371
+      // Re-orient the current position without leveling
372
+      // based on where the steppers are positioned.
373
+      set_current_from_steppers_for_axis(ALL_AXES);
374
+
375
+      // Sync the planner to where the steppers stopped
376
+      SYNC_PLAN_POSITION_KINEMATIC();
377
+    }
378
+
379
+    #if HAS_BED_PROBE
380
+      // Deploy the probe. Probe will raise if needed.
381
+      if (DEPLOY_PROBE()) {
382
+        planner.abl_enabled = abl_should_enable;
383
+        return;
384
+      }
385
+    #endif
386
+
387
+    if (!faux) setup_for_endstop_or_probe_move();
388
+
389
+    #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
390
+
391
+      #if ENABLED(PROBE_MANUALLY)
392
+        if (!no_action)
393
+      #endif
394
+      if ( xGridSpacing != bilinear_grid_spacing[X_AXIS]
395
+        || yGridSpacing != bilinear_grid_spacing[Y_AXIS]
396
+        || left_probe_bed_position != LOGICAL_X_POSITION(bilinear_start[X_AXIS])
397
+        || front_probe_bed_position != LOGICAL_Y_POSITION(bilinear_start[Y_AXIS])
398
+      ) {
399
+        if (dryrun) {
400
+          // Before reset bed level, re-enable to correct the position
401
+          planner.abl_enabled = abl_should_enable;
402
+        }
403
+        // Reset grid to 0.0 or "not probed". (Also disables ABL)
404
+        reset_bed_level();
405
+
406
+        // Initialize a grid with the given dimensions
407
+        bilinear_grid_spacing[X_AXIS] = xGridSpacing;
408
+        bilinear_grid_spacing[Y_AXIS] = yGridSpacing;
409
+        bilinear_start[X_AXIS] = RAW_X_POSITION(left_probe_bed_position);
410
+        bilinear_start[Y_AXIS] = RAW_Y_POSITION(front_probe_bed_position);
411
+
412
+        // Can't re-enable (on error) until the new grid is written
413
+        abl_should_enable = false;
414
+      }
415
+
416
+    #endif // AUTO_BED_LEVELING_BILINEAR
417
+
418
+    #if ENABLED(AUTO_BED_LEVELING_3POINT)
419
+
420
+      #if ENABLED(DEBUG_LEVELING_FEATURE)
421
+        if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> 3-point Leveling");
422
+      #endif
423
+
424
+      // Probe at 3 arbitrary points
425
+      points[0].z = points[1].z = points[2].z = 0;
426
+
427
+    #endif // AUTO_BED_LEVELING_3POINT
428
+
429
+  } // !g29_in_progress
430
+
431
+  #if ENABLED(PROBE_MANUALLY)
432
+
433
+    // For manual probing, get the next index to probe now.
434
+    // On the first probe this will be incremented to 0.
435
+    if (!no_action) {
436
+      ++abl_probe_index;
437
+      g29_in_progress = true;
438
+    }
439
+
440
+    // Abort current G29 procedure, go back to idle state
441
+    if (seenA && g29_in_progress) {
442
+      SERIAL_PROTOCOLLNPGM("Manual G29 aborted");
443
+      #if HAS_SOFTWARE_ENDSTOPS
444
+        soft_endstops_enabled = enable_soft_endstops;
445
+      #endif
446
+      planner.abl_enabled = abl_should_enable;
447
+      g29_in_progress = false;
448
+      #if ENABLED(LCD_BED_LEVELING)
449
+        lcd_wait_for_move = false;
450
+      #endif
451
+    }
452
+
453
+    // Query G29 status
454
+    if (verbose_level || seenQ) {
455
+      SERIAL_PROTOCOLPGM("Manual G29 ");
456
+      if (g29_in_progress) {
457
+        SERIAL_PROTOCOLPAIR("point ", min(abl_probe_index + 1, abl2));
458
+        SERIAL_PROTOCOLLNPAIR(" of ", abl2);
459
+      }
460
+      else
461
+        SERIAL_PROTOCOLLNPGM("idle");
462
+    }
463
+
464
+    if (no_action) return;
465
+
466
+    if (abl_probe_index == 0) {
467
+      // For the initial G29 save software endstop state
468
+      #if HAS_SOFTWARE_ENDSTOPS
469
+        enable_soft_endstops = soft_endstops_enabled;
470
+      #endif
471
+    }
472
+    else {
473
+      // For G29 after adjusting Z.
474
+      // Save the previous Z before going to the next point
475
+      measured_z = current_position[Z_AXIS];
476
+
477
+      #if ENABLED(AUTO_BED_LEVELING_LINEAR)
478
+
479
+        mean += measured_z;
480
+        eqnBVector[abl_probe_index] = measured_z;
481
+        eqnAMatrix[abl_probe_index + 0 * abl2] = xProbe;
482
+        eqnAMatrix[abl_probe_index + 1 * abl2] = yProbe;
483
+        eqnAMatrix[abl_probe_index + 2 * abl2] = 1;
484
+
485
+        incremental_LSF(&lsf_results, xProbe, yProbe, measured_z);
486
+
487
+      #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
488
+
489
+        z_values[xCount][yCount] = measured_z + zoffset;
490
+
491
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
492
+          if (DEBUGGING(LEVELING)) {
493
+            SERIAL_PROTOCOLPAIR("Save X", xCount);
494
+            SERIAL_PROTOCOLPAIR(" Y", yCount);
495
+            SERIAL_PROTOCOLLNPAIR(" Z", measured_z + zoffset);
496
+          }
497
+        #endif
498
+
499
+      #elif ENABLED(AUTO_BED_LEVELING_3POINT)
500
+
501
+        points[abl_probe_index].z = measured_z;
502
+
503
+      #endif
504
+    }
505
+
506
+    //
507
+    // If there's another point to sample, move there with optional lift.
508
+    //
509
+
510
+    #if ABL_GRID
511
+
512
+      // Skip any unreachable points
513
+      while (abl_probe_index < abl2) {
514
+
515
+        // Set xCount, yCount based on abl_probe_index, with zig-zag
516
+        PR_OUTER_VAR = abl_probe_index / PR_INNER_END;
517
+        PR_INNER_VAR = abl_probe_index - (PR_OUTER_VAR * PR_INNER_END);
518
+
519
+        // Probe in reverse order for every other row/column
520
+        bool zig = (PR_OUTER_VAR & 1); // != ((PR_OUTER_END) & 1);
521
+
522
+        if (zig) PR_INNER_VAR = (PR_INNER_END - 1) - PR_INNER_VAR;
523
+
524
+        const float xBase = xCount * xGridSpacing + left_probe_bed_position,
525
+                    yBase = yCount * yGridSpacing + front_probe_bed_position;
526
+
527
+        xProbe = FLOOR(xBase + (xBase < 0 ? 0 : 0.5));
528
+        yProbe = FLOOR(yBase + (yBase < 0 ? 0 : 0.5));
529
+
530
+        #if ENABLED(AUTO_BED_LEVELING_LINEAR)
531
+          indexIntoAB[xCount][yCount] = abl_probe_index;
532
+        #endif
533
+
534
+        // Keep looping till a reachable point is found
535
+        if (position_is_reachable_xy(xProbe, yProbe)) break;
536
+        ++abl_probe_index;
537
+      }
538
+
539
+      // Is there a next point to move to?
540
+      if (abl_probe_index < abl2) {
541
+        _manual_goto_xy(xProbe, yProbe); // Can be used here too!
542
+        #if HAS_SOFTWARE_ENDSTOPS
543
+          // Disable software endstops to allow manual adjustment
544
+          // If G29 is not completed, they will not be re-enabled
545
+          soft_endstops_enabled = false;
546
+        #endif
547
+        return;
548
+      }
549
+      else {
550
+
551
+        // Leveling done! Fall through to G29 finishing code below
552
+
553
+        SERIAL_PROTOCOLLNPGM("Grid probing done.");
554
+
555
+        // Re-enable software endstops, if needed
556
+        #if HAS_SOFTWARE_ENDSTOPS
557
+          soft_endstops_enabled = enable_soft_endstops;
558
+        #endif
559
+      }
560
+
561
+    #elif ENABLED(AUTO_BED_LEVELING_3POINT)
562
+
563
+      // Probe at 3 arbitrary points
564
+      if (abl_probe_index < 3) {
565
+        xProbe = LOGICAL_X_POSITION(points[abl_probe_index].x);
566
+        yProbe = LOGICAL_Y_POSITION(points[abl_probe_index].y);
567
+        #if HAS_SOFTWARE_ENDSTOPS
568
+          // Disable software endstops to allow manual adjustment
569
+          // If G29 is not completed, they will not be re-enabled
570
+          soft_endstops_enabled = false;
571
+        #endif
572
+        return;
573
+      }
574
+      else {
575
+
576
+        SERIAL_PROTOCOLLNPGM("3-point probing done.");
577
+
578
+        // Re-enable software endstops, if needed
579
+        #if HAS_SOFTWARE_ENDSTOPS
580
+          soft_endstops_enabled = enable_soft_endstops;
581
+        #endif
582
+
583
+        if (!dryrun) {
584
+          vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal();
585
+          if (planeNormal.z < 0) {
586
+            planeNormal.x *= -1;
587
+            planeNormal.y *= -1;
588
+            planeNormal.z *= -1;
589
+          }
590
+          planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
591
+
592
+          // Can't re-enable (on error) until the new grid is written
593
+          abl_should_enable = false;
594
+        }
595
+
596
+      }
597
+
598
+    #endif // AUTO_BED_LEVELING_3POINT
599
+
600
+  #else // !PROBE_MANUALLY
601
+  {
602
+    const bool stow_probe_after_each = parser.boolval('E');
603
+
604
+    measured_z = 0;
605
+
606
+    #if ABL_GRID
607
+
608
+      bool zig = PR_OUTER_END & 1;  // Always end at RIGHT and BACK_PROBE_BED_POSITION
609
+
610
+      // Outer loop is Y with PROBE_Y_FIRST disabled
611
+      for (uint8_t PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_END && !isnan(measured_z); PR_OUTER_VAR++) {
612
+
613
+        int8_t inStart, inStop, inInc;
614
+
615
+        if (zig) { // away from origin
616
+          inStart = 0;
617
+          inStop = PR_INNER_END;
618
+          inInc = 1;
619
+        }
620
+        else {     // towards origin
621
+          inStart = PR_INNER_END - 1;
622
+          inStop = -1;
623
+          inInc = -1;
624
+        }
625
+
626
+        zig ^= true; // zag
627
+
628
+        // Inner loop is Y with PROBE_Y_FIRST enabled
629
+        for (int8_t PR_INNER_VAR = inStart; PR_INNER_VAR != inStop; PR_INNER_VAR += inInc) {
630
+
631
+          float xBase = left_probe_bed_position + xGridSpacing * xCount,
632
+                yBase = front_probe_bed_position + yGridSpacing * yCount;
633
+
634
+          xProbe = FLOOR(xBase + (xBase < 0 ? 0 : 0.5));
635
+          yProbe = FLOOR(yBase + (yBase < 0 ? 0 : 0.5));
636
+
637
+          #if ENABLED(AUTO_BED_LEVELING_LINEAR)
638
+            indexIntoAB[xCount][yCount] = ++abl_probe_index; // 0...
639
+          #endif
640
+
641
+          #if IS_KINEMATIC
642
+            // Avoid probing outside the round or hexagonal area
643
+            if (!position_is_reachable_by_probe_xy(xProbe, yProbe)) continue;
644
+          #endif
645
+
646
+          measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level);
647
+
648
+          if (isnan(measured_z)) {
649
+            planner.abl_enabled = abl_should_enable;
650
+            break;
651
+          }
652
+
653
+          #if ENABLED(AUTO_BED_LEVELING_LINEAR)
654
+
655
+            mean += measured_z;
656
+            eqnBVector[abl_probe_index] = measured_z;
657
+            eqnAMatrix[abl_probe_index + 0 * abl2] = xProbe;
658
+            eqnAMatrix[abl_probe_index + 1 * abl2] = yProbe;
659
+            eqnAMatrix[abl_probe_index + 2 * abl2] = 1;
660
+
661
+            incremental_LSF(&lsf_results, xProbe, yProbe, measured_z);
662
+
663
+          #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
664
+
665
+            z_values[xCount][yCount] = measured_z + zoffset;
666
+
667
+          #endif
668
+
669
+          abl_should_enable = false;
670
+          idle();
671
+
672
+        } // inner
673
+      } // outer
674
+
675
+    #elif ENABLED(AUTO_BED_LEVELING_3POINT)
676
+
677
+      // Probe at 3 arbitrary points
678
+
679
+      for (uint8_t i = 0; i < 3; ++i) {
680
+        // Retain the last probe position
681
+        xProbe = LOGICAL_X_POSITION(points[i].x);
682
+        yProbe = LOGICAL_Y_POSITION(points[i].y);
683
+        measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level);
684
+        if (isnan(measured_z)) {
685
+          planner.abl_enabled = abl_should_enable;
686
+          break;
687
+        }
688
+        points[i].z = measured_z;
689
+      }
690
+
691
+      if (!dryrun && !isnan(measured_z)) {
692
+        vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal();
693
+        if (planeNormal.z < 0) {
694
+          planeNormal.x *= -1;
695
+          planeNormal.y *= -1;
696
+          planeNormal.z *= -1;
697
+        }
698
+        planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
699
+
700
+        // Can't re-enable (on error) until the new grid is written
701
+        abl_should_enable = false;
702
+      }
703
+
704
+    #endif // AUTO_BED_LEVELING_3POINT
705
+
706
+    // Raise to _Z_CLEARANCE_DEPLOY_PROBE. Stow the probe.
707
+    if (STOW_PROBE()) {
708
+      planner.abl_enabled = abl_should_enable;
709
+      measured_z = NAN;
710
+    }
711
+  }
712
+  #endif // !PROBE_MANUALLY
713
+
714
+  //
715
+  // G29 Finishing Code
716
+  //
717
+  // Unless this is a dry run, auto bed leveling will
718
+  // definitely be enabled after this point.
719
+  //
720
+  // If code above wants to continue leveling, it should
721
+  // return or loop before this point.
722
+  //
723
+
724
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
725
+    if (DEBUGGING(LEVELING)) DEBUG_POS("> probing complete", current_position);
726
+  #endif
727
+
728
+  #if ENABLED(PROBE_MANUALLY)
729
+    g29_in_progress = false;
730
+    #if ENABLED(LCD_BED_LEVELING)
731
+      lcd_wait_for_move = false;
732
+    #endif
733
+  #endif
734
+
735
+  // Calculate leveling, print reports, correct the position
736
+  if (!isnan(measured_z)) {
737
+    #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
738
+
739
+      if (!dryrun) extrapolate_unprobed_bed_level();
740
+      print_bilinear_leveling_grid();
741
+
742
+      refresh_bed_level();
743
+
744
+      #if ENABLED(ABL_BILINEAR_SUBDIVISION)
745
+        print_bilinear_leveling_grid_virt();
746
+      #endif
747
+
748
+    #elif ENABLED(AUTO_BED_LEVELING_LINEAR)
749
+
750
+      // For LINEAR leveling calculate matrix, print reports, correct the position
751
+
752
+      /**
753
+       * solve the plane equation ax + by + d = z
754
+       * A is the matrix with rows [x y 1] for all the probed points
755
+       * B is the vector of the Z positions
756
+       * the normal vector to the plane is formed by the coefficients of the
757
+       * plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0
758
+       * so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
759
+       */
760
+      float plane_equation_coefficients[3];
761
+
762
+      finish_incremental_LSF(&lsf_results);
763
+      plane_equation_coefficients[0] = -lsf_results.A;  // We should be able to eliminate the '-' on these three lines and down below
764
+      plane_equation_coefficients[1] = -lsf_results.B;  // but that is not yet tested.
765
+      plane_equation_coefficients[2] = -lsf_results.D;
766
+
767
+      mean /= abl2;
768
+
769
+      if (verbose_level) {
770
+        SERIAL_PROTOCOLPGM("Eqn coefficients: a: ");
771
+        SERIAL_PROTOCOL_F(plane_equation_coefficients[0], 8);
772
+        SERIAL_PROTOCOLPGM(" b: ");
773
+        SERIAL_PROTOCOL_F(plane_equation_coefficients[1], 8);
774
+        SERIAL_PROTOCOLPGM(" d: ");
775
+        SERIAL_PROTOCOL_F(plane_equation_coefficients[2], 8);
776
+        SERIAL_EOL();
777
+        if (verbose_level > 2) {
778
+          SERIAL_PROTOCOLPGM("Mean of sampled points: ");
779
+          SERIAL_PROTOCOL_F(mean, 8);
780
+          SERIAL_EOL();
781
+        }
782
+      }
783
+
784
+      // Create the matrix but don't correct the position yet
785
+      if (!dryrun)
786
+        planner.bed_level_matrix = matrix_3x3::create_look_at(
787
+          vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1)    // We can eliminate the '-' here and up above
788
+        );
789
+
790
+      // Show the Topography map if enabled
791
+      if (do_topography_map) {
792
+
793
+        SERIAL_PROTOCOLLNPGM("\nBed Height Topography:\n"
794
+                               "   +--- BACK --+\n"
795
+                               "   |           |\n"
796
+                               " L |    (+)    | R\n"
797
+                               " E |           | I\n"
798
+                               " F | (-) N (+) | G\n"
799
+                               " T |           | H\n"
800
+                               "   |    (-)    | T\n"
801
+                               "   |           |\n"
802
+                               "   O-- FRONT --+\n"
803
+                               " (0,0)");
804
+
805
+        float min_diff = 999;
806
+
807
+        for (int8_t yy = abl_grid_points_y - 1; yy >= 0; yy--) {
808
+          for (uint8_t xx = 0; xx < abl_grid_points_x; xx++) {
809
+            int ind = indexIntoAB[xx][yy];
810
+            float diff = eqnBVector[ind] - mean,
811
+                  x_tmp = eqnAMatrix[ind + 0 * abl2],
812
+                  y_tmp = eqnAMatrix[ind + 1 * abl2],
813
+                  z_tmp = 0;
814
+
815
+            apply_rotation_xyz(planner.bed_level_matrix, x_tmp, y_tmp, z_tmp);
816
+
817
+            NOMORE(min_diff, eqnBVector[ind] - z_tmp);
818
+
819
+            if (diff >= 0.0)
820
+              SERIAL_PROTOCOLPGM(" +");   // Include + for column alignment
821
+            else
822
+              SERIAL_PROTOCOLCHAR(' ');
823
+            SERIAL_PROTOCOL_F(diff, 5);
824
+          } // xx
825
+          SERIAL_EOL();
826
+        } // yy
827
+        SERIAL_EOL();
828
+
829
+        if (verbose_level > 3) {
830
+          SERIAL_PROTOCOLLNPGM("\nCorrected Bed Height vs. Bed Topology:");
831
+
832
+          for (int8_t yy = abl_grid_points_y - 1; yy >= 0; yy--) {
833
+            for (uint8_t xx = 0; xx < abl_grid_points_x; xx++) {
834
+              int ind = indexIntoAB[xx][yy];
835
+              float x_tmp = eqnAMatrix[ind + 0 * abl2],
836
+                    y_tmp = eqnAMatrix[ind + 1 * abl2],
837
+                    z_tmp = 0;
838
+
839
+              apply_rotation_xyz(planner.bed_level_matrix, x_tmp, y_tmp, z_tmp);
840
+
841
+              float diff = eqnBVector[ind] - z_tmp - min_diff;
842
+              if (diff >= 0.0)
843
+                SERIAL_PROTOCOLPGM(" +");
844
+              // Include + for column alignment
845
+              else
846
+                SERIAL_PROTOCOLCHAR(' ');
847
+              SERIAL_PROTOCOL_F(diff, 5);
848
+            } // xx
849
+            SERIAL_EOL();
850
+          } // yy
851
+          SERIAL_EOL();
852
+        }
853
+      } //do_topography_map
854
+
855
+    #endif // AUTO_BED_LEVELING_LINEAR
856
+
857
+    #if ABL_PLANAR
858
+
859
+      // For LINEAR and 3POINT leveling correct the current position
860
+
861
+      if (verbose_level > 0)
862
+        planner.bed_level_matrix.debug(PSTR("\n\nBed Level Correction Matrix:"));
863
+
864
+      if (!dryrun) {
865
+        //
866
+        // Correct the current XYZ position based on the tilted plane.
867
+        //
868
+
869
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
870
+          if (DEBUGGING(LEVELING)) DEBUG_POS("G29 uncorrected XYZ", current_position);
871
+        #endif
872
+
873
+        float converted[XYZ];
874
+        COPY(converted, current_position);
875
+
876
+        planner.abl_enabled = true;
877
+        planner.unapply_leveling(converted); // use conversion machinery
878
+        planner.abl_enabled = false;
879
+
880
+        // Use the last measured distance to the bed, if possible
881
+        if ( NEAR(current_position[X_AXIS], xProbe - (X_PROBE_OFFSET_FROM_EXTRUDER))
882
+          && NEAR(current_position[Y_AXIS], yProbe - (Y_PROBE_OFFSET_FROM_EXTRUDER))
883
+        ) {
884
+          const float simple_z = current_position[Z_AXIS] - measured_z;
885
+          #if ENABLED(DEBUG_LEVELING_FEATURE)
886
+            if (DEBUGGING(LEVELING)) {
887
+              SERIAL_ECHOPAIR("Z from Probe:", simple_z);
888
+              SERIAL_ECHOPAIR("  Matrix:", converted[Z_AXIS]);
889
+              SERIAL_ECHOLNPAIR("  Discrepancy:", simple_z - converted[Z_AXIS]);
890
+            }
891
+          #endif
892
+          converted[Z_AXIS] = simple_z;
893
+        }
894
+
895
+        // The rotated XY and corrected Z are now current_position
896
+        COPY(current_position, converted);
897
+
898
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
899
+          if (DEBUGGING(LEVELING)) DEBUG_POS("G29 corrected XYZ", current_position);
900
+        #endif
901
+      }
902
+
903
+    #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
904
+
905
+      if (!dryrun) {
906
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
907
+          if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("G29 uncorrected Z:", current_position[Z_AXIS]);
908
+        #endif
909
+
910
+        // Unapply the offset because it is going to be immediately applied
911
+        // and cause compensation movement in Z
912
+        current_position[Z_AXIS] -= bilinear_z_offset(current_position);
913
+
914
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
915
+          if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR(" corrected Z:", current_position[Z_AXIS]);
916
+        #endif
917
+      }
918
+
919
+    #endif // ABL_PLANAR
920
+
921
+    #ifdef Z_PROBE_END_SCRIPT
922
+      #if ENABLED(DEBUG_LEVELING_FEATURE)
923
+        if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
924
+      #endif
925
+      enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT));
926
+      stepper.synchronize();
927
+    #endif
928
+
929
+    // Auto Bed Leveling is complete! Enable if possible.
930
+    planner.abl_enabled = dryrun ? abl_should_enable : true;
931
+  } // !isnan(measured_z)
932
+
933
+  // Restore state after probing
934
+  if (!faux) clean_up_after_endstop_or_probe_move();
935
+
936
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
937
+    if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< gcode_G29");
938
+  #endif
939
+
940
+  report_current_position();
941
+
942
+  KEEPALIVE_STATE(IN_HANDLER);
943
+
944
+  if (planner.abl_enabled)
945
+    SYNC_PLAN_POSITION_KINEMATIC();
946
+}

+ 200
- 0
Marlin/src/gcode/calibrate/G29-mbl.h View File

@@ -0,0 +1,200 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../libs/buzzer.h"
24
+#include "../../lcd/ultralcd.h"
25
+
26
+// Save 130 bytes with non-duplication of PSTR
27
+void echo_not_entered() { SERIAL_PROTOCOLLNPGM(" not entered."); }
28
+
29
+void mbl_mesh_report() {
30
+  SERIAL_PROTOCOLLNPGM("Num X,Y: " STRINGIFY(GRID_MAX_POINTS_X) "," STRINGIFY(GRID_MAX_POINTS_Y));
31
+  SERIAL_PROTOCOLPGM("Z offset: "); SERIAL_PROTOCOL_F(mbl.z_offset, 5);
32
+  SERIAL_PROTOCOLLNPGM("\nMeasured points:");
33
+  print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 5,
34
+    [](const uint8_t ix, const uint8_t iy) { return mbl.z_values[ix][iy]; }
35
+  );
36
+}
37
+
38
+void mesh_probing_done() {
39
+  mbl.set_has_mesh(true);
40
+  home_all_axes();
41
+  set_bed_leveling_enabled(true);
42
+  #if ENABLED(MESH_G28_REST_ORIGIN)
43
+    current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS);
44
+    set_destination_to_current();
45
+    line_to_destination(homing_feedrate(Z_AXIS));
46
+    stepper.synchronize();
47
+  #endif
48
+}
49
+
50
+/**
51
+ * G29: Mesh-based Z probe, probes a grid and produces a
52
+ *      mesh to compensate for variable bed height
53
+ *
54
+ * Parameters With MESH_BED_LEVELING:
55
+ *
56
+ *  S0              Produce a mesh report
57
+ *  S1              Start probing mesh points
58
+ *  S2              Probe the next mesh point
59
+ *  S3 Xn Yn Zn.nn  Manually modify a single point
60
+ *  S4 Zn.nn        Set z offset. Positive away from bed, negative closer to bed.
61
+ *  S5              Reset and disable mesh
62
+ *
63
+ * The S0 report the points as below
64
+ *
65
+ *  +----> X-axis  1-n
66
+ *  |
67
+ *  |
68
+ *  v Y-axis  1-n
69
+ *
70
+ */
71
+void gcode_G29() {
72
+
73
+  static int mbl_probe_index = -1;
74
+  #if HAS_SOFTWARE_ENDSTOPS
75
+    static bool enable_soft_endstops;
76
+  #endif
77
+
78
+  const MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
79
+  if (!WITHIN(state, 0, 5)) {
80
+    SERIAL_PROTOCOLLNPGM("S out of range (0-5).");
81
+    return;
82
+  }
83
+
84
+  int8_t px, py;
85
+
86
+  switch (state) {
87
+    case MeshReport:
88
+      if (leveling_is_valid()) {
89
+        SERIAL_PROTOCOLLNPAIR("State: ", leveling_is_active() ? MSG_ON : MSG_OFF);
90
+        mbl_mesh_report();
91
+      }
92
+      else
93
+        SERIAL_PROTOCOLLNPGM("Mesh bed leveling has no data.");
94
+      break;
95
+
96
+    case MeshStart:
97
+      mbl.reset();
98
+      mbl_probe_index = 0;
99
+      enqueue_and_echo_commands_P(PSTR("G28\nG29 S2"));
100
+      break;
101
+
102
+    case MeshNext:
103
+      if (mbl_probe_index < 0) {
104
+        SERIAL_PROTOCOLLNPGM("Start mesh probing with \"G29 S1\" first.");
105
+        return;
106
+      }
107
+      // For each G29 S2...
108
+      if (mbl_probe_index == 0) {
109
+        #if HAS_SOFTWARE_ENDSTOPS
110
+          // For the initial G29 S2 save software endstop state
111
+          enable_soft_endstops = soft_endstops_enabled;
112
+        #endif
113
+      }
114
+      else {
115
+        // For G29 S2 after adjusting Z.
116
+        mbl.set_zigzag_z(mbl_probe_index - 1, current_position[Z_AXIS]);
117
+        #if HAS_SOFTWARE_ENDSTOPS
118
+          soft_endstops_enabled = enable_soft_endstops;
119
+        #endif
120
+      }
121
+      // If there's another point to sample, move there with optional lift.
122
+      if (mbl_probe_index < GRID_MAX_POINTS) {
123
+        mbl.zigzag(mbl_probe_index, px, py);
124
+        _manual_goto_xy(mbl.index_to_xpos[px], mbl.index_to_ypos[py]);
125
+
126
+        #if HAS_SOFTWARE_ENDSTOPS
127
+          // Disable software endstops to allow manual adjustment
128
+          // If G29 is not completed, they will not be re-enabled
129
+          soft_endstops_enabled = false;
130
+        #endif
131
+
132
+        mbl_probe_index++;
133
+      }
134
+      else {
135
+        // One last "return to the bed" (as originally coded) at completion
136
+        current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT;
137
+        line_to_current_position();
138
+        stepper.synchronize();
139
+
140
+        // After recording the last point, activate home and activate
141
+        mbl_probe_index = -1;
142
+        SERIAL_PROTOCOLLNPGM("Mesh probing done.");
143
+        BUZZ(100, 659);
144
+        BUZZ(100, 698);
145
+        mesh_probing_done();
146
+      }
147
+      break;
148
+
149
+    case MeshSet:
150
+      if (parser.seenval('X')) {
151
+        px = parser.value_int() - 1;
152
+        if (!WITHIN(px, 0, GRID_MAX_POINTS_X - 1)) {
153
+          SERIAL_PROTOCOLLNPGM("X out of range (1-" STRINGIFY(GRID_MAX_POINTS_X) ").");
154
+          return;
155
+        }
156
+      }
157
+      else {
158
+        SERIAL_CHAR('X'); echo_not_entered();
159
+        return;
160
+      }
161
+
162
+      if (parser.seenval('Y')) {
163
+        py = parser.value_int() - 1;
164
+        if (!WITHIN(py, 0, GRID_MAX_POINTS_Y - 1)) {
165
+          SERIAL_PROTOCOLLNPGM("Y out of range (1-" STRINGIFY(GRID_MAX_POINTS_Y) ").");
166
+          return;
167
+        }
168
+      }
169
+      else {
170
+        SERIAL_CHAR('Y'); echo_not_entered();
171
+        return;
172
+      }
173
+
174
+      if (parser.seenval('Z')) {
175
+        mbl.z_values[px][py] = parser.value_linear_units();
176
+      }
177
+      else {
178
+        SERIAL_CHAR('Z'); echo_not_entered();
179
+        return;
180
+      }
181
+      break;
182
+
183
+    case MeshSetZOffset:
184
+      if (parser.seenval('Z')) {
185
+        mbl.z_offset = parser.value_linear_units();
186
+      }
187
+      else {
188
+        SERIAL_CHAR('Z'); echo_not_entered();
189
+        return;
190
+      }
191
+      break;
192
+
193
+    case MeshReset:
194
+      reset_bed_level();
195
+      break;
196
+
197
+  } // switch(state)
198
+
199
+  report_current_position();
200
+}

+ 27
- 0
Marlin/src/gcode/calibrate/G29-ubl.h View File

@@ -0,0 +1,27 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+void gcode_G29() {
24
+
25
+  ubl.G29();
26
+
27
+}

+ 65
- 0
Marlin/src/gcode/calibrate/G29.h View File

@@ -0,0 +1,65 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY)
24
+
25
+  #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING)
26
+    extern bool lcd_wait_for_move;
27
+  #endif
28
+
29
+  inline void _manual_goto_xy(const float &x, const float &y) {
30
+    const float old_feedrate_mm_s = feedrate_mm_s;
31
+    #if MANUAL_PROBE_HEIGHT > 0
32
+      const float prev_z = current_position[Z_AXIS];
33
+      feedrate_mm_s = homing_feedrate(Z_AXIS);
34
+      current_position[Z_AXIS] = LOGICAL_Z_POSITION(MANUAL_PROBE_HEIGHT);
35
+      line_to_current_position();
36
+    #endif
37
+
38
+    feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED);
39
+    current_position[X_AXIS] = LOGICAL_X_POSITION(x);
40
+    current_position[Y_AXIS] = LOGICAL_Y_POSITION(y);
41
+    line_to_current_position();
42
+
43
+    #if MANUAL_PROBE_HEIGHT > 0
44
+      feedrate_mm_s = homing_feedrate(Z_AXIS);
45
+      current_position[Z_AXIS] = prev_z; // move back to the previous Z.
46
+      line_to_current_position();
47
+    #endif
48
+
49
+    feedrate_mm_s = old_feedrate_mm_s;
50
+    stepper.synchronize();
51
+
52
+    #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING)
53
+      lcd_wait_for_move = false;
54
+    #endif
55
+  }
56
+
57
+#endif
58
+
59
+#if ENABLED(MESH_BED_LEVELING)
60
+  #include "G29-mbl.h"
61
+#elif ENABLED(AUTO_BED_LEVELING_UBL)
62
+  #include "G29-ubl.h"
63
+#elif HAS_ABL
64
+  #include "G29-abl.h"
65
+#endif

+ 451
- 0
Marlin/src/gcode/calibrate/G33.h View File

@@ -0,0 +1,451 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "common.h"
24
+
25
+#if HOTENDS > 1
26
+  #include "../control/tool_change.h"
27
+#endif
28
+
29
+/**
30
+ * G33 - Delta '1-4-7-point' Auto-Calibration
31
+ *       Calibrate height, endstops, delta radius, and tower angles.
32
+ *
33
+ * Parameters:
34
+ *
35
+ *   Pn  Number of probe points:
36
+ *
37
+ *      P1     Probe center and set height only.
38
+ *      P2     Probe center and towers. Set height, endstops, and delta radius.
39
+ *      P3     Probe all positions: center, towers and opposite towers. Set all.
40
+ *      P4-P7  Probe all positions at different locations and average them.
41
+ *
42
+ *   T0  Don't calibrate tower angle corrections
43
+ *
44
+ *   Cn.nn Calibration precision; when omitted calibrates to maximum precision
45
+ *
46
+ *   Fn  Force to run at least n iterations and takes the best result
47
+ *
48
+ *   Vn  Verbose level:
49
+ *
50
+ *      V0  Dry-run mode. Report settings and probe results. No calibration.
51
+ *      V1  Report settings
52
+ *      V2  Report settings and probe results
53
+ *
54
+ *   E   Engage the probe for each point
55
+ */
56
+
57
+void print_signed_float(const char * const prefix, const float &f) {
58
+  SERIAL_PROTOCOLPGM("  ");
59
+  serialprintPGM(prefix);
60
+  SERIAL_PROTOCOLCHAR(':');
61
+  if (f >= 0) SERIAL_CHAR('+');
62
+  SERIAL_PROTOCOL_F(f, 2);
63
+}
64
+
65
+inline void print_G33_settings(const bool end_stops, const bool tower_angles){ // TODO echo these to LCD ???
66
+  SERIAL_PROTOCOLPAIR(".Height:", DELTA_HEIGHT + home_offset[Z_AXIS]);
67
+  if (end_stops) {
68
+    print_signed_float(PSTR("  Ex"), endstop_adj[A_AXIS]);
69
+    print_signed_float(PSTR("Ey"), endstop_adj[B_AXIS]);
70
+    print_signed_float(PSTR("Ez"), endstop_adj[C_AXIS]);
71
+    SERIAL_PROTOCOLPAIR("    Radius:", delta_radius);
72
+  }
73
+  SERIAL_EOL();
74
+  if (tower_angles) {
75
+    SERIAL_PROTOCOLPGM(".Tower angle :  ");
76
+    print_signed_float(PSTR("Tx"), delta_tower_angle_trim[A_AXIS]);
77
+    print_signed_float(PSTR("Ty"), delta_tower_angle_trim[B_AXIS]);
78
+    SERIAL_PROTOCOLLNPGM("  Tz:+0.00");
79
+  }
80
+}
81
+
82
+void G33_cleanup(
83
+  #if HOTENDS > 1
84
+    const uint8_t old_tool_index
85
+  #endif
86
+) {
87
+  #if ENABLED(DELTA_HOME_TO_SAFE_ZONE)
88
+    do_blocking_move_to_z(delta_clip_start_height);
89
+  #endif
90
+  STOW_PROBE();
91
+  clean_up_after_endstop_or_probe_move();
92
+  #if HOTENDS > 1
93
+    tool_change(old_tool_index, 0, true);
94
+  #endif
95
+}
96
+
97
+void gcode_G33() {
98
+
99
+  const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS);
100
+  if (!WITHIN(probe_points, 1, 7)) {
101
+    SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (1-7).");
102
+    return;
103
+  }
104
+
105
+  const int8_t verbose_level = parser.byteval('V', 1);
106
+  if (!WITHIN(verbose_level, 0, 2)) {
107
+    SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-2).");
108
+    return;
109
+  }
110
+
111
+  const float calibration_precision = parser.floatval('C');
112
+  if (calibration_precision < 0) {
113
+    SERIAL_PROTOCOLLNPGM("?(C)alibration precision is implausible (>0).");
114
+    return;
115
+  }
116
+
117
+  const int8_t force_iterations = parser.intval('F', 0);
118
+  if (!WITHIN(force_iterations, 0, 30)) {
119
+    SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (0-30).");
120
+    return;
121
+  }
122
+
123
+  const bool towers_set           = parser.boolval('T', true),
124
+             stow_after_each      = parser.boolval('E'),
125
+             _1p_calibration      = probe_points == 1,
126
+             _4p_calibration      = probe_points == 2,
127
+             _4p_towers_points    = _4p_calibration && towers_set,
128
+             _4p_opposite_points  = _4p_calibration && !towers_set,
129
+             _7p_calibration      = probe_points >= 3,
130
+             _7p_half_circle      = probe_points == 3,
131
+             _7p_double_circle    = probe_points == 5,
132
+             _7p_triple_circle    = probe_points == 6,
133
+             _7p_quadruple_circle = probe_points == 7,
134
+             _7p_multi_circle     = _7p_double_circle || _7p_triple_circle || _7p_quadruple_circle,
135
+             _7p_intermed_points  = _7p_calibration && !_7p_half_circle;
136
+  const static char save_message[] PROGMEM = "Save with M500 and/or copy to Configuration.h";
137
+  const float dx = (X_PROBE_OFFSET_FROM_EXTRUDER),
138
+              dy = (Y_PROBE_OFFSET_FROM_EXTRUDER);
139
+  int8_t iterations = 0;
140
+  float test_precision,
141
+        zero_std_dev = (verbose_level ? 999.0 : 0.0), // 0.0 in dry-run mode : forced end
142
+        zero_std_dev_old = zero_std_dev,
143
+        zero_std_dev_min = zero_std_dev,
144
+        e_old[XYZ] = {
145
+          endstop_adj[A_AXIS],
146
+          endstop_adj[B_AXIS],
147
+          endstop_adj[C_AXIS]
148
+        },
149
+        dr_old = delta_radius,
150
+        zh_old = home_offset[Z_AXIS],
151
+        alpha_old = delta_tower_angle_trim[A_AXIS],
152
+        beta_old = delta_tower_angle_trim[B_AXIS];
153
+
154
+  if (!_1p_calibration) {  // test if the outer radius is reachable
155
+    const float circles = (_7p_quadruple_circle ? 1.5 :
156
+                           _7p_triple_circle    ? 1.0 :
157
+                           _7p_double_circle    ? 0.5 : 0),
158
+                r = (1 + circles * 0.1) * delta_calibration_radius;
159
+    for (uint8_t axis = 1; axis < 13; ++axis) {
160
+      const float a = RADIANS(180 + 30 * axis);
161
+      if (!position_is_reachable_xy(cos(a) * r, sin(a) * r)) {
162
+        SERIAL_PROTOCOLLNPGM("?(M665 B)ed radius is implausible.");
163
+        return;
164
+      }
165
+    }
166
+  }
167
+  SERIAL_PROTOCOLLNPGM("G33 Auto Calibrate");
168
+
169
+  stepper.synchronize();
170
+  #if HAS_LEVELING
171
+    reset_bed_level(); // After calibration bed-level data is no longer valid
172
+  #endif
173
+
174
+  #if HOTENDS > 1
175
+    const uint8_t old_tool_index = active_extruder;
176
+    tool_change(0, 0, true);
177
+    #define G33_CLEANUP() G33_cleanup(old_tool_index)
178
+  #else
179
+    #define G33_CLEANUP() G33_cleanup()
180
+  #endif
181
+
182
+  setup_for_endstop_or_probe_move();
183
+  endstops.enable(true);
184
+  if (!home_delta())
185
+    return;
186
+  endstops.not_homing();
187
+
188
+  // print settings
189
+
190
+  const char *checkingac = PSTR("Checking... AC"); // TODO: Make translatable string
191
+  serialprintPGM(checkingac);
192
+  if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)");
193
+  SERIAL_EOL();
194
+  lcd_setstatusPGM(checkingac);
195
+
196
+  print_G33_settings(!_1p_calibration, _7p_calibration && towers_set);
197
+
198
+  #if DISABLED(PROBE_MANUALLY)
199
+    const float measured_z = probe_pt(dx, dy, stow_after_each, 1, false); // 1st probe to set height
200
+    if (isnan(measured_z)) return G33_CLEANUP();
201
+    home_offset[Z_AXIS] -= measured_z;
202
+  #endif
203
+
204
+  do {
205
+
206
+    float z_at_pt[13] = { 0.0 };
207
+
208
+    test_precision = zero_std_dev_old != 999.0 ? (zero_std_dev + zero_std_dev_old) / 2 : zero_std_dev;
209
+
210
+    iterations++;
211
+
212
+    // Probe the points
213
+
214
+    if (!_7p_half_circle && !_7p_triple_circle) { // probe the center
215
+      #if ENABLED(PROBE_MANUALLY)
216
+        z_at_pt[0] += lcd_probe_pt(0, 0);
217
+      #else
218
+        z_at_pt[0] += probe_pt(dx, dy, stow_after_each, 1, false);
219
+        if (isnan(z_at_pt[0])) return G33_CLEANUP();
220
+      #endif
221
+    }
222
+    if (_7p_calibration) { // probe extra center points
223
+      for (int8_t axis = _7p_multi_circle ? 11 : 9; axis > 0; axis -= _7p_multi_circle ? 2 : 4) {
224
+        const float a = RADIANS(180 + 30 * axis), r = delta_calibration_radius * 0.1;
225
+        #if ENABLED(PROBE_MANUALLY)
226
+          z_at_pt[0] += lcd_probe_pt(cos(a) * r, sin(a) * r);
227
+        #else
228
+          z_at_pt[0] += probe_pt(cos(a) * r + dx, sin(a) * r + dy, stow_after_each, 1);
229
+          if (isnan(z_at_pt[0])) return G33_CLEANUP();
230
+        #endif
231
+      }
232
+      z_at_pt[0] /= float(_7p_double_circle ? 7 : probe_points);
233
+    }
234
+    if (!_1p_calibration) {  // probe the radius
235
+      bool zig_zag = true;
236
+      const uint8_t start = _4p_opposite_points ? 3 : 1,
237
+                     step = _4p_calibration ? 4 : _7p_half_circle ? 2 : 1;
238
+      for (uint8_t axis = start; axis < 13; axis += step) {
239
+        const float zigadd = (zig_zag ? 0.5 : 0.0),
240
+                    offset_circles = _7p_quadruple_circle ? zigadd + 1.0 :
241
+                                     _7p_triple_circle    ? zigadd + 0.5 :
242
+                                     _7p_double_circle    ? zigadd : 0;
243
+        for (float circles = -offset_circles ; circles <= offset_circles; circles++) {
244
+          const float a = RADIANS(180 + 30 * axis),
245
+                      r = delta_calibration_radius * (1 + circles * (zig_zag ? 0.1 : -0.1));
246
+          #if ENABLED(PROBE_MANUALLY)
247
+            z_at_pt[axis] += lcd_probe_pt(cos(a) * r, sin(a) * r);
248
+          #else
249
+            z_at_pt[axis] += probe_pt(cos(a) * r + dx, sin(a) * r + dy, stow_after_each, 1);
250
+            if (isnan(z_at_pt[axis])) return G33_CLEANUP();
251
+          #endif
252
+        }
253
+        zig_zag = !zig_zag;
254
+        z_at_pt[axis] /= (2 * offset_circles + 1);
255
+      }
256
+    }
257
+    if (_7p_intermed_points) // average intermediates to tower and opposites
258
+      for (uint8_t axis = 1; axis < 13; axis += 2)
259
+        z_at_pt[axis] = (z_at_pt[axis] + (z_at_pt[axis + 1] + z_at_pt[(axis + 10) % 12 + 1]) / 2.0) / 2.0;
260
+
261
+    float S1 = z_at_pt[0],
262
+          S2 = sq(z_at_pt[0]);
263
+    int16_t N = 1;
264
+    if (!_1p_calibration) // std dev from zero plane
265
+      for (uint8_t axis = (_4p_opposite_points ? 3 : 1); axis < 13; axis += (_4p_calibration ? 4 : 2)) {
266
+        S1 += z_at_pt[axis];
267
+        S2 += sq(z_at_pt[axis]);
268
+        N++;
269
+      }
270
+    zero_std_dev_old = zero_std_dev;
271
+    zero_std_dev = round(SQRT(S2 / N) * 1000.0) / 1000.0 + 0.00001;
272
+
273
+    // Solve matrices
274
+
275
+    if ((zero_std_dev < test_precision && zero_std_dev > calibration_precision) || iterations <= force_iterations) {
276
+      if (zero_std_dev < zero_std_dev_min) {
277
+        COPY(e_old, endstop_adj);
278
+        dr_old = delta_radius;
279
+        zh_old = home_offset[Z_AXIS];
280
+        alpha_old = delta_tower_angle_trim[A_AXIS];
281
+        beta_old = delta_tower_angle_trim[B_AXIS];
282
+      }
283
+
284
+      float e_delta[XYZ] = { 0.0 }, r_delta = 0.0, t_alpha = 0.0, t_beta = 0.0;
285
+      const float r_diff = delta_radius - delta_calibration_radius,
286
+                  h_factor = 1.00 + r_diff * 0.001,                          //1.02 for r_diff = 20mm
287
+                  r_factor = -(1.75 + 0.005 * r_diff + 0.001 * sq(r_diff)),  //2.25 for r_diff = 20mm
288
+                  a_factor = 100.0 / delta_calibration_radius;               //1.25 for cal_rd = 80mm
289
+
290
+      #define ZP(N,I) ((N) * z_at_pt[I])
291
+      #define Z1000(I) ZP(1.00, I)
292
+      #define Z1050(I) ZP(h_factor, I)
293
+      #define Z0700(I) ZP(h_factor * 2.0 / 3.00, I)
294
+      #define Z0350(I) ZP(h_factor / 3.00, I)
295
+      #define Z0175(I) ZP(h_factor / 6.00, I)
296
+      #define Z2250(I) ZP(r_factor, I)
297
+      #define Z0750(I) ZP(r_factor / 3.00, I)
298
+      #define Z0375(I) ZP(r_factor / 6.00, I)
299
+      #define Z0444(I) ZP(a_factor * 4.0 / 9.0, I)
300
+      #define Z0888(I) ZP(a_factor * 8.0 / 9.0, I)
301
+
302
+      #if ENABLED(PROBE_MANUALLY)
303
+        test_precision = 0.00; // forced end
304
+      #endif
305
+
306
+      switch (probe_points) {
307
+        case 1:
308
+          test_precision = 0.00; // forced end
309
+          LOOP_XYZ(i) e_delta[i] = Z1000(0);
310
+          break;
311
+
312
+        case 2:
313
+          if (towers_set) {
314
+            e_delta[X_AXIS] = Z1050(0) + Z0700(1) - Z0350(5) - Z0350(9);
315
+            e_delta[Y_AXIS] = Z1050(0) - Z0350(1) + Z0700(5) - Z0350(9);
316
+            e_delta[Z_AXIS] = Z1050(0) - Z0350(1) - Z0350(5) + Z0700(9);
317
+            r_delta         = Z2250(0) - Z0750(1) - Z0750(5) - Z0750(9);
318
+          }
319
+          else {
320
+            e_delta[X_AXIS] = Z1050(0) - Z0700(7) + Z0350(11) + Z0350(3);
321
+            e_delta[Y_AXIS] = Z1050(0) + Z0350(7) - Z0700(11) + Z0350(3);
322
+            e_delta[Z_AXIS] = Z1050(0) + Z0350(7) + Z0350(11) - Z0700(3);
323
+            r_delta         = Z2250(0) - Z0750(7) - Z0750(11) - Z0750(3);
324
+          }
325
+          break;
326
+
327
+        default:
328
+          e_delta[X_AXIS] = Z1050(0) + Z0350(1) - Z0175(5) - Z0175(9) - Z0350(7) + Z0175(11) + Z0175(3);
329
+          e_delta[Y_AXIS] = Z1050(0) - Z0175(1) + Z0350(5) - Z0175(9) + Z0175(7) - Z0350(11) + Z0175(3);
330
+          e_delta[Z_AXIS] = Z1050(0) - Z0175(1) - Z0175(5) + Z0350(9) + Z0175(7) + Z0175(11) - Z0350(3);
331
+          r_delta         = Z2250(0) - Z0375(1) - Z0375(5) - Z0375(9) - Z0375(7) - Z0375(11) - Z0375(3);
332
+
333
+          if (towers_set) {
334
+            t_alpha = Z0444(1) - Z0888(5) + Z0444(9) + Z0444(7) - Z0888(11) + Z0444(3);
335
+            t_beta  = Z0888(1) - Z0444(5) - Z0444(9) + Z0888(7) - Z0444(11) - Z0444(3);
336
+          }
337
+          break;
338
+      }
339
+
340
+      LOOP_XYZ(axis) endstop_adj[axis] += e_delta[axis];
341
+      delta_radius += r_delta;
342
+      delta_tower_angle_trim[A_AXIS] += t_alpha;
343
+      delta_tower_angle_trim[B_AXIS] += t_beta;
344
+
345
+      // adjust delta_height and endstops by the max amount
346
+      const float z_temp = MAX3(endstop_adj[A_AXIS], endstop_adj[B_AXIS], endstop_adj[C_AXIS]);
347
+      home_offset[Z_AXIS] -= z_temp;
348
+      LOOP_XYZ(i) endstop_adj[i] -= z_temp;
349
+
350
+      recalc_delta_settings(delta_radius, delta_diagonal_rod);
351
+    }
352
+    else if (zero_std_dev >= test_precision) {   // step one back
353
+      COPY(endstop_adj, e_old);
354
+      delta_radius = dr_old;
355
+      home_offset[Z_AXIS] = zh_old;
356
+      delta_tower_angle_trim[A_AXIS] = alpha_old;
357
+      delta_tower_angle_trim[B_AXIS] = beta_old;
358
+
359
+      recalc_delta_settings(delta_radius, delta_diagonal_rod);
360
+    }
361
+    NOMORE(zero_std_dev_min, zero_std_dev);
362
+
363
+    // print report
364
+
365
+    if (verbose_level != 1) {
366
+      SERIAL_PROTOCOLPGM(".    ");
367
+      print_signed_float(PSTR("c"), z_at_pt[0]);
368
+      if (_4p_towers_points || _7p_calibration) {
369
+        print_signed_float(PSTR("   x"), z_at_pt[1]);
370
+        print_signed_float(PSTR(" y"), z_at_pt[5]);
371
+        print_signed_float(PSTR(" z"), z_at_pt[9]);
372
+      }
373
+      if (!_4p_opposite_points) SERIAL_EOL();
374
+      if ((_4p_opposite_points) || _7p_calibration) {
375
+        if (_7p_calibration) {
376
+          SERIAL_CHAR('.');
377
+          SERIAL_PROTOCOL_SP(13);
378
+        }
379
+        print_signed_float(PSTR("  yz"), z_at_pt[7]);
380
+        print_signed_float(PSTR("zx"), z_at_pt[11]);
381
+        print_signed_float(PSTR("xy"), z_at_pt[3]);
382
+        SERIAL_EOL();
383
+      }
384
+    }
385
+    if (verbose_level != 0) {                                    // !dry run
386
+      if ((zero_std_dev >= test_precision || zero_std_dev <= calibration_precision) && iterations > force_iterations) {  // end iterations
387
+        SERIAL_PROTOCOLPGM("Calibration OK");
388
+        SERIAL_PROTOCOL_SP(36);
389
+        #if DISABLED(PROBE_MANUALLY)
390
+          if (zero_std_dev >= test_precision && !_1p_calibration)
391
+            SERIAL_PROTOCOLPGM("rolling back.");
392
+          else
393
+        #endif
394
+          {
395
+            SERIAL_PROTOCOLPGM("std dev:");
396
+            SERIAL_PROTOCOL_F(zero_std_dev_min, 3);
397
+          }
398
+        SERIAL_EOL();
399
+        char mess[21];
400
+        sprintf_P(mess, PSTR("Calibration sd:"));
401
+        if (zero_std_dev_min < 1)
402
+          sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev_min * 1000.0));
403
+        else
404
+          sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev_min));
405
+        lcd_setstatus(mess);
406
+        print_G33_settings(!_1p_calibration, _7p_calibration && towers_set);
407
+        serialprintPGM(save_message);
408
+        SERIAL_EOL();
409
+      }
410
+      else {                                                     // !end iterations
411
+        char mess[15];
412
+        if (iterations < 31)
413
+          sprintf_P(mess, PSTR("Iteration : %02i"), (int)iterations);
414
+        else
415
+          sprintf_P(mess, PSTR("No convergence"));
416
+        SERIAL_PROTOCOL(mess);
417
+        SERIAL_PROTOCOL_SP(36);
418
+        SERIAL_PROTOCOLPGM("std dev:");
419
+        SERIAL_PROTOCOL_F(zero_std_dev, 3);
420
+        SERIAL_EOL();
421
+        lcd_setstatus(mess);
422
+        print_G33_settings(!_1p_calibration, _7p_calibration && towers_set);
423
+      }
424
+    }
425
+    else {                                                       // dry run
426
+      const char *enddryrun = PSTR("End DRY-RUN");
427
+      serialprintPGM(enddryrun);
428
+      SERIAL_PROTOCOL_SP(39);
429
+      SERIAL_PROTOCOLPGM("std dev:");
430
+      SERIAL_PROTOCOL_F(zero_std_dev, 3);
431
+      SERIAL_EOL();
432
+
433
+      char mess[21];
434
+      sprintf_P(mess, enddryrun);
435
+      sprintf_P(&mess[11], PSTR(" sd:"));
436
+      if (zero_std_dev < 1)
437
+        sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev * 1000.0));
438
+      else
439
+        sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev));
440
+      lcd_setstatus(mess);
441
+    }
442
+
443
+    endstops.enable(true);
444
+    home_delta();
445
+    endstops.not_homing();
446
+
447
+  }
448
+  while ((zero_std_dev < test_precision && zero_std_dev > calibration_precision && iterations < 31) || iterations <= force_iterations);
449
+
450
+  G33_CLEANUP();
451
+}

Marlin/M100_Free_Mem_Chk.cpp → Marlin/src/gcode/calibrate/M100.h View File

@@ -20,6 +20,8 @@
20 20
  *
21 21
  */
22 22
 
23
+#include "../../libs/hex_print_routines.h"
24
+
23 25
 /**
24 26
  * M100 Free Memory Watcher
25 27
  *
@@ -48,10 +50,6 @@
48 50
 #define M100_FREE_MEMORY_DUMPER     // Enable for the `M110 D` Dump sub-command
49 51
 #define M100_FREE_MEMORY_CORRUPTOR  // Enable for the `M100 C` Corrupt sub-command
50 52
 
51
-#include "MarlinConfig.h"
52
-
53
-#if ENABLED(M100_FREE_MEMORY_WATCHER)
54
-
55 53
 #define TEST_BYTE ((char) 0xE5)
56 54
 
57 55
 extern char command_queue[BUFSIZE][MAX_CMD_SIZE];
@@ -60,16 +58,11 @@ extern char* __brkval;
60 58
 extern size_t  __heap_start, __heap_end, __flp;
61 59
 extern char __bss_end;
62 60
 
63
-#include "Marlin.h"
64
-#include "gcode.h"
65
-#include "hex_print_routines.h"
66
-
67 61
 //
68 62
 // Utility functions
69 63
 //
70 64
 
71 65
 #define END_OF_HEAP() (__brkval ? __brkval : &__bss_end)
72
-int check_for_free_memory_corruption(const char * const title);
73 66
 
74 67
 // Location of a variable on its stack frame. Returns a value above
75 68
 // the stack (once the function returns to the caller).
@@ -137,18 +130,79 @@ int16_t count_test_bytes(const char * const ptr) {
137 130
     }
138 131
   }
139 132
 
140
-void M100_dump_routine(const char * const title, const char *start, const char *end) {
141
-  SERIAL_ECHOLN(title);
142
-  //
143
-  // Round the start and end locations to produce full lines of output
144
-  //
145
-  start = (char*)((uint16_t) start & 0xFFF0);
146
-  end   = (char*)((uint16_t) end   | 0x000F);
147
-  dump_free_memory(start, end);
148
-}
133
+  void M100_dump_routine(const char * const title, const char *start, const char *end) {
134
+    SERIAL_ECHOLN(title);
135
+    //
136
+    // Round the start and end locations to produce full lines of output
137
+    //
138
+    start = (char*)((uint16_t) start & 0xFFF0);
139
+    end   = (char*)((uint16_t) end   | 0x000F);
140
+    dump_free_memory(start, end);
141
+  }
149 142
 
150 143
 #endif // M100_FREE_MEMORY_DUMPER
151 144
 
145
+int check_for_free_memory_corruption(const char * const title) {
146
+  SERIAL_ECHO(title);
147
+
148
+  char *ptr = END_OF_HEAP(), *sp = top_of_stack();
149
+  int n = sp - ptr;
150
+
151
+  SERIAL_ECHOPAIR("\nfmc() n=", n);
152
+  SERIAL_ECHOPAIR("\n&__brkval: ", hex_address(&__brkval));
153
+  SERIAL_ECHOPAIR("=",             hex_address(__brkval));
154
+  SERIAL_ECHOPAIR("\n__bss_end: ", hex_address(&__bss_end));
155
+  SERIAL_ECHOPAIR(" sp=",          hex_address(sp));
156
+
157
+  if (sp < ptr)  {
158
+    SERIAL_ECHOPGM(" sp < Heap ");
159
+    // SET_INPUT_PULLUP(63);           // if the developer has a switch wired up to their controller board
160
+    // safe_delay(5);                  // this code can be enabled to pause the display as soon as the
161
+    // while ( READ(63))               // malfunction is detected.   It is currently defaulting to a switch
162
+    //   idle();                       // being on pin-63 which is unassigend and available on most controller
163
+    // safe_delay(20);                 // boards.
164
+    // while ( !READ(63))
165
+    //   idle();
166
+    safe_delay(20);
167
+    #if ENABLED(M100_FREE_MEMORY_DUMPER)
168
+      M100_dump_routine("   Memory corruption detected with sp<Heap\n", (char*)0x1B80, (char*)0x21FF);
169
+    #endif
170
+  }
171
+
172
+  // Scan through the range looking for the biggest block of 0xE5's we can find
173
+  int block_cnt = 0;
174
+  for (int i = 0; i < n; i++) {
175
+    if (ptr[i] == TEST_BYTE) {
176
+      int16_t j = count_test_bytes(ptr + i);
177
+      if (j > 8) {
178
+        // SERIAL_ECHOPAIR("Found ", j);
179
+        // SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(ptr + i));
180
+        i += j;
181
+        block_cnt++;
182
+        SERIAL_ECHOPAIR(" (", block_cnt);
183
+        SERIAL_ECHOPAIR(") found=", j);
184
+        SERIAL_ECHOPGM("   ");
185
+      }
186
+    }
187
+  }
188
+  SERIAL_ECHOPAIR("  block_found=", block_cnt);
189
+
190
+  if (block_cnt != 1 || __brkval != 0x0000)
191
+    SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
192
+
193
+  if (block_cnt == 0)       // Make sure the special case of no free blocks shows up as an
194
+    block_cnt = -1;         // error to the calling code!
195
+
196
+  SERIAL_ECHOPGM(" return=");
197
+  if (block_cnt == 1) {
198
+    SERIAL_CHAR('0');       // if the block_cnt is 1, nothing has broken up the free memory
199
+    SERIAL_EOL();             // area and it is appropriate to say 'no corruption'.
200
+    return 0;
201
+  }
202
+  SERIAL_ECHOLNPGM("true");
203
+  return block_cnt;
204
+}
205
+
152 206
 /**
153 207
  * M100 F
154 208
  *  Return the number of free bytes in the memory pool,
@@ -266,68 +320,3 @@ void gcode_M100() {
266 320
 
267 321
   #endif
268 322
 }
269
-
270
-int check_for_free_memory_corruption(const char * const title) {
271
-  SERIAL_ECHO(title);
272
-
273
-  char *ptr = END_OF_HEAP(), *sp = top_of_stack();
274
-  int n = sp - ptr;
275
-
276
-  SERIAL_ECHOPAIR("\nfmc() n=", n);
277
-  SERIAL_ECHOPAIR("\n&__brkval: ", hex_address(&__brkval));
278
-  SERIAL_ECHOPAIR("=",             hex_address(__brkval));
279
-  SERIAL_ECHOPAIR("\n__bss_end: ", hex_address(&__bss_end));
280
-  SERIAL_ECHOPAIR(" sp=",          hex_address(sp));
281
-
282
-  if (sp < ptr)  {
283
-    SERIAL_ECHOPGM(" sp < Heap ");
284
-    // SET_INPUT_PULLUP(63);           // if the developer has a switch wired up to their controller board
285
-    // safe_delay(5);                  // this code can be enabled to pause the display as soon as the
286
-    // while ( READ(63))               // malfunction is detected.   It is currently defaulting to a switch
287
-    //   idle();                       // being on pin-63 which is unassigend and available on most controller
288
-    // safe_delay(20);                 // boards.
289
-    // while ( !READ(63))
290
-    //   idle();
291
-    safe_delay(20);
292
-    #ifdef M100_FREE_MEMORY_DUMPER
293
-      M100_dump_routine("   Memory corruption detected with sp<Heap\n", (char*)0x1B80, (char*)0x21FF);
294
-    #endif
295
-  }
296
-
297
-  // Scan through the range looking for the biggest block of 0xE5's we can find
298
-  int block_cnt = 0;
299
-  for (int i = 0; i < n; i++) {
300
-    if (ptr[i] == TEST_BYTE) {
301
-      int16_t j = count_test_bytes(ptr + i);
302
-      if (j > 8) {
303
-        // SERIAL_ECHOPAIR("Found ", j);
304
-        // SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(ptr + i));
305
-        i += j;
306
-        block_cnt++;
307
-        SERIAL_ECHOPAIR(" (", block_cnt);
308
-        SERIAL_ECHOPAIR(") found=", j);
309
-        SERIAL_ECHOPGM("   ");
310
-      }
311
-    }
312
-  }
313
-  SERIAL_ECHOPAIR("  block_found=", block_cnt);
314
-
315
-  if (block_cnt != 1 || __brkval != 0x0000)
316
-    SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
317
-
318
-  if (block_cnt == 0)       // Make sure the special case of no free blocks shows up as an
319
-    block_cnt = -1;         // error to the calling code!
320
-
321
-  SERIAL_ECHOPGM(" return=");
322
-  if (block_cnt == 1) {
323
-    SERIAL_CHAR('0');       // if the block_cnt is 1, nothing has broken up the free memory
324
-    SERIAL_EOL();             // area and it is appropriate to say 'no corruption'.
325
-    return 0;
326
-  }
327
-  SERIAL_ECHOLNPGM("true");
328
-  return block_cnt;
329
-}
330
-
331
-#endif // M100_FREE_MEMORY_WATCHER
332
-
333
-

+ 121
- 0
Marlin/src/gcode/calibrate/M420.h View File

@@ -0,0 +1,121 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M420: Enable/Disable Bed Leveling and/or set the Z fade height.
25
+ *
26
+ *   S[bool]   Turns leveling on or off
27
+ *   Z[height] Sets the Z fade height (0 or none to disable)
28
+ *   V[bool]   Verbose - Print the leveling grid
29
+ *
30
+ * With AUTO_BED_LEVELING_UBL only:
31
+ *
32
+ *   L[index]  Load UBL mesh from index (0 is default)
33
+ */
34
+void gcode_M420() {
35
+
36
+  #if ENABLED(AUTO_BED_LEVELING_UBL)
37
+
38
+    // L to load a mesh from the EEPROM
39
+    if (parser.seen('L')) {
40
+
41
+      #if ENABLED(EEPROM_SETTINGS)
42
+        const int8_t storage_slot = parser.has_value() ? parser.value_int() : ubl.state.storage_slot;
43
+        const int16_t a = settings.calc_num_meshes();
44
+
45
+        if (!a) {
46
+          SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
47
+          return;
48
+        }
49
+
50
+        if (!WITHIN(storage_slot, 0, a - 1)) {
51
+          SERIAL_PROTOCOLLNPGM("?Invalid storage slot.");
52
+          SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1);
53
+          return;
54
+        }
55
+
56
+        settings.load_mesh(storage_slot);
57
+        ubl.state.storage_slot = storage_slot;
58
+
59
+      #else
60
+
61
+        SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
62
+        return;
63
+
64
+      #endif
65
+    }
66
+
67
+    // L to load a mesh from the EEPROM
68
+    if (parser.seen('L') || parser.seen('V')) {
69
+      ubl.display_map(0);  // Currently only supports one map type
70
+      SERIAL_ECHOLNPAIR("UBL_MESH_VALID = ", UBL_MESH_VALID);
71
+      SERIAL_ECHOLNPAIR("ubl.state.storage_slot = ", ubl.state.storage_slot);
72
+    }
73
+
74
+  #endif // AUTO_BED_LEVELING_UBL
75
+
76
+  // V to print the matrix or mesh
77
+  if (parser.seen('V')) {
78
+    #if ABL_PLANAR
79
+      planner.bed_level_matrix.debug(PSTR("Bed Level Correction Matrix:"));
80
+    #else
81
+      if (leveling_is_valid()) {
82
+        #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
83
+          print_bilinear_leveling_grid();
84
+          #if ENABLED(ABL_BILINEAR_SUBDIVISION)
85
+            print_bilinear_leveling_grid_virt();
86
+          #endif
87
+        #elif ENABLED(MESH_BED_LEVELING)
88
+          SERIAL_ECHOLNPGM("Mesh Bed Level data:");
89
+          mbl_mesh_report();
90
+        #endif
91
+      }
92
+    #endif
93
+  }
94
+
95
+  const bool to_enable = parser.boolval('S');
96
+  if (parser.seen('S'))
97
+    set_bed_leveling_enabled(to_enable);
98
+
99
+  #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
100
+    if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units());
101
+  #endif
102
+
103
+  const bool new_status = leveling_is_active();
104
+
105
+  if (to_enable && !new_status) {
106
+    SERIAL_ERROR_START();
107
+    SERIAL_ERRORLNPGM(MSG_ERR_M420_FAILED);
108
+  }
109
+
110
+  SERIAL_ECHO_START();
111
+  SERIAL_ECHOLNPAIR("Bed Leveling ", new_status ? MSG_ON : MSG_OFF);
112
+
113
+  #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
114
+    SERIAL_ECHO_START();
115
+    SERIAL_ECHOPGM("Fade Height ");
116
+    if (planner.z_fade_height > 0.0)
117
+      SERIAL_ECHOLN(planner.z_fade_height);
118
+    else
119
+      SERIAL_ECHOLNPGM(MSG_OFF);
120
+  #endif
121
+}

+ 51
- 0
Marlin/src/gcode/calibrate/M421-abl.h View File

@@ -0,0 +1,51 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M421: Set a single Mesh Bed Leveling Z coordinate
25
+ *
26
+ * Usage:
27
+ *   M421 I<xindex> J<yindex> Z<linear>
28
+ *   M421 I<xindex> J<yindex> Q<offset>
29
+ */
30
+void gcode_M421() {
31
+  int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1);
32
+  const bool hasI = ix >= 0,
33
+             hasJ = iy >= 0,
34
+             hasZ = parser.seen('Z'),
35
+             hasQ = !hasZ && parser.seen('Q');
36
+
37
+  if (!hasI || !hasJ || !(hasZ || hasQ)) {
38
+    SERIAL_ERROR_START();
39
+    SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
40
+  }
41
+  else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1)) {
42
+    SERIAL_ERROR_START();
43
+    SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
44
+  }
45
+  else {
46
+    z_values[ix][iy] = parser.value_linear_units() + (hasQ ? z_values[ix][iy] : 0);
47
+    #if ENABLED(ABL_BILINEAR_SUBDIVISION)
48
+      bed_level_virt_interpolate();
49
+    #endif
50
+  }
51
+}

+ 49
- 0
Marlin/src/gcode/calibrate/M421-mbl.h View File

@@ -0,0 +1,49 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M421: Set a single Mesh Bed Leveling Z coordinate
25
+ *
26
+ * Usage:
27
+ *   M421 X<linear> Y<linear> Z<linear>
28
+ *   M421 X<linear> Y<linear> Q<offset>
29
+ *   M421 I<xindex> J<yindex> Z<linear>
30
+ *   M421 I<xindex> J<yindex> Q<offset>
31
+ */
32
+void gcode_M421() {
33
+  const bool hasX = parser.seen('X'), hasI = parser.seen('I');
34
+  const int8_t ix = hasI ? parser.value_int() : hasX ? mbl.probe_index_x(RAW_X_POSITION(parser.value_linear_units())) : -1;
35
+  const bool hasY = parser.seen('Y'), hasJ = parser.seen('J');
36
+  const int8_t iy = hasJ ? parser.value_int() : hasY ? mbl.probe_index_y(RAW_Y_POSITION(parser.value_linear_units())) : -1;
37
+  const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q');
38
+
39
+  if (int(hasI && hasJ) + int(hasX && hasY) != 1 || !(hasZ || hasQ)) {
40
+    SERIAL_ERROR_START();
41
+    SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
42
+  }
43
+  else if (ix < 0 || iy < 0) {
44
+    SERIAL_ERROR_START();
45
+    SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
46
+  }
47
+  else
48
+    mbl.set_z(ix, iy, parser.value_linear_units() + (hasQ ? mbl.z_values[ix][iy] : 0));
49
+}

+ 56
- 0
Marlin/src/gcode/calibrate/M421-ubl.h View File

@@ -0,0 +1,56 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M421: Set a single Mesh Bed Leveling Z coordinate
25
+ *
26
+ * Usage:
27
+ *   M421 I<xindex> J<yindex> Z<linear>
28
+ *   M421 I<xindex> J<yindex> Q<offset>
29
+ *   M421 C Z<linear>
30
+ *   M421 C Q<offset>
31
+ */
32
+void gcode_M421() {
33
+  int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1);
34
+  const bool hasI = ix >= 0,
35
+             hasJ = iy >= 0,
36
+             hasC = parser.seen('C'),
37
+             hasZ = parser.seen('Z'),
38
+             hasQ = !hasZ && parser.seen('Q');
39
+
40
+  if (hasC) {
41
+    const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false);
42
+    ix = location.x_index;
43
+    iy = location.y_index;
44
+  }
45
+
46
+  if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ)) {
47
+    SERIAL_ERROR_START();
48
+    SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
49
+  }
50
+  else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1)) {
51
+    SERIAL_ERROR_START();
52
+    SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
53
+  }
54
+  else
55
+    ubl.z_values[ix][iy] = parser.value_linear_units() + (hasQ ? ubl.z_values[ix][iy] : 0);
56
+}

+ 273
- 0
Marlin/src/gcode/calibrate/M48.h View File

@@ -0,0 +1,273 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M48: Z probe repeatability measurement function.
25
+ *
26
+ * Usage:
27
+ *   M48 <P#> <X#> <Y#> <V#> <E> <L#>
28
+ *     P = Number of sampled points (4-50, default 10)
29
+ *     X = Sample X position
30
+ *     Y = Sample Y position
31
+ *     V = Verbose level (0-4, default=1)
32
+ *     E = Engage Z probe for each reading
33
+ *     L = Number of legs of movement before probe
34
+ *     S = Schizoid (Or Star if you prefer)
35
+ *
36
+ * This function assumes the bed has been homed.  Specifically, that a G28 command
37
+ * as been issued prior to invoking the M48 Z probe repeatability measurement function.
38
+ * Any information generated by a prior G29 Bed leveling command will be lost and need to be
39
+ * regenerated.
40
+ */
41
+void gcode_M48() {
42
+
43
+  if (axis_unhomed_error()) return;
44
+
45
+  const int8_t verbose_level = parser.byteval('V', 1);
46
+  if (!WITHIN(verbose_level, 0, 4)) {
47
+    SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4).");
48
+    return;
49
+  }
50
+
51
+  if (verbose_level > 0)
52
+    SERIAL_PROTOCOLLNPGM("M48 Z-Probe Repeatability Test");
53
+
54
+  const int8_t n_samples = parser.byteval('P', 10);
55
+  if (!WITHIN(n_samples, 4, 50)) {
56
+    SERIAL_PROTOCOLLNPGM("?Sample size not plausible (4-50).");
57
+    return;
58
+  }
59
+
60
+  const bool stow_probe_after_each = parser.boolval('E');
61
+
62
+  float X_current = current_position[X_AXIS],
63
+        Y_current = current_position[Y_AXIS];
64
+
65
+  const float X_probe_location = parser.linearval('X', X_current + X_PROBE_OFFSET_FROM_EXTRUDER),
66
+              Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER);
67
+
68
+  #if DISABLED(DELTA)
69
+    if (!WITHIN(X_probe_location, LOGICAL_X_POSITION(MIN_PROBE_X), LOGICAL_X_POSITION(MAX_PROBE_X))) {
70
+      out_of_range_error(PSTR("X"));
71
+      return;
72
+    }
73
+    if (!WITHIN(Y_probe_location, LOGICAL_Y_POSITION(MIN_PROBE_Y), LOGICAL_Y_POSITION(MAX_PROBE_Y))) {
74
+      out_of_range_error(PSTR("Y"));
75
+      return;
76
+    }
77
+  #else
78
+    if (!position_is_reachable_by_probe_xy(X_probe_location, Y_probe_location)) {
79
+      SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius.");
80
+      return;
81
+    }
82
+  #endif
83
+
84
+  bool seen_L = parser.seen('L');
85
+  uint8_t n_legs = seen_L ? parser.value_byte() : 0;
86
+  if (n_legs > 15) {
87
+    SERIAL_PROTOCOLLNPGM("?Number of legs in movement not plausible (0-15).");
88
+    return;
89
+  }
90
+  if (n_legs == 1) n_legs = 2;
91
+
92
+  const bool schizoid_flag = parser.boolval('S');
93
+  if (schizoid_flag && !seen_L) n_legs = 7;
94
+
95
+  /**
96
+   * Now get everything to the specified probe point So we can safely do a
97
+   * probe to get us close to the bed.  If the Z-Axis is far from the bed,
98
+   * we don't want to use that as a starting point for each probe.
99
+   */
100
+  if (verbose_level > 2)
101
+    SERIAL_PROTOCOLLNPGM("Positioning the probe...");
102
+
103
+  // Disable bed level correction in M48 because we want the raw data when we probe
104
+
105
+  #if HAS_LEVELING
106
+    const bool was_enabled = leveling_is_active();
107
+    set_bed_leveling_enabled(false);
108
+  #endif
109
+
110
+  setup_for_endstop_or_probe_move();
111
+
112
+  double mean = 0.0, sigma = 0.0, min = 99999.9, max = -99999.9, sample_set[n_samples];
113
+
114
+  // Move to the first point, deploy, and probe
115
+  const float t = probe_pt(X_probe_location, Y_probe_location, stow_probe_after_each, verbose_level);
116
+  bool probing_good = !isnan(t);
117
+
118
+  if (probing_good) {
119
+    randomSeed(millis());
120
+
121
+    for (uint8_t n = 0; n < n_samples; n++) {
122
+      if (n_legs) {
123
+        const int dir = (random(0, 10) > 5.0) ? -1 : 1;  // clockwise or counter clockwise
124
+        float angle = random(0.0, 360.0);
125
+        const float radius = random(
126
+          #if ENABLED(DELTA)
127
+            0.1250000000 * (DELTA_PROBEABLE_RADIUS),
128
+            0.3333333333 * (DELTA_PROBEABLE_RADIUS)
129
+          #else
130
+            5.0, 0.125 * min(X_BED_SIZE, Y_BED_SIZE)
131
+          #endif
132
+        );
133
+
134
+        if (verbose_level > 3) {
135
+          SERIAL_ECHOPAIR("Starting radius: ", radius);
136
+          SERIAL_ECHOPAIR("   angle: ", angle);
137
+          SERIAL_ECHOPGM(" Direction: ");
138
+          if (dir > 0) SERIAL_ECHOPGM("Counter-");
139
+          SERIAL_ECHOLNPGM("Clockwise");
140
+        }
141
+
142
+        for (uint8_t l = 0; l < n_legs - 1; l++) {
143
+          double delta_angle;
144
+
145
+          if (schizoid_flag)
146
+            // The points of a 5 point star are 72 degrees apart.  We need to
147
+            // skip a point and go to the next one on the star.
148
+            delta_angle = dir * 2.0 * 72.0;
149
+
150
+          else
151
+            // If we do this line, we are just trying to move further
152
+            // around the circle.
153
+            delta_angle = dir * (float) random(25, 45);
154
+
155
+          angle += delta_angle;
156
+
157
+          while (angle > 360.0)   // We probably do not need to keep the angle between 0 and 2*PI, but the
158
+            angle -= 360.0;       // Arduino documentation says the trig functions should not be given values
159
+          while (angle < 0.0)     // outside of this range.   It looks like they behave correctly with
160
+            angle += 360.0;       // numbers outside of the range, but just to be safe we clamp them.
161
+
162
+          X_current = X_probe_location - (X_PROBE_OFFSET_FROM_EXTRUDER) + cos(RADIANS(angle)) * radius;
163
+          Y_current = Y_probe_location - (Y_PROBE_OFFSET_FROM_EXTRUDER) + sin(RADIANS(angle)) * radius;
164
+
165
+          #if DISABLED(DELTA)
166
+            X_current = constrain(X_current, X_MIN_POS, X_MAX_POS);
167
+            Y_current = constrain(Y_current, Y_MIN_POS, Y_MAX_POS);
168
+          #else
169
+            // If we have gone out too far, we can do a simple fix and scale the numbers
170
+            // back in closer to the origin.
171
+            while (!position_is_reachable_by_probe_xy(X_current, Y_current)) {
172
+              X_current *= 0.8;
173
+              Y_current *= 0.8;
174
+              if (verbose_level > 3) {
175
+                SERIAL_ECHOPAIR("Pulling point towards center:", X_current);
176
+                SERIAL_ECHOLNPAIR(", ", Y_current);
177
+              }
178
+            }
179
+          #endif
180
+          if (verbose_level > 3) {
181
+            SERIAL_PROTOCOLPGM("Going to:");
182
+            SERIAL_ECHOPAIR(" X", X_current);
183
+            SERIAL_ECHOPAIR(" Y", Y_current);
184
+            SERIAL_ECHOLNPAIR(" Z", current_position[Z_AXIS]);
185
+          }
186
+          do_blocking_move_to_xy(X_current, Y_current);
187
+        } // n_legs loop
188
+      } // n_legs
189
+
190
+      // Probe a single point
191
+      sample_set[n] = probe_pt(X_probe_location, Y_probe_location, stow_probe_after_each, 0);
192
+
193
+      // Break the loop if the probe fails
194
+      probing_good = !isnan(sample_set[n]);
195
+      if (!probing_good) break;
196
+
197
+      /**
198
+       * Get the current mean for the data points we have so far
199
+       */
200
+      double sum = 0.0;
201
+      for (uint8_t j = 0; j <= n; j++) sum += sample_set[j];
202
+      mean = sum / (n + 1);
203
+
204
+      NOMORE(min, sample_set[n]);
205
+      NOLESS(max, sample_set[n]);
206
+
207
+      /**
208
+       * Now, use that mean to calculate the standard deviation for the
209
+       * data points we have so far
210
+       */
211
+      sum = 0.0;
212
+      for (uint8_t j = 0; j <= n; j++)
213
+        sum += sq(sample_set[j] - mean);
214
+
215
+      sigma = SQRT(sum / (n + 1));
216
+      if (verbose_level > 0) {
217
+        if (verbose_level > 1) {
218
+          SERIAL_PROTOCOL(n + 1);
219
+          SERIAL_PROTOCOLPGM(" of ");
220
+          SERIAL_PROTOCOL((int)n_samples);
221
+          SERIAL_PROTOCOLPGM(": z: ");
222
+          SERIAL_PROTOCOL_F(sample_set[n], 3);
223
+          if (verbose_level > 2) {
224
+            SERIAL_PROTOCOLPGM(" mean: ");
225
+            SERIAL_PROTOCOL_F(mean, 4);
226
+            SERIAL_PROTOCOLPGM(" sigma: ");
227
+            SERIAL_PROTOCOL_F(sigma, 6);
228
+            SERIAL_PROTOCOLPGM(" min: ");
229
+            SERIAL_PROTOCOL_F(min, 3);
230
+            SERIAL_PROTOCOLPGM(" max: ");
231
+            SERIAL_PROTOCOL_F(max, 3);
232
+            SERIAL_PROTOCOLPGM(" range: ");
233
+            SERIAL_PROTOCOL_F(max-min, 3);
234
+          }
235
+          SERIAL_EOL();
236
+        }
237
+      }
238
+
239
+    } // n_samples loop
240
+  }
241
+
242
+  STOW_PROBE();
243
+
244
+  if (probing_good) {
245
+    SERIAL_PROTOCOLLNPGM("Finished!");
246
+
247
+    if (verbose_level > 0) {
248
+      SERIAL_PROTOCOLPGM("Mean: ");
249
+      SERIAL_PROTOCOL_F(mean, 6);
250
+      SERIAL_PROTOCOLPGM(" Min: ");
251
+      SERIAL_PROTOCOL_F(min, 3);
252
+      SERIAL_PROTOCOLPGM(" Max: ");
253
+      SERIAL_PROTOCOL_F(max, 3);
254
+      SERIAL_PROTOCOLPGM(" Range: ");
255
+      SERIAL_PROTOCOL_F(max-min, 3);
256
+      SERIAL_EOL();
257
+    }
258
+
259
+    SERIAL_PROTOCOLPGM("Standard Deviation: ");
260
+    SERIAL_PROTOCOL_F(sigma, 6);
261
+    SERIAL_EOL();
262
+    SERIAL_EOL();
263
+  }
264
+
265
+  clean_up_after_endstop_or_probe_move();
266
+
267
+  // Re-enable bed level correction if it had been on
268
+  #if HAS_LEVELING
269
+    set_bed_leveling_enabled(was_enabled);
270
+  #endif
271
+
272
+  report_current_position();
273
+}

+ 27
- 0
Marlin/src/gcode/calibrate/M49.h View File

@@ -0,0 +1,27 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+void gcode_M49() {
24
+  ubl.g26_debug_flag ^= true;
25
+  SERIAL_PROTOCOLPGM("UBL Debug Flag turned ");
26
+  serialprintPGM(ubl.g26_debug_flag ? PSTR("on.") : PSTR("off."));
27
+}

+ 93
- 0
Marlin/src/gcode/calibrate/M665.h View File

@@ -0,0 +1,93 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if ENABLED(DELTA)
24
+
25
+  /**
26
+   * M665: Set delta configurations
27
+   *
28
+   *    H = delta height
29
+   *    L = diagonal rod
30
+   *    R = delta radius
31
+   *    S = segments per second
32
+   *    B = delta calibration radius
33
+   *    X = Alpha (Tower 1) angle trim
34
+   *    Y = Beta (Tower 2) angle trim
35
+   *    Z = Rotate A and B by this angle
36
+   */
37
+  void gcode_M665() {
38
+    if (parser.seen('H')) {
39
+      home_offset[Z_AXIS] = parser.value_linear_units() - DELTA_HEIGHT;
40
+      update_software_endstops(Z_AXIS);
41
+    }
42
+    if (parser.seen('L')) delta_diagonal_rod             = parser.value_linear_units();
43
+    if (parser.seen('R')) delta_radius                   = parser.value_linear_units();
44
+    if (parser.seen('S')) delta_segments_per_second      = parser.value_float();
45
+    if (parser.seen('B')) delta_calibration_radius       = parser.value_float();
46
+    if (parser.seen('X')) delta_tower_angle_trim[A_AXIS] = parser.value_float();
47
+    if (parser.seen('Y')) delta_tower_angle_trim[B_AXIS] = parser.value_float();
48
+    if (parser.seen('Z')) { // rotate all 3 axis for Z = 0
49
+      delta_tower_angle_trim[A_AXIS] -= parser.value_float();
50
+      delta_tower_angle_trim[B_AXIS] -= parser.value_float();
51
+    }
52
+    recalc_delta_settings(delta_radius, delta_diagonal_rod);
53
+  }
54
+
55
+#elif IS_SCARA
56
+
57
+  /**
58
+   * M665: Set SCARA settings
59
+   *
60
+   * Parameters:
61
+   *
62
+   *   S[segments-per-second] - Segments-per-second
63
+   *   P[theta-psi-offset]    - Theta-Psi offset, added to the shoulder (A/X) angle
64
+   *   T[theta-offset]        - Theta     offset, added to the elbow    (B/Y) angle
65
+   *
66
+   *   A, P, and X are all aliases for the shoulder angle
67
+   *   B, T, and Y are all aliases for the elbow angle
68
+   */
69
+  void gcode_M665() {
70
+    if (parser.seen('S')) delta_segments_per_second = parser.value_float();
71
+
72
+    const bool hasA = parser.seen('A'), hasP = parser.seen('P'), hasX = parser.seen('X');
73
+    const uint8_t sumAPX = hasA + hasP + hasX;
74
+    if (sumAPX == 1)
75
+      home_offset[A_AXIS] = parser.value_float();
76
+    else if (sumAPX > 1) {
77
+      SERIAL_ERROR_START();
78
+      SERIAL_ERRORLNPGM("Only one of A, P, or X is allowed.");
79
+      return;
80
+    }
81
+
82
+    const bool hasB = parser.seen('B'), hasT = parser.seen('T'), hasY = parser.seen('Y');
83
+    const uint8_t sumBTY = hasB + hasT + hasY;
84
+    if (sumBTY == 1)
85
+      home_offset[B_AXIS] = parser.value_float();
86
+    else if (sumBTY > 1) {
87
+      SERIAL_ERROR_START();
88
+      SERIAL_ERRORLNPGM("Only one of B, T, or Y is allowed.");
89
+      return;
90
+    }
91
+  }
92
+
93
+#endif

+ 66
- 0
Marlin/src/gcode/calibrate/M666.h View File

@@ -0,0 +1,66 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if ENABLED(DELTA)
24
+
25
+  /**
26
+   * M666: Set delta endstop adjustment
27
+   */
28
+  void gcode_M666() {
29
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
30
+      if (DEBUGGING(LEVELING)) {
31
+        SERIAL_ECHOLNPGM(">>> gcode_M666");
32
+      }
33
+    #endif
34
+    LOOP_XYZ(i) {
35
+      if (parser.seen(axis_codes[i])) {
36
+        endstop_adj[i] = parser.value_linear_units();
37
+        #if ENABLED(DEBUG_LEVELING_FEATURE)
38
+          if (DEBUGGING(LEVELING)) {
39
+            SERIAL_ECHOPAIR("endstop_adj[", axis_codes[i]);
40
+            SERIAL_ECHOLNPAIR("] = ", endstop_adj[i]);
41
+          }
42
+        #endif
43
+      }
44
+    }
45
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
46
+      if (DEBUGGING(LEVELING)) {
47
+        SERIAL_ECHOLNPGM("<<< gcode_M666");
48
+      }
49
+    #endif
50
+    // normalize endstops so all are <=0; set the residue to delta height
51
+    const float z_temp = MAX3(endstop_adj[A_AXIS], endstop_adj[B_AXIS], endstop_adj[C_AXIS]);
52
+    home_offset[Z_AXIS] -= z_temp;
53
+    LOOP_XYZ(i) endstop_adj[i] -= z_temp;
54
+  }
55
+
56
+#elif ENABLED(Z_DUAL_ENDSTOPS) // !DELTA && ENABLED(Z_DUAL_ENDSTOPS)
57
+
58
+  /**
59
+   * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis.
60
+   */
61
+  void gcode_M666() {
62
+    if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units();
63
+    SERIAL_ECHOLNPAIR("Z Endstop Adjustment set to (mm):", z_endstop_adj);
64
+  }
65
+
66
+#endif

+ 81
- 0
Marlin/src/gcode/calibrate/common.h View File

@@ -0,0 +1,81 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifndef CALIBRATE_COMMON_H
24
+#define CALIBRATE_COMMON_H
25
+
26
+#if ENABLED(DELTA)
27
+
28
+  /**
29
+   * A delta can only safely home all axes at the same time
30
+   * This is like quick_home_xy() but for 3 towers.
31
+   */
32
+  inline bool home_delta() {
33
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
34
+      if (DEBUGGING(LEVELING)) DEBUG_POS(">>> home_delta", current_position);
35
+    #endif
36
+    // Init the current position of all carriages to 0,0,0
37
+    ZERO(current_position);
38
+    sync_plan_position();
39
+
40
+    // Move all carriages together linearly until an endstop is hit.
41
+    current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = (DELTA_HEIGHT + home_offset[Z_AXIS] + 10);
42
+    feedrate_mm_s = homing_feedrate(X_AXIS);
43
+    line_to_current_position();
44
+    stepper.synchronize();
45
+
46
+    // If an endstop was not hit, then damage can occur if homing is continued.
47
+    // This can occur if the delta height (DELTA_HEIGHT + home_offset[Z_AXIS]) is
48
+    // not set correctly.
49
+    if (!(Endstops::endstop_hit_bits & (_BV(X_MAX) | _BV(Y_MAX) | _BV(Z_MAX)))) {
50
+      LCD_MESSAGEPGM(MSG_ERR_HOMING_FAILED);
51
+      SERIAL_ERROR_START();
52
+      SERIAL_ERRORLNPGM(MSG_ERR_HOMING_FAILED);
53
+      return false;
54
+    }
55
+
56
+    endstops.hit_on_purpose(); // clear endstop hit flags
57
+
58
+    // At least one carriage has reached the top.
59
+    // Now re-home each carriage separately.
60
+    HOMEAXIS(A);
61
+    HOMEAXIS(B);
62
+    HOMEAXIS(C);
63
+
64
+    // Set all carriages to their home positions
65
+    // Do this here all at once for Delta, because
66
+    // XYZ isn't ABC. Applying this per-tower would
67
+    // give the impression that they are the same.
68
+    LOOP_XYZ(i) set_axis_is_at_home((AxisEnum)i);
69
+
70
+    SYNC_PLAN_POSITION_KINEMATIC();
71
+
72
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
73
+      if (DEBUGGING(LEVELING)) DEBUG_POS("<<< home_delta", current_position);
74
+    #endif
75
+
76
+    return true;
77
+  }
78
+
79
+#endif // DELTA
80
+
81
+#endif // CALIBRATE_COMMON_H

+ 46
- 0
Marlin/src/gcode/config/M200.h View File

@@ -0,0 +1,46 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M200: Set filament diameter and set E axis units to cubic units
25
+ *
26
+ *    T<extruder> - Optional extruder number. Current extruder if omitted.
27
+ *    D<linear> - Diameter of the filament. Use "D0" to switch back to linear units on the E axis.
28
+ */
29
+void gcode_M200() {
30
+
31
+  if (get_target_extruder_from_command(200)) return;
32
+
33
+  if (parser.seen('D')) {
34
+    // setting any extruder filament size disables volumetric on the assumption that
35
+    // slicers either generate in extruder values as cubic mm or as as filament feeds
36
+    // for all extruders
37
+    volumetric_enabled = (parser.value_linear_units() != 0.0);
38
+    if (volumetric_enabled) {
39
+      filament_size[target_extruder] = parser.value_linear_units();
40
+      // make sure all extruders have some sane value for the filament size
41
+      for (uint8_t i = 0; i < COUNT(filament_size); i++)
42
+        if (! filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA;
43
+    }
44
+  }
45
+  calculate_volumetric_multipliers();
46
+}

+ 40
- 0
Marlin/src/gcode/config/M201.h View File

@@ -0,0 +1,40 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M201: Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
25
+ *
26
+ *       With multiple extruders use T to specify which one.
27
+ */
28
+void gcode_M201() {
29
+
30
+  GET_TARGET_EXTRUDER(201);
31
+
32
+  LOOP_XYZE(i) {
33
+    if (parser.seen(axis_codes[i])) {
34
+      const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0);
35
+      planner.max_acceleration_mm_per_s2[a] = parser.value_axis_units((AxisEnum)a);
36
+    }
37
+  }
38
+  // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
39
+  planner.reset_acceleration_rates();
40
+}

+ 37
- 0
Marlin/src/gcode/config/M203.h View File

@@ -0,0 +1,37 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M203: Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec
25
+ *
26
+ *       With multiple extruders use T to specify which one.
27
+ */
28
+void gcode_M203() {
29
+
30
+  GET_TARGET_EXTRUDER(203);
31
+
32
+  LOOP_XYZE(i)
33
+    if (parser.seen(axis_codes[i])) {
34
+      const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0);
35
+      planner.max_feedrate_mm_s[a] = parser.value_axis_units((AxisEnum)a);
36
+    }
37
+}

+ 49
- 0
Marlin/src/gcode/config/M204.h View File

@@ -0,0 +1,49 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M204: Set Accelerations in units/sec^2 (M204 P1200 R3000 T3000)
25
+ *
26
+ *    P = Printing moves
27
+ *    R = Retract only (no X, Y, Z) moves
28
+ *    T = Travel (non printing) moves
29
+ *
30
+ *  Also sets minimum segment time in ms (B20000) to prevent buffer under-runs and M20 minimum feedrate
31
+ */
32
+void gcode_M204() {
33
+  if (parser.seen('S')) {  // Kept for legacy compatibility. Should NOT BE USED for new developments.
34
+    planner.travel_acceleration = planner.acceleration = parser.value_linear_units();
35
+    SERIAL_ECHOLNPAIR("Setting Print and Travel Acceleration: ", planner.acceleration);
36
+  }
37
+  if (parser.seen('P')) {
38
+    planner.acceleration = parser.value_linear_units();
39
+    SERIAL_ECHOLNPAIR("Setting Print Acceleration: ", planner.acceleration);
40
+  }
41
+  if (parser.seen('R')) {
42
+    planner.retract_acceleration = parser.value_linear_units();
43
+    SERIAL_ECHOLNPAIR("Setting Retract Acceleration: ", planner.retract_acceleration);
44
+  }
45
+  if (parser.seen('T')) {
46
+    planner.travel_acceleration = parser.value_linear_units();
47
+    SERIAL_ECHOLNPAIR("Setting Travel Acceleration: ", planner.travel_acceleration);
48
+  }
49
+}

+ 42
- 0
Marlin/src/gcode/config/M205.h View File

@@ -0,0 +1,42 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M205: Set Advanced Settings
25
+ *
26
+ *    S = Min Feed Rate (units/s)
27
+ *    T = Min Travel Feed Rate (units/s)
28
+ *    B = Min Segment Time (µs)
29
+ *    X = Max X Jerk (units/sec^2)
30
+ *    Y = Max Y Jerk (units/sec^2)
31
+ *    Z = Max Z Jerk (units/sec^2)
32
+ *    E = Max E Jerk (units/sec^2)
33
+ */
34
+void gcode_M205() {
35
+  if (parser.seen('S')) planner.min_feedrate_mm_s = parser.value_linear_units();
36
+  if (parser.seen('T')) planner.min_travel_feedrate_mm_s = parser.value_linear_units();
37
+  if (parser.seen('B')) planner.min_segment_time = parser.value_millis();
38
+  if (parser.seen('X')) planner.max_jerk[X_AXIS] = parser.value_linear_units();
39
+  if (parser.seen('Y')) planner.max_jerk[Y_AXIS] = parser.value_linear_units();
40
+  if (parser.seen('Z')) planner.max_jerk[Z_AXIS] = parser.value_linear_units();
41
+  if (parser.seen('E')) planner.max_jerk[E_AXIS] = parser.value_linear_units();
42
+}

+ 54
- 0
Marlin/src/gcode/config/M218.h View File

@@ -0,0 +1,54 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M218 - set hotend offset (in linear units)
25
+ *
26
+ *   T<tool>
27
+ *   X<xoffset>
28
+ *   Y<yoffset>
29
+ *   Z<zoffset> - Available with DUAL_X_CARRIAGE and SWITCHING_NOZZLE
30
+ */
31
+void gcode_M218() {
32
+  if (get_target_extruder_from_command(218) || target_extruder == 0) return;
33
+
34
+  if (parser.seenval('X')) hotend_offset[X_AXIS][target_extruder] = parser.value_linear_units();
35
+  if (parser.seenval('Y')) hotend_offset[Y_AXIS][target_extruder] = parser.value_linear_units();
36
+
37
+  #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER)
38
+    if (parser.seenval('Z')) hotend_offset[Z_AXIS][target_extruder] = parser.value_linear_units();
39
+  #endif
40
+
41
+  SERIAL_ECHO_START();
42
+  SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
43
+  HOTEND_LOOP() {
44
+    SERIAL_CHAR(' ');
45
+    SERIAL_ECHO(hotend_offset[X_AXIS][e]);
46
+    SERIAL_CHAR(',');
47
+    SERIAL_ECHO(hotend_offset[Y_AXIS][e]);
48
+    #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER)
49
+      SERIAL_CHAR(',');
50
+      SERIAL_ECHO(hotend_offset[Z_AXIS][e]);
51
+    #endif
52
+  }
53
+  SERIAL_EOL();
54
+}

+ 28
- 0
Marlin/src/gcode/config/M220.h View File

@@ -0,0 +1,28 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
25
+ */
26
+void gcode_M220() {
27
+  if (parser.seenval('S')) feedrate_percentage = parser.value_int();
28
+}

+ 30
- 0
Marlin/src/gcode/config/M221.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M221: Set extrusion percentage (M221 T0 S95)
25
+ */
26
+void gcode_M221() {
27
+  if (get_target_extruder_from_command(221)) return;
28
+  if (parser.seenval('S'))
29
+    flow_percentage[target_extruder] = parser.value_int();
30
+}

+ 69
- 0
Marlin/src/gcode/config/M301.h View File

@@ -0,0 +1,69 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M301: Set PID parameters P I D (and optionally C, L)
25
+ *
26
+ *   P[float] Kp term
27
+ *   I[float] Ki term (unscaled)
28
+ *   D[float] Kd term (unscaled)
29
+ *
30
+ * With PID_EXTRUSION_SCALING:
31
+ *
32
+ *   C[float] Kc term
33
+ *   L[float] LPQ length
34
+ */
35
+void gcode_M301() {
36
+
37
+  // multi-extruder PID patch: M301 updates or prints a single extruder's PID values
38
+  // default behaviour (omitting E parameter) is to update for extruder 0 only
39
+  const uint8_t e = parser.byteval('E'); // extruder being updated
40
+
41
+  if (e < HOTENDS) { // catch bad input value
42
+    if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float();
43
+    if (parser.seen('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float());
44
+    if (parser.seen('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float());
45
+    #if ENABLED(PID_EXTRUSION_SCALING)
46
+      if (parser.seen('C')) PID_PARAM(Kc, e) = parser.value_float();
47
+      if (parser.seen('L')) lpq_len = parser.value_float();
48
+      NOMORE(lpq_len, LPQ_MAX_LEN);
49
+    #endif
50
+
51
+    thermalManager.updatePID();
52
+    SERIAL_ECHO_START();
53
+    #if ENABLED(PID_PARAMS_PER_HOTEND)
54
+      SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output
55
+    #endif // PID_PARAMS_PER_HOTEND
56
+    SERIAL_ECHOPAIR(" p:", PID_PARAM(Kp, e));
57
+    SERIAL_ECHOPAIR(" i:", unscalePID_i(PID_PARAM(Ki, e)));
58
+    SERIAL_ECHOPAIR(" d:", unscalePID_d(PID_PARAM(Kd, e)));
59
+    #if ENABLED(PID_EXTRUSION_SCALING)
60
+      //Kc does not have scaling applied above, or in resetting defaults
61
+      SERIAL_ECHOPAIR(" c:", PID_PARAM(Kc, e));
62
+    #endif
63
+    SERIAL_EOL();
64
+  }
65
+  else {
66
+    SERIAL_ERROR_START();
67
+    SERIAL_ERRORLN(MSG_INVALID_EXTRUDER);
68
+  }
69
+}

+ 54
- 0
Marlin/src/gcode/config/M302.h View File

@@ -0,0 +1,54 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M302: Allow cold extrudes, or set the minimum extrude temperature
25
+ *
26
+ *       S<temperature> sets the minimum extrude temperature
27
+ *       P<bool> enables (1) or disables (0) cold extrusion
28
+ *
29
+ *  Examples:
30
+ *
31
+ *       M302         ; report current cold extrusion state
32
+ *       M302 P0      ; enable cold extrusion checking
33
+ *       M302 P1      ; disables cold extrusion checking
34
+ *       M302 S0      ; always allow extrusion (disables checking)
35
+ *       M302 S170    ; only allow extrusion above 170
36
+ *       M302 S170 P1 ; set min extrude temp to 170 but leave disabled
37
+ */
38
+void gcode_M302() {
39
+  const bool seen_S = parser.seen('S');
40
+  if (seen_S) {
41
+    thermalManager.extrude_min_temp = parser.value_celsius();
42
+    thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0);
43
+  }
44
+
45
+  if (parser.seen('P'))
46
+    thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0) || parser.value_bool();
47
+  else if (!seen_S) {
48
+    // Report current state
49
+    SERIAL_ECHO_START();
50
+    SERIAL_ECHOPAIR("Cold extrudes are ", (thermalManager.allow_cold_extrude ? "en" : "dis"));
51
+    SERIAL_ECHOPAIR("abled (min temp ", thermalManager.extrude_min_temp);
52
+    SERIAL_ECHOLNPGM("C)");
53
+  }
54
+}

+ 34
- 0
Marlin/src/gcode/config/M304.h View File

@@ -0,0 +1,34 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+void gcode_M304() {
24
+  if (parser.seen('P')) thermalManager.bedKp = parser.value_float();
25
+  if (parser.seen('I')) thermalManager.bedKi = scalePID_i(parser.value_float());
26
+  if (parser.seen('D')) thermalManager.bedKd = scalePID_d(parser.value_float());
27
+
28
+  thermalManager.updatePID();
29
+
30
+  SERIAL_ECHO_START();
31
+  SERIAL_ECHOPAIR(" p:", thermalManager.bedKp);
32
+  SERIAL_ECHOPAIR(" i:", unscalePID_i(thermalManager.bedKi));
33
+  SERIAL_ECHOLNPAIR(" d:", unscalePID_d(thermalManager.bedKd));
34
+}

+ 311
- 0
Marlin/src/gcode/config/M43.h View File

@@ -0,0 +1,311 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../pins/pinsDebug.h"
24
+
25
+inline void toggle_pins() {
26
+  const bool I_flag = parser.boolval('I');
27
+  const int repeat = parser.intval('R', 1),
28
+            start = parser.intval('S'),
29
+            end = parser.intval('E', NUM_DIGITAL_PINS - 1),
30
+            wait = parser.intval('W', 500);
31
+
32
+  for (uint8_t pin = start; pin <= end; pin++) {
33
+    //report_pin_state_extended(pin, I_flag, false);
34
+    if (!VALID_PIN(pin)) continue;
35
+    if (!I_flag && pin_is_protected(pin)) {
36
+      report_pin_state_extended(pin, I_flag, true, "Untouched ");
37
+      SERIAL_EOL();
38
+    }
39
+    else {
40
+      report_pin_state_extended(pin, I_flag, true, "Pulsing   ");
41
+      #if AVR_AT90USB1286_FAMILY // Teensy IDEs don't know about these pins so must use FASTIO
42
+        if (pin == TEENSY_E2) {
43
+          SET_OUTPUT(TEENSY_E2);
44
+          for (int16_t j = 0; j < repeat; j++) {
45
+            WRITE(TEENSY_E2, LOW);  safe_delay(wait);
46
+            WRITE(TEENSY_E2, HIGH); safe_delay(wait);
47
+            WRITE(TEENSY_E2, LOW);  safe_delay(wait);
48
+          }
49
+        }
50
+        else if (pin == TEENSY_E3) {
51
+          SET_OUTPUT(TEENSY_E3);
52
+          for (int16_t j = 0; j < repeat; j++) {
53
+            WRITE(TEENSY_E3, LOW);  safe_delay(wait);
54
+            WRITE(TEENSY_E3, HIGH); safe_delay(wait);
55
+            WRITE(TEENSY_E3, LOW);  safe_delay(wait);
56
+          }
57
+        }
58
+        else
59
+      #endif
60
+      {
61
+        pinMode(pin, OUTPUT);
62
+        for (int16_t j = 0; j < repeat; j++) {
63
+          digitalWrite(pin, 0); safe_delay(wait);
64
+          digitalWrite(pin, 1); safe_delay(wait);
65
+          digitalWrite(pin, 0); safe_delay(wait);
66
+        }
67
+      }
68
+
69
+    }
70
+    SERIAL_EOL();
71
+  }
72
+  SERIAL_ECHOLNPGM("Done.");
73
+
74
+} // toggle_pins
75
+
76
+inline void servo_probe_test() {
77
+  #if !(NUM_SERVOS > 0 && HAS_SERVO_0)
78
+
79
+    SERIAL_ERROR_START();
80
+    SERIAL_ERRORLNPGM("SERVO not setup");
81
+
82
+  #elif !HAS_Z_SERVO_ENDSTOP
83
+
84
+    SERIAL_ERROR_START();
85
+    SERIAL_ERRORLNPGM("Z_ENDSTOP_SERVO_NR not setup");
86
+
87
+  #else // HAS_Z_SERVO_ENDSTOP
88
+
89
+    const uint8_t probe_index = parser.byteval('P', Z_ENDSTOP_SERVO_NR);
90
+
91
+    SERIAL_PROTOCOLLNPGM("Servo probe test");
92
+    SERIAL_PROTOCOLLNPAIR(".  using index:  ", probe_index);
93
+    SERIAL_PROTOCOLLNPAIR(".  deploy angle: ", z_servo_angle[0]);
94
+    SERIAL_PROTOCOLLNPAIR(".  stow angle:   ", z_servo_angle[1]);
95
+
96
+    bool probe_inverting;
97
+
98
+    #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
99
+
100
+      #define PROBE_TEST_PIN Z_MIN_PIN
101
+
102
+      SERIAL_PROTOCOLLNPAIR(". probe uses Z_MIN pin: ", PROBE_TEST_PIN);
103
+      SERIAL_PROTOCOLLNPGM(". uses Z_MIN_ENDSTOP_INVERTING (ignores Z_MIN_PROBE_ENDSTOP_INVERTING)");
104
+      SERIAL_PROTOCOLPGM(". Z_MIN_ENDSTOP_INVERTING: ");
105
+
106
+      #if Z_MIN_ENDSTOP_INVERTING
107
+        SERIAL_PROTOCOLLNPGM("true");
108
+      #else
109
+        SERIAL_PROTOCOLLNPGM("false");
110
+      #endif
111
+
112
+      probe_inverting = Z_MIN_ENDSTOP_INVERTING;
113
+
114
+    #elif ENABLED(Z_MIN_PROBE_ENDSTOP)
115
+
116
+      #define PROBE_TEST_PIN Z_MIN_PROBE_PIN
117
+      SERIAL_PROTOCOLLNPAIR(". probe uses Z_MIN_PROBE_PIN: ", PROBE_TEST_PIN);
118
+      SERIAL_PROTOCOLLNPGM(". uses Z_MIN_PROBE_ENDSTOP_INVERTING (ignores Z_MIN_ENDSTOP_INVERTING)");
119
+      SERIAL_PROTOCOLPGM(". Z_MIN_PROBE_ENDSTOP_INVERTING: ");
120
+
121
+      #if Z_MIN_PROBE_ENDSTOP_INVERTING
122
+        SERIAL_PROTOCOLLNPGM("true");
123
+      #else
124
+        SERIAL_PROTOCOLLNPGM("false");
125
+      #endif
126
+
127
+      probe_inverting = Z_MIN_PROBE_ENDSTOP_INVERTING;
128
+
129
+    #endif
130
+
131
+    SERIAL_PROTOCOLLNPGM(". deploy & stow 4 times");
132
+    SET_INPUT_PULLUP(PROBE_TEST_PIN);
133
+    bool deploy_state, stow_state;
134
+    for (uint8_t i = 0; i < 4; i++) {
135
+      MOVE_SERVO(probe_index, z_servo_angle[0]); //deploy
136
+      safe_delay(500);
137
+      deploy_state = READ(PROBE_TEST_PIN);
138
+      MOVE_SERVO(probe_index, z_servo_angle[1]); //stow
139
+      safe_delay(500);
140
+      stow_state = READ(PROBE_TEST_PIN);
141
+    }
142
+    if (probe_inverting != deploy_state) SERIAL_PROTOCOLLNPGM("WARNING - INVERTING setting probably backwards");
143
+
144
+    refresh_cmd_timeout();
145
+
146
+    if (deploy_state != stow_state) {
147
+      SERIAL_PROTOCOLLNPGM("BLTouch clone detected");
148
+      if (deploy_state) {
149
+        SERIAL_PROTOCOLLNPGM(".  DEPLOYED state: HIGH (logic 1)");
150
+        SERIAL_PROTOCOLLNPGM(".  STOWED (triggered) state: LOW (logic 0)");
151
+      }
152
+      else {
153
+        SERIAL_PROTOCOLLNPGM(".  DEPLOYED state: LOW (logic 0)");
154
+        SERIAL_PROTOCOLLNPGM(".  STOWED (triggered) state: HIGH (logic 1)");
155
+      }
156
+      #if ENABLED(BLTOUCH)
157
+        SERIAL_PROTOCOLLNPGM("ERROR: BLTOUCH enabled - set this device up as a Z Servo Probe with inverting as true.");
158
+      #endif
159
+
160
+    }
161
+    else {                                           // measure active signal length
162
+      MOVE_SERVO(probe_index, z_servo_angle[0]);     // deploy
163
+      safe_delay(500);
164
+      SERIAL_PROTOCOLLNPGM("please trigger probe");
165
+      uint16_t probe_counter = 0;
166
+
167
+      // Allow 30 seconds max for operator to trigger probe
168
+      for (uint16_t j = 0; j < 500 * 30 && probe_counter == 0 ; j++) {
169
+
170
+        safe_delay(2);
171
+
172
+        if (0 == j % (500 * 1)) // keep cmd_timeout happy
173
+          refresh_cmd_timeout();
174
+
175
+        if (deploy_state != READ(PROBE_TEST_PIN)) { // probe triggered
176
+
177
+          for (probe_counter = 1; probe_counter < 50 && deploy_state != READ(PROBE_TEST_PIN); ++probe_counter)
178
+            safe_delay(2);
179
+
180
+          if (probe_counter == 50)
181
+            SERIAL_PROTOCOLLNPGM("Z Servo Probe detected"); // >= 100mS active time
182
+          else if (probe_counter >= 2)
183
+            SERIAL_PROTOCOLLNPAIR("BLTouch compatible probe detected - pulse width (+/- 4mS): ", probe_counter * 2); // allow 4 - 100mS pulse
184
+          else
185
+            SERIAL_PROTOCOLLNPGM("noise detected - please re-run test"); // less than 2mS pulse
186
+
187
+          MOVE_SERVO(probe_index, z_servo_angle[1]); //stow
188
+
189
+        }  // pulse detected
190
+
191
+      } // for loop waiting for trigger
192
+
193
+      if (probe_counter == 0) SERIAL_PROTOCOLLNPGM("trigger not detected");
194
+
195
+    } // measure active signal length
196
+
197
+  #endif
198
+
199
+} // servo_probe_test
200
+
201
+/**
202
+ * M43: Pin debug - report pin state, watch pins, toggle pins and servo probe test/report
203
+ *
204
+ *  M43         - report name and state of pin(s)
205
+ *                  P<pin>  Pin to read or watch. If omitted, reads all pins.
206
+ *                  I       Flag to ignore Marlin's pin protection.
207
+ *
208
+ *  M43 W       - Watch pins -reporting changes- until reset, click, or M108.
209
+ *                  P<pin>  Pin to read or watch. If omitted, read/watch all pins.
210
+ *                  I       Flag to ignore Marlin's pin protection.
211
+ *
212
+ *  M43 E<bool> - Enable / disable background endstop monitoring
213
+ *                  - Machine continues to operate
214
+ *                  - Reports changes to endstops
215
+ *                  - Toggles LED_PIN when an endstop changes
216
+ *                  - Can not reliably catch the 5mS pulse from BLTouch type probes
217
+ *
218
+ *  M43 T       - Toggle pin(s) and report which pin is being toggled
219
+ *                  S<pin>  - Start Pin number.   If not given, will default to 0
220
+ *                  L<pin>  - End Pin number.   If not given, will default to last pin defined for this board
221
+ *                  I<bool> - Flag to ignore Marlin's pin protection.   Use with caution!!!!
222
+ *                  R       - Repeat pulses on each pin this number of times before continueing to next pin
223
+ *                  W       - Wait time (in miliseconds) between pulses.  If not given will default to 500
224
+ *
225
+ *  M43 S       - Servo probe test
226
+ *                  P<index> - Probe index (optional - defaults to 0
227
+ */
228
+void gcode_M43() {
229
+
230
+  if (parser.seen('T')) {   // must be first or else its "S" and "E" parameters will execute endstop or servo test
231
+    toggle_pins();
232
+    return;
233
+  }
234
+
235
+  // Enable or disable endstop monitoring
236
+  if (parser.seen('E')) {
237
+    endstop_monitor_flag = parser.value_bool();
238
+    SERIAL_PROTOCOLPGM("endstop monitor ");
239
+    serialprintPGM(endstop_monitor_flag ? PSTR("en") : PSTR("dis"));
240
+    SERIAL_PROTOCOLLNPGM("abled");
241
+    return;
242
+  }
243
+
244
+  if (parser.seen('S')) {
245
+    servo_probe_test();
246
+    return;
247
+  }
248
+
249
+  // Get the range of pins to test or watch
250
+  const uint8_t first_pin = parser.byteval('P'),
251
+                last_pin = parser.seenval('P') ? first_pin : NUM_DIGITAL_PINS - 1;
252
+
253
+  if (first_pin > last_pin) return;
254
+
255
+  const bool ignore_protection = parser.boolval('I');
256
+
257
+  // Watch until click, M108, or reset
258
+  if (parser.boolval('W')) {
259
+    SERIAL_PROTOCOLLNPGM("Watching pins");
260
+    uint8_t pin_state[last_pin - first_pin + 1];
261
+    for (int8_t pin = first_pin; pin <= last_pin; pin++) {
262
+      if (!VALID_PIN(pin)) continue;
263
+      if (pin_is_protected(pin) && !ignore_protection) continue;
264
+      pinMode(pin, INPUT_PULLUP);
265
+      delay(1);
266
+      /*
267
+        if (IS_ANALOG(pin))
268
+          pin_state[pin - first_pin] = analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)); // int16_t pin_state[...]
269
+        else
270
+      //*/
271
+          pin_state[pin - first_pin] = digitalRead(pin);
272
+    }
273
+
274
+    #if HAS_RESUME_CONTINUE
275
+      wait_for_user = true;
276
+      KEEPALIVE_STATE(PAUSED_FOR_USER);
277
+    #endif
278
+
279
+    for (;;) {
280
+      for (int8_t pin = first_pin; pin <= last_pin; pin++) {
281
+        if (!VALID_PIN(pin)) continue;
282
+        if (pin_is_protected(pin) && !ignore_protection) continue;
283
+        const byte val =
284
+          /*
285
+            IS_ANALOG(pin)
286
+              ? analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)) : // int16_t val
287
+              :
288
+          //*/
289
+            digitalRead(pin);
290
+        if (val != pin_state[pin - first_pin]) {
291
+          report_pin_state_extended(pin, ignore_protection, false);
292
+          pin_state[pin - first_pin] = val;
293
+        }
294
+      }
295
+
296
+      #if HAS_RESUME_CONTINUE
297
+        if (!wait_for_user) {
298
+          KEEPALIVE_STATE(IN_HANDLER);
299
+          break;
300
+        }
301
+      #endif
302
+
303
+      safe_delay(200);
304
+    }
305
+    return;
306
+  }
307
+
308
+  // Report current state of selected pin(s)
309
+  for (uint8_t pin = first_pin; pin <= last_pin; pin++)
310
+    if (VALID_PIN(pin)) report_pin_state_extended(pin, ignore_protection, true);
311
+}

+ 28
- 0
Marlin/src/gcode/config/M540.h View File

@@ -0,0 +1,28 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M540: Set whether SD card print should abort on endstop hit (M540 S<0|1>)
25
+ */
26
+void gcode_M540() {
27
+  if (parser.seen('S')) stepper.abort_on_endstop_hit = parser.value_bool();
28
+}

+ 51
- 0
Marlin/src/gcode/config/M92.h View File

@@ -0,0 +1,51 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M92: Set axis steps-per-unit for one or more axes, X, Y, Z, and E.
25
+ *      (Follows the same syntax as G92)
26
+ *
27
+ *      With multiple extruders use T to specify which one.
28
+ */
29
+void gcode_M92() {
30
+
31
+  GET_TARGET_EXTRUDER(92);
32
+
33
+  LOOP_XYZE(i) {
34
+    if (parser.seen(axis_codes[i])) {
35
+      if (i == E_AXIS) {
36
+        const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER));
37
+        if (value < 20.0) {
38
+          float factor = planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab.
39
+          planner.max_jerk[E_AXIS] *= factor;
40
+          planner.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor;
41
+          planner.max_acceleration_steps_per_s2[E_AXIS + TARGET_EXTRUDER] *= factor;
42
+        }
43
+        planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] = value;
44
+      }
45
+      else {
46
+        planner.axis_steps_per_mm[i] = parser.value_per_axis_unit((AxisEnum)i);
47
+      }
48
+    }
49
+  }
50
+  planner.refresh_positioning();
51
+}

+ 30
- 0
Marlin/src/gcode/control/M108.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature.
25
+ */
26
+void gcode_M108() {
27
+
28
+  wait_for_heatup = false;
29
+
30
+}

+ 61
- 0
Marlin/src/gcode/control/M111.h View File

@@ -0,0 +1,61 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M111: Set the debug level
25
+ */
26
+void gcode_M111() {
27
+  if (parser.seen('S')) marlin_debug_flags = parser.byteval('S');
28
+
29
+  const static char str_debug_1[] PROGMEM = MSG_DEBUG_ECHO,
30
+                    str_debug_2[] PROGMEM = MSG_DEBUG_INFO,
31
+                    str_debug_4[] PROGMEM = MSG_DEBUG_ERRORS,
32
+                    str_debug_8[] PROGMEM = MSG_DEBUG_DRYRUN,
33
+                    str_debug_16[] PROGMEM = MSG_DEBUG_COMMUNICATION
34
+                    #if ENABLED(DEBUG_LEVELING_FEATURE)
35
+                      , str_debug_32[] PROGMEM = MSG_DEBUG_LEVELING
36
+                    #endif
37
+                    ;
38
+
39
+  const static char* const debug_strings[] PROGMEM = {
40
+    str_debug_1, str_debug_2, str_debug_4, str_debug_8, str_debug_16
41
+    #if ENABLED(DEBUG_LEVELING_FEATURE)
42
+      , str_debug_32
43
+    #endif
44
+  };
45
+
46
+  SERIAL_ECHO_START();
47
+  SERIAL_ECHOPGM(MSG_DEBUG_PREFIX);
48
+  if (marlin_debug_flags) {
49
+    uint8_t comma = 0;
50
+    for (uint8_t i = 0; i < COUNT(debug_strings); i++) {
51
+      if (TEST(marlin_debug_flags, i)) {
52
+        if (comma++) SERIAL_CHAR(',');
53
+        serialprintPGM((char*)pgm_read_word(&debug_strings[i]));
54
+      }
55
+    }
56
+  }
57
+  else {
58
+    SERIAL_ECHOPGM(MSG_DEBUG_OFF);
59
+  }
60
+  SERIAL_EOL();
61
+}

+ 30
- 0
Marlin/src/gcode/control/M112.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M112: Emergency Stop
25
+ */
26
+void gcode_M112() {
27
+
28
+  kill(PSTR(MSG_KILLED));
29
+
30
+}

+ 39
- 0
Marlin/src/gcode/control/M120_M121.h View File

@@ -0,0 +1,39 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M120: Enable endstops and set non-homing endstop state to "enabled"
25
+ */
26
+void gcode_M120() {
27
+
28
+  endstops.enable_globally(true);
29
+
30
+}
31
+
32
+/**
33
+ * M121: Disable endstops and set non-homing endstop state to "disabled"
34
+ */
35
+void gcode_M121() {
36
+
37
+  endstops.enable_globally(false);
38
+
39
+}

+ 29
- 0
Marlin/src/gcode/control/M17.h View File

@@ -0,0 +1,29 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M17: Enable power on all stepper motors
25
+ */
26
+void gcode_M17() {
27
+  LCD_MESSAGEPGM(MSG_NO_MOVE);
28
+  enable_all_steppers();
29
+}

+ 53
- 0
Marlin/src/gcode/control/M18_M84.h View File

@@ -0,0 +1,53 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTRA_LCD)
24
+  extern bool defer_return_to_status;
25
+#endif
26
+
27
+/**
28
+ * M18, M84: Disable stepper motors
29
+ */
30
+void gcode_M18_M84() {
31
+  if (parser.seenval('S')) {
32
+    stepper_inactive_time = parser.value_millis_from_seconds();
33
+  }
34
+  else {
35
+    bool all_axis = !((parser.seen('X')) || (parser.seen('Y')) || (parser.seen('Z')) || (parser.seen('E')));
36
+    if (all_axis) {
37
+      stepper.finish_and_disable();
38
+    }
39
+    else {
40
+      stepper.synchronize();
41
+      if (parser.seen('X')) disable_X();
42
+      if (parser.seen('Y')) disable_Y();
43
+      if (parser.seen('Z')) disable_Z();
44
+      #if E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN // Only enable on boards that have separate ENABLE_PINS
45
+        if (parser.seen('E')) disable_e_steppers();
46
+      #endif
47
+    }
48
+
49
+    #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTRA_LCD)  // Only needed with an LCD
50
+      ubl_lcd_map_control = defer_return_to_status = false;
51
+    #endif
52
+  }
53
+}

+ 46
- 0
Marlin/src/gcode/control/M211.h View File

@@ -0,0 +1,46 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M211: Enable, Disable, and/or Report software endstops
25
+ *
26
+ * Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report
27
+ */
28
+void gcode_M211() {
29
+  SERIAL_ECHO_START();
30
+  #if HAS_SOFTWARE_ENDSTOPS
31
+    if (parser.seen('S')) soft_endstops_enabled = parser.value_bool();
32
+    SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS);
33
+    serialprintPGM(soft_endstops_enabled ? PSTR(MSG_ON) : PSTR(MSG_OFF));
34
+  #else
35
+    SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS);
36
+    SERIAL_ECHOPGM(MSG_OFF);
37
+  #endif
38
+  SERIAL_ECHOPGM(MSG_SOFT_MIN);
39
+  SERIAL_ECHOPAIR(    MSG_X, soft_endstop_min[X_AXIS]);
40
+  SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_min[Y_AXIS]);
41
+  SERIAL_ECHOPAIR(" " MSG_Z, soft_endstop_min[Z_AXIS]);
42
+  SERIAL_ECHOPGM(MSG_SOFT_MAX);
43
+  SERIAL_ECHOPAIR(    MSG_X, soft_endstop_max[X_AXIS]);
44
+  SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_max[Y_AXIS]);
45
+  SERIAL_ECHOLNPAIR(" " MSG_Z, soft_endstop_max[Z_AXIS]);
46
+}

+ 54
- 0
Marlin/src/gcode/control/M226.h View File

@@ -0,0 +1,54 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M226: Wait until the specified pin reaches the state required (M226 P<pin> S<state>)
25
+ */
26
+void gcode_M226() {
27
+  if (parser.seen('P')) {
28
+    const int pin_number = parser.value_int(),
29
+              pin_state = parser.intval('S', -1); // required pin state - default is inverted
30
+
31
+    if (WITHIN(pin_state, -1, 1) && pin_number > -1 && !pin_is_protected(pin_number)) {
32
+
33
+      int target = LOW;
34
+
35
+      stepper.synchronize();
36
+
37
+      pinMode(pin_number, INPUT);
38
+      switch (pin_state) {
39
+        case 1:
40
+          target = HIGH;
41
+          break;
42
+        case 0:
43
+          target = LOW;
44
+          break;
45
+        case -1:
46
+          target = !digitalRead(pin_number);
47
+          break;
48
+      }
49
+
50
+      while (digitalRead(pin_number) != target) idle();
51
+
52
+    } // pin_state -1 0 1 && pin_number > -1
53
+  } // parser.seen('P')
54
+}

+ 43
- 0
Marlin/src/gcode/control/M280.h View File

@@ -0,0 +1,43 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M280: Get or set servo position. P<index> [S<angle>]
25
+ */
26
+void gcode_M280() {
27
+  if (!parser.seen('P')) return;
28
+  const int servo_index = parser.value_int();
29
+  if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) {
30
+    if (parser.seen('S'))
31
+      MOVE_SERVO(servo_index, parser.value_int());
32
+    else {
33
+      SERIAL_ECHO_START();
34
+      SERIAL_ECHOPAIR(" Servo ", servo_index);
35
+      SERIAL_ECHOLNPAIR(": ", servo[servo_index].read());
36
+    }
37
+  }
38
+  else {
39
+    SERIAL_ERROR_START();
40
+    SERIAL_ECHOPAIR("Servo ", servo_index);
41
+    SERIAL_ECHOLNPGM(" out of range");
42
+  }
43
+}

+ 127
- 0
Marlin/src/gcode/control/M3-M5.h View File

@@ -0,0 +1,127 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M3: Spindle Clockwise
25
+ * M4: Spindle Counter-clockwise
26
+ *
27
+ *  S0 turns off spindle.
28
+ *
29
+ *  If no speed PWM output is defined then M3/M4 just turns it on.
30
+ *
31
+ *  At least 12.8KHz (50Hz * 256) is needed for spindle PWM.
32
+ *  Hardware PWM is required. ISRs are too slow.
33
+ *
34
+ * NOTE: WGM for timers 3, 4, and 5 must be either Mode 1 or Mode 5.
35
+ *       No other settings give a PWM signal that goes from 0 to 5 volts.
36
+ *
37
+ *       The system automatically sets WGM to Mode 1, so no special
38
+ *       initialization is needed.
39
+ *
40
+ *       WGM bits for timer 2 are automatically set by the system to
41
+ *       Mode 1. This produces an acceptable 0 to 5 volt signal.
42
+ *       No special initialization is needed.
43
+ *
44
+ * NOTE: A minimum PWM frequency of 50 Hz is needed. All prescaler
45
+ *       factors for timers 2, 3, 4, and 5 are acceptable.
46
+ *
47
+ *  SPINDLE_LASER_ENABLE_PIN needs an external pullup or it may power on
48
+ *  the spindle/laser during power-up or when connecting to the host
49
+ *  (usually goes through a reset which sets all I/O pins to tri-state)
50
+ *
51
+ *  PWM duty cycle goes from 0 (off) to 255 (always on).
52
+ */
53
+
54
+// Wait for spindle to come up to speed
55
+inline void delay_for_power_up() { dwell(SPINDLE_LASER_POWERUP_DELAY); }
56
+
57
+// Wait for spindle to stop turning
58
+inline void delay_for_power_down() { dwell(SPINDLE_LASER_POWERDOWN_DELAY); }
59
+
60
+/**
61
+ * ocr_val_mode() is used for debugging and to get the points needed to compute the RPM vs ocr_val line
62
+ *
63
+ * it accepts inputs of 0-255
64
+ */
65
+
66
+inline void ocr_val_mode() {
67
+  uint8_t spindle_laser_power = parser.value_byte();
68
+  WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low)
69
+  if (SPINDLE_LASER_PWM_INVERT) spindle_laser_power = 255 - spindle_laser_power;
70
+  analogWrite(SPINDLE_LASER_PWM_PIN, spindle_laser_power);
71
+}
72
+
73
+void gcode_M3_M4(bool is_M3) {
74
+
75
+  stepper.synchronize();   // wait until previous movement commands (G0/G0/G2/G3) have completed before playing with the spindle
76
+  #if SPINDLE_DIR_CHANGE
77
+    const bool rotation_dir = (is_M3 != SPINDLE_INVERT_DIR);
78
+    if (SPINDLE_STOP_ON_DIR_CHANGE \
79
+       && READ(SPINDLE_LASER_ENABLE_PIN) == SPINDLE_LASER_ENABLE_INVERT \
80
+       && READ(SPINDLE_DIR_PIN) != rotation_dir
81
+    ) {
82
+      WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);  // turn spindle off
83
+      delay_for_power_down();
84
+    }
85
+    WRITE(SPINDLE_DIR_PIN, rotation_dir);
86
+  #endif
87
+
88
+  /**
89
+   * Our final value for ocr_val is an unsigned 8 bit value between 0 and 255 which usually means uint8_t.
90
+   * Went to uint16_t because some of the uint8_t calculations would sometimes give 1000 0000 rather than 1111 1111.
91
+   * Then needed to AND the uint16_t result with 0x00FF to make sure we only wrote the byte of interest.
92
+   */
93
+  #if ENABLED(SPINDLE_LASER_PWM)
94
+    if (parser.seen('O')) ocr_val_mode();
95
+    else {
96
+      const float spindle_laser_power = parser.floatval('S');
97
+      if (spindle_laser_power == 0) {
98
+        WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);                                    // turn spindle off (active low)
99
+        delay_for_power_down();
100
+      }
101
+      else {
102
+        int16_t ocr_val = (spindle_laser_power - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE));  // convert RPM to PWM duty cycle
103
+        NOMORE(ocr_val, 255);                                                                             // limit to max the Atmel PWM will support
104
+        if (spindle_laser_power <= SPEED_POWER_MIN)
105
+          ocr_val = (SPEED_POWER_MIN - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE));            // minimum setting
106
+        if (spindle_laser_power >= SPEED_POWER_MAX)
107
+          ocr_val = (SPEED_POWER_MAX - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE));            // limit to max RPM
108
+        if (SPINDLE_LASER_PWM_INVERT) ocr_val = 255 - ocr_val;
109
+        WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT);                                     // turn spindle on (active low)
110
+        analogWrite(SPINDLE_LASER_PWM_PIN, ocr_val & 0xFF);                                               // only write low byte
111
+        delay_for_power_up();
112
+      }
113
+    }
114
+  #else
115
+    WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low) if spindle speed option not enabled
116
+    delay_for_power_up();
117
+  #endif
118
+}
119
+
120
+/**
121
+* M5 turn off spindle
122
+*/
123
+void gcode_M5() {
124
+  stepper.synchronize();
125
+  WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);
126
+  delay_for_power_down();
127
+}

+ 33
- 0
Marlin/src/gcode/control/M350.h View File

@@ -0,0 +1,33 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M350: Set axis microstepping modes. S sets mode for all drivers.
25
+ *
26
+ * Warning: Steps-per-unit remains unchanged.
27
+ */
28
+void gcode_M350() {
29
+  if (parser.seen('S')) for (int i = 0; i <= 4; i++) stepper.microstep_mode(i, parser.value_byte());
30
+  LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_mode(i, parser.value_byte());
31
+  if (parser.seen('B')) stepper.microstep_mode(4, parser.value_byte());
32
+  stepper.microstep_readings();
33
+}

+ 39
- 0
Marlin/src/gcode/control/M351.h View File

@@ -0,0 +1,39 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M351: Toggle MS1 MS2 pins directly with axis codes X Y Z E B
25
+ *       S# determines MS1 or MS2, X# sets the pin high/low.
26
+ */
27
+void gcode_M351() {
28
+  if (parser.seenval('S')) switch (parser.value_byte()) {
29
+    case 1:
30
+      LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1);
31
+      if (parser.seenval('B')) stepper.microstep_ms(4, parser.value_byte(), -1);
32
+      break;
33
+    case 2:
34
+      LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte());
35
+      if (parser.seenval('B')) stepper.microstep_ms(4, -1, parser.value_byte());
36
+      break;
37
+  }
38
+  stepper.microstep_readings();
39
+}

+ 93
- 0
Marlin/src/gcode/control/M380_M381.h View File

@@ -0,0 +1,93 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if ENABLED(EXT_SOLENOID)
24
+
25
+void enable_solenoid(const uint8_t num) {
26
+  switch (num) {
27
+    case 0:
28
+      OUT_WRITE(SOL0_PIN, HIGH);
29
+      break;
30
+      #if HAS_SOLENOID_1 && EXTRUDERS > 1
31
+        case 1:
32
+          OUT_WRITE(SOL1_PIN, HIGH);
33
+          break;
34
+      #endif
35
+      #if HAS_SOLENOID_2 && EXTRUDERS > 2
36
+        case 2:
37
+          OUT_WRITE(SOL2_PIN, HIGH);
38
+          break;
39
+      #endif
40
+      #if HAS_SOLENOID_3 && EXTRUDERS > 3
41
+        case 3:
42
+          OUT_WRITE(SOL3_PIN, HIGH);
43
+          break;
44
+      #endif
45
+      #if HAS_SOLENOID_4 && EXTRUDERS > 4
46
+        case 4:
47
+          OUT_WRITE(SOL4_PIN, HIGH);
48
+          break;
49
+      #endif
50
+    default:
51
+      SERIAL_ECHO_START();
52
+      SERIAL_ECHOLNPGM(MSG_INVALID_SOLENOID);
53
+      break;
54
+  }
55
+}
56
+
57
+void enable_solenoid_on_active_extruder() { enable_solenoid(active_extruder); }
58
+
59
+void disable_all_solenoids() {
60
+  OUT_WRITE(SOL0_PIN, LOW);
61
+  #if HAS_SOLENOID_1 && EXTRUDERS > 1
62
+    OUT_WRITE(SOL1_PIN, LOW);
63
+  #endif
64
+  #if HAS_SOLENOID_2 && EXTRUDERS > 2
65
+    OUT_WRITE(SOL2_PIN, LOW);
66
+  #endif
67
+  #if HAS_SOLENOID_3 && EXTRUDERS > 3
68
+    OUT_WRITE(SOL3_PIN, LOW);
69
+  #endif
70
+  #if HAS_SOLENOID_4 && EXTRUDERS > 4
71
+    OUT_WRITE(SOL4_PIN, LOW);
72
+  #endif
73
+}
74
+
75
+/**
76
+ * M380: Enable solenoid on the active extruder
77
+ */
78
+void gcode_M380() {
79
+
80
+  enable_solenoid_on_active_extruder();
81
+
82
+}
83
+
84
+/**
85
+ * M381: Disable all solenoids
86
+ */
87
+void gcode_M381() {
88
+
89
+  disable_all_solenoids();
90
+
91
+}
92
+
93
+#endif // EXT_SOLENOID

+ 30
- 0
Marlin/src/gcode/control/M400.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M400: Finish all moves
25
+ */
26
+void gcode_M400() {
27
+
28
+  stepper.synchronize();
29
+
30
+}

+ 33
- 0
Marlin/src/gcode/control/M410.h View File

@@ -0,0 +1,33 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M410: Quickstop - Abort all planned moves
25
+ *
26
+ * This will stop the carriages mid-move, so most likely they
27
+ * will be out of sync with the stepper position after this.
28
+ */
29
+void gcode_M410() {
30
+
31
+  quickstop_stepper();
32
+
33
+}

+ 59
- 0
Marlin/src/gcode/control/M42.h View File

@@ -0,0 +1,59 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M42: Change pin status via GCode
25
+ *
26
+ *  P<pin>  Pin number (LED if omitted)
27
+ *  S<byte> Pin status from 0 - 255
28
+ */
29
+void gcode_M42() {
30
+  if (!parser.seenval('S')) return;
31
+  const byte pin_status = parser.value_byte();
32
+
33
+  const int pin_number = parser.intval('P', LED_PIN);
34
+  if (pin_number < 0) return;
35
+
36
+  if (pin_is_protected(pin_number)) {
37
+    SERIAL_ERROR_START();
38
+    SERIAL_ERRORLNPGM(MSG_ERR_PROTECTED_PIN);
39
+    return;
40
+  }
41
+
42
+  pinMode(pin_number, OUTPUT);
43
+  digitalWrite(pin_number, pin_status);
44
+  analogWrite(pin_number, pin_status);
45
+
46
+  #if FAN_COUNT > 0
47
+    switch (pin_number) {
48
+      #if HAS_FAN0
49
+        case FAN_PIN: fanSpeeds[0] = pin_status; break;
50
+      #endif
51
+      #if HAS_FAN1
52
+        case FAN1_PIN: fanSpeeds[1] = pin_status; break;
53
+      #endif
54
+      #if HAS_FAN2
55
+        case FAN2_PIN: fanSpeeds[2] = pin_status; break;
56
+      #endif
57
+    }
58
+  #endif
59
+}

+ 76
- 0
Marlin/src/gcode/control/M605.h View File

@@ -0,0 +1,76 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if ENABLED(DUAL_X_CARRIAGE)
24
+
25
+  /**
26
+   * M605: Set dual x-carriage movement mode
27
+   *
28
+   *    M605 S0: Full control mode. The slicer has full control over x-carriage movement
29
+   *    M605 S1: Auto-park mode. The inactive head will auto park/unpark without slicer involvement
30
+   *    M605 S2 [Xnnn] [Rmmm]: Duplication mode. The second extruder will duplicate the first with nnn
31
+   *                         units x-offset and an optional differential hotend temperature of
32
+   *                         mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate
33
+   *                         the first with a spacing of 100mm in the x direction and 2 degrees hotter.
34
+   *
35
+   *    Note: the X axis should be homed after changing dual x-carriage mode.
36
+   */
37
+  void gcode_M605() {
38
+    stepper.synchronize();
39
+    if (parser.seen('S')) dual_x_carriage_mode = (DualXMode)parser.value_byte();
40
+    switch (dual_x_carriage_mode) {
41
+      case DXC_FULL_CONTROL_MODE:
42
+      case DXC_AUTO_PARK_MODE:
43
+        break;
44
+      case DXC_DUPLICATION_MODE:
45
+        if (parser.seen('X')) duplicate_extruder_x_offset = max(parser.value_linear_units(), X2_MIN_POS - x_home_pos(0));
46
+        if (parser.seen('R')) duplicate_extruder_temp_offset = parser.value_celsius_diff();
47
+        SERIAL_ECHO_START();
48
+        SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
49
+        SERIAL_CHAR(' ');
50
+        SERIAL_ECHO(hotend_offset[X_AXIS][0]);
51
+        SERIAL_CHAR(',');
52
+        SERIAL_ECHO(hotend_offset[Y_AXIS][0]);
53
+        SERIAL_CHAR(' ');
54
+        SERIAL_ECHO(duplicate_extruder_x_offset);
55
+        SERIAL_CHAR(',');
56
+        SERIAL_ECHOLN(hotend_offset[Y_AXIS][1]);
57
+        break;
58
+      default:
59
+        dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
60
+        break;
61
+    }
62
+    active_extruder_parked = false;
63
+    extruder_duplication_enabled = false;
64
+    delayed_move_time = 0;
65
+  }
66
+
67
+#elif ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
68
+
69
+  void gcode_M605() {
70
+    stepper.synchronize();
71
+    extruder_duplication_enabled = parser.intval('S') == (int)DXC_DUPLICATION_MODE;
72
+    SERIAL_ECHO_START();
73
+    SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF);
74
+  }
75
+
76
+#endif // DUAL_NOZZLE_DUPLICATION_MODE

+ 56
- 0
Marlin/src/gcode/control/M80.h View File

@@ -0,0 +1,56 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M80   : Turn on the Power Supply
25
+ * M80 S : Report the current state and exit
26
+ */
27
+void gcode_M80() {
28
+
29
+  // S: Report the current power supply state and exit
30
+  if (parser.seen('S')) {
31
+    serialprintPGM(powersupply_on ? PSTR("PS:1\n") : PSTR("PS:0\n"));
32
+    return;
33
+  }
34
+
35
+  OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE); // GND
36
+
37
+  /**
38
+   * If you have a switch on suicide pin, this is useful
39
+   * if you want to start another print with suicide feature after
40
+   * a print without suicide...
41
+   */
42
+  #if HAS_SUICIDE
43
+    OUT_WRITE(SUICIDE_PIN, HIGH);
44
+  #endif
45
+
46
+  #if ENABLED(HAVE_TMC2130)
47
+    delay(100);
48
+    tmc2130_init(); // Settings only stick when the driver has power
49
+  #endif
50
+
51
+  powersupply_on = true;
52
+
53
+  #if ENABLED(ULTIPANEL)
54
+    LCD_MESSAGEPGM(WELCOME_MSG);
55
+  #endif
56
+}

+ 53
- 0
Marlin/src/gcode/control/M81.h View File

@@ -0,0 +1,53 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M81: Turn off Power, including Power Supply, if there is one.
25
+ *
26
+ *      This code should ALWAYS be available for EMERGENCY SHUTDOWN!
27
+ */
28
+void gcode_M81() {
29
+  thermalManager.disable_all_heaters();
30
+  stepper.finish_and_disable();
31
+
32
+  #if FAN_COUNT > 0
33
+    for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
34
+    #if ENABLED(PROBING_FANS_OFF)
35
+      fans_paused = false;
36
+      ZERO(paused_fanSpeeds);
37
+    #endif
38
+  #endif
39
+
40
+  safe_delay(1000); // Wait 1 second before switching off
41
+
42
+  #if HAS_SUICIDE
43
+    stepper.synchronize();
44
+    suicide();
45
+  #elif HAS_POWER_SWITCH
46
+    OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP);
47
+    powersupply_on = false;
48
+  #endif
49
+
50
+  #if ENABLED(ULTIPANEL)
51
+    LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF ".");
52
+  #endif
53
+}

+ 31
- 0
Marlin/src/gcode/control/M85.h View File

@@ -0,0 +1,31 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M85: Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
25
+ */
26
+void gcode_M85() {
27
+
28
+  if (parser.seen('S')) max_inactive_time = parser.value_millis_from_seconds();
29
+
30
+}
31
+

+ 41
- 0
Marlin/src/gcode/control/M999.h View File

@@ -0,0 +1,41 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M999: Restart after being stopped
25
+ *
26
+ * Default behaviour is to flush the serial buffer and request
27
+ * a resend to the host starting on the last N line received.
28
+ *
29
+ * Sending "M999 S1" will resume printing without flushing the
30
+ * existing command buffer.
31
+ *
32
+ */
33
+void gcode_M999() {
34
+  Running = true;
35
+  lcd_reset_alert_level();
36
+
37
+  if (parser.boolval('S')) return;
38
+
39
+  // gcode_LastN = Stopped_gcode_LastN;
40
+  FlushSerialRequestResend();
41
+}

+ 62
- 0
Marlin/src/gcode/control/T.h View File

@@ -0,0 +1,62 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../module/tool_change.h"
24
+
25
+/**
26
+ * T0-T3: Switch tool, usually switching extruders
27
+ *
28
+ *   F[units/min] Set the movement feedrate
29
+ *   S1           Don't move the tool in XY after change
30
+ */
31
+void gcode_T(uint8_t tmp_extruder) {
32
+
33
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
34
+    if (DEBUGGING(LEVELING)) {
35
+      SERIAL_ECHOPAIR(">>> gcode_T(", tmp_extruder);
36
+      SERIAL_CHAR(')');
37
+      SERIAL_EOL();
38
+      DEBUG_POS("BEFORE", current_position);
39
+    }
40
+  #endif
41
+
42
+  #if HOTENDS == 1 || (ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1)
43
+
44
+    tool_change(tmp_extruder);
45
+
46
+  #elif HOTENDS > 1
47
+
48
+    tool_change(
49
+      tmp_extruder,
50
+      MMM_TO_MMS(parser.linearval('F')),
51
+      (tmp_extruder == active_extruder) || parser.boolval('S')
52
+    );
53
+
54
+  #endif
55
+
56
+  #if ENABLED(DEBUG_LEVELING_FEATURE)
57
+    if (DEBUGGING(LEVELING)) {
58
+      DEBUG_POS("AFTER", current_position);
59
+      SERIAL_ECHOLNPGM("<<< gcode_T");
60
+    }
61
+  #endif
62
+}

+ 28
- 0
Marlin/src/gcode/eeprom/M500.h View File

@@ -0,0 +1,28 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M500: Store settings in EEPROM
25
+ */
26
+void gcode_M500() {
27
+  (void)settings.save();
28
+}

+ 28
- 0
Marlin/src/gcode/eeprom/M501.h View File

@@ -0,0 +1,28 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M501: Read settings from EEPROM
25
+ */
26
+void gcode_M501() {
27
+  (void)settings.load();
28
+}

+ 28
- 0
Marlin/src/gcode/eeprom/M502.h View File

@@ -0,0 +1,28 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M502: Revert to default settings
25
+ */
26
+void gcode_M502() {
27
+  (void)settings.reset();
28
+}

+ 28
- 0
Marlin/src/gcode/eeprom/M503.h View File

@@ -0,0 +1,28 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M503: print settings currently in memory
25
+ */
26
+void gcode_M503() {
27
+  (void)settings.report(!parser.boolval('S', true));
28
+}

+ 52
- 0
Marlin/src/gcode/feature/advance/M900.h View File

@@ -0,0 +1,52 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M900: Set and/or Get advance K factor and WH/D ratio
25
+ *
26
+ *  K<factor>                  Set advance K factor
27
+ *  R<ratio>                   Set ratio directly (overrides WH/D)
28
+ *  W<width> H<height> D<diam> Set ratio from WH/D
29
+ */
30
+void gcode_M900() {
31
+  stepper.synchronize();
32
+
33
+  const float newK = parser.floatval('K', -1);
34
+  if (newK >= 0) planner.extruder_advance_k = newK;
35
+
36
+  float newR = parser.floatval('R', -1);
37
+  if (newR < 0) {
38
+    const float newD = parser.floatval('D', -1),
39
+                newW = parser.floatval('W', -1),
40
+                newH = parser.floatval('H', -1);
41
+    if (newD >= 0 && newW >= 0 && newH >= 0)
42
+      newR = newD ? (newW * newH) / (sq(newD * 0.5) * M_PI) : 0;
43
+  }
44
+  if (newR >= 0) planner.advance_ed_ratio = newR;
45
+
46
+  SERIAL_ECHO_START();
47
+  SERIAL_ECHOPAIR("Advance K=", planner.extruder_advance_k);
48
+  SERIAL_ECHOPGM(" E/D=");
49
+  const float ratio = planner.advance_ed_ratio;
50
+  if (ratio) SERIAL_ECHO(ratio); else SERIAL_ECHOPGM("Auto");
51
+  SERIAL_EOL();
52
+}

+ 30
- 0
Marlin/src/gcode/feature/baricuda/M126.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M126: Heater 1 valve open
25
+ */
26
+void gcode_M126() {
27
+
28
+  baricuda_valve_pressure = parser.byteval('S', 255);
29
+
30
+}

+ 30
- 0
Marlin/src/gcode/feature/baricuda/M127.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M127: Heater 1 valve close
25
+ */
26
+void gcode_M127() {
27
+
28
+  baricuda_valve_pressure = 0;
29
+
30
+}

+ 30
- 0
Marlin/src/gcode/feature/baricuda/M128.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M128: Heater 2 valve open
25
+ */
26
+void gcode_M128() {
27
+
28
+  baricuda_e_to_p_pressure = parser.byteval('S', 255);
29
+
30
+}

+ 30
- 0
Marlin/src/gcode/feature/baricuda/M129.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M129: Heater 2 valve close
25
+ */
26
+void gcode_M129() {
27
+
28
+  baricuda_e_to_p_pressure = 0;
29
+
30
+}

+ 53
- 0
Marlin/src/gcode/feature/camera/M240.h View File

@@ -0,0 +1,53 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M240: Trigger a camera by emulating a Canon RC-1
25
+ *       See http://www.doc-diy.net/photo/rc-1_hacked/
26
+ */
27
+void gcode_M240() {
28
+  #ifdef CHDK
29
+
30
+    OUT_WRITE(CHDK, HIGH);
31
+    chdkHigh = millis();
32
+    chdkActive = true;
33
+
34
+  #elif HAS_PHOTOGRAPH
35
+
36
+    const uint8_t NUM_PULSES = 16;
37
+    const float PULSE_LENGTH = 0.01524;
38
+    for (int i = 0; i < NUM_PULSES; i++) {
39
+      WRITE(PHOTOGRAPH_PIN, HIGH);
40
+      _delay_ms(PULSE_LENGTH);
41
+      WRITE(PHOTOGRAPH_PIN, LOW);
42
+      _delay_ms(PULSE_LENGTH);
43
+    }
44
+    delay(7.33);
45
+    for (int i = 0; i < NUM_PULSES; i++) {
46
+      WRITE(PHOTOGRAPH_PIN, HIGH);
47
+      _delay_ms(PULSE_LENGTH);
48
+      WRITE(PHOTOGRAPH_PIN, LOW);
49
+      _delay_ms(PULSE_LENGTH);
50
+    }
51
+
52
+  #endif
53
+}

+ 77
- 0
Marlin/src/gcode/feature/caselight/M355.h View File

@@ -0,0 +1,77 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#if HAS_CASE_LIGHT
24
+
25
+  #ifndef INVERT_CASE_LIGHT
26
+    #define INVERT_CASE_LIGHT false
27
+  #endif
28
+  int case_light_brightness;  // LCD routine wants INT
29
+  bool case_light_on;
30
+
31
+  void update_case_light() {
32
+    pinMode(CASE_LIGHT_PIN, OUTPUT); // digitalWrite doesn't set the port mode
33
+    uint8_t case_light_bright = (uint8_t)case_light_brightness;
34
+    if (case_light_on) {
35
+      if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) {
36
+        analogWrite(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? 255 - case_light_brightness : case_light_brightness );
37
+      }
38
+      else WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? LOW : HIGH);
39
+    }
40
+    else WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? HIGH : LOW);
41
+  }
42
+
43
+#endif // HAS_CASE_LIGHT
44
+
45
+/**
46
+ * M355: Turn case light on/off and set brightness
47
+ *
48
+ *   P<byte>  Set case light brightness (PWM pin required - ignored otherwise)
49
+ *
50
+ *   S<bool>  Set case light on/off
51
+ *
52
+ *   When S turns on the light on a PWM pin then the current brightness level is used/restored
53
+ *
54
+ *   M355 P200 S0 turns off the light & sets the brightness level
55
+ *   M355 S1 turns on the light with a brightness of 200 (assuming a PWM pin)
56
+ */
57
+void gcode_M355() {
58
+  #if HAS_CASE_LIGHT
59
+    uint8_t args = 0;
60
+    if (parser.seenval('P')) ++args, case_light_brightness = parser.value_byte();
61
+    if (parser.seenval('S')) ++args, case_light_on = parser.value_bool();
62
+    if (args) update_case_light();
63
+
64
+    // always report case light status
65
+    SERIAL_ECHO_START();
66
+    if (!case_light_on) {
67
+      SERIAL_ECHOLN("Case light: off");
68
+    }
69
+    else {
70
+      if (!USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) SERIAL_ECHOLN("Case light: on");
71
+      else SERIAL_ECHOLNPAIR("Case light: ", case_light_brightness);
72
+    }
73
+  #else
74
+    SERIAL_ERROR_START();
75
+    SERIAL_ERRORLNPGM(MSG_ERR_M355_NONE);
76
+  #endif
77
+}

+ 36
- 0
Marlin/src/gcode/feature/clean/G12.h View File

@@ -0,0 +1,36 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * G12: Clean the nozzle
25
+ */
26
+void gcode_G12() {
27
+  // Don't allow nozzle cleaning without homing first
28
+  if (axis_unhomed_error()) return;
29
+
30
+  const uint8_t pattern = parser.ushortval('P', 0),
31
+                strokes = parser.ushortval('S', NOZZLE_CLEAN_STROKES),
32
+                objects = parser.ushortval('T', NOZZLE_CLEAN_TRIANGLES);
33
+  const float radius = parser.floatval('R', NOZZLE_CLEAN_CIRCLE_RADIUS);
34
+
35
+  Nozzle::clean(pattern, strokes, radius, objects);
36
+}

+ 61
- 0
Marlin/src/gcode/feature/digipot/M907.h View File

@@ -0,0 +1,61 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S
25
+ */
26
+void gcode_M907() {
27
+  #if HAS_DIGIPOTSS
28
+
29
+    LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.digipot_current(i, parser.value_int());
30
+    if (parser.seen('B')) stepper.digipot_current(4, parser.value_int());
31
+    if (parser.seen('S')) for (uint8_t i = 0; i <= 4; i++) stepper.digipot_current(i, parser.value_int());
32
+
33
+  #elif HAS_MOTOR_CURRENT_PWM
34
+
35
+    #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
36
+      if (parser.seen('X')) stepper.digipot_current(0, parser.value_int());
37
+    #endif
38
+    #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
39
+      if (parser.seen('Z')) stepper.digipot_current(1, parser.value_int());
40
+    #endif
41
+    #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
42
+      if (parser.seen('E')) stepper.digipot_current(2, parser.value_int());
43
+    #endif
44
+
45
+  #endif
46
+
47
+  #if ENABLED(DIGIPOT_I2C)
48
+    // this one uses actual amps in floating point
49
+    LOOP_XYZE(i) if (parser.seen(axis_codes[i])) digipot_i2c_set_current(i, parser.value_float());
50
+    // for each additional extruder (named B,C,D,E..., channels 4,5,6,7...)
51
+    for (uint8_t i = NUM_AXIS; i < DIGIPOT_I2C_NUM_CHANNELS; i++) if (parser.seen('B' + i - (NUM_AXIS))) digipot_i2c_set_current(i, parser.value_float());
52
+  #endif
53
+
54
+  #if ENABLED(DAC_STEPPER_CURRENT)
55
+    if (parser.seen('S')) {
56
+      const float dac_percent = parser.value_float();
57
+      for (uint8_t i = 0; i <= 4; i++) dac_current_percent(i, dac_percent);
58
+    }
59
+    LOOP_XYZE(i) if (parser.seen(axis_codes[i])) dac_current_percent(i, parser.value_float());
60
+  #endif
61
+}

+ 39
- 0
Marlin/src/gcode/feature/digipot/M908.h View File

@@ -0,0 +1,39 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M908: Control digital trimpot directly (M908 P<pin> S<current>)
25
+ */
26
+void gcode_M908() {
27
+  #if HAS_DIGIPOTSS
28
+    stepper.digitalPotWrite(
29
+      parser.intval('P'),
30
+      parser.intval('S')
31
+    );
32
+  #endif
33
+  #ifdef DAC_STEPPER_CURRENT
34
+    dac_current_raw(
35
+      parser.byteval('P', -1),
36
+      parser.ushortval('S', 0)
37
+    );
38
+  #endif
39
+}

+ 27
- 0
Marlin/src/gcode/feature/digipot/M909.h View File

@@ -0,0 +1,27 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+void gcode_M909() {
24
+
25
+  dac_print_values();
26
+
27
+}

+ 27
- 0
Marlin/src/gcode/feature/digipot/M910.h View File

@@ -0,0 +1,27 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+void gcode_M910() {
24
+
25
+  dac_commit_eeprom();
26
+
27
+}

+ 41
- 0
Marlin/src/gcode/feature/fwretract/G10_G11.h View File

@@ -0,0 +1,41 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * G10 - Retract filament according to settings of M207
25
+ */
26
+void gcode_G10() {
27
+  #if EXTRUDERS > 1
28
+    const bool rs = parser.boolval('S');
29
+    retracted_swap[active_extruder] = rs; // Use 'S' for swap, default to false
30
+  #endif
31
+  retract(true
32
+    #if EXTRUDERS > 1
33
+      , rs
34
+    #endif
35
+  );
36
+}
37
+
38
+/**
39
+ * G11 - Recover filament according to settings of M208
40
+ */
41
+void gcode_G11() { retract(false); }

+ 36
- 0
Marlin/src/gcode/feature/fwretract/M207.h View File

@@ -0,0 +1,36 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M207: Set firmware retraction values
25
+ *
26
+ *   S[+units]    retract_length
27
+ *   W[+units]    swap_retract_length (multi-extruder)
28
+ *   F[units/min] retract_feedrate_mm_s
29
+ *   Z[units]     retract_zlift
30
+ */
31
+void gcode_M207() {
32
+  if (parser.seen('S')) retract_length = parser.value_axis_units(E_AXIS);
33
+  if (parser.seen('F')) retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
34
+  if (parser.seen('Z')) retract_zlift = parser.value_linear_units();
35
+  if (parser.seen('W')) swap_retract_length = parser.value_axis_units(E_AXIS);
36
+}

+ 36
- 0
Marlin/src/gcode/feature/fwretract/M208.h View File

@@ -0,0 +1,36 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M208: Set firmware un-retraction values
25
+ *
26
+ *   S[+units]    retract_recover_length (in addition to M207 S*)
27
+ *   W[+units]    swap_retract_recover_length (multi-extruder)
28
+ *   F[units/min] retract_recover_feedrate_mm_s
29
+ *   R[units/min] swap_retract_recover_feedrate_mm_s
30
+ */
31
+void gcode_M208() {
32
+  if (parser.seen('S')) retract_recover_length = parser.value_axis_units(E_AXIS);
33
+  if (parser.seen('F')) retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
34
+  if (parser.seen('R')) swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
35
+  if (parser.seen('W')) swap_retract_recover_length = parser.value_axis_units(E_AXIS);
36
+}

+ 35
- 0
Marlin/src/gcode/feature/fwretract/M209.h View File

@@ -0,0 +1,35 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M209: Enable automatic retract (M209 S1)
25
+ *   For slicers that don't support G10/11, reversed extrude-only
26
+ *   moves will be classified as retraction.
27
+ */
28
+void gcode_M209() {
29
+  if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
30
+    if (parser.seen('S')) {
31
+      autoretract_enabled = parser.value_bool();
32
+      for (uint8_t i = 0; i < EXTRUDERS; i++) retracted[i] = false;
33
+    }
34
+  }
35
+}

+ 70
- 0
Marlin/src/gcode/feature/i2c/M260_M261.h View File

@@ -0,0 +1,70 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M260: Send data to a I2C slave device
25
+ *
26
+ * This is a PoC, the formating and arguments for the GCODE will
27
+ * change to be more compatible, the current proposal is:
28
+ *
29
+ *  M260 A<slave device address base 10> ; Sets the I2C slave address the data will be sent to
30
+ *
31
+ *  M260 B<byte-1 value in base 10>
32
+ *  M260 B<byte-2 value in base 10>
33
+ *  M260 B<byte-3 value in base 10>
34
+ *
35
+ *  M260 S1 ; Send the buffered data and reset the buffer
36
+ *  M260 R1 ; Reset the buffer without sending data
37
+ *
38
+ */
39
+void gcode_M260() {
40
+  // Set the target address
41
+  if (parser.seen('A')) i2c.address(parser.value_byte());
42
+
43
+  // Add a new byte to the buffer
44
+  if (parser.seen('B')) i2c.addbyte(parser.value_byte());
45
+
46
+  // Flush the buffer to the bus
47
+  if (parser.seen('S')) i2c.send();
48
+
49
+  // Reset and rewind the buffer
50
+  else if (parser.seen('R')) i2c.reset();
51
+}
52
+
53
+/**
54
+ * M261: Request X bytes from I2C slave device
55
+ *
56
+ * Usage: M261 A<slave device address base 10> B<number of bytes>
57
+ */
58
+void gcode_M261() {
59
+  if (parser.seen('A')) i2c.address(parser.value_byte());
60
+
61
+  uint8_t bytes = parser.byteval('B', 1);
62
+
63
+  if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE) {
64
+    i2c.relay(bytes);
65
+  }
66
+  else {
67
+    SERIAL_ERROR_START();
68
+    SERIAL_ERRORLN("Bad i2c request");
69
+  }
70
+}

+ 46
- 0
Marlin/src/gcode/feature/leds/M150.h View File

@@ -0,0 +1,46 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M150: Set Status LED Color - Use R-U-B-W for R-G-B-W
25
+ *
26
+ * Always sets all 3 or 4 components. If a component is left out, set to 0.
27
+ *
28
+ * Examples:
29
+ *
30
+ *   M150 R255       ; Turn LED red
31
+ *   M150 R255 U127  ; Turn LED orange (PWM only)
32
+ *   M150            ; Turn LED off
33
+ *   M150 R U B      ; Turn LED white
34
+ *   M150 W          ; Turn LED white using a white LED
35
+ *
36
+ */
37
+void gcode_M150() {
38
+  set_led_color(
39
+    parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
40
+    parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
41
+    parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0
42
+    #if ENABLED(RGBW_LED) || ENABLED(NEOPIXEL_RGBW_LED)
43
+      , parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0
44
+    #endif
45
+  );
46
+}

+ 38
- 0
Marlin/src/gcode/feature/mixing/M163.h View File

@@ -0,0 +1,38 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M163: Set a single mix factor for a mixing extruder
25
+ *       This is called "weight" by some systems.
26
+ *
27
+ *   S[index]   The channel index to set
28
+ *   P[float]   The mix value
29
+ *
30
+ */
31
+void gcode_M163() {
32
+  const int mix_index = parser.intval('S');
33
+  if (mix_index < MIXING_STEPPERS) {
34
+    float mix_value = parser.floatval('P');
35
+    NOLESS(mix_value, 0.0);
36
+    mixing_factor[mix_index] = RECIPROCAL(mix_value);
37
+  }
38
+}

+ 36
- 0
Marlin/src/gcode/feature/mixing/M164.h View File

@@ -0,0 +1,36 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M164: Store the current mix factors as a virtual tool.
25
+ *
26
+ *   S[index]   The virtual tool to store
27
+ *
28
+ */
29
+void gcode_M164() {
30
+  const int tool_index = parser.intval('S');
31
+  if (tool_index < MIXING_VIRTUAL_TOOLS) {
32
+    normalize_mix();
33
+    for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
34
+      mixing_virtual_tool_mix[tool_index][i] = mixing_factor[i];
35
+  }
36
+}

+ 36
- 0
Marlin/src/gcode/feature/mixing/M165.h View File

@@ -0,0 +1,36 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M165: Set multiple mix factors for a mixing extruder.
25
+ *       Factors that are left out will be set to 0.
26
+ *       All factors together must add up to 1.0.
27
+ *
28
+ *   A[factor] Mix factor for extruder stepper 1
29
+ *   B[factor] Mix factor for extruder stepper 2
30
+ *   C[factor] Mix factor for extruder stepper 3
31
+ *   D[factor] Mix factor for extruder stepper 4
32
+ *   H[factor] Mix factor for extruder stepper 5
33
+ *   I[factor] Mix factor for extruder stepper 6
34
+ *
35
+ */
36
+void gcode_M165() { gcode_get_mix(); }

+ 30
- 0
Marlin/src/gcode/feature/pause/G27.h View File

@@ -0,0 +1,30 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * G27: Park the nozzle
25
+ */
26
+void gcode_G27() {
27
+  // Don't allow nozzle parking without homing first
28
+  if (axis_unhomed_error()) return;
29
+  Nozzle::park(parser.ushortval('P'));
30
+}

+ 89
- 0
Marlin/src/gcode/feature/pause/M125.h View File

@@ -0,0 +1,89 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "common.h"
24
+
25
+/**
26
+ * M125: Store current position and move to filament change position.
27
+ *       Called on pause (by M25) to prevent material leaking onto the
28
+ *       object. On resume (M24) the head will be moved back and the
29
+ *       print will resume.
30
+ *
31
+ *       If Marlin is compiled without SD Card support, M125 can be
32
+ *       used directly to pause the print and move to park position,
33
+ *       resuming with a button click or M108.
34
+ *
35
+ *    L = override retract length
36
+ *    X = override X
37
+ *    Y = override Y
38
+ *    Z = override Z raise
39
+ */
40
+void gcode_M125() {
41
+
42
+  // Initial retract before move to filament change position
43
+  const float retract = parser.seen('L') ? parser.value_axis_units(E_AXIS) : 0
44
+    #ifdef PAUSE_PARK_RETRACT_LENGTH
45
+      - (PAUSE_PARK_RETRACT_LENGTH)
46
+    #endif
47
+  ;
48
+
49
+  // Lift Z axis
50
+  const float z_lift = parser.linearval('Z')
51
+    #ifdef PAUSE_PARK_Z_ADD
52
+      + PAUSE_PARK_Z_ADD
53
+    #endif
54
+  ;
55
+
56
+  // Move XY axes to filament change position or given position
57
+  const float x_pos = parser.linearval('X')
58
+    #ifdef PAUSE_PARK_X_POS
59
+      + PAUSE_PARK_X_POS
60
+    #endif
61
+    #if HOTENDS > 1 && DISABLED(DUAL_X_CARRIAGE)
62
+      + (active_extruder ? hotend_offset[X_AXIS][active_extruder] : 0)
63
+    #endif
64
+  ;
65
+  const float y_pos = parser.linearval('Y')
66
+    #ifdef PAUSE_PARK_Y_POS
67
+      + PAUSE_PARK_Y_POS
68
+    #endif
69
+    #if HOTENDS > 1 && DISABLED(DUAL_X_CARRIAGE)
70
+      + (active_extruder ? hotend_offset[Y_AXIS][active_extruder] : 0)
71
+    #endif
72
+  ;
73
+
74
+  #if DISABLED(SDSUPPORT)
75
+    const bool job_running = print_job_timer.isRunning();
76
+  #endif
77
+
78
+  if (pause_print(retract, z_lift, x_pos, y_pos)) {
79
+    #if DISABLED(SDSUPPORT)
80
+      // Wait for lcd click or M108
81
+      wait_for_filament_reload();
82
+
83
+      // Return to print position and continue
84
+      resume_print();
85
+
86
+      if (job_running) print_job_timer.start();
87
+    #endif
88
+  }
89
+}

+ 103
- 0
Marlin/src/gcode/feature/pause/M600.h View File

@@ -0,0 +1,103 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "common.h"
24
+
25
+/**
26
+ * M600: Pause for filament change
27
+ *
28
+ *  E[distance] - Retract the filament this far (negative value)
29
+ *  Z[distance] - Move the Z axis by this distance
30
+ *  X[position] - Move to this X position, with Y
31
+ *  Y[position] - Move to this Y position, with X
32
+ *  U[distance] - Retract distance for removal (negative value) (manual reload)
33
+ *  L[distance] - Extrude distance for insertion (positive value) (manual reload)
34
+ *  B[count]    - Number of times to beep, -1 for indefinite (if equipped with a buzzer)
35
+ *
36
+ *  Default values are used for omitted arguments.
37
+ *
38
+ */
39
+void gcode_M600() {
40
+
41
+  #if ENABLED(HOME_BEFORE_FILAMENT_CHANGE)
42
+    // Don't allow filament change without homing first
43
+    if (axis_unhomed_error()) home_all_axes();
44
+  #endif
45
+
46
+  // Initial retract before move to filament change position
47
+  const float retract = parser.seen('E') ? parser.value_axis_units(E_AXIS) : 0
48
+    #ifdef PAUSE_PARK_RETRACT_LENGTH
49
+      - (PAUSE_PARK_RETRACT_LENGTH)
50
+    #endif
51
+  ;
52
+
53
+  // Lift Z axis
54
+  const float z_lift = parser.linearval('Z', 0
55
+    #ifdef PAUSE_PARK_Z_ADD
56
+      + PAUSE_PARK_Z_ADD
57
+    #endif
58
+  );
59
+
60
+  // Move XY axes to filament exchange position
61
+  const float x_pos = parser.linearval('X', 0
62
+    #ifdef PAUSE_PARK_X_POS
63
+      + PAUSE_PARK_X_POS
64
+    #endif
65
+  );
66
+  const float y_pos = parser.linearval('Y', 0
67
+    #ifdef PAUSE_PARK_Y_POS
68
+      + PAUSE_PARK_Y_POS
69
+    #endif
70
+  );
71
+
72
+  // Unload filament
73
+  const float unload_length = parser.seen('U') ? parser.value_axis_units(E_AXIS) : 0
74
+    #if defined(FILAMENT_CHANGE_UNLOAD_LENGTH) && FILAMENT_CHANGE_UNLOAD_LENGTH > 0
75
+      - (FILAMENT_CHANGE_UNLOAD_LENGTH)
76
+    #endif
77
+  ;
78
+
79
+  // Load filament
80
+  const float load_length = parser.seen('L') ? parser.value_axis_units(E_AXIS) : 0
81
+    #ifdef FILAMENT_CHANGE_LOAD_LENGTH
82
+      + FILAMENT_CHANGE_LOAD_LENGTH
83
+    #endif
84
+  ;
85
+
86
+  const int beep_count = parser.intval('B',
87
+    #ifdef FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS
88
+      FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS
89
+    #else
90
+      -1
91
+    #endif
92
+  );
93
+
94
+  const bool job_running = print_job_timer.isRunning();
95
+
96
+  if (pause_print(retract, z_lift, x_pos, y_pos, unload_length, beep_count, true)) {
97
+    wait_for_filament_reload(beep_count);
98
+    resume_print(load_length, ADVANCED_PAUSE_EXTRUDE_LENGTH, beep_count);
99
+  }
100
+
101
+  // Resume the print job timer if it was running
102
+  if (job_running) print_job_timer.start();
103
+}

+ 335
- 0
Marlin/src/gcode/feature/pause/common.h View File

@@ -0,0 +1,335 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * feature/pause/common.h - Merge this with its G-codes in the refactor
25
+ */
26
+
27
+#ifndef PAUSE_COMMON_H
28
+#define PAUSE_COMMON_H
29
+
30
+#if IS_KINEMATIC
31
+  #define RUNPLAN(RATE_MM_S) planner.buffer_line_kinematic(destination, RATE_MM_S, active_extruder)
32
+#else
33
+  #define RUNPLAN(RATE_MM_S) line_to_destination(RATE_MM_S)
34
+#endif
35
+
36
+static float resume_position[XYZE];
37
+static bool move_away_flag = false;
38
+#if ENABLED(SDSUPPORT)
39
+  static bool sd_print_paused = false;
40
+#endif
41
+
42
+static void filament_change_beep(const int8_t max_beep_count, const bool init=false) {
43
+  static millis_t next_buzz = 0;
44
+  static int8_t runout_beep = 0;
45
+
46
+  if (init) next_buzz = runout_beep = 0;
47
+
48
+  const millis_t ms = millis();
49
+  if (ELAPSED(ms, next_buzz)) {
50
+    if (max_beep_count < 0 || runout_beep < max_beep_count + 5) { // Only beep as long as we're supposed to
51
+      next_buzz = ms + ((max_beep_count < 0 || runout_beep < max_beep_count) ? 2500 : 400);
52
+      BUZZ(300, 2000);
53
+      runout_beep++;
54
+    }
55
+  }
56
+}
57
+
58
+static void ensure_safe_temperature() {
59
+  bool heaters_heating = true;
60
+
61
+  wait_for_heatup = true;    // M108 will clear this
62
+  while (wait_for_heatup && heaters_heating) {
63
+    idle();
64
+    heaters_heating = false;
65
+    HOTEND_LOOP() {
66
+      if (thermalManager.degTargetHotend(e) && abs(thermalManager.degHotend(e) - thermalManager.degTargetHotend(e)) > TEMP_HYSTERESIS) {
67
+        heaters_heating = true;
68
+        #if ENABLED(ULTIPANEL)
69
+          lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_WAIT_FOR_NOZZLES_TO_HEAT);
70
+        #endif
71
+        break;
72
+      }
73
+    }
74
+  }
75
+}
76
+
77
+static bool pause_print(const float &retract, const float &z_lift, const float &x_pos, const float &y_pos,
78
+                        const float &unload_length = 0 , const int8_t max_beep_count = 0, const bool show_lcd = false
79
+) {
80
+  if (move_away_flag) return false; // already paused
81
+
82
+  if (!DEBUGGING(DRYRUN) && (unload_length != 0 || retract != 0)) {
83
+    #if ENABLED(PREVENT_COLD_EXTRUSION)
84
+      if (!thermalManager.allow_cold_extrude &&
85
+          thermalManager.degTargetHotend(active_extruder) < thermalManager.extrude_min_temp) {
86
+        SERIAL_ERROR_START();
87
+        SERIAL_ERRORLNPGM(MSG_TOO_COLD_FOR_M600);
88
+        return false;
89
+      }
90
+    #endif
91
+
92
+    ensure_safe_temperature(); // wait for extruder to heat up before unloading
93
+  }
94
+
95
+  // Indicate that the printer is paused
96
+  move_away_flag = true;
97
+
98
+  // Pause the print job and timer
99
+  #if ENABLED(SDSUPPORT)
100
+    if (IS_SD_PRINTING) {
101
+      card.pauseSDPrint();
102
+      sd_print_paused = true;
103
+    }
104
+  #endif
105
+  print_job_timer.pause();
106
+
107
+  // Show initial message and wait for synchronize steppers
108
+  if (show_lcd) {
109
+    #if ENABLED(ULTIPANEL)
110
+      lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INIT);
111
+    #endif
112
+  }
113
+
114
+  // Save current position
115
+  stepper.synchronize();
116
+  COPY(resume_position, current_position);
117
+
118
+  if (retract) {
119
+    // Initial retract before move to filament change position
120
+    set_destination_to_current();
121
+    destination[E_AXIS] += retract;
122
+    RUNPLAN(PAUSE_PARK_RETRACT_FEEDRATE);
123
+    stepper.synchronize();
124
+  }
125
+
126
+  // Lift Z axis
127
+  if (z_lift > 0)
128
+    do_blocking_move_to_z(current_position[Z_AXIS] + z_lift, PAUSE_PARK_Z_FEEDRATE);
129
+
130
+  // Move XY axes to filament exchange position
131
+  do_blocking_move_to_xy(x_pos, y_pos, PAUSE_PARK_XY_FEEDRATE);
132
+
133
+  if (unload_length != 0) {
134
+    if (show_lcd) {
135
+      #if ENABLED(ULTIPANEL)
136
+        lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_UNLOAD);
137
+        idle();
138
+      #endif
139
+    }
140
+
141
+    // Unload filament
142
+    set_destination_to_current();
143
+    destination[E_AXIS] += unload_length;
144
+    RUNPLAN(FILAMENT_CHANGE_UNLOAD_FEEDRATE);
145
+    stepper.synchronize();
146
+  }
147
+
148
+  if (show_lcd) {
149
+    #if ENABLED(ULTIPANEL)
150
+      lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INSERT);
151
+    #endif
152
+  }
153
+
154
+  #if HAS_BUZZER
155
+    filament_change_beep(max_beep_count, true);
156
+  #endif
157
+
158
+  idle();
159
+
160
+  // Disable extruders steppers for manual filament changing (only on boards that have separate ENABLE_PINS)
161
+  #if E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN
162
+    disable_e_steppers();
163
+    safe_delay(100);
164
+  #endif
165
+
166
+  // Start the heater idle timers
167
+  const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL;
168
+
169
+  HOTEND_LOOP()
170
+    thermalManager.start_heater_idle_timer(e, nozzle_timeout);
171
+
172
+  return true;
173
+}
174
+
175
+static void wait_for_filament_reload(const int8_t max_beep_count = 0) {
176
+  bool nozzle_timed_out = false;
177
+
178
+  // Wait for filament insert by user and press button
179
+  KEEPALIVE_STATE(PAUSED_FOR_USER);
180
+  wait_for_user = true;    // LCD click or M108 will clear this
181
+  while (wait_for_user) {
182
+    #if HAS_BUZZER
183
+      filament_change_beep(max_beep_count);
184
+    #endif
185
+
186
+    // If the nozzle has timed out, wait for the user to press the button to re-heat the nozzle, then
187
+    // re-heat the nozzle, re-show the insert screen, restart the idle timers, and start over
188
+    if (!nozzle_timed_out)
189
+      HOTEND_LOOP()
190
+        nozzle_timed_out |= thermalManager.is_heater_idle(e);
191
+
192
+    if (nozzle_timed_out) {
193
+      #if ENABLED(ULTIPANEL)
194
+        lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_CLICK_TO_HEAT_NOZZLE);
195
+      #endif
196
+
197
+      // Wait for LCD click or M108
198
+      while (wait_for_user) idle(true);
199
+
200
+      // Re-enable the heaters if they timed out
201
+      HOTEND_LOOP() thermalManager.reset_heater_idle_timer(e);
202
+
203
+      // Wait for the heaters to reach the target temperatures
204
+      ensure_safe_temperature();
205
+
206
+      #if ENABLED(ULTIPANEL)
207
+        lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INSERT);
208
+      #endif
209
+
210
+      // Start the heater idle timers
211
+      const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL;
212
+
213
+      HOTEND_LOOP()
214
+        thermalManager.start_heater_idle_timer(e, nozzle_timeout);
215
+
216
+      wait_for_user = true; /* Wait for user to load filament */
217
+      nozzle_timed_out = false;
218
+
219
+      #if HAS_BUZZER
220
+        filament_change_beep(max_beep_count, true);
221
+      #endif
222
+    }
223
+
224
+    idle(true);
225
+  }
226
+  KEEPALIVE_STATE(IN_HANDLER);
227
+}
228
+
229
+static void resume_print(const float &load_length = 0, const float &initial_extrude_length = 0, const int8_t max_beep_count = 0) {
230
+  bool nozzle_timed_out = false;
231
+
232
+  if (!move_away_flag) return;
233
+
234
+  // Re-enable the heaters if they timed out
235
+  HOTEND_LOOP() {
236
+    nozzle_timed_out |= thermalManager.is_heater_idle(e);
237
+    thermalManager.reset_heater_idle_timer(e);
238
+  }
239
+
240
+  if (nozzle_timed_out) ensure_safe_temperature();
241
+
242
+  #if HAS_BUZZER
243
+    filament_change_beep(max_beep_count, true);
244
+  #endif
245
+
246
+  if (load_length != 0) {
247
+    #if ENABLED(ULTIPANEL)
248
+      // Show "insert filament"
249
+      if (nozzle_timed_out)
250
+        lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INSERT);
251
+    #endif
252
+
253
+    KEEPALIVE_STATE(PAUSED_FOR_USER);
254
+    wait_for_user = true;    // LCD click or M108 will clear this
255
+    while (wait_for_user && nozzle_timed_out) {
256
+      #if HAS_BUZZER
257
+        filament_change_beep(max_beep_count);
258
+      #endif
259
+      idle(true);
260
+    }
261
+    KEEPALIVE_STATE(IN_HANDLER);
262
+
263
+    #if ENABLED(ULTIPANEL)
264
+      // Show "load" message
265
+      lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_LOAD);
266
+    #endif
267
+
268
+    // Load filament
269
+    destination[E_AXIS] += load_length;
270
+    RUNPLAN(FILAMENT_CHANGE_LOAD_FEEDRATE);
271
+    stepper.synchronize();
272
+  }
273
+
274
+  #if ENABLED(ULTIPANEL) && ADVANCED_PAUSE_EXTRUDE_LENGTH > 0
275
+
276
+    float extrude_length = initial_extrude_length;
277
+
278
+    do {
279
+      if (extrude_length > 0) {
280
+        // "Wait for filament extrude"
281
+        lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_EXTRUDE);
282
+
283
+        // Extrude filament to get into hotend
284
+        destination[E_AXIS] += extrude_length;
285
+        RUNPLAN(ADVANCED_PAUSE_EXTRUDE_FEEDRATE);
286
+        stepper.synchronize();
287
+      }
288
+
289
+      // Show "Extrude More" / "Resume" menu and wait for reply
290
+      KEEPALIVE_STATE(PAUSED_FOR_USER);
291
+      wait_for_user = false;
292
+      lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_OPTION);
293
+      while (advanced_pause_menu_response == ADVANCED_PAUSE_RESPONSE_WAIT_FOR) idle(true);
294
+      KEEPALIVE_STATE(IN_HANDLER);
295
+
296
+      extrude_length = ADVANCED_PAUSE_EXTRUDE_LENGTH;
297
+
298
+      // Keep looping if "Extrude More" was selected
299
+    } while (advanced_pause_menu_response == ADVANCED_PAUSE_RESPONSE_EXTRUDE_MORE);
300
+
301
+  #endif
302
+
303
+  #if ENABLED(ULTIPANEL)
304
+    // "Wait for print to resume"
305
+    lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_RESUME);
306
+  #endif
307
+
308
+  // Set extruder to saved position
309
+  destination[E_AXIS] = current_position[E_AXIS] = resume_position[E_AXIS];
310
+  planner.set_e_position_mm(current_position[E_AXIS]);
311
+
312
+  // Move XY to starting position, then Z
313
+  do_blocking_move_to_xy(resume_position[X_AXIS], resume_position[Y_AXIS], PAUSE_PARK_XY_FEEDRATE);
314
+  do_blocking_move_to_z(resume_position[Z_AXIS], PAUSE_PARK_Z_FEEDRATE);
315
+
316
+  #if ENABLED(FILAMENT_RUNOUT_SENSOR)
317
+    filament_ran_out = false;
318
+  #endif
319
+
320
+  #if ENABLED(ULTIPANEL)
321
+    // Show status screen
322
+    lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_STATUS);
323
+  #endif
324
+
325
+  #if ENABLED(SDSUPPORT)
326
+    if (sd_print_paused) {
327
+      card.startFileprint();
328
+      sd_print_paused = false;
329
+    }
330
+  #endif
331
+
332
+  move_away_flag = false;
333
+}
334
+
335
+#endif // PAUSE_COMMON_H

+ 50
- 0
Marlin/src/gcode/feature/snmm/M702.h View File

@@ -0,0 +1,50 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+inline void select_multiplexed_stepper(const uint8_t e) {
24
+  stepper.synchronize();
25
+  disable_e_steppers();
26
+  WRITE(E_MUX0_PIN, TEST(e, 0) ? HIGH : LOW);
27
+  WRITE(E_MUX1_PIN, TEST(e, 1) ? HIGH : LOW);
28
+  WRITE(E_MUX2_PIN, TEST(e, 2) ? HIGH : LOW);
29
+  safe_delay(100);
30
+}
31
+
32
+/**
33
+ * M702: Unload all extruders
34
+ */
35
+void gcode_M702() {
36
+  for (uint8_t s = 0; s < E_STEPPERS; s++) {
37
+    select_multiplexed_stepper(e);
38
+    // TODO: standard unload filament function
39
+    // MK2 firmware behavior:
40
+    //  - Make sure temperature is high enough
41
+    //  - Raise Z to at least 15 to make room
42
+    //  - Extrude 1cm of filament in 1 second
43
+    //  - Under 230C quickly purge ~12mm, over 230C purge ~10mm
44
+    //  - Change E max feedrate to 80, eject the filament from the tube. Sync.
45
+    //  - Restore E max feedrate to 50
46
+  }
47
+  // Go back to the last active extruder
48
+  select_multiplexed_stepper(active_extruder);
49
+  disable_e_steppers();
50
+}

+ 65
- 0
Marlin/src/gcode/feature/trinamic/M906.h View File

@@ -0,0 +1,65 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+static void tmc2130_get_current(TMC2130Stepper &st, const char name) {
24
+  SERIAL_CHAR(name);
25
+  SERIAL_ECHOPGM(" axis driver current: ");
26
+  SERIAL_ECHOLN(st.getCurrent());
27
+}
28
+static void tmc2130_set_current(TMC2130Stepper &st, const char name, const int mA) {
29
+  st.setCurrent(mA, R_SENSE, HOLD_MULTIPLIER);
30
+  tmc2130_get_current(st, name);
31
+}
32
+
33
+/**
34
+ * M906: Set motor current in milliamps using axis codes X, Y, Z, E
35
+ * Report driver currents when no axis specified
36
+ *
37
+ * S1: Enable automatic current control
38
+ * S0: Disable
39
+ */
40
+void gcode_M906() {
41
+  uint16_t values[XYZE];
42
+  LOOP_XYZE(i)
43
+    values[i] = parser.intval(axis_codes[i]);
44
+
45
+  #if ENABLED(X_IS_TMC2130)
46
+    if (values[X_AXIS]) tmc2130_set_current(stepperX, 'X', values[X_AXIS]);
47
+    else tmc2130_get_current(stepperX, 'X');
48
+  #endif
49
+  #if ENABLED(Y_IS_TMC2130)
50
+    if (values[Y_AXIS]) tmc2130_set_current(stepperY, 'Y', values[Y_AXIS]);
51
+    else tmc2130_get_current(stepperY, 'Y');
52
+  #endif
53
+  #if ENABLED(Z_IS_TMC2130)
54
+    if (values[Z_AXIS]) tmc2130_set_current(stepperZ, 'Z', values[Z_AXIS]);
55
+    else tmc2130_get_current(stepperZ, 'Z');
56
+  #endif
57
+  #if ENABLED(E0_IS_TMC2130)
58
+    if (values[E_AXIS]) tmc2130_set_current(stepperE0, 'E', values[E_AXIS]);
59
+    else tmc2130_get_current(stepperE0, 'E');
60
+  #endif
61
+
62
+  #if ENABLED(AUTOMATIC_CURRENT_CONTROL)
63
+    if (parser.seen('S')) auto_current_control = parser.value_bool();
64
+  #endif
65
+}

+ 49
- 0
Marlin/src/gcode/feature/trinamic/M911.h View File

@@ -0,0 +1,49 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+static void tmc2130_report_otpw(TMC2130Stepper &st, const char name) {
24
+  SERIAL_CHAR(name);
25
+  SERIAL_ECHOPGM(" axis temperature prewarn triggered: ");
26
+  serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false"));
27
+  SERIAL_EOL();
28
+}
29
+
30
+/**
31
+ * M911: Report TMC2130 stepper driver overtemperature pre-warn flag
32
+ * The flag is held by the library and persist until manually cleared by M912
33
+ */
34
+void gcode_M911() {
35
+  const bool reportX = parser.seen('X'), reportY = parser.seen('Y'), reportZ = parser.seen('Z'), reportE = parser.seen('E'),
36
+           reportAll = (!reportX && !reportY && !reportZ && !reportE) || (reportX && reportY && reportZ && reportE);
37
+  #if ENABLED(X_IS_TMC2130)
38
+    if (reportX || reportAll) tmc2130_report_otpw(stepperX, 'X');
39
+  #endif
40
+  #if ENABLED(Y_IS_TMC2130)
41
+    if (reportY || reportAll) tmc2130_report_otpw(stepperY, 'Y');
42
+  #endif
43
+  #if ENABLED(Z_IS_TMC2130)
44
+    if (reportZ || reportAll) tmc2130_report_otpw(stepperZ, 'Z');
45
+  #endif
46
+  #if ENABLED(E0_IS_TMC2130)
47
+    if (reportE || reportAll) tmc2130_report_otpw(stepperE0, 'E');
48
+  #endif
49
+}

+ 47
- 0
Marlin/src/gcode/feature/trinamic/M912.h View File

@@ -0,0 +1,47 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+static void tmc2130_clear_otpw(TMC2130Stepper &st, const char name) {
24
+  st.clear_otpw();
25
+  SERIAL_CHAR(name);
26
+  SERIAL_ECHOLNPGM(" prewarn flag cleared");
27
+}
28
+
29
+/**
30
+ * M912: Clear TMC2130 stepper driver overtemperature pre-warn flag held by the library
31
+ */
32
+void gcode_M912() {
33
+  const bool clearX = parser.seen('X'), clearY = parser.seen('Y'), clearZ = parser.seen('Z'), clearE = parser.seen('E'),
34
+           clearAll = (!clearX && !clearY && !clearZ && !clearE) || (clearX && clearY && clearZ && clearE);
35
+  #if ENABLED(X_IS_TMC2130)
36
+    if (clearX || clearAll) tmc2130_clear_otpw(stepperX, 'X');
37
+  #endif
38
+  #if ENABLED(Y_IS_TMC2130)
39
+    if (clearY || clearAll) tmc2130_clear_otpw(stepperY, 'Y');
40
+  #endif
41
+  #if ENABLED(Z_IS_TMC2130)
42
+    if (clearZ || clearAll) tmc2130_clear_otpw(stepperZ, 'Z');
43
+  #endif
44
+  #if ENABLED(E0_IS_TMC2130)
45
+    if (clearE || clearAll) tmc2130_clear_otpw(stepperE0, 'E');
46
+  #endif
47
+}

+ 57
- 0
Marlin/src/gcode/feature/trinamic/M913.h View File

@@ -0,0 +1,57 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+static void tmc2130_get_pwmthrs(TMC2130Stepper &st, const char name, const uint16_t spmm) {
24
+  SERIAL_CHAR(name);
25
+  SERIAL_ECHOPGM(" stealthChop max speed set to ");
26
+  SERIAL_ECHOLN(12650000UL * st.microsteps() / (256 * st.stealth_max_speed() * spmm));
27
+}
28
+static void tmc2130_set_pwmthrs(TMC2130Stepper &st, const char name, const int32_t thrs, const uint32_t spmm) {
29
+  st.stealth_max_speed(12650000UL * st.microsteps() / (256 * thrs * spmm));
30
+  tmc2130_get_pwmthrs(st, name, spmm);
31
+}
32
+
33
+/**
34
+ * M913: Set HYBRID_THRESHOLD speed.
35
+ */
36
+void gcode_M913() {
37
+  uint16_t values[XYZE];
38
+  LOOP_XYZE(i)
39
+    values[i] = parser.intval(axis_codes[i]);
40
+
41
+  #if ENABLED(X_IS_TMC2130)
42
+    if (values[X_AXIS]) tmc2130_set_pwmthrs(stepperX, 'X', values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]);
43
+    else tmc2130_get_pwmthrs(stepperX, 'X', planner.axis_steps_per_mm[X_AXIS]);
44
+  #endif
45
+  #if ENABLED(Y_IS_TMC2130)
46
+    if (values[Y_AXIS]) tmc2130_set_pwmthrs(stepperY, 'Y', values[Y_AXIS], planner.axis_steps_per_mm[Y_AXIS]);
47
+    else tmc2130_get_pwmthrs(stepperY, 'Y', planner.axis_steps_per_mm[Y_AXIS]);
48
+  #endif
49
+  #if ENABLED(Z_IS_TMC2130)
50
+    if (values[Z_AXIS]) tmc2130_set_pwmthrs(stepperZ, 'Z', values[Z_AXIS], planner.axis_steps_per_mm[Z_AXIS]);
51
+    else tmc2130_get_pwmthrs(stepperZ, 'Z', planner.axis_steps_per_mm[Z_AXIS]);
52
+  #endif
53
+  #if ENABLED(E0_IS_TMC2130)
54
+    if (values[E_AXIS]) tmc2130_set_pwmthrs(stepperE0, 'E', values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]);
55
+    else tmc2130_get_pwmthrs(stepperE0, 'E', planner.axis_steps_per_mm[E_AXIS]);
56
+  #endif
57
+}

+ 45
- 0
Marlin/src/gcode/feature/trinamic/M914.h View File

@@ -0,0 +1,45 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+static void tmc2130_get_sgt(TMC2130Stepper &st, const char name) {
24
+  SERIAL_CHAR(name);
25
+  SERIAL_ECHOPGM(" driver homing sensitivity set to ");
26
+  SERIAL_ECHOLN(st.sgt());
27
+}
28
+static void tmc2130_set_sgt(TMC2130Stepper &st, const char name, const int8_t sgt_val) {
29
+  st.sgt(sgt_val);
30
+  tmc2130_get_sgt(st, name);
31
+}
32
+
33
+/**
34
+ * M914: Set SENSORLESS_HOMING sensitivity.
35
+ */
36
+void gcode_M914() {
37
+  #if ENABLED(X_IS_TMC2130)
38
+    if (parser.seen(axis_codes[X_AXIS])) tmc2130_set_sgt(stepperX, 'X', parser.value_int());
39
+    else tmc2130_get_sgt(stepperX, 'X');
40
+  #endif
41
+  #if ENABLED(Y_IS_TMC2130)
42
+    if (parser.seen(axis_codes[Y_AXIS])) tmc2130_set_sgt(stepperY, 'Y', parser.value_int());
43
+    else tmc2130_get_sgt(stepperY, 'Y');
44
+  #endif
45
+}

+ 682
- 0
Marlin/src/gcode/gcode.h View File

@@ -0,0 +1,682 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * gcode.h - Temporary container for all gcode handlers
25
+ */
26
+
27
+/**
28
+ * -----------------
29
+ * G-Codes in Marlin
30
+ * -----------------
31
+ *
32
+ * Helpful G-code references:
33
+ *  - http://linuxcnc.org/handbook/gcode/g-code.html
34
+ *  - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
35
+ *
36
+ * Help to document Marlin's G-codes online:
37
+ *  - http://reprap.org/wiki/G-code
38
+ *  - https://github.com/MarlinFirmware/MarlinDocumentation
39
+ *
40
+ * -----------------
41
+ *
42
+ * "G" Codes
43
+ *
44
+ * G0   -> G1
45
+ * G1   - Coordinated Movement X Y Z E
46
+ * G2   - CW ARC
47
+ * G3   - CCW ARC
48
+ * G4   - Dwell S<seconds> or P<milliseconds>
49
+ * G5   - Cubic B-spline with XYZE destination and IJPQ offsets
50
+ * G10  - Retract filament according to settings of M207 (Requires FWRETRACT)
51
+ * G11  - Retract recover filament according to settings of M208 (Requires FWRETRACT)
52
+ * G12  - Clean tool (Requires NOZZLE_CLEAN_FEATURE)
53
+ * G17  - Select Plane XY (Requires CNC_WORKSPACE_PLANES)
54
+ * G18  - Select Plane ZX (Requires CNC_WORKSPACE_PLANES)
55
+ * G19  - Select Plane YZ (Requires CNC_WORKSPACE_PLANES)
56
+ * G20  - Set input units to inches (Requires INCH_MODE_SUPPORT)
57
+ * G21  - Set input units to millimeters (Requires INCH_MODE_SUPPORT)
58
+ * G26  - Mesh Validation Pattern (Requires UBL_G26_MESH_VALIDATION)
59
+ * G27  - Park Nozzle (Requires NOZZLE_PARK_FEATURE)
60
+ * G28  - Home one or more axes
61
+ * G29  - Start or continue the bed leveling probe procedure (Requires bed leveling)
62
+ * G30  - Single Z probe, probes bed at X Y location (defaults to current XY location)
63
+ * G31  - Dock sled (Z_PROBE_SLED only)
64
+ * G32  - Undock sled (Z_PROBE_SLED only)
65
+ * G33  - Delta Auto-Calibration (Requires DELTA_AUTO_CALIBRATION)
66
+ * G38  - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET)
67
+ * G42  - Coordinated move to a mesh point (Requires AUTO_BED_LEVELING_UBL)
68
+ * G90  - Use Absolute Coordinates
69
+ * G91  - Use Relative Coordinates
70
+ * G92  - Set current position to coordinates given
71
+ *
72
+ * "M" Codes
73
+ *
74
+ * M0   - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled)
75
+ * M1   -> M0
76
+ * M3   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to clockwise
77
+ * M4   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to counter-clockwise
78
+ * M5   - Turn laser/spindle off
79
+ * M17  - Enable/Power all stepper motors
80
+ * M18  - Disable all stepper motors; same as M84
81
+ * M20  - List SD card. (Requires SDSUPPORT)
82
+ * M21  - Init SD card. (Requires SDSUPPORT)
83
+ * M22  - Release SD card. (Requires SDSUPPORT)
84
+ * M23  - Select SD file: "M23 /path/file.gco". (Requires SDSUPPORT)
85
+ * M24  - Start/resume SD print. (Requires SDSUPPORT)
86
+ * M25  - Pause SD print. (Requires SDSUPPORT)
87
+ * M26  - Set SD position in bytes: "M26 S12345". (Requires SDSUPPORT)
88
+ * M27  - Report SD print status. (Requires SDSUPPORT)
89
+ * M28  - Start SD write: "M28 /path/file.gco". (Requires SDSUPPORT)
90
+ * M29  - Stop SD write. (Requires SDSUPPORT)
91
+ * M30  - Delete file from SD: "M30 /path/file.gco"
92
+ * M31  - Report time since last M109 or SD card start to serial.
93
+ * M32  - Select file and start SD print: "M32 [S<bytepos>] !/path/file.gco#". (Requires SDSUPPORT)
94
+ *        Use P to run other files as sub-programs: "M32 P !filename#"
95
+ *        The '#' is necessary when calling from within sd files, as it stops buffer prereading
96
+ * M33  - Get the longname version of a path. (Requires LONG_FILENAME_HOST_SUPPORT)
97
+ * M34  - Set SD Card sorting options. (Requires SDCARD_SORT_ALPHA)
98
+ * M42  - Change pin status via gcode: M42 P<pin> S<value>. LED pin assumed if P is omitted.
99
+ * M43  - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
100
+ * M48  - Measure Z Probe repeatability: M48 P<points> X<pos> Y<pos> V<level> E<engage> L<legs>. (Requires Z_MIN_PROBE_REPEATABILITY_TEST)
101
+ * M75  - Start the print job timer.
102
+ * M76  - Pause the print job timer.
103
+ * M77  - Stop the print job timer.
104
+ * M78  - Show statistical information about the print jobs. (Requires PRINTCOUNTER)
105
+ * M80  - Turn on Power Supply. (Requires POWER_SUPPLY > 0)
106
+ * M81  - Turn off Power Supply. (Requires POWER_SUPPLY > 0)
107
+ * M82  - Set E codes absolute (default).
108
+ * M83  - Set E codes relative while in Absolute (G90) mode.
109
+ * M84  - Disable steppers until next move, or use S<seconds> to specify an idle
110
+ *        duration after which steppers should turn off. S0 disables the timeout.
111
+ * M85  - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
112
+ * M92  - Set planner.axis_steps_per_mm for one or more axes.
113
+ * M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER)
114
+ * M104 - Set extruder target temp.
115
+ * M105 - Report current temperatures.
116
+ * M106 - Fan on.
117
+ * M107 - Fan off.
118
+ * M108 - Break out of heating loops (M109, M190, M303). With no controller, breaks out of M0/M1. (Requires EMERGENCY_PARSER)
119
+ * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
120
+ *        Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
121
+ *        If AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
122
+ * M110 - Set the current line number. (Used by host printing)
123
+ * M111 - Set debug flags: "M111 S<flagbits>". See flag bits defined in enum.h.
124
+ * M112 - Emergency stop.
125
+ * M113 - Get or set the timeout interval for Host Keepalive "busy" messages. (Requires HOST_KEEPALIVE_FEATURE)
126
+ * M114 - Report current position.
127
+ * M115 - Report capabilities. (Extended capabilities requires EXTENDED_CAPABILITIES_REPORT)
128
+ * M117 - Display a message on the controller screen. (Requires an LCD)
129
+ * M118 - Display a message in the host console.
130
+ * M119 - Report endstops status.
131
+ * M120 - Enable endstops detection.
132
+ * M121 - Disable endstops detection.
133
+ * M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE)
134
+ * M126 - Solenoid Air Valve Open. (Requires BARICUDA)
135
+ * M127 - Solenoid Air Valve Closed. (Requires BARICUDA)
136
+ * M128 - EtoP Open. (Requires BARICUDA)
137
+ * M129 - EtoP Closed. (Requires BARICUDA)
138
+ * M140 - Set bed target temp. S<temp>
139
+ * M145 - Set heatup values for materials on the LCD. H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS)
140
+ * M149 - Set temperature units. (Requires TEMPERATURE_UNITS_SUPPORT)
141
+ * M150 - Set Status LED Color as R<red> U<green> B<blue>. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, or PCA9632)
142
+ * M155 - Auto-report temperatures with interval of S<seconds>. (Requires AUTO_REPORT_TEMPERATURES)
143
+ * M163 - Set a single proportion for a mixing extruder. (Requires MIXING_EXTRUDER)
144
+ * M164 - Save the mix as a virtual extruder. (Requires MIXING_EXTRUDER and MIXING_VIRTUAL_TOOLS)
145
+ * M165 - Set the proportions for a mixing extruder. Use parameters ABCDHI to set the mixing factors. (Requires MIXING_EXTRUDER)
146
+ * M190 - Sxxx Wait for bed current temp to reach target temp. ** Waits only when heating! **
147
+ *        Rxxx Wait for bed current temp to reach target temp. ** Waits for heating or cooling. **
148
+ * M200 - Set filament diameter, D<diameter>, setting E axis units to cubic. (Use S0 to revert to linear units.)
149
+ * M201 - Set max acceleration in units/s^2 for print moves: "M201 X<accel> Y<accel> Z<accel> E<accel>"
150
+ * M202 - Set max acceleration in units/s^2 for travel moves: "M202 X<accel> Y<accel> Z<accel> E<accel>" ** UNUSED IN MARLIN! **
151
+ * M203 - Set maximum feedrate: "M203 X<fr> Y<fr> Z<fr> E<fr>" in units/sec.
152
+ * M204 - Set default acceleration in units/sec^2: P<printing> R<extruder_only> T<travel>
153
+ * M205 - Set advanced settings. Current units apply:
154
+            S<print> T<travel> minimum speeds
155
+            B<minimum segment time>
156
+            X<max X jerk>, Y<max Y jerk>, Z<max Z jerk>, E<max E jerk>
157
+ * M206 - Set additional homing offset. (Disabled by NO_WORKSPACE_OFFSETS or DELTA)
158
+ * M207 - Set Retract Length: S<length>, Feedrate: F<units/min>, and Z lift: Z<distance>. (Requires FWRETRACT)
159
+ * M208 - Set Recover (unretract) Additional (!) Length: S<length> and Feedrate: F<units/min>. (Requires FWRETRACT)
160
+ * M209 - Turn Automatic Retract Detection on/off: S<0|1> (For slicers that don't support G10/11). (Requires FWRETRACT)
161
+          Every normal extrude-only move will be classified as retract depending on the direction.
162
+ * M211 - Enable, Disable, and/or Report software endstops: S<0|1> (Requires MIN_SOFTWARE_ENDSTOPS or MAX_SOFTWARE_ENDSTOPS)
163
+ * M218 - Set a tool offset: "M218 T<index> X<offset> Y<offset>". (Requires 2 or more extruders)
164
+ * M220 - Set Feedrate Percentage: "M220 S<percent>" (i.e., "FR" on the LCD)
165
+ * M221 - Set Flow Percentage: "M221 S<percent>"
166
+ * M226 - Wait until a pin is in a given state: "M226 P<pin> S<state>"
167
+ * M240 - Trigger a camera to take a photograph. (Requires CHDK or PHOTOGRAPH_PIN)
168
+ * M250 - Set LCD contrast: "M250 C<contrast>" (0-63). (Requires LCD support)
169
+ * M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS)
170
+ * M261 - i2c Request Data (Requires EXPERIMENTAL_I2CBUS)
171
+ * M280 - Set servo position absolute: "M280 P<index> S<angle|µs>". (Requires servos)
172
+ * M300 - Play beep sound S<frequency Hz> P<duration ms>
173
+ * M301 - Set PID parameters P I and D. (Requires PIDTEMP)
174
+ * M302 - Allow cold extrudes, or set the minimum extrude S<temperature>. (Requires PREVENT_COLD_EXTRUSION)
175
+ * M303 - PID relay autotune S<temperature> sets the target temperature. Default 150C. (Requires PIDTEMP)
176
+ * M304 - Set bed PID parameters P I and D. (Requires PIDTEMPBED)
177
+ * M350 - Set microstepping mode. (Requires digital microstepping pins.)
178
+ * M351 - Toggle MS1 MS2 pins directly. (Requires digital microstepping pins.)
179
+ * M355 - Set Case Light on/off and set brightness. (Requires CASE_LIGHT_PIN)
180
+ * M380 - Activate solenoid on active extruder. (Requires EXT_SOLENOID)
181
+ * M381 - Disable all solenoids. (Requires EXT_SOLENOID)
182
+ * M400 - Finish all moves.
183
+ * M401 - Lower Z probe. (Requires a probe)
184
+ * M402 - Raise Z probe. (Requires a probe)
185
+ * M404 - Display or set the Nominal Filament Width: "W<diameter>". (Requires FILAMENT_WIDTH_SENSOR)
186
+ * M405 - Enable Filament Sensor flow control. "M405 D<delay_cm>". (Requires FILAMENT_WIDTH_SENSOR)
187
+ * M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR)
188
+ * M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR)
189
+ * M410 - Quickstop. Abort all planned moves.
190
+ * M420 - Enable/Disable Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING or ABL)
191
+ * M421 - Set a single Z coordinate in the Mesh Leveling grid. X<units> Y<units> Z<units> (Requires MESH_BED_LEVELING or AUTO_BED_LEVELING_UBL)
192
+ * M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA)
193
+ * M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS)
194
+ * M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS)
195
+ * M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
196
+ * M503 - Print the current settings (in memory): "M503 S<verbose>". S0 specifies compact output.
197
+ * M540 - Enable/disable SD card abort on endstop hit: "M540 S<state>". (Requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
198
+ * M600 - Pause for filament change: "M600 X<pos> Y<pos> Z<raise> E<first_retract> L<later_retract>". (Requires ADVANCED_PAUSE_FEATURE)
199
+ * M665 - Set delta configurations: "M665 L<diagonal rod> R<delta radius> S<segments/s> A<rod A trim mm> B<rod B trim mm> C<rod C trim mm> I<tower A trim angle> J<tower B trim angle> K<tower C trim angle>" (Requires DELTA)
200
+ * M666 - Set delta endstop adjustment. (Requires DELTA)
201
+ * M605 - Set dual x-carriage movement mode: "M605 S<mode> [X<x_offset>] [R<temp_offset>]". (Requires DUAL_X_CARRIAGE)
202
+ * M851 - Set Z probe's Z offset in current units. (Negative = below the nozzle.)
203
+ * M860 - Report the position of position encoder modules.
204
+ * M861 - Report the status of position encoder modules.
205
+ * M862 - Perform an axis continuity test for position encoder modules.
206
+ * M863 - Perform steps-per-mm calibration for position encoder modules.
207
+ * M864 - Change position encoder module I2C address.
208
+ * M865 - Check position encoder module firmware version.
209
+ * M866 - Report or reset position encoder module error count.
210
+ * M867 - Enable/disable or toggle error correction for position encoder modules.
211
+ * M868 - Report or set position encoder module error correction threshold.
212
+ * M869 - Report position encoder module error.
213
+ * M900 - Get and/or Set advance K factor and WH/D ratio. (Requires LIN_ADVANCE)
214
+ * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires HAVE_TMC2130)
215
+ * M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots)
216
+ * M908 - Control digital trimpot directly. (Requires DAC_STEPPER_CURRENT or DIGIPOTSS_PIN)
217
+ * M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT)
218
+ * M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT)
219
+ * M911 - Report stepper driver overtemperature pre-warn condition. (Requires HAVE_TMC2130)
220
+ * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires HAVE_TMC2130)
221
+ * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD)
222
+ * M914 - Set SENSORLESS_HOMING sensitivity. (Requires SENSORLESS_HOMING)
223
+ *
224
+ * M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
225
+ * M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
226
+ * M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration)
227
+ * M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
228
+ * M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position)
229
+ *
230
+ * ************ Custom codes - This can change to suit future G-code regulations
231
+ * M928 - Start SD logging: "M928 filename.gco". Stop with M29. (Requires SDSUPPORT)
232
+ * M999 - Restart after being stopped by error
233
+ *
234
+ * "T" Codes
235
+ *
236
+ * T0-T3 - Select an extruder (tool) by index: "T<n> F<units/min>"
237
+ *
238
+ */
239
+
240
+#ifndef GCODE_H
241
+#define GCODE_H
242
+
243
+#include "../inc/MarlinConfig.h"
244
+#include "parser.h"
245
+
246
+#if ENABLED(I2C_POSITION_ENCODERS)
247
+  #include "../feature/I2CPositionEncoder.h"
248
+#endif
249
+
250
+class GcodeSuite {
251
+public:
252
+
253
+  GcodeSuite() {}
254
+
255
+private:
256
+
257
+  static void G0_G1(
258
+    #if IS_SCARA
259
+      bool fast_move=false
260
+    #endif
261
+  );
262
+
263
+  #if ENABLED(ARC_SUPPORT)
264
+    static void G2_G3(bool clockwise);
265
+  #endif
266
+
267
+  static void G4();
268
+
269
+  #if ENABLED(BEZIER_CURVE_SUPPORT)
270
+    static void G5();
271
+  #endif
272
+
273
+  #if ENABLED(FWRETRACT)
274
+    static void G10();
275
+    static void G11();
276
+  #endif
277
+
278
+  #if ENABLED(NOZZLE_CLEAN_FEATURE)
279
+    static void G12();
280
+  #endif
281
+
282
+  #if ENABLED(CNC_WORKSPACE_PLANES)
283
+    static void G17();
284
+    static void G18();
285
+    static void G19();
286
+  #endif
287
+
288
+  #if ENABLED(INCH_MODE_SUPPORT)
289
+    static void G20();
290
+    static void G21();
291
+  #endif
292
+
293
+  #if ENABLED(UBL_G26_MESH_VALIDATION)
294
+    static void G26();
295
+  #endif
296
+
297
+  #if ENABLED(NOZZLE_PARK_FEATURE)
298
+    static void G27();
299
+  #endif
300
+
301
+  static void G28(const bool always_home_all);
302
+
303
+  #if HAS_LEVELING
304
+    static void G29();
305
+  #endif
306
+
307
+  #if HAS_BED_PROBE
308
+    static void G30();
309
+    #if ENABLED(Z_PROBE_SLED)
310
+      static void G31();
311
+      static void G32();
312
+    #endif
313
+  #endif
314
+
315
+  #if PROBE_SELECTED && ENABLED(DELTA_AUTO_CALIBRATION)
316
+    static void G33();
317
+  #endif
318
+
319
+  #if ENABLED(G38_PROBE_TARGET)
320
+    static void G38(bool is_38_2);
321
+  #endif
322
+
323
+  #if HAS_MESH
324
+    static void G42();
325
+  #endif
326
+
327
+  static void G92();
328
+
329
+  #if HAS_RESUME_CONTINUE
330
+    static void M0_M1();
331
+  #endif
332
+
333
+  #if ENABLED(SPINDLE_LASER_ENABLE)
334
+    static void M3_M4(bool is_M3);
335
+    static void M5();
336
+  #endif
337
+
338
+  static void M17();
339
+
340
+  static void M18_M84();
341
+
342
+  #if ENABLED(SDSUPPORT)
343
+    static void M20();
344
+    static void M21();
345
+    static void M22();
346
+    static void M23();
347
+    static void M24();
348
+    static void M25();
349
+    static void M26();
350
+    static void M27();
351
+    static void M28();
352
+    static void M29();
353
+    static void M30();
354
+  #endif
355
+
356
+  static void M31();
357
+
358
+  #if ENABLED(SDSUPPORT)
359
+    static void M32();
360
+    #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
361
+      static void M33();
362
+    #endif
363
+    #if ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_GCODE)
364
+      static void M34();
365
+    #endif
366
+  #endif
367
+
368
+  static void M42();
369
+
370
+  #if ENABLED(PINS_DEBUGGING)
371
+    static void M43();
372
+  #endif
373
+
374
+  #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)
375
+    static void M48();
376
+  #endif
377
+
378
+  #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION)
379
+    static void M49();
380
+  #endif
381
+
382
+  static void M75();
383
+  static void M76();
384
+  static void M77();
385
+
386
+  #if ENABLED(PRINTCOUNTER)
387
+    static void M78();
388
+  #endif
389
+
390
+  #if HAS_POWER_SWITCH
391
+    static void M80();
392
+  #endif
393
+
394
+  static void M81();
395
+  static void M82();
396
+  static void M83();
397
+  static void M85();
398
+  static void M92();
399
+
400
+  #if ENABLED(M100_FREE_MEMORY_WATCHER)
401
+    static void M100();
402
+  #endif
403
+
404
+  static void M104();
405
+  static void M105();
406
+  static void M106();
407
+  static void M107();
408
+
409
+  #if DISABLED(EMERGENCY_PARSER)
410
+    static void M108();
411
+  #endif
412
+
413
+  static void M109();
414
+
415
+  static void M110();
416
+  static void M111();
417
+
418
+  #if DISABLED(EMERGENCY_PARSER)
419
+    static void M112();
420
+  #endif
421
+
422
+  #if ENABLED(HOST_KEEPALIVE_FEATURE)
423
+    static void M113();
424
+  #endif
425
+
426
+  static void M114();
427
+  static void M115();
428
+  static void M117();
429
+  static void M118();
430
+  static void M119();
431
+  static void M120();
432
+  static void M121();
433
+
434
+  #if ENABLED(PARK_HEAD_ON_PAUSE)
435
+    static void M125();
436
+  #endif
437
+
438
+  #if ENABLED(BARICUDA)
439
+    #if HAS_HEATER_1
440
+      static void M126();
441
+      static void M127();
442
+    #endif
443
+    #if HAS_HEATER_2
444
+      static void M128();
445
+      static void M129();
446
+    #endif
447
+  #endif
448
+
449
+  #if HAS_TEMP_BED
450
+    static void M140();
451
+  #endif
452
+
453
+  #if ENABLED(ULTIPANEL)
454
+    static void M145();
455
+  #endif
456
+
457
+  #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
458
+    static void M149();
459
+  #endif
460
+
461
+  #if HAS_COLOR_LEDS
462
+    static void M150();
463
+  #endif
464
+
465
+  #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED)
466
+    static void M155();
467
+  #endif
468
+
469
+  #if ENABLED(MIXING_EXTRUDER)
470
+    static void M163();
471
+    #if MIXING_VIRTUAL_TOOLS > 1
472
+      static void M164();
473
+    #endif
474
+    #if ENABLED(DIRECT_MIXING_IN_G1)
475
+      static void M165();
476
+    #endif
477
+  #endif
478
+
479
+  #if HAS_TEMP_BED
480
+    static void M190();
481
+  #endif
482
+
483
+  static void M200();
484
+  static void M201();
485
+
486
+  #if 0
487
+    static void M202(); // Not used for Sprinter/grbl gen6
488
+  #endif
489
+
490
+  static void M203();
491
+  static void M204();
492
+  static void M205();
493
+
494
+  #if HAS_M206_COMMAND
495
+    static void M206();
496
+  #endif
497
+
498
+  #if ENABLED(FWRETRACT)
499
+    static void M207();
500
+    static void M208();
501
+    static void M209();
502
+  #endif
503
+
504
+  static void M211();
505
+
506
+  #if HOTENDS > 1
507
+    static void M218();
508
+  #endif
509
+
510
+  static void M220();
511
+  static void M221();
512
+  static void M226();
513
+
514
+  #if defined(CHDK) || HAS_PHOTOGRAPH
515
+    static void M240();
516
+  #endif
517
+
518
+  #if HAS_LCD_CONTRAST
519
+    static void M250();
520
+  #endif
521
+
522
+  #if ENABLED(EXPERIMENTAL_I2CBUS)
523
+    static void M260();
524
+    static void M261();
525
+  #endif
526
+
527
+  #if HAS_SERVOS
528
+    static void M280();
529
+  #endif
530
+
531
+  #if HAS_BUZZER
532
+    static void M300();
533
+  #endif
534
+
535
+  #if ENABLED(PIDTEMP)
536
+    static void M301();
537
+  #endif
538
+
539
+  #if ENABLED(PREVENT_COLD_EXTRUSION)
540
+    static void M302();
541
+  #endif
542
+
543
+  static void M303();
544
+
545
+  #if ENABLED(PIDTEMPBED)
546
+    static void M304();
547
+  #endif
548
+
549
+  #if HAS_MICROSTEPS
550
+    static void M350();
551
+    static void M351();
552
+  #endif
553
+
554
+  static void M355();
555
+
556
+  #if ENABLED(MORGAN_SCARA)
557
+    static bool M360();
558
+    static bool M361();
559
+    static bool M362();
560
+    static bool M363();
561
+    static bool M364();
562
+  #endif
563
+
564
+  #if ENABLED(EXT_SOLENOID)
565
+    static void M380();
566
+    static void M381();
567
+  #endif
568
+
569
+  static void M400();
570
+
571
+  #if HAS_BED_PROBE
572
+    static void M401();
573
+    static void M402();
574
+  #endif
575
+
576
+  #if ENABLED(FILAMENT_WIDTH_SENSOR)
577
+    static void M404();
578
+    static void M405();
579
+    static void M406();
580
+    static void M407();
581
+  #endif
582
+
583
+  #if DISABLED(EMERGENCY_PARSER)
584
+    static void M410();
585
+  #endif
586
+
587
+  #if HAS_LEVELING
588
+    static void M420();
589
+    static void M421();
590
+  #endif
591
+
592
+  #if HAS_M206_COMMAND
593
+    static void M428();
594
+  #endif
595
+
596
+  static void M500();
597
+  static void M501();
598
+  static void M502();
599
+  #if DISABLED(DISABLE_M503)
600
+    static void M503();
601
+  #endif
602
+
603
+  #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
604
+    static void M540();
605
+  #endif
606
+
607
+  #if ENABLED(ADVANCED_PAUSE_FEATURE)
608
+    static void M600();
609
+  #endif
610
+
611
+  #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
612
+    static void M605();
613
+  #endif
614
+
615
+  #if IS_KINEMATIC
616
+    static void M665();
617
+  #endif
618
+
619
+  #if ENABLED(DELTA) || ENABLED(Z_DUAL_ENDSTOPS)
620
+    static void M666();
621
+  #endif
622
+
623
+  #if ENABLED(MK2_MULTIPLEXER)
624
+    static void M702();
625
+  #endif
626
+
627
+  #if HAS_BED_PROBE
628
+    static void M851();
629
+  #endif
630
+
631
+  #if ENABLED(I2C_POSITION_ENCODERS)
632
+    FORCE_INLINE static void M860() { I2CPEM.M860(); }
633
+    FORCE_INLINE static void M861() { I2CPEM.M861(); }
634
+    FORCE_INLINE static void M862() { I2CPEM.M862(); }
635
+    FORCE_INLINE static void M863() { I2CPEM.M863(); }
636
+    FORCE_INLINE static void M864() { I2CPEM.M864(); }
637
+    FORCE_INLINE static void M865() { I2CPEM.M865(); }
638
+    FORCE_INLINE static void M866() { I2CPEM.M866(); }
639
+    FORCE_INLINE static void M867() { I2CPEM.M867(); }
640
+    FORCE_INLINE static void M868() { I2CPEM.M868(); }
641
+    FORCE_INLINE static void M869() { I2CPEM.M869(); }
642
+  #endif
643
+
644
+  #if ENABLED(LIN_ADVANCE)
645
+    static void M900();
646
+  #endif
647
+
648
+  #if ENABLED(HAVE_TMC2130)
649
+    static void M906();
650
+    static void M911();
651
+    static void M912();
652
+    #if ENABLED(HYBRID_THRESHOLD)
653
+      static void M913();
654
+    #endif
655
+    #if ENABLED(SENSORLESS_HOMING)
656
+      static void M914();
657
+    #endif
658
+  #endif
659
+
660
+  static void M907();
661
+
662
+  #if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT)
663
+    static void M908();
664
+    #if ENABLED(DAC_STEPPER_CURRENT)
665
+      static void M909();
666
+      static void M910();
667
+    #endif
668
+  #endif
669
+
670
+  #if ENABLED(SDSUPPORT)
671
+    static void M928();
672
+  #endif
673
+
674
+  static void M999();
675
+
676
+  static void T(uint8_t tmp_extruder);
677
+
678
+};
679
+
680
+extern GcodeSuite gcode;
681
+
682
+#endif // GCODE_H

+ 36
- 0
Marlin/src/gcode/geometry/G17-G19.h View File

@@ -0,0 +1,36 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+void report_workspace_plane() {
24
+  SERIAL_ECHO_START();
25
+  SERIAL_ECHOPGM("Workspace Plane ");
26
+  serialprintPGM(workspace_plane == PLANE_YZ ? PSTR("YZ\n") : workspace_plane == PLANE_ZX ? PSTR("ZX\n") : PSTR("XY\n"));
27
+}
28
+
29
+/**
30
+ * G17: Select Plane XY
31
+ * G18: Select Plane ZX
32
+ * G19: Select Plane YZ
33
+ */
34
+void gcode_G17() { workspace_plane = PLANE_XY; }
35
+void gcode_G18() { workspace_plane = PLANE_ZX; }
36
+void gcode_G19() { workspace_plane = PLANE_YZ; }

+ 66
- 0
Marlin/src/gcode/geometry/G92.h View File

@@ -0,0 +1,66 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * G92: Set current position to given X Y Z E
25
+ */
26
+void gcode_G92() {
27
+  bool didXYZ = false,
28
+       didE = parser.seenval('E');
29
+
30
+  if (!didE) stepper.synchronize();
31
+
32
+  LOOP_XYZE(i) {
33
+    if (parser.seenval(axis_codes[i])) {
34
+      #if IS_SCARA
35
+        current_position[i] = parser.value_axis_units((AxisEnum)i);
36
+        if (i != E_AXIS) didXYZ = true;
37
+      #else
38
+        #if HAS_POSITION_SHIFT
39
+          const float p = current_position[i];
40
+        #endif
41
+        const float v = parser.value_axis_units((AxisEnum)i);
42
+
43
+        current_position[i] = v;
44
+
45
+        if (i != E_AXIS) {
46
+          didXYZ = true;
47
+          #if HAS_POSITION_SHIFT
48
+            position_shift[i] += v - p; // Offset the coordinate space
49
+            update_software_endstops((AxisEnum)i);
50
+
51
+            #if ENABLED(I2C_POSITION_ENCODERS)
52
+              I2CPEM.encoders[I2CPEM.idx_from_axis((AxisEnum)i)].set_axis_offset(position_shift[i]);
53
+            #endif
54
+
55
+          #endif
56
+        }
57
+      #endif
58
+    }
59
+  }
60
+  if (didXYZ)
61
+    SYNC_PLAN_POSITION_KINEMATIC();
62
+  else if (didE)
63
+    sync_plan_position_e();
64
+
65
+  report_current_position();
66
+}

+ 42
- 0
Marlin/src/gcode/geometry/M206.h View File

@@ -0,0 +1,42 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y
25
+ *
26
+ * *** @thinkyhead: I recommend deprecating M206 for SCARA in favor of M665.
27
+ * ***              M206 for SCARA will remain enabled in 1.1.x for compatibility.
28
+ * ***              In the 2.0 release, it will simply be disabled by default.
29
+ */
30
+void gcode_M206() {
31
+  LOOP_XYZ(i)
32
+    if (parser.seen(axis_codes[i]))
33
+      set_home_offset((AxisEnum)i, parser.value_linear_units());
34
+
35
+  #if ENABLED(MORGAN_SCARA)
36
+    if (parser.seen('T')) set_home_offset(A_AXIS, parser.value_linear_units()); // Theta
37
+    if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_linear_units()); // Psi
38
+  #endif
39
+
40
+  SYNC_PLAN_POSITION_KINEMATIC();
41
+  report_current_position();
42
+}

+ 61
- 0
Marlin/src/gcode/geometry/M428.h View File

@@ -0,0 +1,61 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * M428: Set home_offset based on the distance between the
25
+ *       current_position and the nearest "reference point."
26
+ *       If an axis is past center its endstop position
27
+ *       is the reference-point. Otherwise it uses 0. This allows
28
+ *       the Z offset to be set near the bed when using a max endstop.
29
+ *
30
+ *       M428 can't be used more than 2cm away from 0 or an endstop.
31
+ *
32
+ *       Use M206 to set these values directly.
33
+ */
34
+void gcode_M428() {
35
+  bool err = false;
36
+  LOOP_XYZ(i) {
37
+    if (axis_homed[i]) {
38
+      const float base = (current_position[i] > (soft_endstop_min[i] + soft_endstop_max[i]) * 0.5) ? base_home_pos((AxisEnum)i) : 0,
39
+                  diff = base - RAW_POSITION(current_position[i], i);
40
+      if (WITHIN(diff, -20, 20)) {
41
+        set_home_offset((AxisEnum)i, diff);
42
+      }
43
+      else {
44
+        SERIAL_ERROR_START();
45
+        SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
46
+        LCD_ALERTMESSAGEPGM("Err: Too far!");
47
+        BUZZ(200, 40);
48
+        err = true;
49
+        break;
50
+      }
51
+    }
52
+  }
53
+
54
+  if (!err) {
55
+    SYNC_PLAN_POSITION_KINEMATIC();
56
+    report_current_position();
57
+    LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED);
58
+    BUZZ(100, 659);
59
+    BUZZ(100, 698);
60
+  }
61
+}

+ 0
- 0
Marlin/src/gcode/host/M110.h View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save