|
@@ -1,30 +1,30 @@
|
1
|
|
-/* -*- c++ -*- */
|
2
|
|
-
|
3
|
|
-/*
|
4
|
|
- Reprap firmware based on Sprinter and grbl.
|
5
|
|
- Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
6
|
|
-
|
7
|
|
- This program is free software: you can redistribute it and/or modify
|
8
|
|
- it under the terms of the GNU General Public License as published by
|
9
|
|
- the Free Software Foundation, either version 3 of the License, or
|
10
|
|
- (at your option) any later version.
|
11
|
|
-
|
12
|
|
- This program is distributed in the hope that it will be useful,
|
13
|
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
|
- GNU General Public License for more details.
|
16
|
|
-
|
17
|
|
- You should have received a copy of the GNU General Public License
|
18
|
|
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
|
- */
|
20
|
|
-
|
21
|
|
-/*
|
22
|
|
- This firmware is a mashup between Sprinter and grbl.
|
23
|
|
- (https://github.com/kliment/Sprinter)
|
24
|
|
- (https://github.com/simen/grbl/tree)
|
25
|
|
-
|
26
|
|
- It has preliminary support for Matthew Roberts advance algorithm
|
27
|
|
- http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
|
1
|
+/**
|
|
2
|
+ * Marlin Firmware
|
|
3
|
+ *
|
|
4
|
+ * Based on Sprinter and grbl.
|
|
5
|
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
|
6
|
+ *
|
|
7
|
+ * This program is free software: you can redistribute it and/or modify
|
|
8
|
+ * it under the terms of the GNU General Public License as published by
|
|
9
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+ * (at your option) any later version.
|
|
11
|
+ *
|
|
12
|
+ * This program is distributed in the hope that it will be useful,
|
|
13
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+ * GNU General Public License for more details.
|
|
16
|
+ *
|
|
17
|
+ * You should have received a copy of the GNU General Public License
|
|
18
|
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+ *
|
|
20
|
+ * About Marlin
|
|
21
|
+ *
|
|
22
|
+ * This firmware is a mashup between Sprinter and grbl.
|
|
23
|
+ * - https://github.com/kliment/Sprinter
|
|
24
|
+ * - https://github.com/simen/grbl/tree
|
|
25
|
+ *
|
|
26
|
+ * It has preliminary support for Matthew Roberts advance algorithm
|
|
27
|
+ * - http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
28
|
28
|
*/
|
29
|
29
|
|
30
|
30
|
#include "Marlin.h"
|
|
@@ -73,13 +73,12 @@
|
73
|
73
|
* - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
|
74
|
74
|
*
|
75
|
75
|
* Help us document these G-codes online:
|
|
76
|
+ * - http://www.marlinfirmware.org/index.php/G-Code
|
76
|
77
|
* - http://reprap.org/wiki/G-code
|
77
|
|
- * - https://github.com/MarlinFirmware/Marlin/wiki/Marlin-G-Code
|
78
|
|
- */
|
79
|
|
-
|
80
|
|
-/**
|
|
78
|
+ *
|
|
79
|
+ * -----------------
|
81
|
80
|
* Implemented Codes
|
82
|
|
- * -------------------
|
|
81
|
+ * -----------------
|
83
|
82
|
*
|
84
|
83
|
* "G" Codes
|
85
|
84
|
*
|
|
@@ -163,7 +162,7 @@
|
163
|
162
|
* M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk
|
164
|
163
|
* M206 - Set additional homing offset
|
165
|
164
|
* M207 - Set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting
|
166
|
|
- * M208 - Set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/sec]
|
|
165
|
+ * M208 - Set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min]
|
167
|
166
|
* M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
|
168
|
167
|
* M218 - Set hotend offset (in mm): T<extruder_number> X<offset_on_X> Y<offset_on_Y>
|
169
|
168
|
* M220 - Set speed factor override percentage: S<factor in percent>
|
|
@@ -215,6 +214,11 @@
|
215
|
214
|
*
|
216
|
215
|
* M928 - Start SD logging (M928 filename.g) - ended by M29
|
217
|
216
|
* M999 - Restart after being stopped by error
|
|
217
|
+ *
|
|
218
|
+ * "T" Codes
|
|
219
|
+ *
|
|
220
|
+ * T0-T3 - Select a tool by index (usually an extruder) [ F<mm/min> ]
|
|
221
|
+ *
|
218
|
222
|
*/
|
219
|
223
|
|
220
|
224
|
#ifdef SDSUPPORT
|
|
@@ -557,9 +561,9 @@ void servo_init() {
|
557
|
561
|
|
558
|
562
|
// Set position of Servo Endstops that are defined
|
559
|
563
|
#ifdef SERVO_ENDSTOPS
|
560
|
|
- for (int i = 0; i < 3; i++)
|
561
|
|
- if (servo_endstops[i] >= 0)
|
562
|
|
- servo[servo_endstops[i]].write(servo_endstop_angles[i * 2 + 1]);
|
|
564
|
+ for (int i = 0; i < 3; i++)
|
|
565
|
+ if (servo_endstops[i] >= 0)
|
|
566
|
+ servo[servo_endstops[i]].write(servo_endstop_angles[i * 2 + 1]);
|
563
|
567
|
#endif
|
564
|
568
|
|
565
|
569
|
#if SERVO_LEVELING
|
|
@@ -993,7 +997,7 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR);
|
993
|
997
|
|
994
|
998
|
#endif //DUAL_X_CARRIAGE
|
995
|
999
|
|
996
|
|
-static void axis_is_at_home(int axis) {
|
|
1000
|
+static void axis_is_at_home(AxisEnum axis) {
|
997
|
1001
|
|
998
|
1002
|
#ifdef DUAL_X_CARRIAGE
|
999
|
1003
|
if (axis == X_AXIS) {
|
|
@@ -1198,12 +1202,12 @@ static void setup_for_endstop_move() {
|
1198
|
1202
|
plan_bed_level_matrix.set_to_identity();
|
1199
|
1203
|
feedrate = homing_feedrate[Z_AXIS];
|
1200
|
1204
|
|
1201
|
|
- // move down until you find the bed
|
|
1205
|
+ // Move down until the probe (or endstop?) is triggered
|
1202
|
1206
|
float zPosition = -10;
|
1203
|
1207
|
line_to_z(zPosition);
|
1204
|
1208
|
st_synchronize();
|
1205
|
1209
|
|
1206
|
|
- // we have to let the planner know where we are right now as it is not where we said to go.
|
|
1210
|
+ // Tell the planner where we ended up - Get this from the stepper handler
|
1207
|
1211
|
zPosition = st_get_position_mm(Z_AXIS);
|
1208
|
1212
|
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]);
|
1209
|
1213
|
|
|
@@ -1313,21 +1317,21 @@ static void setup_for_endstop_move() {
|
1313
|
1317
|
|
1314
|
1318
|
st_synchronize();
|
1315
|
1319
|
|
1316
|
|
- #ifdef Z_PROBE_ENDSTOP
|
1317
|
|
- bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
|
1318
|
|
- if (z_probe_endstop)
|
1319
|
|
- #else
|
1320
|
|
- bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
1321
|
|
- if (z_min_endstop)
|
1322
|
|
- #endif
|
1323
|
|
- {
|
1324
|
|
- if (IsRunning()) {
|
1325
|
|
- SERIAL_ERROR_START;
|
1326
|
|
- SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
|
1327
|
|
- LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
|
1320
|
+ #ifdef Z_PROBE_ENDSTOP
|
|
1321
|
+ bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
|
|
1322
|
+ if (z_probe_endstop)
|
|
1323
|
+ #else
|
|
1324
|
+ bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
|
1325
|
+ if (z_min_endstop)
|
|
1326
|
+ #endif
|
|
1327
|
+ {
|
|
1328
|
+ if (IsRunning()) {
|
|
1329
|
+ SERIAL_ERROR_START;
|
|
1330
|
+ SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
|
|
1331
|
+ LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
|
1332
|
+ }
|
|
1333
|
+ Stop();
|
1328
|
1334
|
}
|
1329
|
|
- Stop();
|
1330
|
|
- }
|
1331
|
1335
|
|
1332
|
1336
|
#endif // Z_PROBE_ALLEN_KEY
|
1333
|
1337
|
|
|
@@ -1390,23 +1394,23 @@ static void setup_for_endstop_move() {
|
1390
|
1394
|
|
1391
|
1395
|
st_synchronize();
|
1392
|
1396
|
|
1393
|
|
- #ifdef Z_PROBE_ENDSTOP
|
1394
|
|
- bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
|
1395
|
|
- if (!z_probe_endstop)
|
1396
|
|
- #else
|
1397
|
|
- bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
1398
|
|
- if (!z_min_endstop)
|
1399
|
|
- #endif
|
1400
|
|
- {
|
1401
|
|
- if (IsRunning()) {
|
1402
|
|
- SERIAL_ERROR_START;
|
1403
|
|
- SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
|
1404
|
|
- LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
|
1397
|
+ #ifdef Z_PROBE_ENDSTOP
|
|
1398
|
+ bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
|
|
1399
|
+ if (!z_probe_endstop)
|
|
1400
|
+ #else
|
|
1401
|
+ bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
|
1402
|
+ if (!z_min_endstop)
|
|
1403
|
+ #endif
|
|
1404
|
+ {
|
|
1405
|
+ if (IsRunning()) {
|
|
1406
|
+ SERIAL_ERROR_START;
|
|
1407
|
+ SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
|
|
1408
|
+ LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
|
1409
|
+ }
|
|
1410
|
+ Stop();
|
1405
|
1411
|
}
|
1406
|
|
- Stop();
|
1407
|
|
- }
|
1408
|
1412
|
|
1409
|
|
- #endif
|
|
1413
|
+ #endif // Z_PROBE_ALLEN_KEY
|
1410
|
1414
|
|
1411
|
1415
|
}
|
1412
|
1416
|
|
|
@@ -1418,32 +1422,31 @@ static void setup_for_endstop_move() {
|
1418
|
1422
|
};
|
1419
|
1423
|
|
1420
|
1424
|
// Probe bed height at position (x,y), returns the measured z value
|
1421
|
|
- static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeDeployAndStow, int verbose_level=1) {
|
|
1425
|
+ static float probe_pt(float x, float y, float z_before, ProbeAction probe_action=ProbeDeployAndStow, int verbose_level=1) {
|
1422
|
1426
|
// move to right place
|
1423
|
1427
|
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before); // this also updates current_position
|
1424
|
1428
|
do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]); // this also updates current_position
|
1425
|
1429
|
|
1426
|
1430
|
#if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
|
1427
|
|
- if (retract_action & ProbeDeploy) deploy_z_probe();
|
|
1431
|
+ if (probe_action & ProbeDeploy) deploy_z_probe();
|
1428
|
1432
|
#endif
|
1429
|
1433
|
|
1430
|
1434
|
run_z_probe();
|
1431
|
1435
|
float measured_z = current_position[Z_AXIS];
|
1432
|
1436
|
|
1433
|
1437
|
#if Z_RAISE_BETWEEN_PROBINGS > 0
|
1434
|
|
- if (retract_action == ProbeStay) {
|
|
1438
|
+ if (probe_action == ProbeStay) {
|
1435
|
1439
|
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS); // this also updates current_position
|
1436
|
1440
|
st_synchronize();
|
1437
|
1441
|
}
|
1438
|
1442
|
#endif
|
1439
|
1443
|
|
1440
|
1444
|
#if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
|
1441
|
|
- if (retract_action & ProbeStow) stow_z_probe();
|
|
1445
|
+ if (probe_action & ProbeStow) stow_z_probe();
|
1442
|
1446
|
#endif
|
1443
|
1447
|
|
1444
|
1448
|
if (verbose_level > 2) {
|
1445
|
|
- SERIAL_PROTOCOLPGM("Bed");
|
1446
|
|
- SERIAL_PROTOCOLPGM(" X: ");
|
|
1449
|
+ SERIAL_PROTOCOLPGM("Bed X: ");
|
1447
|
1450
|
SERIAL_PROTOCOL_F(x, 3);
|
1448
|
1451
|
SERIAL_PROTOCOLPGM(" Y: ");
|
1449
|
1452
|
SERIAL_PROTOCOL_F(y, 3);
|
|
@@ -1593,12 +1596,11 @@ static void homeaxis(AxisEnum axis) {
|
1593
|
1596
|
if (axis == Z_AXIS) {
|
1594
|
1597
|
if (axis_home_dir < 0) deploy_z_probe();
|
1595
|
1598
|
}
|
1596
|
|
- else
|
1597
|
1599
|
|
1598
|
1600
|
#endif
|
1599
|
1601
|
|
1600
|
1602
|
#ifdef SERVO_ENDSTOPS
|
1601
|
|
- {
|
|
1603
|
+ if (axis != Z_AXIS) {
|
1602
|
1604
|
// Engage Servo endstop if enabled
|
1603
|
1605
|
if (servo_endstops[axis] > -1)
|
1604
|
1606
|
servo[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
|
|
@@ -2763,8 +2765,8 @@ inline void gcode_G28() {
|
2763
|
2765
|
z_tmp = current_position[Z_AXIS],
|
2764
|
2766
|
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)
|
2765
|
2767
|
|
2766
|
|
- apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp); //Apply the correction sending the probe offset
|
2767
|
|
- current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS]; //The difference is added to current position and sent to planner.
|
|
2768
|
+ apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp); // Apply the correction sending the probe offset
|
|
2769
|
+ current_position[Z_AXIS] += z_tmp - real_z; // The difference is added to current position and sent to planner.
|
2768
|
2770
|
sync_plan_position();
|
2769
|
2771
|
}
|
2770
|
2772
|
#endif // !DELTA
|
|
@@ -2792,8 +2794,7 @@ inline void gcode_G28() {
|
2792
|
2794
|
feedrate = homing_feedrate[Z_AXIS];
|
2793
|
2795
|
|
2794
|
2796
|
run_z_probe();
|
2795
|
|
- SERIAL_PROTOCOLPGM("Bed");
|
2796
|
|
- SERIAL_PROTOCOLPGM(" X: ");
|
|
2797
|
+ SERIAL_PROTOCOLPGM("Bed X: ");
|
2797
|
2798
|
SERIAL_PROTOCOL(current_position[X_AXIS] + 0.0001);
|
2798
|
2799
|
SERIAL_PROTOCOLPGM(" Y: ");
|
2799
|
2800
|
SERIAL_PROTOCOL(current_position[Y_AXIS] + 0.0001);
|
|
@@ -4624,7 +4625,7 @@ inline void gcode_M400() { st_synchronize(); }
|
4624
|
4625
|
stow_z_probe(false);
|
4625
|
4626
|
}
|
4626
|
4627
|
|
4627
|
|
-#endif
|
|
4628
|
+#endif // ENABLE_AUTO_BED_LEVELING && (SERVO_ENDSTOPS || Z_PROBE_ALLEN_KEY) && !Z_PROBE_SLED
|
4628
|
4629
|
|
4629
|
4630
|
#ifdef FILAMENT_SENSOR
|
4630
|
4631
|
|
|
@@ -4819,7 +4820,7 @@ inline void gcode_M503() {
|
4819
|
4820
|
if (code_seen('Z')) {
|
4820
|
4821
|
value = code_value();
|
4821
|
4822
|
if (Z_PROBE_OFFSET_RANGE_MIN <= value && value <= Z_PROBE_OFFSET_RANGE_MAX) {
|
4822
|
|
- zprobe_zoffset = -value; // compare w/ line 278 of configuration_store.cpp
|
|
4823
|
+ zprobe_zoffset = -value;
|
4823
|
4824
|
SERIAL_ECHO_START;
|
4824
|
4825
|
SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " " MSG_OK);
|
4825
|
4826
|
SERIAL_EOL;
|
|
@@ -5074,9 +5075,11 @@ inline void gcode_M999() {
|
5074
|
5075
|
|
5075
|
5076
|
/**
|
5076
|
5077
|
* T0-T3: Switch tool, usually switching extruders
|
|
5078
|
+ *
|
|
5079
|
+ * F[mm/min] Set the movement feedrate
|
5077
|
5080
|
*/
|
5078
|
5081
|
inline void gcode_T() {
|
5079
|
|
- int tmp_extruder = code_value();
|
|
5082
|
+ uint16_t tmp_extruder = code_value_short();
|
5080
|
5083
|
if (tmp_extruder >= EXTRUDERS) {
|
5081
|
5084
|
SERIAL_ECHO_START;
|
5082
|
5085
|
SERIAL_CHAR('T');
|
|
@@ -5589,14 +5592,14 @@ void process_next_command() {
|
5589
|
5592
|
gcode_M400();
|
5590
|
5593
|
break;
|
5591
|
5594
|
|
5592
|
|
- #if defined(ENABLE_AUTO_BED_LEVELING) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY)) && not defined(Z_PROBE_SLED)
|
|
5595
|
+ #if defined(ENABLE_AUTO_BED_LEVELING) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY)) && !defined(Z_PROBE_SLED)
|
5593
|
5596
|
case 401:
|
5594
|
5597
|
gcode_M401();
|
5595
|
5598
|
break;
|
5596
|
5599
|
case 402:
|
5597
|
5600
|
gcode_M402();
|
5598
|
5601
|
break;
|
5599
|
|
- #endif
|
|
5602
|
+ #endif // ENABLE_AUTO_BED_LEVELING && (SERVO_ENDSTOPS || Z_PROBE_ALLEN_KEY) && !Z_PROBE_SLED
|
5600
|
5603
|
|
5601
|
5604
|
#ifdef FILAMENT_SENSOR
|
5602
|
5605
|
case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width
|
|
@@ -6089,82 +6092,83 @@ void prepare_move() {
|
6089
|
6092
|
#endif // HAS_CONTROLLERFAN
|
6090
|
6093
|
|
6091
|
6094
|
#ifdef SCARA
|
6092
|
|
-void calculate_SCARA_forward_Transform(float f_scara[3])
|
6093
|
|
-{
|
6094
|
|
- // Perform forward kinematics, and place results in delta[3]
|
6095
|
|
- // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
|
6096
|
|
-
|
6097
|
|
- float x_sin, x_cos, y_sin, y_cos;
|
6098
|
|
-
|
|
6095
|
+
|
|
6096
|
+ void calculate_SCARA_forward_Transform(float f_scara[3]) {
|
|
6097
|
+ // Perform forward kinematics, and place results in delta[3]
|
|
6098
|
+ // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
|
|
6099
|
+
|
|
6100
|
+ float x_sin, x_cos, y_sin, y_cos;
|
|
6101
|
+
|
6099
|
6102
|
//SERIAL_ECHOPGM("f_delta x="); SERIAL_ECHO(f_scara[X_AXIS]);
|
6100
|
6103
|
//SERIAL_ECHOPGM(" y="); SERIAL_ECHO(f_scara[Y_AXIS]);
|
6101
|
|
-
|
|
6104
|
+
|
6102
|
6105
|
x_sin = sin(f_scara[X_AXIS]/SCARA_RAD2DEG) * Linkage_1;
|
6103
|
6106
|
x_cos = cos(f_scara[X_AXIS]/SCARA_RAD2DEG) * Linkage_1;
|
6104
|
6107
|
y_sin = sin(f_scara[Y_AXIS]/SCARA_RAD2DEG) * Linkage_2;
|
6105
|
6108
|
y_cos = cos(f_scara[Y_AXIS]/SCARA_RAD2DEG) * Linkage_2;
|
6106
|
|
-
|
6107
|
|
- // SERIAL_ECHOPGM(" x_sin="); SERIAL_ECHO(x_sin);
|
6108
|
|
- // SERIAL_ECHOPGM(" x_cos="); SERIAL_ECHO(x_cos);
|
6109
|
|
- // SERIAL_ECHOPGM(" y_sin="); SERIAL_ECHO(y_sin);
|
6110
|
|
- // SERIAL_ECHOPGM(" y_cos="); SERIAL_ECHOLN(y_cos);
|
6111
|
|
-
|
|
6109
|
+
|
|
6110
|
+ //SERIAL_ECHOPGM(" x_sin="); SERIAL_ECHO(x_sin);
|
|
6111
|
+ //SERIAL_ECHOPGM(" x_cos="); SERIAL_ECHO(x_cos);
|
|
6112
|
+ //SERIAL_ECHOPGM(" y_sin="); SERIAL_ECHO(y_sin);
|
|
6113
|
+ //SERIAL_ECHOPGM(" y_cos="); SERIAL_ECHOLN(y_cos);
|
|
6114
|
+
|
6112
|
6115
|
delta[X_AXIS] = x_cos + y_cos + SCARA_offset_x; //theta
|
6113
|
6116
|
delta[Y_AXIS] = x_sin + y_sin + SCARA_offset_y; //theta+phi
|
6114
|
6117
|
|
6115
|
6118
|
//SERIAL_ECHOPGM(" delta[X_AXIS]="); SERIAL_ECHO(delta[X_AXIS]);
|
6116
|
6119
|
//SERIAL_ECHOPGM(" delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
|
6117
|
|
-}
|
|
6120
|
+ }
|
6118
|
6121
|
|
6119
|
|
-void calculate_delta(float cartesian[3]){
|
6120
|
|
- //reverse kinematics.
|
6121
|
|
- // Perform reversed kinematics, and place results in delta[3]
|
6122
|
|
- // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
|
6123
|
|
-
|
6124
|
|
- float SCARA_pos[2];
|
6125
|
|
- static float SCARA_C2, SCARA_S2, SCARA_K1, SCARA_K2, SCARA_theta, SCARA_psi;
|
6126
|
|
-
|
6127
|
|
- SCARA_pos[X_AXIS] = cartesian[X_AXIS] * axis_scaling[X_AXIS] - SCARA_offset_x; //Translate SCARA to standard X Y
|
6128
|
|
- SCARA_pos[Y_AXIS] = cartesian[Y_AXIS] * axis_scaling[Y_AXIS] - SCARA_offset_y; // With scaling factor.
|
6129
|
|
-
|
6130
|
|
- #if (Linkage_1 == Linkage_2)
|
6131
|
|
- SCARA_C2 = ( ( sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS]) ) / (2 * (float)L1_2) ) - 1;
|
6132
|
|
- #else
|
6133
|
|
- SCARA_C2 = ( sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS]) - (float)L1_2 - (float)L2_2 ) / 45000;
|
6134
|
|
- #endif
|
6135
|
|
-
|
6136
|
|
- SCARA_S2 = sqrt( 1 - sq(SCARA_C2) );
|
6137
|
|
-
|
6138
|
|
- SCARA_K1 = Linkage_1 + Linkage_2 * SCARA_C2;
|
6139
|
|
- SCARA_K2 = Linkage_2 * SCARA_S2;
|
6140
|
|
-
|
6141
|
|
- SCARA_theta = ( atan2(SCARA_pos[X_AXIS],SCARA_pos[Y_AXIS])-atan2(SCARA_K1, SCARA_K2) ) * -1;
|
6142
|
|
- SCARA_psi = atan2(SCARA_S2,SCARA_C2);
|
6143
|
|
-
|
6144
|
|
- delta[X_AXIS] = SCARA_theta * SCARA_RAD2DEG; // Multiply by 180/Pi - theta is support arm angle
|
6145
|
|
- delta[Y_AXIS] = (SCARA_theta + SCARA_psi) * SCARA_RAD2DEG; // - equal to sub arm angle (inverted motor)
|
6146
|
|
- delta[Z_AXIS] = cartesian[Z_AXIS];
|
6147
|
|
-
|
6148
|
|
- /*
|
6149
|
|
- SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]);
|
6150
|
|
- SERIAL_ECHOPGM(" y="); SERIAL_ECHO(cartesian[Y_AXIS]);
|
6151
|
|
- SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(cartesian[Z_AXIS]);
|
6152
|
|
-
|
6153
|
|
- SERIAL_ECHOPGM("scara x="); SERIAL_ECHO(SCARA_pos[X_AXIS]);
|
6154
|
|
- SERIAL_ECHOPGM(" y="); SERIAL_ECHOLN(SCARA_pos[Y_AXIS]);
|
6155
|
|
-
|
6156
|
|
- SERIAL_ECHOPGM("delta x="); SERIAL_ECHO(delta[X_AXIS]);
|
6157
|
|
- SERIAL_ECHOPGM(" y="); SERIAL_ECHO(delta[Y_AXIS]);
|
6158
|
|
- SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(delta[Z_AXIS]);
|
6159
|
|
-
|
6160
|
|
- SERIAL_ECHOPGM("C2="); SERIAL_ECHO(SCARA_C2);
|
6161
|
|
- SERIAL_ECHOPGM(" S2="); SERIAL_ECHO(SCARA_S2);
|
6162
|
|
- SERIAL_ECHOPGM(" Theta="); SERIAL_ECHO(SCARA_theta);
|
6163
|
|
- SERIAL_ECHOPGM(" Psi="); SERIAL_ECHOLN(SCARA_psi);
|
6164
|
|
- SERIAL_ECHOLN(" ");*/
|
6165
|
|
-}
|
|
6122
|
+ void calculate_delta(float cartesian[3]){
|
|
6123
|
+ //reverse kinematics.
|
|
6124
|
+ // Perform reversed kinematics, and place results in delta[3]
|
|
6125
|
+ // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
|
|
6126
|
+
|
|
6127
|
+ float SCARA_pos[2];
|
|
6128
|
+ static float SCARA_C2, SCARA_S2, SCARA_K1, SCARA_K2, SCARA_theta, SCARA_psi;
|
|
6129
|
+
|
|
6130
|
+ SCARA_pos[X_AXIS] = cartesian[X_AXIS] * axis_scaling[X_AXIS] - SCARA_offset_x; //Translate SCARA to standard X Y
|
|
6131
|
+ SCARA_pos[Y_AXIS] = cartesian[Y_AXIS] * axis_scaling[Y_AXIS] - SCARA_offset_y; // With scaling factor.
|
|
6132
|
+
|
|
6133
|
+ #if (Linkage_1 == Linkage_2)
|
|
6134
|
+ SCARA_C2 = ( ( sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS]) ) / (2 * (float)L1_2) ) - 1;
|
|
6135
|
+ #else
|
|
6136
|
+ SCARA_C2 = ( sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS]) - (float)L1_2 - (float)L2_2 ) / 45000;
|
|
6137
|
+ #endif
|
|
6138
|
+
|
|
6139
|
+ SCARA_S2 = sqrt( 1 - sq(SCARA_C2) );
|
|
6140
|
+
|
|
6141
|
+ SCARA_K1 = Linkage_1 + Linkage_2 * SCARA_C2;
|
|
6142
|
+ SCARA_K2 = Linkage_2 * SCARA_S2;
|
|
6143
|
+
|
|
6144
|
+ SCARA_theta = ( atan2(SCARA_pos[X_AXIS],SCARA_pos[Y_AXIS])-atan2(SCARA_K1, SCARA_K2) ) * -1;
|
|
6145
|
+ SCARA_psi = atan2(SCARA_S2,SCARA_C2);
|
|
6146
|
+
|
|
6147
|
+ delta[X_AXIS] = SCARA_theta * SCARA_RAD2DEG; // Multiply by 180/Pi - theta is support arm angle
|
|
6148
|
+ delta[Y_AXIS] = (SCARA_theta + SCARA_psi) * SCARA_RAD2DEG; // - equal to sub arm angle (inverted motor)
|
|
6149
|
+ delta[Z_AXIS] = cartesian[Z_AXIS];
|
|
6150
|
+
|
|
6151
|
+ /*
|
|
6152
|
+ SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]);
|
|
6153
|
+ SERIAL_ECHOPGM(" y="); SERIAL_ECHO(cartesian[Y_AXIS]);
|
|
6154
|
+ SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(cartesian[Z_AXIS]);
|
|
6155
|
+
|
|
6156
|
+ SERIAL_ECHOPGM("scara x="); SERIAL_ECHO(SCARA_pos[X_AXIS]);
|
|
6157
|
+ SERIAL_ECHOPGM(" y="); SERIAL_ECHOLN(SCARA_pos[Y_AXIS]);
|
|
6158
|
+
|
|
6159
|
+ SERIAL_ECHOPGM("delta x="); SERIAL_ECHO(delta[X_AXIS]);
|
|
6160
|
+ SERIAL_ECHOPGM(" y="); SERIAL_ECHO(delta[Y_AXIS]);
|
|
6161
|
+ SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(delta[Z_AXIS]);
|
|
6162
|
+
|
|
6163
|
+ SERIAL_ECHOPGM("C2="); SERIAL_ECHO(SCARA_C2);
|
|
6164
|
+ SERIAL_ECHOPGM(" S2="); SERIAL_ECHO(SCARA_S2);
|
|
6165
|
+ SERIAL_ECHOPGM(" Theta="); SERIAL_ECHO(SCARA_theta);
|
|
6166
|
+ SERIAL_ECHOPGM(" Psi="); SERIAL_ECHOLN(SCARA_psi);
|
|
6167
|
+ SERIAL_EOL;
|
|
6168
|
+ */
|
|
6169
|
+ }
|
6166
|
6170
|
|
6167
|
|
-#endif
|
|
6171
|
+#endif // SCARA
|
6168
|
6172
|
|
6169
|
6173
|
#ifdef TEMP_STAT_LEDS
|
6170
|
6174
|
|
|
@@ -6395,88 +6399,89 @@ void kill()
|
6395
|
6399
|
st_synchronize();
|
6396
|
6400
|
}
|
6397
|
6401
|
}
|
6398
|
|
-#endif
|
6399
|
6402
|
|
6400
|
|
-void Stop() {
|
6401
|
|
- disable_all_heaters();
|
6402
|
|
- if (IsRunning()) {
|
6403
|
|
- Running = false;
|
6404
|
|
- Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
6405
|
|
- SERIAL_ERROR_START;
|
6406
|
|
- SERIAL_ERRORLNPGM(MSG_ERR_STOPPED);
|
6407
|
|
- LCD_MESSAGEPGM(MSG_STOPPED);
|
6408
|
|
- }
|
6409
|
|
-}
|
|
6403
|
+#endif // FILAMENT_RUNOUT_SENSOR
|
6410
|
6404
|
|
6411
|
6405
|
#ifdef FAST_PWM_FAN
|
6412
|
|
-void setPwmFrequency(uint8_t pin, int val)
|
6413
|
|
-{
|
6414
|
|
- val &= 0x07;
|
6415
|
|
- switch(digitalPinToTimer(pin))
|
6416
|
|
- {
|
6417
|
6406
|
|
6418
|
|
- #if defined(TCCR0A)
|
6419
|
|
- case TIMER0A:
|
6420
|
|
- case TIMER0B:
|
6421
|
|
-// TCCR0B &= ~(_BV(CS00) | _BV(CS01) | _BV(CS02));
|
6422
|
|
-// TCCR0B |= val;
|
6423
|
|
- break;
|
6424
|
|
- #endif
|
|
6407
|
+ void setPwmFrequency(uint8_t pin, int val) {
|
|
6408
|
+ val &= 0x07;
|
|
6409
|
+ switch (digitalPinToTimer(pin)) {
|
6425
|
6410
|
|
6426
|
|
- #if defined(TCCR1A)
|
6427
|
|
- case TIMER1A:
|
6428
|
|
- case TIMER1B:
|
6429
|
|
-// TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
|
6430
|
|
-// TCCR1B |= val;
|
6431
|
|
- break;
|
6432
|
|
- #endif
|
|
6411
|
+ #if defined(TCCR0A)
|
|
6412
|
+ case TIMER0A:
|
|
6413
|
+ case TIMER0B:
|
|
6414
|
+ // TCCR0B &= ~(_BV(CS00) | _BV(CS01) | _BV(CS02));
|
|
6415
|
+ // TCCR0B |= val;
|
|
6416
|
+ break;
|
|
6417
|
+ #endif
|
6433
|
6418
|
|
6434
|
|
- #if defined(TCCR2)
|
6435
|
|
- case TIMER2:
|
6436
|
|
- case TIMER2:
|
6437
|
|
- TCCR2 &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
|
6438
|
|
- TCCR2 |= val;
|
6439
|
|
- break;
|
6440
|
|
- #endif
|
|
6419
|
+ #if defined(TCCR1A)
|
|
6420
|
+ case TIMER1A:
|
|
6421
|
+ case TIMER1B:
|
|
6422
|
+ // TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
|
|
6423
|
+ // TCCR1B |= val;
|
|
6424
|
+ break;
|
|
6425
|
+ #endif
|
6441
|
6426
|
|
6442
|
|
- #if defined(TCCR2A)
|
6443
|
|
- case TIMER2A:
|
6444
|
|
- case TIMER2B:
|
6445
|
|
- TCCR2B &= ~(_BV(CS20) | _BV(CS21) | _BV(CS22));
|
6446
|
|
- TCCR2B |= val;
|
6447
|
|
- break;
|
6448
|
|
- #endif
|
|
6427
|
+ #if defined(TCCR2)
|
|
6428
|
+ case TIMER2:
|
|
6429
|
+ case TIMER2:
|
|
6430
|
+ TCCR2 &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
|
|
6431
|
+ TCCR2 |= val;
|
|
6432
|
+ break;
|
|
6433
|
+ #endif
|
6449
|
6434
|
|
6450
|
|
- #if defined(TCCR3A)
|
6451
|
|
- case TIMER3A:
|
6452
|
|
- case TIMER3B:
|
6453
|
|
- case TIMER3C:
|
6454
|
|
- TCCR3B &= ~(_BV(CS30) | _BV(CS31) | _BV(CS32));
|
6455
|
|
- TCCR3B |= val;
|
6456
|
|
- break;
|
6457
|
|
- #endif
|
|
6435
|
+ #if defined(TCCR2A)
|
|
6436
|
+ case TIMER2A:
|
|
6437
|
+ case TIMER2B:
|
|
6438
|
+ TCCR2B &= ~(_BV(CS20) | _BV(CS21) | _BV(CS22));
|
|
6439
|
+ TCCR2B |= val;
|
|
6440
|
+ break;
|
|
6441
|
+ #endif
|
6458
|
6442
|
|
6459
|
|
- #if defined(TCCR4A)
|
6460
|
|
- case TIMER4A:
|
6461
|
|
- case TIMER4B:
|
6462
|
|
- case TIMER4C:
|
6463
|
|
- TCCR4B &= ~(_BV(CS40) | _BV(CS41) | _BV(CS42));
|
6464
|
|
- TCCR4B |= val;
|
6465
|
|
- break;
|
6466
|
|
- #endif
|
6467
|
|
-
|
6468
|
|
- #if defined(TCCR5A)
|
6469
|
|
- case TIMER5A:
|
6470
|
|
- case TIMER5B:
|
6471
|
|
- case TIMER5C:
|
6472
|
|
- TCCR5B &= ~(_BV(CS50) | _BV(CS51) | _BV(CS52));
|
6473
|
|
- TCCR5B |= val;
|
6474
|
|
- break;
|
6475
|
|
- #endif
|
|
6443
|
+ #if defined(TCCR3A)
|
|
6444
|
+ case TIMER3A:
|
|
6445
|
+ case TIMER3B:
|
|
6446
|
+ case TIMER3C:
|
|
6447
|
+ TCCR3B &= ~(_BV(CS30) | _BV(CS31) | _BV(CS32));
|
|
6448
|
+ TCCR3B |= val;
|
|
6449
|
+ break;
|
|
6450
|
+ #endif
|
|
6451
|
+
|
|
6452
|
+ #if defined(TCCR4A)
|
|
6453
|
+ case TIMER4A:
|
|
6454
|
+ case TIMER4B:
|
|
6455
|
+ case TIMER4C:
|
|
6456
|
+ TCCR4B &= ~(_BV(CS40) | _BV(CS41) | _BV(CS42));
|
|
6457
|
+ TCCR4B |= val;
|
|
6458
|
+ break;
|
|
6459
|
+ #endif
|
|
6460
|
+
|
|
6461
|
+ #if defined(TCCR5A)
|
|
6462
|
+ case TIMER5A:
|
|
6463
|
+ case TIMER5B:
|
|
6464
|
+ case TIMER5C:
|
|
6465
|
+ TCCR5B &= ~(_BV(CS50) | _BV(CS51) | _BV(CS52));
|
|
6466
|
+ TCCR5B |= val;
|
|
6467
|
+ break;
|
|
6468
|
+ #endif
|
|
6469
|
+
|
|
6470
|
+ }
|
|
6471
|
+ }
|
|
6472
|
+
|
|
6473
|
+#endif // FAST_PWM_FAN
|
6476
|
6474
|
|
|
6475
|
+void Stop() {
|
|
6476
|
+ disable_all_heaters();
|
|
6477
|
+ if (IsRunning()) {
|
|
6478
|
+ Running = false;
|
|
6479
|
+ Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
|
6480
|
+ SERIAL_ERROR_START;
|
|
6481
|
+ SERIAL_ERRORLNPGM(MSG_ERR_STOPPED);
|
|
6482
|
+ LCD_MESSAGEPGM(MSG_STOPPED);
|
6477
|
6483
|
}
|
6478
|
6484
|
}
|
6479
|
|
-#endif //FAST_PWM_FAN
|
6480
|
6485
|
|
6481
|
6486
|
bool setTargetedHotend(int code){
|
6482
|
6487
|
target_extruder = active_extruder;
|