|
@@ -284,32 +284,51 @@ bool volumetric_enabled = false;
|
284
|
284
|
float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(DEFAULT_NOMINAL_FILAMENT_DIA);
|
285
|
285
|
float volumetric_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0);
|
286
|
286
|
|
|
287
|
+// The distance that XYZ has been offset by G92. Reset by G28.
|
287
|
288
|
float position_shift[3] = { 0 };
|
|
289
|
+
|
|
290
|
+// This offset is added to the configured home position.
|
|
291
|
+// Set by M206, M428, or menu item. Saved to EEPROM.
|
288
|
292
|
float home_offset[3] = { 0 };
|
289
|
|
-float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS };
|
290
|
|
-float max_pos[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
|
|
293
|
+
|
|
294
|
+// Software Endstops. Default to configured limits.
|
|
295
|
+float sw_endstop_min[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS };
|
|
296
|
+float sw_endstop_max[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
|
291
|
297
|
|
292
|
298
|
#if FAN_COUNT > 0
|
293
|
299
|
int fanSpeeds[FAN_COUNT] = { 0 };
|
294
|
300
|
#endif
|
295
|
301
|
|
|
302
|
+// The active extruder (tool). Set with T<extruder> command.
|
296
|
303
|
uint8_t active_extruder = 0;
|
|
304
|
+
|
|
305
|
+// Relative Mode. Enable with G91, disable with G90.
|
|
306
|
+static bool relative_mode = false;
|
|
307
|
+
|
297
|
308
|
bool cancel_heatup = false;
|
298
|
309
|
|
299
|
310
|
const char errormagic[] PROGMEM = "Error:";
|
300
|
311
|
const char echomagic[] PROGMEM = "echo:";
|
301
|
312
|
const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
|
302
|
313
|
|
303
|
|
-static bool relative_mode = false; //Determines Absolute or Relative Coordinates
|
304
|
314
|
static int serial_count = 0;
|
305
|
|
-static char* seen_pointer; ///< A pointer to find chars in the command string (X, Y, Z, E, etc.)
|
306
|
|
-const char* queued_commands_P = NULL; /* pointer to the current line in the active sequence of commands, or NULL when none */
|
|
315
|
+
|
|
316
|
+// GCode parameter pointer used by code_seen(), code_value(), etc.
|
|
317
|
+static char* seen_pointer;
|
|
318
|
+
|
|
319
|
+// Next Immediate GCode Command pointer. NULL if none.
|
|
320
|
+const char* queued_commands_P = NULL;
|
|
321
|
+
|
307
|
322
|
const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
|
|
323
|
+
|
308
|
324
|
// Inactivity shutdown
|
309
|
325
|
millis_t previous_cmd_ms = 0;
|
310
|
326
|
static millis_t max_inactive_time = 0;
|
311
|
327
|
static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL;
|
|
328
|
+
|
|
329
|
+// Print Job Timer
|
312
|
330
|
Stopwatch print_job_timer = Stopwatch();
|
|
331
|
+
|
313
|
332
|
static uint8_t target_extruder;
|
314
|
333
|
|
315
|
334
|
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
@@ -344,8 +363,8 @@ static uint8_t target_extruder;
|
344
|
363
|
#endif
|
345
|
364
|
|
346
|
365
|
#if ENABLED(BARICUDA)
|
347
|
|
- int ValvePressure = 0;
|
348
|
|
- int EtoPPressure = 0;
|
|
366
|
+ int baricuda_valve_pressure = 0;
|
|
367
|
+ int baricuda_e_to_p_pressure = 0;
|
349
|
368
|
#endif
|
350
|
369
|
|
351
|
370
|
#if ENABLED(FWRETRACT)
|
|
@@ -427,7 +446,7 @@ static uint8_t target_extruder;
|
427
|
446
|
#endif
|
428
|
447
|
|
429
|
448
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
430
|
|
- static bool filrunoutEnqueued = false;
|
|
449
|
+ static bool filament_ran_out = false;
|
431
|
450
|
#endif
|
432
|
451
|
|
433
|
452
|
static bool send_ok[BUFSIZE];
|
|
@@ -472,13 +491,13 @@ static bool send_ok[BUFSIZE];
|
472
|
491
|
* ***************************************************************************
|
473
|
492
|
*/
|
474
|
493
|
|
|
494
|
+void stop();
|
|
495
|
+
|
475
|
496
|
void get_available_commands();
|
476
|
497
|
void process_next_command();
|
477
|
498
|
|
478
|
499
|
void plan_arc(float target[NUM_AXIS], float* offset, uint8_t clockwise);
|
479
|
500
|
|
480
|
|
-bool setTargetedHotend(int code);
|
481
|
|
-
|
482
|
501
|
void serial_echopair_P(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
483
|
502
|
void serial_echopair_P(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
484
|
503
|
void serial_echopair_P(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
|
@@ -1142,6 +1161,30 @@ bool code_seen(char code) {
|
1142
|
1161
|
return (seen_pointer != NULL); // Return TRUE if the code-letter was found
|
1143
|
1162
|
}
|
1144
|
1163
|
|
|
1164
|
+/**
|
|
1165
|
+ * Set target_extruder from the T parameter or the active_extruder
|
|
1166
|
+ *
|
|
1167
|
+ * Returns TRUE if the target is invalid
|
|
1168
|
+ */
|
|
1169
|
+bool get_target_extruder_from_command(int code) {
|
|
1170
|
+ if (code_seen('T')) {
|
|
1171
|
+ short t = code_value_short();
|
|
1172
|
+ if (t >= EXTRUDERS) {
|
|
1173
|
+ SERIAL_ECHO_START;
|
|
1174
|
+ SERIAL_CHAR('M');
|
|
1175
|
+ SERIAL_ECHO(code);
|
|
1176
|
+ SERIAL_ECHOPAIR(" " MSG_INVALID_EXTRUDER " ", t);
|
|
1177
|
+ SERIAL_EOL;
|
|
1178
|
+ return true;
|
|
1179
|
+ }
|
|
1180
|
+ target_extruder = t;
|
|
1181
|
+ }
|
|
1182
|
+ else
|
|
1183
|
+ target_extruder = active_extruder;
|
|
1184
|
+
|
|
1185
|
+ return false;
|
|
1186
|
+}
|
|
1187
|
+
|
1145
|
1188
|
#define DEFINE_PGM_READ_ANY(type, reader) \
|
1146
|
1189
|
static inline type pgm_read_any(const type *p) \
|
1147
|
1190
|
{ return pgm_read_##reader##_near(p); }
|
|
@@ -1212,24 +1255,32 @@ static void update_software_endstops(AxisEnum axis) {
|
1212
|
1255
|
if (axis == X_AXIS) {
|
1213
|
1256
|
float dual_max_x = max(extruder_offset[X_AXIS][1], X2_MAX_POS);
|
1214
|
1257
|
if (active_extruder != 0) {
|
1215
|
|
- min_pos[X_AXIS] = X2_MIN_POS + offs;
|
1216
|
|
- max_pos[X_AXIS] = dual_max_x + offs;
|
|
1258
|
+ sw_endstop_min[X_AXIS] = X2_MIN_POS + offs;
|
|
1259
|
+ sw_endstop_max[X_AXIS] = dual_max_x + offs;
|
1217
|
1260
|
return;
|
1218
|
1261
|
}
|
1219
|
1262
|
else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
|
1220
|
|
- min_pos[X_AXIS] = base_min_pos(X_AXIS) + offs;
|
1221
|
|
- max_pos[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs;
|
|
1263
|
+ sw_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs;
|
|
1264
|
+ sw_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs;
|
1222
|
1265
|
return;
|
1223
|
1266
|
}
|
1224
|
1267
|
}
|
1225
|
1268
|
else
|
1226
|
1269
|
#endif
|
1227
|
1270
|
{
|
1228
|
|
- min_pos[axis] = base_min_pos(axis) + offs;
|
1229
|
|
- max_pos[axis] = base_max_pos(axis) + offs;
|
|
1271
|
+ sw_endstop_min[axis] = base_min_pos(axis) + offs;
|
|
1272
|
+ sw_endstop_max[axis] = base_max_pos(axis) + offs;
|
1230
|
1273
|
}
|
1231
|
1274
|
}
|
1232
|
1275
|
|
|
1276
|
+/**
|
|
1277
|
+ * Change the home offset for an axis, update the current
|
|
1278
|
+ * position and the software endstops to retain the same
|
|
1279
|
+ * relative distance to the new home.
|
|
1280
|
+ *
|
|
1281
|
+ * Since this changes the current_position, code should
|
|
1282
|
+ * call sync_plan_position soon after this.
|
|
1283
|
+ */
|
1233
|
1284
|
static void set_home_offset(AxisEnum axis, float v) {
|
1234
|
1285
|
current_position[axis] += v - home_offset[axis];
|
1235
|
1286
|
home_offset[axis] = v;
|
|
@@ -1294,8 +1345,8 @@ static void set_axis_is_at_home(AxisEnum axis) {
|
1294
|
1345
|
* SCARA home positions are based on configuration since the actual
|
1295
|
1346
|
* limits are determined by the inverse kinematic transform.
|
1296
|
1347
|
*/
|
1297
|
|
- min_pos[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis));
|
1298
|
|
- max_pos[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis));
|
|
1348
|
+ sw_endstop_min[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis));
|
|
1349
|
+ sw_endstop_max[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis));
|
1299
|
1350
|
}
|
1300
|
1351
|
else
|
1301
|
1352
|
#endif
|
|
@@ -1712,7 +1763,7 @@ static void setup_for_endstop_move() {
|
1712
|
1763
|
SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
|
1713
|
1764
|
LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
1714
|
1765
|
}
|
1715
|
|
- Stop();
|
|
1766
|
+ stop();
|
1716
|
1767
|
}
|
1717
|
1768
|
|
1718
|
1769
|
#endif // Z_PROBE_ALLEN_KEY
|
|
@@ -1816,7 +1867,7 @@ static void setup_for_endstop_move() {
|
1816
|
1867
|
SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
|
1817
|
1868
|
LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
1818
|
1869
|
}
|
1819
|
|
- Stop();
|
|
1870
|
+ stop();
|
1820
|
1871
|
}
|
1821
|
1872
|
#endif // Z_PROBE_ALLEN_KEY
|
1822
|
1873
|
|
|
@@ -4206,7 +4257,7 @@ inline void gcode_M77() {
|
4206
|
4257
|
* M104: Set hot end temperature
|
4207
|
4258
|
*/
|
4208
|
4259
|
inline void gcode_M104() {
|
4209
|
|
- if (setTargetedHotend(104)) return;
|
|
4260
|
+ if (get_target_extruder_from_command(104)) return;
|
4210
|
4261
|
if (DEBUGGING(DRYRUN)) return;
|
4211
|
4262
|
|
4212
|
4263
|
if (code_seen('S')) {
|
|
@@ -4314,7 +4365,7 @@ inline void gcode_M104() {
|
4314
|
4365
|
* M105: Read hot end and bed temperature
|
4315
|
4366
|
*/
|
4316
|
4367
|
inline void gcode_M105() {
|
4317
|
|
- if (setTargetedHotend(105)) return;
|
|
4368
|
+ if (get_target_extruder_from_command(105)) return;
|
4318
|
4369
|
|
4319
|
4370
|
#if HAS_TEMP_HOTEND || HAS_TEMP_BED
|
4320
|
4371
|
SERIAL_PROTOCOLPGM(MSG_OK);
|
|
@@ -4358,7 +4409,7 @@ inline void gcode_M105() {
|
4358
|
4409
|
*/
|
4359
|
4410
|
inline void gcode_M109() {
|
4360
|
4411
|
|
4361
|
|
- if (setTargetedHotend(109)) return;
|
|
4412
|
+ if (get_target_extruder_from_command(109)) return;
|
4362
|
4413
|
if (DEBUGGING(DRYRUN)) return;
|
4363
|
4414
|
|
4364
|
4415
|
bool no_wait_for_cooling = code_seen('S');
|
|
@@ -4612,22 +4663,22 @@ inline void gcode_M112() { kill(PSTR(MSG_KILLED)); }
|
4612
|
4663
|
/**
|
4613
|
4664
|
* M126: Heater 1 valve open
|
4614
|
4665
|
*/
|
4615
|
|
- inline void gcode_M126() { ValvePressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; }
|
|
4666
|
+ inline void gcode_M126() { baricuda_valve_pressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; }
|
4616
|
4667
|
/**
|
4617
|
4668
|
* M127: Heater 1 valve close
|
4618
|
4669
|
*/
|
4619
|
|
- inline void gcode_M127() { ValvePressure = 0; }
|
|
4670
|
+ inline void gcode_M127() { baricuda_valve_pressure = 0; }
|
4620
|
4671
|
#endif
|
4621
|
4672
|
|
4622
|
4673
|
#if HAS_HEATER_2
|
4623
|
4674
|
/**
|
4624
|
4675
|
* M128: Heater 2 valve open
|
4625
|
4676
|
*/
|
4626
|
|
- inline void gcode_M128() { EtoPPressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; }
|
|
4677
|
+ inline void gcode_M128() { baricuda_e_to_p_pressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; }
|
4627
|
4678
|
/**
|
4628
|
4679
|
* M129: Heater 2 valve close
|
4629
|
4680
|
*/
|
4630
|
|
- inline void gcode_M129() { EtoPPressure = 0; }
|
|
4681
|
+ inline void gcode_M129() { baricuda_e_to_p_pressure = 0; }
|
4631
|
4682
|
#endif
|
4632
|
4683
|
|
4633
|
4684
|
#endif //BARICUDA
|
|
@@ -5025,7 +5076,7 @@ inline void gcode_M121() { enable_endstops_globally(false); }
|
5025
|
5076
|
*/
|
5026
|
5077
|
inline void gcode_M200() {
|
5027
|
5078
|
|
5028
|
|
- if (setTargetedHotend(200)) return;
|
|
5079
|
+ if (get_target_extruder_from_command(200)) return;
|
5029
|
5080
|
|
5030
|
5081
|
if (code_seen('D')) {
|
5031
|
5082
|
float diameter = code_value();
|
|
@@ -5277,7 +5328,7 @@ inline void gcode_M206() {
|
5277
|
5328
|
* Z<zoffset> - Available with DUAL_X_CARRIAGE
|
5278
|
5329
|
*/
|
5279
|
5330
|
inline void gcode_M218() {
|
5280
|
|
- if (setTargetedHotend(218)) return;
|
|
5331
|
+ if (get_target_extruder_from_command(218)) return;
|
5281
|
5332
|
|
5282
|
5333
|
if (code_seen('X')) extruder_offset[X_AXIS][target_extruder] = code_value();
|
5283
|
5334
|
if (code_seen('Y')) extruder_offset[Y_AXIS][target_extruder] = code_value();
|
|
@@ -5316,7 +5367,7 @@ inline void gcode_M220() {
|
5316
|
5367
|
inline void gcode_M221() {
|
5317
|
5368
|
if (code_seen('S')) {
|
5318
|
5369
|
int sval = code_value();
|
5319
|
|
- if (setTargetedHotend(221)) return;
|
|
5370
|
+ if (get_target_extruder_from_command(221)) return;
|
5320
|
5371
|
extruder_multiplier[target_extruder] = sval;
|
5321
|
5372
|
}
|
5322
|
5373
|
}
|
|
@@ -5842,7 +5893,7 @@ inline void gcode_M428() {
|
5842
|
5893
|
bool err = false;
|
5843
|
5894
|
for (int8_t i = X_AXIS; i <= Z_AXIS; i++) {
|
5844
|
5895
|
if (axis_homed[i]) {
|
5845
|
|
- float base = (current_position[i] > (min_pos[i] + max_pos[i]) / 2) ? base_home_pos(i) : 0,
|
|
5896
|
+ float base = (current_position[i] > (sw_endstop_min[i] + sw_endstop_max[i]) / 2) ? base_home_pos(i) : 0,
|
5846
|
5897
|
diff = current_position[i] - base;
|
5847
|
5898
|
if (diff > -20 && diff < 20) {
|
5848
|
5899
|
set_home_offset((AxisEnum)i, home_offset[i] - diff);
|
|
@@ -6078,7 +6129,7 @@ inline void gcode_M503() {
|
6078
|
6129
|
#endif
|
6079
|
6130
|
|
6080
|
6131
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
6081
|
|
- filrunoutEnqueued = false;
|
|
6132
|
+ filament_ran_out = false;
|
6082
|
6133
|
#endif
|
6083
|
6134
|
|
6084
|
6135
|
}
|
|
@@ -7032,8 +7083,8 @@ void ok_to_send() {
|
7032
|
7083
|
|
7033
|
7084
|
void clamp_to_software_endstops(float target[3]) {
|
7034
|
7085
|
if (min_software_endstops) {
|
7035
|
|
- NOLESS(target[X_AXIS], min_pos[X_AXIS]);
|
7036
|
|
- NOLESS(target[Y_AXIS], min_pos[Y_AXIS]);
|
|
7086
|
+ NOLESS(target[X_AXIS], sw_endstop_min[X_AXIS]);
|
|
7087
|
+ NOLESS(target[Y_AXIS], sw_endstop_min[Y_AXIS]);
|
7037
|
7088
|
|
7038
|
7089
|
float negative_z_offset = 0;
|
7039
|
7090
|
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
@@ -7048,13 +7099,13 @@ void clamp_to_software_endstops(float target[3]) {
|
7048
|
7099
|
negative_z_offset += home_offset[Z_AXIS];
|
7049
|
7100
|
}
|
7050
|
7101
|
#endif
|
7051
|
|
- NOLESS(target[Z_AXIS], min_pos[Z_AXIS] + negative_z_offset);
|
|
7102
|
+ NOLESS(target[Z_AXIS], sw_endstop_min[Z_AXIS] + negative_z_offset);
|
7052
|
7103
|
}
|
7053
|
7104
|
|
7054
|
7105
|
if (max_software_endstops) {
|
7055
|
|
- NOMORE(target[X_AXIS], max_pos[X_AXIS]);
|
7056
|
|
- NOMORE(target[Y_AXIS], max_pos[Y_AXIS]);
|
7057
|
|
- NOMORE(target[Z_AXIS], max_pos[Z_AXIS]);
|
|
7106
|
+ NOMORE(target[X_AXIS], sw_endstop_max[X_AXIS]);
|
|
7107
|
+ NOMORE(target[Y_AXIS], sw_endstop_max[Y_AXIS]);
|
|
7108
|
+ NOMORE(target[Z_AXIS], sw_endstop_max[Z_AXIS]);
|
7058
|
7109
|
}
|
7059
|
7110
|
}
|
7060
|
7111
|
|
|
@@ -7714,7 +7765,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
|
7714
|
7765
|
|
7715
|
7766
|
#if HAS_FILRUNOUT
|
7716
|
7767
|
if (IS_SD_PRINTING && !(READ(FILRUNOUT_PIN) ^ FIL_RUNOUT_INVERTING))
|
7717
|
|
- filrunout();
|
|
7768
|
+ handle_filament_runout();
|
7718
|
7769
|
#endif
|
7719
|
7770
|
|
7720
|
7771
|
if (commands_in_queue < BUFSIZE) get_available_commands();
|
|
@@ -7897,9 +7948,9 @@ void kill(const char* lcd_msg) {
|
7897
|
7948
|
|
7898
|
7949
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
7899
|
7950
|
|
7900
|
|
- void filrunout() {
|
7901
|
|
- if (!filrunoutEnqueued) {
|
7902
|
|
- filrunoutEnqueued = true;
|
|
7951
|
+ void handle_filament_runout() {
|
|
7952
|
+ if (!filament_ran_out) {
|
|
7953
|
+ filament_ran_out = true;
|
7903
|
7954
|
enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
|
7904
|
7955
|
st_synchronize();
|
7905
|
7956
|
}
|
|
@@ -7968,7 +8019,7 @@ void kill(const char* lcd_msg) {
|
7968
|
8019
|
}
|
7969
|
8020
|
#endif // FAST_PWM_FAN
|
7970
|
8021
|
|
7971
|
|
-void Stop() {
|
|
8022
|
+void stop() {
|
7972
|
8023
|
disable_all_heaters();
|
7973
|
8024
|
if (IsRunning()) {
|
7974
|
8025
|
Running = false;
|
|
@@ -7979,27 +8030,6 @@ void Stop() {
|
7979
|
8030
|
}
|
7980
|
8031
|
}
|
7981
|
8032
|
|
7982
|
|
-/**
|
7983
|
|
- * Set target_extruder from the T parameter or the active_extruder
|
7984
|
|
- *
|
7985
|
|
- * Returns TRUE if the target is invalid
|
7986
|
|
- */
|
7987
|
|
-bool setTargetedHotend(int code) {
|
7988
|
|
- target_extruder = active_extruder;
|
7989
|
|
- if (code_seen('T')) {
|
7990
|
|
- target_extruder = code_value_short();
|
7991
|
|
- if (target_extruder >= EXTRUDERS) {
|
7992
|
|
- SERIAL_ECHO_START;
|
7993
|
|
- SERIAL_CHAR('M');
|
7994
|
|
- SERIAL_ECHO(code);
|
7995
|
|
- SERIAL_ECHOPGM(" " MSG_INVALID_EXTRUDER " ");
|
7996
|
|
- SERIAL_ECHOLN((int)target_extruder);
|
7997
|
|
- return true;
|
7998
|
|
- }
|
7999
|
|
- }
|
8000
|
|
- return false;
|
8001
|
|
-}
|
8002
|
|
-
|
8003
|
8033
|
float calculate_volumetric_multiplier(float diameter) {
|
8004
|
8034
|
if (!volumetric_enabled || diameter == 0) return 1.0;
|
8005
|
8035
|
float d2 = diameter * 0.5;
|