|
@@ -3516,22 +3516,16 @@ inline void gcode_G28() {
|
3516
|
3516
|
float measured_z,
|
3517
|
3517
|
z_before = probePointCounter ? Z_RAISE_BETWEEN_PROBINGS + current_position[Z_AXIS] : Z_RAISE_BEFORE_PROBING + home_offset[Z_AXIS];
|
3518
|
3518
|
|
3519
|
|
- if (probePointCounter) {
|
3520
|
|
- #if ENABLED(DEBUG_LEVELING_FEATURE)
|
3521
|
|
- if (DEBUGGING(LEVELING)) {
|
3522
|
|
- SERIAL_ECHOPAIR("z_before = (between) ", (Z_RAISE_BETWEEN_PROBINGS + current_position[Z_AXIS]));
|
3523
|
|
- SERIAL_EOL;
|
3524
|
|
- }
|
3525
|
|
- #endif
|
3526
|
|
- }
|
3527
|
|
- else {
|
3528
|
|
- #if ENABLED(DEBUG_LEVELING_FEATURE)
|
3529
|
|
- if (DEBUGGING(LEVELING)) {
|
3530
|
|
- SERIAL_ECHOPAIR("z_before = (before) ", Z_RAISE_BEFORE_PROBING + home_offset[Z_AXIS]);
|
3531
|
|
- SERIAL_EOL;
|
3532
|
|
- }
|
3533
|
|
- #endif
|
3534
|
|
- }
|
|
3519
|
+ #if ENABLED(DEBUG_LEVELING_FEATURE)
|
|
3520
|
+ if (DEBUGGING(LEVELING)) {
|
|
3521
|
+ SERIAL_ECHOPGM("z_before = (");
|
|
3522
|
+ if (probePointCounter)
|
|
3523
|
+ SERIAL_ECHOPGM("between) ");
|
|
3524
|
+ else
|
|
3525
|
+ SERIAL_ECHOPGM("before) ");
|
|
3526
|
+ SERIAL_ECHOLN(z_before);
|
|
3527
|
+ }
|
|
3528
|
+ #endif
|
3535
|
3529
|
|
3536
|
3530
|
#if ENABLED(DELTA)
|
3537
|
3531
|
// Avoid probing the corners (outside the round or hexagon print surface) on a delta printer.
|
|
@@ -4199,57 +4193,41 @@ inline void gcode_M42() {
|
4199
|
4193
|
return;
|
4200
|
4194
|
}
|
4201
|
4195
|
|
4202
|
|
- double sum = 0.0, mean = 0.0, sigma = 0.0, sample_set[50];
|
4203
|
|
- int8_t verbose_level = 1, n_samples = 10, n_legs = 0, schizoid_flag = 0;
|
4204
|
|
-
|
4205
|
|
- if (code_seen('V')) {
|
4206
|
|
- verbose_level = code_value_byte();
|
4207
|
|
- if (verbose_level < 0 || verbose_level > 4) {
|
4208
|
|
- SERIAL_PROTOCOLPGM("?Verbose Level not plausible (0-4).\n");
|
4209
|
|
- return;
|
4210
|
|
- }
|
|
4196
|
+ int8_t verbose_level = code_seen('V') ? code_value_byte() : 1;
|
|
4197
|
+ if (verbose_level < 0 || verbose_level > 4) {
|
|
4198
|
+ SERIAL_PROTOCOLPGM("?Verbose Level not plausible (0-4).\n");
|
|
4199
|
+ return;
|
4211
|
4200
|
}
|
4212
|
4201
|
|
4213
|
4202
|
if (verbose_level > 0)
|
4214
|
4203
|
SERIAL_PROTOCOLPGM("M48 Z-Probe Repeatability test\n");
|
4215
|
4204
|
|
4216
|
|
- if (code_seen('P')) {
|
4217
|
|
- n_samples = code_value_byte();
|
4218
|
|
- if (n_samples < 4 || n_samples > 50) {
|
4219
|
|
- SERIAL_PROTOCOLPGM("?Sample size not plausible (4-50).\n");
|
4220
|
|
- return;
|
4221
|
|
- }
|
|
4205
|
+ int8_t n_samples = code_seen('P') ? code_value_byte() : 10;
|
|
4206
|
+ if (n_samples < 4 || n_samples > 50) {
|
|
4207
|
+ SERIAL_PROTOCOLPGM("?Sample size not plausible (4-50).\n");
|
|
4208
|
+ return;
|
4222
|
4209
|
}
|
4223
|
4210
|
|
4224
|
4211
|
float X_current = current_position[X_AXIS],
|
4225
|
4212
|
Y_current = current_position[Y_AXIS],
|
4226
|
|
- Z_current = current_position[Z_AXIS],
|
4227
|
|
- X_probe_location = X_current + X_PROBE_OFFSET_FROM_EXTRUDER,
|
4228
|
|
- Y_probe_location = Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER,
|
4229
|
|
- Z_start_location = Z_current + Z_RAISE_BEFORE_PROBING;
|
|
4213
|
+ Z_start_location = current_position[Z_AXIS] + Z_RAISE_BEFORE_PROBING;
|
4230
|
4214
|
bool deploy_probe_for_each_reading = code_seen('E');
|
4231
|
4215
|
|
4232
|
|
- if (code_seen('X')) {
|
4233
|
|
- X_probe_location = code_value_axis_units(X_AXIS);
|
4234
|
|
- #if DISABLED(DELTA)
|
4235
|
|
- if (X_probe_location < MIN_PROBE_X || X_probe_location > MAX_PROBE_X) {
|
4236
|
|
- out_of_range_error(PSTR("X"));
|
4237
|
|
- return;
|
4238
|
|
- }
|
4239
|
|
- #endif
|
4240
|
|
- }
|
4241
|
|
-
|
4242
|
|
- if (code_seen('Y')) {
|
4243
|
|
- Y_probe_location = code_value_axis_units(Y_AXIS);
|
4244
|
|
- #if DISABLED(DELTA)
|
4245
|
|
- if (Y_probe_location < MIN_PROBE_Y || Y_probe_location > MAX_PROBE_Y) {
|
4246
|
|
- out_of_range_error(PSTR("Y"));
|
4247
|
|
- return;
|
4248
|
|
- }
|
4249
|
|
- #endif
|
4250
|
|
- }
|
|
4216
|
+ float X_probe_location = code_seen('X') ? code_value_axis_units(X_AXIS) : X_current + X_PROBE_OFFSET_FROM_EXTRUDER;
|
|
4217
|
+ #if DISABLED(DELTA)
|
|
4218
|
+ if (X_probe_location < MIN_PROBE_X || X_probe_location > MAX_PROBE_X) {
|
|
4219
|
+ out_of_range_error(PSTR("X"));
|
|
4220
|
+ return;
|
|
4221
|
+ }
|
|
4222
|
+ #endif
|
4251
|
4223
|
|
4252
|
|
- #if ENABLED(DELTA)
|
|
4224
|
+ float Y_probe_location = code_seen('Y') ? code_value_axis_units(Y_AXIS) : Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER;
|
|
4225
|
+ #if DISABLED(DELTA)
|
|
4226
|
+ if (Y_probe_location < MIN_PROBE_Y || Y_probe_location > MAX_PROBE_Y) {
|
|
4227
|
+ out_of_range_error(PSTR("Y"));
|
|
4228
|
+ return;
|
|
4229
|
+ }
|
|
4230
|
+ #else
|
4253
|
4231
|
if (sqrt(X_probe_location * X_probe_location + Y_probe_location * Y_probe_location) > DELTA_PROBEABLE_RADIUS) {
|
4254
|
4232
|
SERIAL_PROTOCOLPGM("? (X,Y) location outside of probeable radius.\n");
|
4255
|
4233
|
return;
|
|
@@ -4257,20 +4235,15 @@ inline void gcode_M42() {
|
4257
|
4235
|
#endif
|
4258
|
4236
|
|
4259
|
4237
|
bool seen_L = code_seen('L');
|
4260
|
|
-
|
4261
|
|
- if (seen_L) {
|
4262
|
|
- n_legs = code_value_byte();
|
4263
|
|
- if (n_legs < 0 || n_legs > 15) {
|
4264
|
|
- SERIAL_PROTOCOLPGM("?Number of legs in movement not plausible (0-15).\n");
|
4265
|
|
- return;
|
4266
|
|
- }
|
4267
|
|
- if (n_legs == 1) n_legs = 2;
|
|
4238
|
+ uint8_t n_legs = seen_L ? code_value_byte() : 0;
|
|
4239
|
+ if (n_legs < 0 || n_legs > 15) {
|
|
4240
|
+ SERIAL_PROTOCOLPGM("?Number of legs in movement not plausible (0-15).\n");
|
|
4241
|
+ return;
|
4268
|
4242
|
}
|
|
4243
|
+ if (n_legs == 1) n_legs = 2;
|
4269
|
4244
|
|
4270
|
|
- if (code_seen('S')) {
|
4271
|
|
- schizoid_flag++;
|
4272
|
|
- if (!seen_L) n_legs = 7;
|
4273
|
|
- }
|
|
4245
|
+ bool schizoid_flag = code_seen('S');
|
|
4246
|
+ if (schizoid_flag && !seen_L) n_legs = 7;
|
4274
|
4247
|
|
4275
|
4248
|
/**
|
4276
|
4249
|
* Now get everything to the specified probe point So we can safely do a
|
|
@@ -4299,26 +4272,29 @@ inline void gcode_M42() {
|
4299
|
4272
|
*/
|
4300
|
4273
|
setup_for_endstop_move();
|
4301
|
4274
|
|
4302
|
|
- probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING,
|
|
4275
|
+ // Height before each probe (except the first)
|
|
4276
|
+ float z_between = home_offset[Z_AXIS] + (deploy_probe_for_each_reading ? Z_RAISE_BEFORE_PROBING : Z_RAISE_BETWEEN_PROBINGS);
|
|
4277
|
+
|
|
4278
|
+ // Deploy the probe and probe the first point
|
|
4279
|
+ probe_pt(X_probe_location, Y_probe_location,
|
|
4280
|
+ home_offset[Z_AXIS] + Z_RAISE_BEFORE_PROBING,
|
4303
|
4281
|
deploy_probe_for_each_reading ? ProbeDeployAndStow : ProbeDeploy,
|
4304
|
4282
|
verbose_level);
|
4305
|
4283
|
|
4306
|
|
- raise_z_after_probing();
|
|
4284
|
+ randomSeed(millis());
|
4307
|
4285
|
|
|
4286
|
+ double mean, sigma, sample_set[n_samples];
|
4308
|
4287
|
for (uint8_t n = 0; n < n_samples; n++) {
|
4309
|
|
- randomSeed(millis());
|
4310
|
|
- delay(500);
|
4311
|
4288
|
if (n_legs) {
|
4312
|
|
- float radius, angle = random(0.0, 360.0);
|
4313
|
4289
|
int dir = (random(0, 10) > 5.0) ? -1 : 1; // clockwise or counter clockwise
|
4314
|
|
-
|
4315
|
|
- radius = random(
|
4316
|
|
- #if ENABLED(DELTA)
|
4317
|
|
- DELTA_PROBEABLE_RADIUS / 8, DELTA_PROBEABLE_RADIUS / 3
|
4318
|
|
- #else
|
4319
|
|
- 5, X_MAX_LENGTH / 8
|
4320
|
|
- #endif
|
4321
|
|
- );
|
|
4290
|
+ float angle = random(0.0, 360.0),
|
|
4291
|
+ radius = random(
|
|
4292
|
+ #if ENABLED(DELTA)
|
|
4293
|
+ DELTA_PROBEABLE_RADIUS / 8, DELTA_PROBEABLE_RADIUS / 3
|
|
4294
|
+ #else
|
|
4295
|
+ 5, X_MAX_LENGTH / 8
|
|
4296
|
+ #endif
|
|
4297
|
+ );
|
4322
|
4298
|
|
4323
|
4299
|
if (verbose_level > 3) {
|
4324
|
4300
|
SERIAL_ECHOPAIR("Starting radius: ", radius);
|
|
@@ -4383,26 +4359,21 @@ inline void gcode_M42() {
|
4383
|
4359
|
} // n_legs loop
|
4384
|
4360
|
} // n_legs
|
4385
|
4361
|
|
4386
|
|
- /**
|
4387
|
|
- * We don't really have to do this move, but if we don't we can see a
|
4388
|
|
- * funny shift in the Z Height because the user might not have the
|
4389
|
|
- * Z_RAISE_BEFORE_PROBING height identical to the Z_RAISE_BETWEEN_PROBING
|
4390
|
|
- * height. This gets us back to the probe location at the same height that
|
4391
|
|
- * we have been running around the circle at.
|
4392
|
|
- */
|
4393
|
|
- do_blocking_move_to_xy(X_probe_location - (X_PROBE_OFFSET_FROM_EXTRUDER), Y_probe_location - (Y_PROBE_OFFSET_FROM_EXTRUDER));
|
4394
|
|
- if (deploy_probe_for_each_reading)
|
4395
|
|
- sample_set[n] = probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING, ProbeDeployAndStow, verbose_level);
|
4396
|
|
- else {
|
4397
|
|
- if (n == n_samples - 1)
|
4398
|
|
- sample_set[n] = probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING, ProbeStow, verbose_level); else
|
4399
|
|
- sample_set[n] = probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING, ProbeStay, verbose_level);
|
4400
|
|
- }
|
|
4362
|
+ // The last probe will differ
|
|
4363
|
+ bool last_probe = (n == n_samples - 1);
|
|
4364
|
+
|
|
4365
|
+ // Probe a single point
|
|
4366
|
+ sample_set[n] = probe_pt(
|
|
4367
|
+ X_probe_location, Y_probe_location,
|
|
4368
|
+ z_between,
|
|
4369
|
+ deploy_probe_for_each_reading ? ProbeDeployAndStow : last_probe ? ProbeStow : ProbeStay,
|
|
4370
|
+ verbose_level
|
|
4371
|
+ );
|
4401
|
4372
|
|
4402
|
4373
|
/**
|
4403
|
4374
|
* Get the current mean for the data points we have so far
|
4404
|
4375
|
*/
|
4405
|
|
- sum = 0.0;
|
|
4376
|
+ double sum = 0.0;
|
4406
|
4377
|
for (uint8_t j = 0; j <= n; j++) sum += sample_set[j];
|
4407
|
4378
|
mean = sum / (n + 1);
|
4408
|
4379
|
|
|
@@ -4416,38 +4387,42 @@ inline void gcode_M42() {
|
4416
|
4387
|
sum += ss * ss;
|
4417
|
4388
|
}
|
4418
|
4389
|
sigma = sqrt(sum / (n + 1));
|
4419
|
|
- if (verbose_level > 1) {
|
4420
|
|
- SERIAL_PROTOCOL(n + 1);
|
4421
|
|
- SERIAL_PROTOCOLPGM(" of ");
|
4422
|
|
- SERIAL_PROTOCOL((int)n_samples);
|
4423
|
|
- SERIAL_PROTOCOLPGM(" z: ");
|
4424
|
|
- SERIAL_PROTOCOL_F(current_position[Z_AXIS], 6);
|
4425
|
|
- delay(50);
|
4426
|
|
- if (verbose_level > 2) {
|
4427
|
|
- SERIAL_PROTOCOLPGM(" mean: ");
|
4428
|
|
- SERIAL_PROTOCOL_F(mean, 6);
|
4429
|
|
- SERIAL_PROTOCOLPGM(" sigma: ");
|
4430
|
|
- SERIAL_PROTOCOL_F(sigma, 6);
|
|
4390
|
+ if (verbose_level > 0) {
|
|
4391
|
+ if (verbose_level > 1) {
|
|
4392
|
+ SERIAL_PROTOCOL(n + 1);
|
|
4393
|
+ SERIAL_PROTOCOLPGM(" of ");
|
|
4394
|
+ SERIAL_PROTOCOL((int)n_samples);
|
|
4395
|
+ SERIAL_PROTOCOLPGM(" z: ");
|
|
4396
|
+ SERIAL_PROTOCOL_F(current_position[Z_AXIS], 6);
|
|
4397
|
+ delay(50);
|
|
4398
|
+ if (verbose_level > 2) {
|
|
4399
|
+ SERIAL_PROTOCOLPGM(" mean: ");
|
|
4400
|
+ SERIAL_PROTOCOL_F(mean, 6);
|
|
4401
|
+ SERIAL_PROTOCOLPGM(" sigma: ");
|
|
4402
|
+ SERIAL_PROTOCOL_F(sigma, 6);
|
|
4403
|
+ }
|
4431
|
4404
|
}
|
|
4405
|
+ SERIAL_EOL;
|
|
4406
|
+ }
|
|
4407
|
+
|
|
4408
|
+ // Raise before the next loop for the legs,
|
|
4409
|
+ // or do the final raise after the last probe
|
|
4410
|
+ if (n_legs || last_probe) {
|
|
4411
|
+ do_blocking_move_to_z(last_probe ? home_offset[Z_AXIS] + Z_RAISE_AFTER_PROBING : z_between);
|
|
4412
|
+ if (!last_probe) delay(500);
|
4432
|
4413
|
}
|
4433
|
|
- if (verbose_level > 0) SERIAL_EOL;
|
4434
|
|
- delay(50);
|
4435
|
|
- do_blocking_move_to_z(current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
|
4436
|
|
- } // End of probe loop code
|
4437
|
4414
|
|
4438
|
|
- // raise_z_after_probing();
|
|
4415
|
+ } // End of probe loop
|
4439
|
4416
|
|
4440
|
4417
|
if (verbose_level > 0) {
|
4441
|
4418
|
SERIAL_PROTOCOLPGM("Mean: ");
|
4442
|
4419
|
SERIAL_PROTOCOL_F(mean, 6);
|
4443
|
4420
|
SERIAL_EOL;
|
4444
|
|
- delay(25);
|
4445
|
4421
|
}
|
4446
|
4422
|
|
4447
|
4423
|
SERIAL_PROTOCOLPGM("Standard Deviation: ");
|
4448
|
4424
|
SERIAL_PROTOCOL_F(sigma, 6);
|
4449
|
4425
|
SERIAL_EOL; SERIAL_EOL;
|
4450
|
|
- delay(25);
|
4451
|
4426
|
|
4452
|
4427
|
clean_up_after_endstop_move();
|
4453
|
4428
|
|