Browse Source

Merge https://github.com/MarlinFirmware/Marlin into tm-utf-minus-kanji

Conflicts:
	README.md
Solved
AnHardt 9 years ago
parent
commit
20f909567a

+ 76
- 0
Documentation/MeshBedLeveling.md View File

@@ -0,0 +1,76 @@
1
+==============================================
2
+Instructions for configuring Mesh Bed Leveling
3
+==============================================
4
+
5
+Background
6
+----------
7
+
8
+This mesh based method of leveling/compensating can compensate for an non-flat bed. There are various opinions about doing this. It was primarily written to compensate a RigidBot BIG bed (40x30cm) that was somewhat bent.
9
+
10
+Currently there is no automatic way to probe the bed like the Auto Bed Leveling feature. This might soon be implemented though, stay tuned.
11
+
12
+Theory
13
+------
14
+
15
+The bed is manually probed in a grid maner. During a print the Z axis compensation will be interpolated within each square using a bi-linear method. Because the grid squares can be tilting in different directions a printing move can be split on the borders of the grid squares. During fast travel moves one can sometimes notice a de-acceleration on these borders. 
16
+
17
+Mesh point probing can either be carried out from the display, or by issuing `G29` commands.
18
+
19
+The Z-endstop should be set slightly above the bed. An opto endstop is preferable but a switch with a metal arm that allow some travel though should also work.
20
+
21
+Configuration
22
+-------------
23
+
24
+In `Configuration.h` there are two options that can be enabled.
25
+
26
+`MESH_BED_LEVELING` will enable mesh bed leveling.<br/>
27
+`MANUAL_BED_LEVELING` will add the menu option for bed leveling.
28
+
29
+There are also some values that can be set.
30
+
31
+Following four define the area to cover. Default 10mm from max bed size
32
+
33
+`MESH_MIN_X`<br/>
34
+`MESH_MAX_X`<br/>
35
+`MESH_MIN_Y`<br/>
36
+`MESH_MAX_Y`
37
+
38
+Following two define the number of points to probe, total number will be these two multiplied. Default is 3x3 points. Don't probe more than 7x7 points (software limited)
39
+
40
+`MESH_NUM_X_POINTS`<br/> 
41
+`MESH_NUM_Y_POINTS`<br/>
42
+
43
+The following will set the Z-endstop height during probing. When initiating a bed leveling probing, a homing will take place and the Z-endstop will be set to this height so lowering through the endstop can take place and the bed should be within this distance. Default is 4mm
44
+
45
+`MESH_HOME_SEARCH_Z`
46
+
47
+The probed points will also be saved in the EEPROM if it has been enables. Otherwise a new probe sequence needs to be made next time the printer has been turned on.
48
+
49
+Probing the bed with the display
50
+--------------------------------
51
+
52
+If `MANUAL_BED_LEVELING` has been enabled then will a `Level bed` menu option be available in the `Prepare` menu.
53
+
54
+When selecting this option the printer will first do a homing, and then travel to the first probe point. There it will wait. By turning the encoder on the display the hotend can now be lowered until it touches the bed. Using a paper to feel the distance when it gets close. Pressing the encoder/button will store this point and then travel to the next point. Repeating this until all points have been probed.
55
+
56
+If the EEPROM has been enable it can be good to issue a `M500` to get these points saved.
57
+
58
+Issuing a `G29` will return the state of the mesh leveling.
59
+
60
+Probing the bed with G-codes
61
+----------------------------
62
+
63
+Probing the bed by G-codes follows the sequence much like doing it with the display.
64
+
65
+`G29` or `G29 S0` will return the state bed leveling.
66
+
67
+`G29 S1` will initiate the bed leveling, homing and traveling to the first point to probe.
68
+
69
+Then use your preferred Printer controller program, i.e. Printrun, to lower the hotend until it touches the bed. Using a paper to feel the distance when it gets close.
70
+
71
+`G29 S2` will store the point and travel to the next point until last point has been probed.
72
+
73
+Note
74
+----
75
+
76
+Depending how firm feel you aim for on the paper you can use the `Z offset` option in Slic3r to compensate a slight height diff. (I like the paper loose so I needed to put `-0.05` in Slic3r)

+ 0
- 11
Marlin/Conditionals.h View File

@@ -390,16 +390,5 @@
390 390
     #define WRITE_FAN(v) WRITE(FAN_PIN, v)
391 391
   #endif
392 392
 
393
-  /**
394
-   * Sampling period of the temperature routine
395
-   * This override comes originally from temperature.cpp
396
-   * The Configuration.h option is basically ignored.
397
-   */
398
-  #ifdef PID_dT
399
-    #undef PID_dT
400
-  #endif
401
-  #define PID_dT ((OVERSAMPLENR * 12.0)/(F_CPU / 64.0 / 256.0))
402
-
403
-
404 393
 #endif //CONFIGURATION_LCD
405 394
 #endif //CONDITIONALS_H

+ 1
- 2
Marlin/Configuration.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
190 189
 // Ultimaker
@@ -209,7 +208,7 @@ Here are some standard links for getting your machine calibrated:
209 208
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
210 209
 //
211 210
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
212
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
211
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
213 212
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
214 213
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
215 214
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 22
- 0
Marlin/ConfigurationStore.cpp View File

@@ -67,6 +67,9 @@
67 67
  *
68 68
  *  filament_size (x4)
69 69
  *
70
+ * Z_DUAL_ENDSTOPS
71
+ *  z_endstop_adj
72
+ *
70 73
  */
71 74
 #include "Marlin.h"
72 75
 #include "language.h"
@@ -165,6 +168,10 @@ void Config_StoreSettings()  {
165 168
     EEPROM_WRITE_VAR(i, delta_radius);              // 1 float
166 169
     EEPROM_WRITE_VAR(i, delta_diagonal_rod);        // 1 float
167 170
     EEPROM_WRITE_VAR(i, delta_segments_per_second); // 1 float
171
+  #elif defined(Z_DUAL_ENDSTOPS)
172
+    EEPROM_WRITE_VAR(i, z_endstop_adj);            // 1 floats
173
+    dummy = 0.0f;
174
+    for (int q=5; q--;) EEPROM_WRITE_VAR(i, dummy);
168 175
   #else
169 176
     dummy = 0.0f;
170 177
     for (int q=6; q--;) EEPROM_WRITE_VAR(i, dummy);
@@ -326,7 +333,12 @@ void Config_RetrieveSettings() {
326 333
       EEPROM_READ_VAR(i, delta_radius);               // 1 float
327 334
       EEPROM_READ_VAR(i, delta_diagonal_rod);         // 1 float
328 335
       EEPROM_READ_VAR(i, delta_segments_per_second);  // 1 float
336
+    #elif defined(Z_DUAL_ENDSTOPS)
337
+      EEPROM_READ_VAR(i, z_endstop_adj);
338
+      dummy = 0.0f;
339
+      for (int q=5; q--;) EEPROM_READ_VAR(i, dummy);
329 340
     #else
341
+      dummy = 0.0f;
330 342
       for (int q=6; q--;) EEPROM_READ_VAR(i, dummy);
331 343
     #endif
332 344
 
@@ -459,6 +471,8 @@ void Config_ResetDefault() {
459 471
     delta_diagonal_rod =  DELTA_DIAGONAL_ROD;
460 472
     delta_segments_per_second =  DELTA_SEGMENTS_PER_SECOND;
461 473
     recalc_delta_settings(delta_radius, delta_diagonal_rod);
474
+  #elif defined(Z_DUAL_ENDSTOPS)
475
+    z_endstop_adj = 0;
462 476
   #endif
463 477
 
464 478
   #ifdef ULTIPANEL
@@ -629,6 +643,14 @@ void Config_PrintSettings(bool forReplay) {
629 643
     SERIAL_ECHOPAIR(" R", delta_radius );
630 644
     SERIAL_ECHOPAIR(" S", delta_segments_per_second );
631 645
     SERIAL_EOL;
646
+  #elif defined(Z_DUAL_ENDSTOPS)
647
+    SERIAL_ECHO_START;
648
+    if (!forReplay) {
649
+      SERIAL_ECHOLNPGM("Z2 Endstop adjustement (mm):");
650
+      SERIAL_ECHO_START;
651
+    }
652
+    SERIAL_ECHOPAIR("  M666 Z", z_endstop_adj );
653
+    SERIAL_EOL;  
632 654
   #endif // DELTA
633 655
 
634 656
   #ifdef PIDTEMP

+ 25
- 0
Marlin/Configuration_adv.h View File

@@ -100,6 +100,31 @@
100 100
 // On a RAMPS (or other 5 driver) motherboard, using this feature will limit you to using 1 extruder.
101 101
 //#define Z_DUAL_STEPPER_DRIVERS
102 102
 
103
+#ifdef Z_DUAL_STEPPER_DRIVERS
104
+
105
+// Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper.
106
+// That way the machine is capable to align the bed during home, since both Z steppers are homed. 
107
+// There is also an implementation of M666 (software endstops adjustment) to this feature.
108
+// After Z homing, this adjustment is applied to just one of the steppers in order to align the bed.
109
+// One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2.
110
+// If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive.
111
+// Play a little bit with small adjustments (0.5mm) and check the behaviour.
112
+// The M119 (endstops report) will start reporting the Z2 Endstop as well.
113
+
114
+#define Z_DUAL_ENDSTOPS
115
+
116
+#ifdef Z_DUAL_ENDSTOPS
117
+  #define Z2_STEP_PIN E2_STEP_PIN           // Stepper to be used to Z2 axis.
118
+  #define Z2_DIR_PIN E2_DIR_PIN
119
+  #define Z2_ENABLE_PIN E2_ENABLE_PIN
120
+  #define Z2_MAX_PIN 36                     //Endstop used for Z2 axis. In this case I'm using XMAX in a Rumba Board (pin 36)
121
+  const bool Z2_MAX_ENDSTOP_INVERTING = false;
122
+  #define DISABLE_XMAX_ENDSTOP              //Better to disable the XMAX to avoid conflict. Just rename "XMAX_ENDSTOP" by the endstop you are using for Z2 axis.
123
+#endif
124
+
125
+
126
+#endif
127
+
103 128
 // Same again but for Y Axis.
104 129
 //#define Y_DUAL_STEPPER_DRIVERS
105 130
 

+ 2
- 0
Marlin/Marlin.h View File

@@ -242,6 +242,8 @@ extern float home_offset[3];
242 242
   extern float delta_diagonal_rod;
243 243
   extern float delta_segments_per_second;
244 244
   void recalc_delta_settings(float radius, float diagonal_rod);
245
+#elif defined(Z_DUAL_ENDSTOPS)
246
+extern float z_endstop_adj;
245 247
 #endif
246 248
 #ifdef SCARA
247 249
   extern float axis_scaling[3];  // Build size scaling

+ 102
- 38
Marlin/Marlin_main.cpp View File

@@ -248,6 +248,8 @@ float current_position[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0 };
248 248
 float home_offset[3] = { 0, 0, 0 };
249 249
 #ifdef DELTA
250 250
   float endstop_adj[3] = { 0, 0, 0 };
251
+#elif defined(Z_DUAL_ENDSTOPS)
252
+  float z_endstop_adj = 0;
251 253
 #endif
252 254
 
253 255
 float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS };
@@ -393,7 +395,9 @@ static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
393 395
 static bool relative_mode = false;  //Determines Absolute or Relative Coordinates
394 396
 
395 397
 static char cmdbuffer[BUFSIZE][MAX_CMD_SIZE];
398
+#ifdef SDSUPPORT
396 399
 static bool fromsd[BUFSIZE];
400
+#endif //!SDSUPPORT
397 401
 static int bufindr = 0;
398 402
 static int bufindw = 0;
399 403
 static int buflen = 0;
@@ -653,10 +657,12 @@ void setup()
653 657
   SERIAL_ECHO(freeMemory());
654 658
   SERIAL_ECHOPGM(MSG_PLANNER_BUFFER_BYTES);
655 659
   SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE);
660
+  #ifdef SDSUPPORT
656 661
   for(int8_t i = 0; i < BUFSIZE; i++)
657 662
   {
658 663
     fromsd[i] = false;
659 664
   }
665
+  #endif //!SDSUPPORT
660 666
 
661 667
   // loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
662 668
   Config_RetrieveSettings();
@@ -762,8 +768,9 @@ void get_command()
762 768
         return;
763 769
       }
764 770
       cmdbuffer[bufindw][serial_count] = 0; //terminate string
765
-
771
+      #ifdef SDSUPPORT
766 772
       fromsd[bufindw] = false;
773
+      #endif //!SDSUPPORT
767 774
       if(strchr(cmdbuffer[bufindw], 'N') != NULL)
768 775
       {
769 776
         strchr_pointer = strchr(cmdbuffer[bufindw], 'N');
@@ -973,7 +980,7 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir,  HOME_DIR);
973 980
 
974 981
   static float x_home_pos(int extruder) {
975 982
     if (extruder == 0)
976
-      return base_home_pos(X_AXIS) + add_homing[X_AXIS];
983
+    return base_home_pos(X_AXIS) + home_offset[X_AXIS];
977 984
     else
978 985
       // In dual carriage mode the extruder offset provides an override of the
979 986
       // second X-carriage offset when homed - otherwise X2_HOME_POS is used.
@@ -1166,6 +1173,7 @@ static void run_z_probe() {
1166 1173
     zPosition += home_retract_mm(Z_AXIS);
1167 1174
     plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
1168 1175
     st_synchronize();
1176
+    endstops_hit_on_purpose();
1169 1177
 
1170 1178
     // move back down slowly to find bed
1171 1179
     
@@ -1183,6 +1191,7 @@ static void run_z_probe() {
1183 1191
     zPosition -= home_retract_mm(Z_AXIS) * 2;
1184 1192
     plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
1185 1193
     st_synchronize();
1194
+    endstops_hit_on_purpose();
1186 1195
 
1187 1196
     current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
1188 1197
     // make sure the planner knows where we are as it may be a bit different than we last said to move to
@@ -1387,11 +1396,11 @@ static float probe_pt(float x, float y, float z_before, ProbeAction retract_acti
1387 1396
   if (verbose_level > 2) {
1388 1397
     SERIAL_PROTOCOLPGM(MSG_BED);
1389 1398
     SERIAL_PROTOCOLPGM(" X: ");
1390
-    SERIAL_PROTOCOL(x + 0.0001);
1399
+    SERIAL_PROTOCOL_F(x, 3);
1391 1400
     SERIAL_PROTOCOLPGM(" Y: ");
1392
-    SERIAL_PROTOCOL(y + 0.0001);
1401
+    SERIAL_PROTOCOL_F(y, 3);
1393 1402
     SERIAL_PROTOCOLPGM(" Z: ");
1394
-    SERIAL_PROTOCOL(measured_z + 0.0001);
1403
+    SERIAL_PROTOCOL_F(measured_z, 3);
1395 1404
     SERIAL_EOL;
1396 1405
   }
1397 1406
   return measured_z;
@@ -1487,6 +1496,9 @@ static void homeaxis(int axis) {
1487 1496
       }
1488 1497
     #endif
1489 1498
 #endif // Z_PROBE_SLED
1499
+    #ifdef Z_DUAL_ENDSTOPS
1500
+      if (axis==Z_AXIS) In_Homing_Process(true);
1501
+    #endif
1490 1502
     destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
1491 1503
     feedrate = homing_feedrate[axis];
1492 1504
     plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
@@ -1512,6 +1524,27 @@ static void homeaxis(int axis) {
1512 1524
 
1513 1525
     plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
1514 1526
     st_synchronize();
1527
+    #ifdef Z_DUAL_ENDSTOPS
1528
+      if (axis==Z_AXIS)
1529
+      {
1530
+        feedrate = homing_feedrate[axis];
1531
+        plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1532
+        if (axis_home_dir > 0)
1533
+        {
1534
+          destination[axis] = (-1) * fabs(z_endstop_adj);
1535
+          if (z_endstop_adj > 0) Lock_z_motor(true); else Lock_z2_motor(true);
1536
+        } else {
1537
+          destination[axis] = fabs(z_endstop_adj);
1538
+          if (z_endstop_adj < 0) Lock_z_motor(true); else Lock_z2_motor(true);        
1539
+        }
1540
+        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
1541
+        st_synchronize();
1542
+        Lock_z_motor(false);
1543
+        Lock_z2_motor(false);
1544
+        In_Homing_Process(false);
1545
+      }
1546
+    #endif
1547
+
1515 1548
 #ifdef DELTA
1516 1549
     // retrace by the amount specified in endstop_adj
1517 1550
     if (endstop_adj[axis] * axis_home_dir < 0) {
@@ -1754,7 +1787,7 @@ inline void gcode_G28() {
1754 1787
 
1755 1788
   enable_endstops(true);
1756 1789
 
1757
-  for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = current_position[i];
1790
+  for (int i = X_AXIS; i <= NUM_AXIS; i++) destination[i] = current_position[i];
1758 1791
 
1759 1792
   feedrate = 0.0;
1760 1793
 
@@ -1944,7 +1977,7 @@ inline void gcode_G28() {
1944 1977
     if (code_seen(axis_codes[Z_AXIS]) && code_value_long() != 0)
1945 1978
       current_position[Z_AXIS] = code_value() + home_offset[Z_AXIS];
1946 1979
 
1947
-    #ifdef ENABLE_AUTO_BED_LEVELING
1980
+    #if defined(ENABLE_AUTO_BED_LEVELING) && (Z_HOME_DIR < 0)
1948 1981
       if (home_all_axis || code_seen(axis_codes[Z_AXIS]))
1949 1982
         current_position[Z_AXIS] += zprobe_zoffset;  //Add Z_Probe offset (the distance is negative)
1950 1983
     #endif
@@ -2083,6 +2116,9 @@ inline void gcode_G28() {
2083 2116
    *
2084 2117
    *  S  Set the XY travel speed between probe points (in mm/min)
2085 2118
    *
2119
+   *  D  Dry-Run mode. Just evaluate the bed Topology - It does not apply or clean the rotation Matrix
2120
+   *     Useful to check the topology after a first run of G29.
2121
+   *
2086 2122
    *  V  Set the verbose level (0-4). Example: "G29 V3"
2087 2123
    *
2088 2124
    *  T  Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report.
@@ -2124,6 +2160,7 @@ inline void gcode_G28() {
2124 2160
       }
2125 2161
     }
2126 2162
 
2163
+    bool dryrun = code_seen('D') || code_seen('d');
2127 2164
     bool enhanced_g29 = code_seen('E') || code_seen('e');
2128 2165
 
2129 2166
     #ifdef AUTO_BED_LEVELING_GRID
@@ -2133,7 +2170,10 @@ inline void gcode_G28() {
2133 2170
     #endif
2134 2171
 
2135 2172
       if (verbose_level > 0)
2173
+      {
2136 2174
         SERIAL_PROTOCOLPGM("G29 Auto Bed Leveling\n");
2175
+        if (dryrun) SERIAL_ECHOLN("Running in DRY-RUN mode");
2176
+      }
2137 2177
 
2138 2178
       int auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS;
2139 2179
       #ifndef DELTA
@@ -2190,22 +2230,27 @@ inline void gcode_G28() {
2190 2230
 
2191 2231
     st_synchronize();
2192 2232
 
2193
-    #ifdef DELTA
2194
-      reset_bed_level();
2195
-    #else
2233
+    if (!dryrun)
2234
+    {
2235
+      #ifdef DELTA
2236
+        reset_bed_level();
2237
+      #else
2196 2238
 
2197
-    // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
2198
-    //vector_3 corrected_position = plan_get_position_mm();
2199
-    //corrected_position.debug("position before G29");
2200
-    plan_bed_level_matrix.set_to_identity();
2201
-    vector_3 uncorrected_position = plan_get_position();
2202
-    //uncorrected_position.debug("position during G29");
2203
-    current_position[X_AXIS] = uncorrected_position.x;
2204
-    current_position[Y_AXIS] = uncorrected_position.y;
2205
-    current_position[Z_AXIS] = uncorrected_position.z;
2206
-    plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2207
-  #endif
2239
+      // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
2240
+      //vector_3 corrected_position = plan_get_position_mm();
2241
+      //corrected_position.debug("position before G29");
2242
+      plan_bed_level_matrix.set_to_identity();
2243
+      vector_3 uncorrected_position = plan_get_position();
2244
+//    uncorrected_position.debug("position during G29");
2208 2245
 
2246
+      current_position[X_AXIS] = uncorrected_position.x;
2247
+      current_position[Y_AXIS] = uncorrected_position.y;
2248
+      current_position[Z_AXIS] = uncorrected_position.z;
2249
+      plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2250
+
2251
+      #endif
2252
+    }
2253
+    
2209 2254
     setup_for_endstop_move();
2210 2255
 
2211 2256
     feedrate = homing_feedrate[Z_AXIS];
@@ -2248,13 +2293,11 @@ inline void gcode_G28() {
2248 2293
           xStart = 0;
2249 2294
           xStop = auto_bed_leveling_grid_points;
2250 2295
           xInc = 1;
2251
-          zig = false;
2252 2296
         }
2253 2297
         else {
2254 2298
           xStart = auto_bed_leveling_grid_points - 1;
2255 2299
           xStop = -1;
2256 2300
           xInc = -1;
2257
-          zig = true;
2258 2301
         }
2259 2302
 
2260 2303
         #ifndef DELTA
@@ -2341,7 +2384,7 @@ inline void gcode_G28() {
2341 2384
         SERIAL_PROTOCOLPGM("+-----------+\n");
2342 2385
 
2343 2386
         for (int yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--) {
2344
-          for (int xx = auto_bed_leveling_grid_points - 1; xx >= 0; xx--) {
2387
+          for (int xx = 0; xx < auto_bed_leveling_grid_points; xx++) {
2345 2388
             int ind = yy * auto_bed_leveling_grid_points + xx;
2346 2389
             float diff = eqnBVector[ind] - mean;
2347 2390
             if (diff >= 0.0)
@@ -2357,12 +2400,12 @@ inline void gcode_G28() {
2357 2400
       } //do_topography_map
2358 2401
 
2359 2402
 
2360
-      set_bed_level_equation_lsq(plane_equation_coefficients);
2403
+      if (!dryrun) set_bed_level_equation_lsq(plane_equation_coefficients);
2361 2404
       free(plane_equation_coefficients);
2362
-    #else
2363
-      extrapolate_unprobed_bed_level();
2405
+    #else //Delta
2406
+      if (!dryrun) extrapolate_unprobed_bed_level();
2364 2407
       print_bed_level();
2365
-    #endif
2408
+    #endif //Delta
2366 2409
 
2367 2410
     #else // !AUTO_BED_LEVELING_GRID
2368 2411
 
@@ -2381,25 +2424,27 @@ inline void gcode_G28() {
2381 2424
         z_at_pt_3 = probe_pt(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS, ProbeEngageAndRetract, verbose_level);
2382 2425
       }
2383 2426
       clean_up_after_endstop_move();
2384
-      set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3);
2427
+      if (!dryrun) set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3);
2385 2428
 
2386 2429
     #endif // !AUTO_BED_LEVELING_GRID
2387 2430
 
2388 2431
   #ifndef DELTA
2389
-    if (verbose_level > 0)
2390
-      plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
2432
+    if (verbose_level > 0) plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
2391 2433
 
2392 2434
     // Correct the Z height difference from z-probe position and hotend tip position.
2393 2435
     // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
2394 2436
     // When the bed is uneven, this height must be corrected.
2395
-    real_z = float(st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
2396
-    x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER;
2397
-    y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER;
2398
-    z_tmp = current_position[Z_AXIS];
2437
+    if (!dryrun)
2438
+    {
2439
+      real_z = float(st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
2440
+      x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER;
2441
+      y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER;
2442
+      z_tmp = current_position[Z_AXIS];
2399 2443
 
2400
-    apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp);         //Apply the correction sending the probe offset
2401
-    current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS];   //The difference is added to current position and sent to planner.
2402
-    plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2444
+      apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp);         //Apply the correction sending the probe offset
2445
+      current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS];   //The difference is added to current position and sent to planner.
2446
+      plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2447
+    }
2403 2448
   #endif
2404 2449
 
2405 2450
   #ifdef Z_PROBE_SLED
@@ -3452,6 +3497,11 @@ inline void gcode_M119() {
3452 3497
     SERIAL_PROTOCOLPGM(MSG_Z_MAX);
3453 3498
     SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
3454 3499
   #endif
3500
+  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN > -1
3501
+    SERIAL_PROTOCOLPGM(MSG_Z2_MAX);
3502
+    SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
3503
+  #endif
3504
+  
3455 3505
 }
3456 3506
 
3457 3507
 /**
@@ -3645,6 +3695,16 @@ inline void gcode_M206() {
3645 3695
       }
3646 3696
     }
3647 3697
   }
3698
+#elif defined(Z_DUAL_ENDSTOPS)
3699
+  /**
3700
+   * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis.
3701
+   */
3702
+  inline void gcode_M666() {
3703
+   if (code_seen('Z')) z_endstop_adj = code_value();
3704
+   SERIAL_ECHOPAIR("Z Endstop Adjustment set to (mm):", z_endstop_adj );
3705
+   SERIAL_EOL;
3706
+  }
3707
+  
3648 3708
 #endif // DELTA
3649 3709
 
3650 3710
 #ifdef FWRETRACT
@@ -4894,6 +4954,10 @@ void process_commands() {
4894 4954
         case 666: // M666 set delta endstop adjustment
4895 4955
           gcode_M666();
4896 4956
           break;
4957
+      #elif defined(Z_DUAL_ENDSTOPS)
4958
+        case 666: // M666 set delta endstop adjustment
4959
+          gcode_M666();
4960
+          break;
4897 4961
       #endif // DELTA
4898 4962
 
4899 4963
       #ifdef FWRETRACT

+ 1
- 2
Marlin/configurator/config/Configuration.h View File

@@ -193,7 +193,6 @@ Here are some standard links for getting your machine calibrated:
193 193
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
194 194
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
195 195
   #define K1 0.95 //smoothing factor within the PID
196
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
197 196
 
198 197
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
199 198
 // Ultimaker
@@ -218,7 +217,7 @@ Here are some standard links for getting your machine calibrated:
218 217
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
219 218
 //
220 219
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
221
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
220
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
222 221
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
223 222
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
224 223
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/Felix/Configuration.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
   // Felix 2.0+ electronics with v4 Hotend
190 189
   #define DEFAULT_Kp 12
@@ -199,7 +198,7 @@ Here are some standard links for getting your machine calibrated:
199 198
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
200 199
 //
201 200
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
202
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
201
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
203 202
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
204 203
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
205 204
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/Felix/Configuration_DUAL.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
   // Felix 2.0+ electronics with v4 Hotend
190 189
   #define DEFAULT_Kp 12
@@ -199,7 +198,7 @@ Here are some standard links for getting your machine calibrated:
199 198
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
200 199
 //
201 200
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
202
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
201
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
203 202
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
204 203
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
205 204
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/Hephestos/Configuration.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
190 189
 // Ultimaker
@@ -215,7 +214,7 @@ Here are some standard links for getting your machine calibrated:
215 214
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
216 215
 //
217 216
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
218
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
217
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
219 218
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
220 219
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
221 220
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/K8200/Configuration.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
190 189
 // Ultimaker
@@ -214,7 +213,7 @@ Here are some standard links for getting your machine calibrated:
214 213
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
215 214
 //
216 215
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
217
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
216
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
218 217
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
219 218
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
220 219
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/SCARA/Configuration.h View File

@@ -202,7 +202,6 @@ Here are some standard links for getting your machine calibrated:
202 202
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
203 203
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
204 204
   #define K1 0.95 //smoothing factor within the PID
205
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
206 205
 
207 206
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
208 207
 // Ultimaker
@@ -238,7 +237,7 @@ Here are some standard links for getting your machine calibrated:
238 237
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
239 238
 //
240 239
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
241
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
240
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
242 241
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
243 242
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
244 243
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/WITBOX/Configuration.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
190 189
 // Ultimaker
@@ -214,7 +213,7 @@ Here are some standard links for getting your machine calibrated:
214 213
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
215 214
 //
216 215
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
217
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
216
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
218 217
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
219 218
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
220 219
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/delta/generic/Configuration.h View File

@@ -217,7 +217,6 @@ Here are some standard links for getting your machine calibrated:
217 217
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
218 218
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
219 219
   #define K1 0.95 //smoothing factor within the PID
220
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
221 220
 
222 221
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
223 222
 // Ultimaker
@@ -242,7 +241,7 @@ Here are some standard links for getting your machine calibrated:
242 241
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
243 242
 //
244 243
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
245
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
244
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
246 245
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
247 246
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
248 247
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/delta/kossel_mini/Configuration.h View File

@@ -218,7 +218,6 @@ Here are some standard links for getting your machine calibrated:
218 218
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
219 219
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
220 220
   #define K1 0.95 //smoothing factor within the PID
221
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
222 221
 
223 222
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
224 223
 // Ultimaker
@@ -243,7 +242,7 @@ Here are some standard links for getting your machine calibrated:
243 242
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
244 243
 //
245 244
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
246
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
245
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
247 246
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
248 247
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
249 248
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/makibox/Configuration.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
190 189
 // Ultimaker
@@ -209,7 +208,7 @@ Here are some standard links for getting your machine calibrated:
209 208
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
210 209
 //
211 210
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
212
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
211
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
213 212
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
214 213
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
215 214
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 2
Marlin/example_configurations/tvrrug/Round2/Configuration.h View File

@@ -184,7 +184,6 @@ Here are some standard links for getting your machine calibrated:
184 184
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
185 185
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term
186 186
   #define K1 0.95 //smoothing factor within the PID
187
-  #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
188 187
 
189 188
 // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
190 189
 // J-Head Mk V-B
@@ -214,7 +213,7 @@ Here are some standard links for getting your machine calibrated:
214 213
 // Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
215 214
 //
216 215
 // Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
217
-// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
216
+// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
218 217
 // which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
219 218
 // This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
220 219
 // If your configuration is significantly different than this and you don't understand the issues involved, you probably

+ 1
- 0
Marlin/language.h View File

@@ -131,6 +131,7 @@
131 131
 #define MSG_Y_MAX                           "y_max: "
132 132
 #define MSG_Z_MIN                           "z_min: "
133 133
 #define MSG_Z_MAX                           "z_max: "
134
+#define MSG_Z2_MAX                          "z2_max: "
134 135
 #define MSG_M119_REPORT                     "Reporting endstop status"
135 136
 #define MSG_ENDSTOP_HIT                     "TRIGGERED"
136 137
 #define MSG_ENDSTOP_OPEN                    "open"

+ 29
- 0
Marlin/pins.h View File

@@ -178,6 +178,35 @@
178 178
   #define Z_MIN_PIN          -1
179 179
 #endif
180 180
 
181
+#ifdef DISABLE_XMAX_ENDSTOP
182
+  #undef X_MAX_PIN
183
+  #define X_MAX_PIN          -1
184
+#endif
185
+
186
+#ifdef DISABLE_XMIN_ENDSTOP
187
+  #undef X_MIN_PIN 
188
+  #define X_MIN_PIN          -1
189
+#endif
190
+
191
+#ifdef DISABLE_YMAX_ENDSTOP
192
+  #define Y_MAX_PIN          -1
193
+#endif
194
+
195
+#ifdef DISABLE_YMIN_ENDSTOP
196
+  #undef Y_MIN_PIN
197
+  #define Y_MIN_PIN          -1
198
+#endif
199
+
200
+#ifdef DISABLE_ZMAX_ENDSTOP
201
+  #undef Z_MAX_PIN
202
+  #define Z_MAX_PIN          -1
203
+#endif
204
+
205
+#ifdef DISABLE_ZMIN_ENDSTOP
206
+  #undef Z_MIN_PIN 
207
+  #define Z_MIN_PIN          -1
208
+#endif
209
+
181 210
 #define SENSITIVE_PINS { 0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, PS_ON_PIN, \
182 211
                         HEATER_BED_PIN, FAN_PIN, \
183 212
                         _E0_PINS _E1_PINS _E2_PINS _E3_PINS \

+ 94
- 15
Marlin/stepper.cpp View File

@@ -48,6 +48,12 @@ block_t *current_block;  // A pointer to the block currently being traced
48 48
 static unsigned char out_bits;        // The next stepping-bits to be output
49 49
 static unsigned int cleaning_buffer_counter;  
50 50
 
51
+#ifdef Z_DUAL_ENDSTOPS
52
+  static bool performing_homing = false, 
53
+              locked_z_motor = false, 
54
+              locked_z2_motor = false;
55
+#endif
56
+
51 57
 // Counter variables for the bresenham line tracer
52 58
 static long counter_x, counter_y, counter_z, counter_e;
53 59
 volatile static unsigned long step_events_completed; // The number of step events executed in the current block
@@ -84,7 +90,13 @@ static bool old_x_min_endstop = false,
84 90
             old_y_min_endstop = false,
85 91
             old_y_max_endstop = false,
86 92
             old_z_min_endstop = false,
93
+            #ifndef Z_DUAL_ENDSTOPS
87 94
             old_z_max_endstop = false;
95
+            #else
96
+              old_z_max_endstop = false,
97
+              old_z2_min_endstop = false,
98
+              old_z2_max_endstop = false;
99
+            #endif
88 100
 
89 101
 static bool check_endstops = true;
90 102
 
@@ -128,7 +140,23 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
128 140
 
129 141
 #ifdef Z_DUAL_STEPPER_DRIVERS
130 142
   #define Z_APPLY_DIR(v,Q) { Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }
131
-  #define Z_APPLY_STEP(v,Q) { Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }
143
+  #ifdef Z_DUAL_ENDSTOPS
144
+    #define Z_APPLY_STEP(v,Q) \
145
+    if (performing_homing) { \
146
+      if (Z_HOME_DIR > 0) {\
147
+        if (!(old_z_max_endstop && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
148
+        if (!(old_z2_max_endstop && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
149
+      } else {\
150
+        if (!(old_z_min_endstop && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
151
+        if (!(old_z2_min_endstop && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
152
+      } \
153
+    } else { \
154
+      Z_STEP_WRITE(v); \
155
+      Z2_STEP_WRITE(v); \
156
+    }
157
+  #else
158
+    #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v), Z2_STEP_WRITE(v)
159
+  #endif
132 160
 #else
133 161
   #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v)
134 162
   #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v)
@@ -465,28 +493,66 @@ ISR(TIMER1_COMPA_vect) {
465 493
     }
466 494
 
467 495
     if (TEST(out_bits, Z_AXIS)) {   // -direction
468
-      Z_DIR_WRITE(INVERT_Z_DIR);
469
-      #ifdef Z_DUAL_STEPPER_DRIVERS
470
-        Z2_DIR_WRITE(INVERT_Z_DIR);
471
-      #endif
472
-
496
+      Z_APPLY_DIR(INVERT_Z_DIR,0);
473 497
       count_direction[Z_AXIS] = -1;
474
-      if (check_endstops) {
475
-        #if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0
476
-          UPDATE_ENDSTOP(z, Z, min, MIN);
498
+      if (check_endstops) 
499
+      {
500
+        #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
501
+          #ifndef Z_DUAL_ENDSTOPS
502
+            UPDATE_ENDSTOP(z, Z, min, MIN);
503
+          #else
504
+            bool z_min_endstop=(READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
505
+            #if defined(Z2_MIN_PIN) && Z2_MIN_PIN > -1
506
+              bool z2_min_endstop=(READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING);
507
+            #else
508
+              bool z2_min_endstop=z_min_endstop;
509
+            #endif
510
+            if(((z_min_endstop && old_z_min_endstop) || (z2_min_endstop && old_z2_min_endstop)) && (current_block->steps[Z_AXIS] > 0))
511
+            {
512
+              endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
513
+              endstop_z_hit=true;
514
+              if (!(performing_homing) || ((performing_homing)&&(z_min_endstop && old_z_min_endstop)&&(z2_min_endstop && old_z2_min_endstop))) //if not performing home or if both endstops were trigged during homing...
515
+              {
516
+                step_events_completed = current_block->step_event_count;
517
+              } 
518
+            }
519
+            old_z_min_endstop = z_min_endstop;
520
+            old_z2_min_endstop = z2_min_endstop;
521
+          #endif
477 522
         #endif
478 523
       }
479 524
     }
480 525
     else { // +direction
481
-      Z_DIR_WRITE(!INVERT_Z_DIR);
482
-      #ifdef Z_DUAL_STEPPER_DRIVERS
483
-        Z2_DIR_WRITE(!INVERT_Z_DIR);
484
-      #endif
485
-
526
+      Z_APPLY_DIR(!INVERT_Z_DIR,0);
486 527
       count_direction[Z_AXIS] = 1;
487 528
       if (check_endstops) {
488 529
         #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0
489
-          UPDATE_ENDSTOP(z, Z, max, MAX);
530
+          #ifndef Z_DUAL_ENDSTOPS
531
+            UPDATE_ENDSTOP(z, Z, max, MAX);
532
+          #else
533
+            bool z_max_endstop=(READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING);
534
+            #if defined(Z2_MAX_PIN) && Z2_MAX_PIN > -1
535
+              bool z2_max_endstop=(READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING);
536
+            #else
537
+              bool z2_max_endstop=z_max_endstop;
538
+            #endif
539
+            if(((z_max_endstop && old_z_max_endstop) || (z2_max_endstop && old_z2_max_endstop)) && (current_block->steps[Z_AXIS] > 0))
540
+            {
541
+              endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
542
+              endstop_z_hit=true;
543
+
544
+//              if (z_max_endstop && old_z_max_endstop) SERIAL_ECHOLN("z_max_endstop = true");
545
+//              if (z2_max_endstop && old_z2_max_endstop) SERIAL_ECHOLN("z2_max_endstop = true");
546
+
547
+            
548
+              if (!(performing_homing) || ((performing_homing)&&(z_max_endstop && old_z_max_endstop)&&(z2_max_endstop && old_z2_max_endstop))) //if not performing home or if both endstops were trigged during homing...
549
+              {
550
+                step_events_completed = current_block->step_event_count;
551
+              } 
552
+            }
553
+            old_z_max_endstop = z_max_endstop;
554
+            old_z2_max_endstop = z2_max_endstop;
555
+          #endif
490 556
         #endif
491 557
       }
492 558
     }
@@ -845,6 +911,13 @@ void st_init() {
845 911
     #endif
846 912
   #endif
847 913
 
914
+  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN >= 0
915
+    SET_INPUT(Z2_MAX_PIN);
916
+    #ifdef ENDSTOPPULLUP_ZMAX
917
+      WRITE(Z2_MAX_PIN,HIGH);
918
+    #endif
919
+  #endif  
920
+  
848 921
   #define AXIS_INIT(axis, AXIS, PIN) \
849 922
     AXIS ##_STEP_INIT; \
850 923
     AXIS ##_STEP_WRITE(INVERT_## PIN ##_STEP_PIN); \
@@ -1174,3 +1247,9 @@ void microstep_readings() {
1174 1247
     SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN));
1175 1248
   #endif
1176 1249
 }
1250
+
1251
+#ifdef Z_DUAL_ENDSTOPS
1252
+  void In_Homing_Process(bool state) { performing_homing = state; }
1253
+  void Lock_z_motor(bool state) { locked_z_motor = state; }
1254
+  void Lock_z2_motor(bool state) { locked_z2_motor = state; }
1255
+#endif

+ 6
- 0
Marlin/stepper.h View File

@@ -97,6 +97,12 @@ void digipot_current(uint8_t driver, int current);
97 97
 void microstep_init();
98 98
 void microstep_readings();
99 99
 
100
+#ifdef Z_DUAL_ENDSTOPS
101
+  void In_Homing_Process(bool state);
102
+  void Lock_z_motor(bool state);
103
+  void Lock_z2_motor(bool state);
104
+#endif
105
+
100 106
 #ifdef BABYSTEPPING
101 107
   void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention
102 108
 #endif

+ 41
- 30
Marlin/temperature.cpp View File

@@ -45,6 +45,10 @@
45 45
   #define K2 (1.0-K1)
46 46
 #endif
47 47
 
48
+#if defined(PIDTEMPBED) || defined(PIDTEMP)
49
+  #define PID_dT ((OVERSAMPLENR * 12.0)/(F_CPU / 64.0 / 256.0))
50
+#endif
51
+
48 52
 //===========================================================================
49 53
 //============================= public variables ============================
50 54
 //===========================================================================
@@ -576,6 +580,12 @@ void manage_heater() {
576 580
 
577 581
   updateTemperaturesFromRawValues();
578 582
 
583
+  #ifdef HEATER_0_USES_MAX6675
584
+    float ct = current_temperature[0];
585
+    if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0);
586
+    if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
587
+  #endif //HEATER_0_USES_MAX6675
588
+
579 589
   unsigned long ms = millis();
580 590
 
581 591
   // Loop through all extruders
@@ -607,7 +617,7 @@ void manage_heater() {
607 617
     #ifdef TEMP_SENSOR_1_AS_REDUNDANT
608 618
       if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
609 619
         disable_heater();
610
-        _temp_error(-1, MSG_EXTRUDER_SWITCHED_OFF, MSG_ERR_REDUNDANT_TEMP);
620
+        _temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP));
611 621
       }
612 622
     #endif //TEMP_SENSOR_1_AS_REDUNDANT
613 623
 
@@ -1162,20 +1172,40 @@ enum TempState {
1162 1172
   StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle
1163 1173
 };
1164 1174
 
1175
+#ifdef TEMP_SENSOR_1_AS_REDUNDANT
1176
+  #define TEMP_SENSOR_COUNT 2
1177
+#else
1178
+  #define TEMP_SENSOR_COUNT EXTRUDERS
1179
+#endif
1180
+
1181
+static unsigned long raw_temp_value[TEMP_SENSOR_COUNT] = { 0 };
1182
+static unsigned long raw_temp_bed_value = 0;
1183
+
1184
+static void set_current_temp_raw() {
1185
+  #ifndef HEATER_0_USES_MAX6675
1186
+    current_temperature_raw[0] = raw_temp_value[0];
1187
+  #endif
1188
+  #if EXTRUDERS > 1
1189
+    current_temperature_raw[1] = raw_temp_value[1];
1190
+    #if EXTRUDERS > 2
1191
+      current_temperature_raw[2] = raw_temp_value[2];
1192
+      #if EXTRUDERS > 3
1193
+        current_temperature_raw[3] = raw_temp_value[3];
1194
+      #endif
1195
+    #endif
1196
+  #endif
1197
+  #ifdef TEMP_SENSOR_1_AS_REDUNDANT
1198
+    redundant_temperature_raw = raw_temp_value[1];
1199
+  #endif
1200
+  current_temperature_bed_raw = raw_temp_bed_value;
1201
+}
1202
+
1165 1203
 //
1166 1204
 // Timer 0 is shared with millies
1167 1205
 //
1168 1206
 ISR(TIMER0_COMPB_vect) {
1169
-  #ifdef TEMP_SENSOR_1_AS_REDUNDANT
1170
-    #define TEMP_SENSOR_COUNT 2
1171
-  #else 
1172
-    #define TEMP_SENSOR_COUNT EXTRUDERS
1173
-  #endif
1174
-
1175 1207
   //these variables are only accesible from the ISR, but static, so they don't lose their value
1176 1208
   static unsigned char temp_count = 0;
1177
-  static unsigned long raw_temp_value[TEMP_SENSOR_COUNT] = { 0 };
1178
-  static unsigned long raw_temp_bed_value = 0;
1179 1209
   static TempState temp_state = StartupDelay;
1180 1210
   static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
1181 1211
 
@@ -1478,22 +1508,7 @@ ISR(TIMER0_COMPB_vect) {
1478 1508
 
1479 1509
   if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256)  = 164ms.
1480 1510
     if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading.
1481
-      #ifndef HEATER_0_USES_MAX6675
1482
-        current_temperature_raw[0] = raw_temp_value[0];
1483
-      #endif
1484
-      #if EXTRUDERS > 1
1485
-        current_temperature_raw[1] = raw_temp_value[1];
1486
-        #if EXTRUDERS > 2
1487
-          current_temperature_raw[2] = raw_temp_value[2];
1488
-          #if EXTRUDERS > 3
1489
-            current_temperature_raw[3] = raw_temp_value[3];
1490
-          #endif
1491
-        #endif
1492
-      #endif
1493
-      #ifdef TEMP_SENSOR_1_AS_REDUNDANT
1494
-        redundant_temperature_raw = raw_temp_value[1];
1495
-      #endif
1496
-      current_temperature_bed_raw = raw_temp_bed_value;
1511
+      set_current_temp_raw();
1497 1512
     } //!temp_meas_ready
1498 1513
 
1499 1514
     // Filament Sensor - can be read any time since IIR filtering is used
@@ -1506,11 +1521,7 @@ ISR(TIMER0_COMPB_vect) {
1506 1521
     for (int i = 0; i < TEMP_SENSOR_COUNT; i++) raw_temp_value[i] = 0;
1507 1522
     raw_temp_bed_value = 0;
1508 1523
 
1509
-    #ifdef HEATER_0_USES_MAX6675
1510
-      float ct = current_temperature[0];
1511
-      if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0);
1512
-      if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
1513
-    #else
1524
+    #ifndef HEATER_0_USES_MAX6675
1514 1525
       #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
1515 1526
         #define GE0 <=
1516 1527
       #else

+ 1
- 1
Marlin/ultralcd.cpp View File

@@ -204,7 +204,7 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l
204 204
   #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
205 205
 #endif //!ENCODER_RATE_MULTIPLIER
206 206
 #define END_MENU() \
207
-    if (encoderLine >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\
207
+    if (encoderLine >= _menuItemNr) { encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; }\
208 208
     if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
209 209
     } } while(0)
210 210
 

+ 1
- 0
README.md View File

@@ -11,6 +11,7 @@
11 11
     * [Filament Sensor](/Documentation/FilamentSensor.md)
12 12
     * [Ramps Servo Power](/Documentation/RampsServoPower.md)
13 13
     * [LCD Language - Font - System](Documentation/LCDLanguageFont.md)
14
+    * [Mesh Bed Leveling](/Documentation/MeshBedLeveling.md)
14 15
 
15 16
 ##### [RepRap.org Wiki Page](http://reprap.org/wiki/Marlin)
16 17
 

Loading…
Cancel
Save