Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
MarlinKimbra
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
machinery
MarlinKimbra
Commits
439d4e2c
Commit
439d4e2c
authored
Jan 31, 2015
by
MagoKimbra
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite Marlin. Insert specific fuction for G-code
parent
a00a83f3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1096 additions
and
1053 deletions
+1096
-1053
Marlin_main.cpp
MarlinKimbra/Marlin_main.cpp
+1096
-1053
No files found.
MarlinKimbra/Marlin_main.cpp
View file @
439d4e2c
...
@@ -227,9 +227,9 @@ int extruder_multiply[EXTRUDERS] = { 100
...
@@ -227,9 +227,9 @@ int extruder_multiply[EXTRUDERS] = { 100
,
100
,
100
#if EXTRUDERS > 2
#if EXTRUDERS > 2
,
100
,
100
#if EXTRUDERS > 3
#if EXTRUDERS > 3
,
100
,
100
#endif
#endif
#endif
#endif
#endif
#endif
};
};
...
@@ -336,8 +336,8 @@ int fanSpeed = 0;
...
@@ -336,8 +336,8 @@ int fanSpeed = 0;
#if EXTRUDERS > 2
#if EXTRUDERS > 2
,
false
,
false
#if EXTRUDERS > 3
#if EXTRUDERS > 3
,
false
,
false
#endif
#endif
#endif
#endif
#endif
#endif
};
};
...
@@ -347,8 +347,8 @@ int fanSpeed = 0;
...
@@ -347,8 +347,8 @@ int fanSpeed = 0;
#if EXTRUDERS > 2
#if EXTRUDERS > 2
,
false
,
false
#if EXTRUDERS > 3
#if EXTRUDERS > 3
,
false
,
false
#endif
#endif
#endif
#endif
#endif
#endif
};
};
...
@@ -371,8 +371,8 @@ int fanSpeed = 0;
...
@@ -371,8 +371,8 @@ int fanSpeed = 0;
#endif
#endif
#endif //ULTIPANEL
#endif //ULTIPANEL
#ifdef SCARA
// Build size scaling
#ifdef SCARA
float
axis_scaling
[
3
]
=
{
1
,
1
,
1
};
// Build size scaling, default to 1
float
axis_scaling
[
3
]
=
{
1
,
1
,
1
};
// Build size scaling, default to 1
#endif //SCARA
#endif //SCARA
bool
cancel_heatup
=
false
;
bool
cancel_heatup
=
false
;
...
@@ -432,6 +432,7 @@ static bool fromsd[BUFSIZE];
...
@@ -432,6 +432,7 @@ static bool fromsd[BUFSIZE];
static
int
bufindr
=
0
;
static
int
bufindr
=
0
;
static
int
bufindw
=
0
;
static
int
bufindw
=
0
;
static
int
buflen
=
0
;
static
int
buflen
=
0
;
static
char
serial_char
;
static
char
serial_char
;
static
int
serial_count
=
0
;
static
int
serial_count
=
0
;
static
boolean
comment_mode
=
false
;
static
boolean
comment_mode
=
false
;
...
@@ -577,6 +578,16 @@ void setup_photpin()
...
@@ -577,6 +578,16 @@ void setup_photpin()
#endif
#endif
}
}
void
setup_laserbeampin
()
{
#ifdef LASERBEAM
SET_OUTPUT
(
LASER_PWR_PIN
);
WRITE
(
LASER_PWR_PIN
,
LOW
);
SET_OUTPUT
(
LASER_TTL_PIN
);
WRITE
(
LASER_TTL_PIN
,
LOW
);
#endif
}
void
setup_powerhold
()
void
setup_powerhold
()
{
{
#if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
#if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
...
@@ -585,11 +596,11 @@ void setup_powerhold()
...
@@ -585,11 +596,11 @@ void setup_powerhold()
#endif
#endif
#if defined(PS_ON_PIN) && PS_ON_PIN > -1
#if defined(PS_ON_PIN) && PS_ON_PIN > -1
SET_OUTPUT
(
PS_ON_PIN
);
SET_OUTPUT
(
PS_ON_PIN
);
#if defined(PS_DEFAULT_OFF)
#if defined(PS_DEFAULT_OFF)
WRITE
(
PS_ON_PIN
,
PS_ON_ASLEEP
);
WRITE
(
PS_ON_PIN
,
PS_ON_ASLEEP
);
#else
#else
WRITE
(
PS_ON_PIN
,
PS_ON_AWAKE
);
WRITE
(
PS_ON_PIN
,
PS_ON_AWAKE
);
#endif
#endif
#endif
#endif
}
}
...
@@ -636,8 +647,8 @@ void servo_init()
...
@@ -636,8 +647,8 @@ void servo_init()
}
}
void
setup
()
void
setup
()
{
{
setup_killpin
();
setup_killpin
();
setup_pausepin
();
setup_pausepin
();
...
@@ -686,17 +697,11 @@ void setup()
...
@@ -686,17 +697,11 @@ void setup()
watchdog_init
();
watchdog_init
();
st_init
();
// Initialize stepper, this enables interrupts!
st_init
();
// Initialize stepper, this enables interrupts!
setup_photpin
();
setup_photpin
();
#ifdef LASERBEAM // Initialize Laser beam
setup_laserbeampin
();
// Initialize Laserbeam
SET_OUTPUT
(
LASER_PWR_PIN
);
WRITE
(
LASER_PWR_PIN
,
LOW
);
SET_OUTPUT
(
LASER_TTL_PIN
);
WRITE
(
LASER_TTL_PIN
,
LOW
);
#endif
servo_init
();
servo_init
();
lcd_init
();
lcd_init
();
_delay_ms
(
1000
);
// wait 1sec to display the splash screen
_delay_ms
(
1000
);
// wait 1sec to display the splash screen
#if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
#if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
SET_OUTPUT
(
CONTROLLERFAN_PIN
);
//Set pin used for driver cooling fan
SET_OUTPUT
(
CONTROLLERFAN_PIN
);
//Set pin used for driver cooling fan
...
@@ -716,38 +721,30 @@ void setup()
...
@@ -716,38 +721,30 @@ void setup()
}
}
void
loop
()
void
loop
()
{
{
if
(
buflen
<
(
BUFSIZE
-
1
))
if
(
buflen
<
(
BUFSIZE
-
1
))
get_command
();
get_command
();
#ifdef SDSUPPORT
#ifdef SDSUPPORT
card
.
checkautostart
(
false
);
card
.
checkautostart
(
false
);
#endif
#endif
if
(
buflen
)
if
(
buflen
)
{
{
#ifdef SDSUPPORT
#ifdef SDSUPPORT
if
(
card
.
saving
)
if
(
card
.
saving
)
{
{
if
(
strstr_P
(
cmdbuffer
[
bufindr
],
PSTR
(
"M29"
))
==
NULL
)
{
if
(
strstr_P
(
cmdbuffer
[
bufindr
],
PSTR
(
"M29"
))
==
NULL
)
{
card
.
write_command
(
cmdbuffer
[
bufindr
]);
card
.
write_command
(
cmdbuffer
[
bufindr
]);
if
(
card
.
logging
)
if
(
card
.
logging
)
{
{
process_commands
();
process_commands
();
}
}
else
else
{
{
SERIAL_PROTOCOLLNPGM
(
MSG_OK
);
SERIAL_PROTOCOLLNPGM
(
MSG_OK
);
}
}
}
}
else
else
{
{
card
.
closefile
();
card
.
closefile
();
SERIAL_PROTOCOLLNPGM
(
MSG_FILE_SAVED
);
SERIAL_PROTOCOLLNPGM
(
MSG_FILE_SAVED
);
}
}
}
}
else
else
{
{
process_commands
();
process_commands
();
}
}
#else
#else
...
@@ -763,8 +760,8 @@ void loop()
...
@@ -763,8 +760,8 @@ void loop()
lcd_update
();
lcd_update
();
}
}
void
get_command
()
void
get_command
()
{
{
while
(
MYSERIAL
.
available
()
>
0
&&
buflen
<
BUFSIZE
)
{
while
(
MYSERIAL
.
available
()
>
0
&&
buflen
<
BUFSIZE
)
{
serial_char
=
MYSERIAL
.
read
();
serial_char
=
MYSERIAL
.
read
();
if
(
serial_char
==
'\n'
||
if
(
serial_char
==
'\n'
||
...
@@ -777,11 +774,10 @@ void get_command()
...
@@ -777,11 +774,10 @@ void get_command()
return
;
return
;
}
}
cmdbuffer
[
bufindw
][
serial_count
]
=
0
;
//terminate string
cmdbuffer
[
bufindw
][
serial_count
]
=
0
;
//terminate string
if
(
!
comment_mode
){
if
(
!
comment_mode
)
{
comment_mode
=
false
;
//for new command
comment_mode
=
false
;
//for new command
fromsd
[
bufindw
]
=
false
;
fromsd
[
bufindw
]
=
false
;
if
(
strchr
(
cmdbuffer
[
bufindw
],
'N'
)
!=
NULL
)
if
(
strchr
(
cmdbuffer
[
bufindw
],
'N'
)
!=
NULL
)
{
{
strchr_pointer
=
strchr
(
cmdbuffer
[
bufindw
],
'N'
);
strchr_pointer
=
strchr
(
cmdbuffer
[
bufindw
],
'N'
);
gcode_N
=
(
strtol
(
&
cmdbuffer
[
bufindw
][
strchr_pointer
-
cmdbuffer
[
bufindw
]
+
1
],
NULL
,
10
));
gcode_N
=
(
strtol
(
&
cmdbuffer
[
bufindw
][
strchr_pointer
-
cmdbuffer
[
bufindw
]
+
1
],
NULL
,
10
));
if
(
gcode_N
!=
gcode_LastN
+
1
&&
(
strstr_P
(
cmdbuffer
[
bufindw
],
PSTR
(
"M110"
))
==
NULL
)
)
{
if
(
gcode_N
!=
gcode_LastN
+
1
&&
(
strstr_P
(
cmdbuffer
[
bufindw
],
PSTR
(
"M110"
))
==
NULL
)
)
{
...
@@ -794,8 +790,7 @@ void get_command()
...
@@ -794,8 +790,7 @@ void get_command()
return
;
return
;
}
}
if
(
strchr
(
cmdbuffer
[
bufindw
],
'*'
)
!=
NULL
)
if
(
strchr
(
cmdbuffer
[
bufindw
],
'*'
)
!=
NULL
)
{
{
byte
checksum
=
0
;
byte
checksum
=
0
;
byte
count
=
0
;
byte
count
=
0
;
while
(
cmdbuffer
[
bufindw
][
count
]
!=
'*'
)
checksum
=
checksum
^
cmdbuffer
[
bufindw
][
count
++
];
while
(
cmdbuffer
[
bufindw
][
count
]
!=
'*'
)
checksum
=
checksum
^
cmdbuffer
[
bufindw
][
count
++
];
...
@@ -826,8 +821,7 @@ void get_command()
...
@@ -826,8 +821,7 @@ void get_command()
}
}
else
// if we don't receive 'N' but still see '*'
else
// if we don't receive 'N' but still see '*'
{
{
if
((
strchr
(
cmdbuffer
[
bufindw
],
'*'
)
!=
NULL
))
if
((
strchr
(
cmdbuffer
[
bufindw
],
'*'
)
!=
NULL
))
{
{
SERIAL_ERROR_START
;
SERIAL_ERROR_START
;
SERIAL_ERRORPGM
(
MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM
);
SERIAL_ERRORPGM
(
MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM
);
SERIAL_ERRORLN
(
gcode_LastN
);
SERIAL_ERRORLN
(
gcode_LastN
);
...
@@ -835,7 +829,7 @@ void get_command()
...
@@ -835,7 +829,7 @@ void get_command()
return
;
return
;
}
}
}
}
if
((
strchr
(
cmdbuffer
[
bufindw
],
'G'
)
!=
NULL
)){
if
((
strchr
(
cmdbuffer
[
bufindw
],
'G'
)
!=
NULL
))
{
strchr_pointer
=
strchr
(
cmdbuffer
[
bufindw
],
'G'
);
strchr_pointer
=
strchr
(
cmdbuffer
[
bufindw
],
'G'
);
switch
((
int
)((
strtod
(
&
cmdbuffer
[
bufindw
][
strchr_pointer
-
cmdbuffer
[
bufindw
]
+
1
],
NULL
)))){
switch
((
int
)((
strtod
(
&
cmdbuffer
[
bufindw
][
strchr_pointer
-
cmdbuffer
[
bufindw
]
+
1
],
NULL
)))){
case
0
:
case
0
:
...
@@ -850,12 +844,10 @@ void get_command()
...
@@ -850,12 +844,10 @@ void get_command()
default
:
default
:
break
;
break
;
}
}
}
}
//If command was e-stop process now
//If command was e-stop process now
if
(
strcmp
(
cmdbuffer
[
bufindw
],
"M112"
)
==
0
)
if
(
strcmp
(
cmdbuffer
[
bufindw
],
"M112"
)
==
0
)
kill
();
kill
();
bufindw
=
(
bufindw
+
1
)
%
BUFSIZE
;
bufindw
=
(
bufindw
+
1
)
%
BUFSIZE
;
buflen
+=
1
;
buflen
+=
1
;
...
@@ -958,7 +950,7 @@ DEFINE_PGM_READ_ANY(float, float);
...
@@ -958,7 +950,7 @@ DEFINE_PGM_READ_ANY(float, float);
DEFINE_PGM_READ_ANY
(
signed
char
,
byte
);
DEFINE_PGM_READ_ANY
(
signed
char
,
byte
);
#define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \
#define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \
static const PROGMEM type array##_P[3] =
\
static const PROGMEM type array##_P[3] = \
{ X_##CONFIG, Y_##CONFIG, Z_##CONFIG }; \
{ X_##CONFIG, Y_##CONFIG, Z_##CONFIG }; \
static inline type array(int axis) \
static inline type array(int axis) \
{ return pgm_read_any(&array##_P[axis]); }
{ return pgm_read_any(&array##_P[axis]); }
...
@@ -1248,18 +1240,20 @@ static void retract_z_probe() {
...
@@ -1248,18 +1240,20 @@ static void retract_z_probe() {
}
}
/// Probe bed height at position (x,y), returns the measured z value
/// Probe bed height at position (x,y), returns the measured z value
static
float
probe_pt
(
float
x
,
float
y
,
float
z_before
)
{
static
float
probe_pt
(
float
x
,
float
y
,
float
z_before
,
int
retract_action
=
0
)
{
// move to right place
// move to right place
do_blocking_move_to
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
z_before
);
do_blocking_move_to
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
z_before
);
do_blocking_move_to
(
x
-
X_PROBE_OFFSET_FROM_EXTRUDER
,
y
-
Y_PROBE_OFFSET_FROM_EXTRUDER
,
current_position
[
Z_AXIS
]);
do_blocking_move_to
(
x
-
X_PROBE_OFFSET_FROM_EXTRUDER
,
y
-
Y_PROBE_OFFSET_FROM_EXTRUDER
,
current_position
[
Z_AXIS
]);
#ifndef Z_PROBE_SLED
#ifndef Z_PROBE_SLED
engage_z_probe
();
// Engage Z Servo endstop if available
if
((
retract_action
==
0
)
||
(
retract_action
==
1
))
engage_z_probe
();
// Engage Z Servo endstop if available
#endif // Z_PROBE_SLED
#endif // Z_PROBE_SLED
run_z_probe
();
run_z_probe
();
float
measured_z
=
current_position
[
Z_AXIS
];
float
measured_z
=
current_position
[
Z_AXIS
];
#ifndef Z_PROBE_SLED
#ifndef Z_PROBE_SLED
retract_z_probe
();
if
((
retract_action
==
0
)
||
(
retract_action
==
3
))
retract_z_probe
();
#endif // Z_PROBE_SLED
#endif // Z_PROBE_SLED
SERIAL_PROTOCOLPGM
(
MSG_BED
);
SERIAL_PROTOCOLPGM
(
MSG_BED
);
...
@@ -1800,8 +1794,7 @@ void refresh_cmd_timeout(void)
...
@@ -1800,8 +1794,7 @@ void refresh_cmd_timeout(void)
}
}
#ifdef FWRETRACT
#ifdef FWRETRACT
void
retract
(
bool
retracting
,
bool
swapretract
=
false
)
void
retract
(
bool
retracting
,
bool
swapretract
=
false
)
{
{
if
(
retracting
&&
!
retracted
[
active_extruder
])
{
if
(
retracting
&&
!
retracted
[
active_extruder
])
{
destination
[
X_AXIS
]
=
current_position
[
X_AXIS
];
destination
[
X_AXIS
]
=
current_position
[
X_AXIS
];
destination
[
Y_AXIS
]
=
current_position
[
Y_AXIS
];
destination
[
Y_AXIS
]
=
current_position
[
Y_AXIS
];
...
@@ -1817,28 +1810,32 @@ void retract(bool retracting, bool swapretract = false)
...
@@ -1817,28 +1810,32 @@ void retract(bool retracting, bool swapretract = false)
feedrate
=
retract_feedrate
*
60
;
feedrate
=
retract_feedrate
*
60
;
retracted
[
active_extruder
]
=
true
;
retracted
[
active_extruder
]
=
true
;
prepare_move
();
prepare_move
();
current_position
[
Z_AXIS
]
-=
retract_zlift
;
if
(
retract_zlift
>
0.01
)
{
current_position
[
Z_AXIS
]
-=
retract_zlift
;
#ifdef DELTA
#ifdef DELTA
calculate_delta
(
current_position
);
// change cartesian kinematic to delta kinematic;
calculate_delta
(
current_position
);
// change cartesian kinematic to delta kinematic;
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#else
#else
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#endif
#endif
prepare_move
();
prepare_move
();
}
feedrate
=
oldFeedrate
;
feedrate
=
oldFeedrate
;
}
else
if
(
!
retracting
&&
retracted
[
active_extruder
])
{
}
else
if
(
!
retracting
&&
retracted
[
active_extruder
])
{
destination
[
X_AXIS
]
=
current_position
[
X_AXIS
];
destination
[
X_AXIS
]
=
current_position
[
X_AXIS
];
destination
[
Y_AXIS
]
=
current_position
[
Y_AXIS
];
destination
[
Y_AXIS
]
=
current_position
[
Y_AXIS
];
destination
[
Z_AXIS
]
=
current_position
[
Z_AXIS
];
destination
[
Z_AXIS
]
=
current_position
[
Z_AXIS
];
destination
[
E_AXIS
]
=
current_position
[
E_AXIS
];
destination
[
E_AXIS
]
=
current_position
[
E_AXIS
];
current_position
[
Z_AXIS
]
+=
retract_zlift
;
if
(
retract_zlift
>
0.01
)
{
current_position
[
Z_AXIS
]
+=
retract_zlift
;
#ifdef DELTA
#ifdef DELTA
calculate_delta
(
current_position
);
// change cartesian kinematic to delta kinematic;
calculate_delta
(
current_position
);
// change cartesian kinematic to delta kinematic;
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#else
#else
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#endif
#endif
//prepare_move();
//prepare_move();
}
if
(
swapretract
)
{
if
(
swapretract
)
{
current_position
[
E_AXIS
]
-=
(
retract_length_swap
+
retract_recover_length_swap
)
/
volumetric_multiplier
[
active_extruder
];
current_position
[
E_AXIS
]
-=
(
retract_length_swap
+
retract_recover_length_swap
)
/
volumetric_multiplier
[
active_extruder
];
}
else
{
}
else
{
...
@@ -1891,170 +1888,166 @@ static void dock_sled(bool dock, int offset=0)
...
@@ -1891,170 +1888,166 @@ static void dock_sled(bool dock, int offset=0)
}
}
#endif //Z_PROBE_SLED
#endif //Z_PROBE_SLED
void
process_commands
()
{
unsigned
long
codenum
;
//throw away variable
char
*
starpos
=
NULL
;
#ifdef ENABLE_AUTO_BED_LEVELING
float
x_tmp
,
y_tmp
,
z_tmp
,
real_z
;
#endif
if
(
code_seen
(
'G'
))
{
switch
((
int
)
code_value
())
{
case
0
:
// G0 -> G1
case
1
:
// G1
if
(
Stopped
==
false
)
{
get_coordinates
();
// For X Y Z E F
#ifdef FWRETRACT
if
(
autoretract_enabled
)
if
(
!
(
code_seen
(
'X'
)
||
code_seen
(
'Y'
)
||
code_seen
(
'Z'
))
&&
code_seen
(
'E'
))
{
float
echange
=
destination
[
E_AXIS
]
-
current_position
[
E_AXIS
];
if
((
echange
<-
MIN_RETRACT
&&
!
retracted
)
||
(
echange
>
MIN_RETRACT
&&
retracted
))
{
//move appears to be an attempt to retract or recover
current_position
[
E_AXIS
]
=
destination
[
E_AXIS
];
//hide the slicer-generated retract/recover from calculations
plan_set_e_position
(
current_position
[
E_AXIS
]);
//AND from the planner
retract
(
!
retracted
);
return
;
}
}
#endif //FWRETRACT
prepare_move
();
//ClearToSend();
}
break
;
#ifndef SCARA //disable arc support
/******************************************************************************
case
2
:
// G2 - CW ARC
* G-Code Functions
if
(
Stopped
==
false
)
{
*******************************************************************************/
get_arc_coordinates
();
prepare_arc_move
(
true
);
/**
}
* G0 / G1: Coordinated movement of X Y Z E axes
break
;
*/
case
3
:
// G3 - CCW ARC
void
gcode_G0_G1
()
{
if
(
Stopped
==
false
)
{
if
(
!
Stopped
)
{
get_arc_coordinates
();
get_coordinates
();
// For X Y Z E F
prepare_arc_move
(
false
);
#ifdef FWRETRACT
if
(
autoretract_enabled
)
if
(
!
(
code_seen
(
'X'
)
||
code_seen
(
'Y'
)
||
code_seen
(
'Z'
))
&&
code_seen
(
'E'
))
{
float
echange
=
destination
[
E_AXIS
]
-
current_position
[
E_AXIS
];
// Is this move an attempt to retract or recover?
if
((
echange
<
-
MIN_RETRACT
&&
!
retracted
)
||
(
echange
>
MIN_RETRACT
&&
retracted
))
{
current_position
[
E_AXIS
]
=
destination
[
E_AXIS
];
// hide the slicer-generated retract/recover from calculations
plan_set_e_position
(
current_position
[
E_AXIS
]);
// AND from the planner
retract
(
!
retracted
);
return
;
}
}
}
break
;
#endif //FWRETRACT
#endif // no SCARA
prepare_move
();
//ClearToSend();
}
}
/**
* G2: Clockwise Arc
* G3: Counterclockwise Arc
*/
void
gcode_G2_G3
(
bool
clockwise
)
{
if
(
!
Stopped
)
{
get_arc_coordinates
();
prepare_arc_move
(
clockwise
);
}
}
case
4
:
// G4 dwell
/**
LCD_MESSAGEPGM
(
MSG_DWELL
);
* G4: Dwell S<seconds> or P<milliseconds>
codenum
=
0
;
*/
if
(
code_seen
(
'P'
))
codenum
=
code_value
();
// milliseconds to wait
void
gcode_G4
()
{
if
(
code_seen
(
'S'
))
codenum
=
code_value
()
*
1000
;
// seconds to wait
unsigned
long
codenum
;
st_synchronize
();
LCD_MESSAGEPGM
(
MSG_DWELL
);
codenum
+=
millis
();
// keep track of when we started waiting
refresh_cmd_timeout
();
if
(
code_seen
(
'P'
))
codenum
=
code_value
();
// milliseconds to wait
while
(
millis
()
<
codenum
)
{
if
(
code_seen
(
'S'
))
codenum
=
code_value
()
*
1000
;
// seconds to wait
manage_heater
();
manage_inactivity
();
st_synchronize
();
lcd_update
();
codenum
+=
millis
();
// keep track of when we started waiting
}
previous_millis_cmd
=
millis
();
break
;
while
(
millis
()
<
codenum
)
{
manage_heater
();
manage_inactivity
();
lcd_update
();
}
}
#ifdef FWRETRACT
#ifdef FWRETRACT
case
10
:
// G10 retract
/**
#if EXTRUDERS > 1
* G10 - Retract filament according to settings of M207
retracted_swap
[
active_extruder
]
=
(
code_seen
(
'S'
)
&&
code_value_long
()
==
1
);
// checks for swap retract argument
* G11 - Recover filament according to settings of M208
retract
(
true
,
retracted_swap
[
active_extruder
]);
*/
#else
void
gcode_G10_G11
(
bool
doRetract
=
false
)
{
retract
(
true
);
#if EXTRUDERS > 1
#endif
if
(
doRetract
)
{
break
;
retracted_swap
[
active_extruder
]
=
(
code_seen
(
'S'
)
&&
code_value_long
()
==
1
);
// checks for swap retract argument
case
11
:
// G11 retract_recover
}
#if EXTRUDERS > 1
#endif
retract
(
false
,
retracted_swap
[
active_extruder
]);
retract
(
doRetract
#else
#if EXTRUDERS > 1
retract
(
false
);
,
retracted_swap
[
active_extruder
]
#endif
#endif
break
;
);
}
#endif //FWRETRACT
#endif //FWRETRACT
case
28
:
//G28 Home all Axis one at a time
/**
#ifdef ENABLE_AUTO_BED_LEVELING
* G28: Home all axes, one at a time
plan_bed_level_matrix
.
set_to_identity
();
//Reset the plane ("erase" all leveling data)
*/
#endif //ENABLE_AUTO_BED_LEVELING
void
gcode_G28
()
{
#ifdef ENABLE_AUTO_BED_LEVELING
plan_bed_level_matrix
.
set_to_identity
();
//Reset the plane ("erase" all leveling data)
#endif //ENABLE_AUTO_BED_LEVELING
saved_feedrate
=
feedrate
;
saved_feedrate
=
feedrate
;
saved_feedmultiply
=
feedmultiply
;
saved_feedmultiply
=
feedmultiply
;
feedmultiply
=
100
;
feedmultiply
=
100
;
refresh_cmd_timeout
();
refresh_cmd_timeout
();
enable_endstops
(
true
);
enable_endstops
(
true
);
for
(
int8_t
i
=
0
;
i
<
NUM_AXIS
;
i
++
)
{
for
(
int8_t
i
=
0
;
i
<
NUM_AXIS
;
i
++
)
destination
[
i
]
=
current_position
[
i
];
destination
[
i
]
=
current_position
[
i
];
}
feedrate
=
0.0
;
home_all_axis
=
!
((
code_seen
(
axis_codes
[
X_AXIS
]))
||
(
code_seen
(
axis_codes
[
Y_AXIS
]))
||
(
code_seen
(
axis_codes
[
Z_AXIS
]))
||
(
code_seen
(
axis_codes
[
E_AXIS
])))
;
feedrate
=
0.0
;
#ifdef NPR2
home_all_axis
=
!
((
code_seen
(
axis_codes
[
X_AXIS
]))
||
(
code_seen
(
axis_codes
[
Y_AXIS
]))
||
(
code_seen
(
axis_codes
[
Z_AXIS
]))
||
(
code_seen
(
axis_codes
[
E_AXIS
])));
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
E_AXIS
])))
{
active_driver
=
active_extruder
=
1
;
plan_buffer_line
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
-
200
,
COLOR_HOMERATE
,
active_extruder
,
active_driver
);
st_synchronize
();
old_color
=
99
;
active_driver
=
active_extruder
=
0
;
}
#endif
#ifdef DELTA
#ifdef NPR2
// A delta can only safely home all axis at the same time
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
E_AXIS
])))
{
// all axis have to home at the same time
active_driver
=
active_extruder
=
1
;
// Move all carriages up together until the first endstop is hit.
plan_buffer_line
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
-
200
,
COLOR_HOMERATE
,
active_extruder
,
active_driver
);
st_synchronize
();
old_color
=
99
;
active_driver
=
active_extruder
=
0
;
}
#endif
current_position
[
X_AXIS
]
=
0
;
#ifdef DELTA
current_position
[
Y_AXIS
]
=
0
;
// A delta can only safely home all axis at the same time
current_position
[
Z_AXIS
]
=
0
;
// all axis have to home at the same time
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
// Move all carriages up together until the first endstop is hit.
destination
[
X_AXIS
]
=
3
*
max_length
[
Z_AXIS
];
for
(
int
i
=
X_AXIS
;
i
<=
Z_AXIS
;
i
++
)
current_position
[
i
]
=
0
;
destination
[
Y_AXIS
]
=
3
*
max_length
[
Z_AXIS
];
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
destination
[
Z_AXIS
]
=
3
*
max_length
[
Z_AXIS
];
feedrate
=
1.732
*
homing_feedrate
[
X_AXIS
];
for
(
int
i
=
X_AXIS
;
i
<=
Z_AXIS
;
i
++
)
destination
[
i
]
=
3
*
max_length
[
Z_AXIS
];
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
/
60
,
active_extruder
,
active_driver
);
feedrate
=
1.732
*
homing_feedrate
[
X_AXIS
];
st_synchronize
();
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
/
60
,
active_extruder
,
active_driver
);
endstops_hit_on_purpose
();
st_synchronize
();
endstops_hit_on_purpose
();
current_position
[
X_AXIS
]
=
destination
[
X_AXIS
];
// Destination reached
current_position
[
Y_AXIS
]
=
destination
[
Y_AXIS
];
for
(
int
i
=
X_AXIS
;
i
<=
Z_AXIS
;
i
++
)
current_position
[
i
]
=
destination
[
i
];
current_position
[
Z_AXIS
]
=
destination
[
Z_AXIS
];
// take care of back off and rehome now we are all at the top
// take care of back off and rehome now we are all at the top
HOMEAXIS
(
X
);
HOMEAXIS
(
X
);
HOMEAXIS
(
Y
);
HOMEAXIS
(
Y
);
HOMEAXIS
(
Z
);
HOMEAXIS
(
Z
);
calculate_delta
(
current_position
);
calculate_delta
(
current_position
);
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#else // NOT DELTA
#else // NOT DELTA
#if Z_HOME_DIR > 0
// If homing away from BED do Z first
#if Z_HOME_DIR > 0
// If homing away from BED do Z first
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Z_AXIS
])))
{
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Z_AXIS
])))
{
HOMEAXIS
(
Z
);
HOMEAXIS
(
Z
);
}
}
#endif
#endif
#ifdef QUICK_HOME
#ifdef QUICK_HOME
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
X_AXIS
])
&&
code_seen
(
axis_codes
[
Y_AXIS
])))
{
//first diagonal move
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
X_AXIS
])
&&
code_seen
(
axis_codes
[
Y_AXIS
])))
{
//first diagonal move
current_position
[
X_AXIS
]
=
0
;
current_position
[
X_AXIS
]
=
current_position
[
Y_AXIS
]
=
0
;
current_position
[
Y_AXIS
]
=
0
;
#ifndef DUAL_X_CARRIAGE
#ifndef DUAL_X_CARRIAGE
int
x_axis_home_dir
=
home_dir
(
X_AXIS
);
int
x_axis_home_dir
=
home_dir
(
X_AXIS
);
#else
#else
int
x_axis_home_dir
=
x_home_dir
(
active_extruder
);
int
x_axis_home_dir
=
x_home_dir
(
active_extruder
);
extruder_duplication_enabled
=
false
;
extruder_duplication_enabled
=
false
;
#endif
#endif
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
destination
[
X_AXIS
]
=
1.5
*
max_length
(
X_AXIS
)
*
x_axis_home_dir
;
destination
[
X_AXIS
]
=
1.5
*
max_length
(
X_AXIS
)
*
x_axis_home_dir
;
destination
[
Y_AXIS
]
=
1.5
*
max_length
(
Y_AXIS
)
*
home_dir
(
Y_AXIS
);
destination
[
Y_AXIS
]
=
1.5
*
max_length
(
Y_AXIS
)
*
home_dir
(
Y_AXIS
);
feedrate
=
homing_feedrate
[
X_AXIS
];
feedrate
=
homing_feedrate
[
X_AXIS
];
if
(
homing_feedrate
[
Y_AXIS
]
<
feedrate
)
if
(
homing_feedrate
[
Y_AXIS
]
<
feedrate
)
feedrate
=
homing_feedrate
[
Y_AXIS
];
feedrate
=
homing_feedrate
[
Y_AXIS
];
if
(
max_length
(
X_AXIS
)
>
max_length
(
Y_AXIS
))
{
if
(
max_length
(
X_AXIS
)
>
max_length
(
Y_AXIS
))
{
feedrate
*=
sqrt
(
pow
(
max_length
(
Y_AXIS
)
/
max_length
(
X_AXIS
),
2
)
+
1
);
feedrate
*=
sqrt
(
pow
(
max_length
(
Y_AXIS
)
/
max_length
(
X_AXIS
),
2
)
+
1
);
}
}
...
@@ -2076,14 +2069,14 @@ void process_commands()
...
@@ -2076,14 +2069,14 @@ void process_commands()
current_position
[
X_AXIS
]
=
destination
[
X_AXIS
];
current_position
[
X_AXIS
]
=
destination
[
X_AXIS
];
current_position
[
Y_AXIS
]
=
destination
[
Y_AXIS
];
current_position
[
Y_AXIS
]
=
destination
[
Y_AXIS
];
#ifndef SCARA
#ifndef SCARA
current_position
[
Z_AXIS
]
=
destination
[
Z_AXIS
];
current_position
[
Z_AXIS
]
=
destination
[
Z_AXIS
];
#endif
#endif
}
}
#endif // QUICK_HOME
#endif // QUICK_HOME
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
X_AXIS
])))
{
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
X_AXIS
])))
{
#ifdef DUAL_X_CARRIAGE
#ifdef DUAL_X_CARRIAGE
int
tmp_extruder
=
active_extruder
;
int
tmp_extruder
=
active_extruder
;
extruder_duplication_enabled
=
false
;
extruder_duplication_enabled
=
false
;
active_extruder
=
!
active_extruder
;
active_extruder
=
!
active_extruder
;
...
@@ -2095,937 +2088,1009 @@ void process_commands()
...
@@ -2095,937 +2088,1009 @@ void process_commands()
memcpy
(
raised_parked_position
,
current_position
,
sizeof
(
raised_parked_position
));
memcpy
(
raised_parked_position
,
current_position
,
sizeof
(
raised_parked_position
));
delayed_move_time
=
0
;
delayed_move_time
=
0
;
active_extruder_parked
=
true
;
active_extruder_parked
=
true
;
#else
#else
HOMEAXIS
(
X
);
HOMEAXIS
(
X
);
#endif // DUAL_X_CARRIAGE
#endif // DUAL_X_CARRIAGE
}
}
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Y_AXIS
])))
{
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Y_AXIS
])))
HOMEAXIS
(
Y
);
HOMEAXIS
(
Y
);
}
if
(
code_seen
(
axis_codes
[
X_AXIS
]))
{
if
(
code_seen
(
axis_codes
[
X_AXIS
]))
{
if
(
code_value_long
()
!=
0
)
{
if
(
code_value_long
()
!=
0
)
{
#ifdef SCARA
#ifdef SCARA
current_position
[
X_AXIS
]
=
code_value
();
current_position
[
X_AXIS
]
=
code_value
();
#else
#else
current_position
[
X_AXIS
]
=
code_value
()
+
add_homing
[
X_AXIS
];
current_position
[
X_AXIS
]
=
code_value
()
+
add_homing
[
X_AXIS
];
#endif
#endif
}
}
}
}
if
(
code_seen
(
axis_codes
[
Y_AXIS
]))
{
if
(
code_seen
(
axis_codes
[
Y_AXIS
])
&&
code_value_long
()
!=
0
)
{
if
(
code_value_long
()
!=
0
)
{
#ifdef SCARA
#ifdef SCARA
current_position
[
Y_AXIS
]
=
code_value
();
current_position
[
Y_AXIS
]
=
code_value
();
#else
#else
current_position
[
Y_AXIS
]
=
code_value
()
+
add_homing
[
Y_AXIS
];
current_position
[
Y_AXIS
]
=
code_value
()
+
add_homing
[
Y_AXIS
];
#endif
#endif
}
}
}
#if Z_HOME_DIR < 0 // If homing towards BED do Z last
#if Z_HOME_DIR < 0 // If homing towards BED do Z last
#ifndef Z_SAFE_HOMING
#ifndef Z_SAFE_HOMING
if
(
code_seen
(
'M'
))
{
// Manual G28
if
(
code_seen
(
'M'
))
{
// Manual G28
#ifdef ULTIPANEL
#ifdef ULTIPANEL
if
(
home_all_axis
)
{
if
(
home_all_axis
)
{
boolean
zig
=
true
;
boolean
zig
=
true
;
int
xGridSpacing
=
(
RIGHT_PROBE_BED_POSITION
-
LEFT_PROBE_BED_POSITION
);
int
xGridSpacing
=
(
RIGHT_PROBE_BED_POSITION
-
LEFT_PROBE_BED_POSITION
);
int
yGridSpacing
=
(
BACK_PROBE_BED_POSITION
-
FRONT_PROBE_BED_POSITION
);
int
yGridSpacing
=
(
BACK_PROBE_BED_POSITION
-
FRONT_PROBE_BED_POSITION
);
for
(
int
yProbe
=
FRONT_PROBE_BED_POSITION
;
yProbe
<=
BACK_PROBE_BED_POSITION
;
yProbe
+=
yGridSpacing
)
{
for
(
int
yProbe
=
FRONT_PROBE_BED_POSITION
;
yProbe
<=
BACK_PROBE_BED_POSITION
;
yProbe
+=
yGridSpacing
)
{
int
xProbe
,
xInc
;
int
xProbe
,
xInc
;
if
(
zig
)
{
if
(
zig
)
{
xProbe
=
LEFT_PROBE_BED_POSITION
;
xProbe
=
LEFT_PROBE_BED_POSITION
;
xInc
=
xGridSpacing
;
xInc
=
xGridSpacing
;
zig
=
false
;
zig
=
false
;
}
}
else
{
// zag
else
{
// zag
xProbe
=
RIGHT_PROBE_BED_POSITION
;
xProbe
=
RIGHT_PROBE_BED_POSITION
;
xInc
=
-
xGridSpacing
;
xInc
=
-
xGridSpacing
;
zig
=
true
;
zig
=
true
;
}
}
for
(
int
xCount
=
0
;
xCount
<
2
;
xCount
++
)
{
for
(
int
xCount
=
0
;
xCount
<
2
;
xCount
++
)
{
destination
[
X_AXIS
]
=
xProbe
;
destination
[
X_AXIS
]
=
xProbe
;
destination
[
Y_AXIS
]
=
yProbe
;
destination
[
Y_AXIS
]
=
yProbe
;
destination
[
Z_AXIS
]
=
5
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
destination
[
Z_AXIS
]
=
5
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
feedrate
=
XY_TRAVEL_SPEED
;
feedrate
=
XY_TRAVEL_SPEED
;
current_position
[
Z_AXIS
]
=
0
;
current_position
[
Z_AXIS
]
=
0
;
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
/
60
,
active_extruder
,
active_driver
);
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
/
60
,
active_extruder
,
active_driver
);
st_synchronize
();
st_synchronize
();
current_position
[
X_AXIS
]
=
destination
[
X_AXIS
];
current_position
[
X_AXIS
]
=
destination
[
X_AXIS
];
current_position
[
Y_AXIS
]
=
destination
[
Y_AXIS
];
current_position
[
Y_AXIS
]
=
destination
[
Y_AXIS
];
HOMEAXIS
(
Z
);
HOMEAXIS
(
Z
);
lcd_setstatus
(
"Press button "
);
lcd_setstatus
(
"Press button "
);
boolean
beepbutton
=
true
;
boolean
beepbutton
=
true
;
while
(
!
lcd_clicked
())
{
while
(
!
lcd_clicked
())
{
manage_heater
();
manage_heater
();
manage_inactivity
();
manage_inactivity
();
lcd_update
();
lcd_update
();
if
(
beepbutton
)
{
if
(
beepbutton
)
{
#if BEEPER > 0
#if BEEPER > 0
SET_OUTPUT
(
BEEPER
);
SET_OUTPUT
(
BEEPER
);
WRITE
(
BEEPER
,
HIGH
);
WRITE
(
BEEPER
,
HIGH
);
delay
(
100
);
delay
(
100
);
WRITE
(
BEEPER
,
LOW
);
WRITE
(
BEEPER
,
LOW
);
delay
(
3
);
delay
(
3
);
#else
#else
#if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS)
#if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS)
lcd_buzz
(
1000
/
6
,
100
);
lcd_buzz
(
1000
/
6
,
100
);
#else
#else lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS,LCD_FEEDBACK_FREQUENCY_HZ);
lcd_buzz
(
LCD_FEEDBACK_FREQUENCY_DURATION_MS
,
LCD_FEEDBACK_FREQUENCY_HZ
);
#endif
#endif
#endif
#endif
beepbutton
=
false
;
beepbutton
=
false
;
}
}
xProbe
+=
xInc
;
}
}
}
}
xProbe
+=
xInc
;
lcd_setstatus
(
"Finish "
);
enquecommand
(
"G28 X0 Y0"
);
enquecommand
(
"G4 P0"
);
enquecommand
(
"G4 P0"
);
enquecommand
(
"G4 P0"
);
}
}
}
#endif // ULTIPANEL
lcd_setstatus
(
"Finish "
);
enquecommand
(
"G28 X0 Y0"
);
enquecommand
(
"G4 P0"
);
enquecommand
(
"G4 P0"
);
enquecommand
(
"G4 P0"
);
}
}
#endif // ULTIPANEL
else
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Z_AXIS
])))
{
}
#if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
else
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Z_AXIS
])))
{
destination
[
Z_AXIS
]
=
Z_RAISE_BEFORE_HOMING
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
// Set destination away from bed
#if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
feedrate
=
max_feedrate
[
Z_AXIS
];
destination
[
Z_AXIS
]
=
Z_RAISE_BEFORE_HOMING
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
// Set destination away from bed
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
,
active_extruder
,
active_driver
);
feedrate
=
max_feedrate
[
Z_AXIS
];
st_synchronize
();
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
,
active_extruder
,
active_driver
);
#endif
st_synchronize
();
HOMEAXIS
(
Z
);
#endif
}
HOMEAXIS
(
Z
);
#else // Z Safe mode activated.
}
if
(
home_all_axis
)
{
#else // Z Safe mode activated.
destination
[
X_AXIS
]
=
round
(
Z_SAFE_HOMING_X_POINT
-
X_PROBE_OFFSET_FROM_EXTRUDER
);
if
(
home_all_axis
)
{
destination
[
Y_AXIS
]
=
round
(
Z_SAFE_HOMING_Y_POINT
-
Y_PROBE_OFFSET_FROM_EXTRUDER
);
destination
[
X_AXIS
]
=
round
(
Z_SAFE_HOMING_X_POINT
-
X_PROBE_OFFSET_FROM_EXTRUDER
);
destination
[
Z_AXIS
]
=
Z_RAISE_BEFORE_HOMING
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
// Set destination away from bed
destination
[
Y_AXIS
]
=
round
(
Z_SAFE_HOMING_Y_POINT
-
Y_PROBE_OFFSET_FROM_EXTRUDER
);
feedrate
=
XY_TRAVEL_SPEED
;
destination
[
Z_AXIS
]
=
Z_RAISE_BEFORE_HOMING
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
// Set destination away from bed
feedrate
=
XY_TRAVEL_SPEED
;
current_position
[
Z_AXIS
]
=
0
;
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
/
60
,
active_extruder
,
active_driver
);
st_synchronize
();
current_position
[
X_AXIS
]
=
destination
[
X_AXIS
];
current_position
[
Y_AXIS
]
=
destination
[
Y_AXIS
];
HOMEAXIS
(
Z
);
}
// Let's see if X and Y are homed and probe is inside bed area.
if
(
code_seen
(
axis_codes
[
Z_AXIS
]))
{
if
(
(
axis_known_position
[
X_AXIS
])
&&
(
axis_known_position
[
Y_AXIS
])
\
&&
(
current_position
[
X_AXIS
]
+
X_PROBE_OFFSET_FROM_EXTRUDER
>=
X_MIN_POS
)
\
&&
(
current_position
[
X_AXIS
]
+
X_PROBE_OFFSET_FROM_EXTRUDER
<=
X_MAX_POS
)
\
&&
(
current_position
[
Y_AXIS
]
+
Y_PROBE_OFFSET_FROM_EXTRUDER
>=
Y_MIN_POS
)
\
&&
(
current_position
[
Y_AXIS
]
+
Y_PROBE_OFFSET_FROM_EXTRUDER
<=
Y_MAX_POS
))
{
current_position
[
Z_AXIS
]
=
0
;
current_position
[
Z_AXIS
]
=
0
;
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
destination
[
Z_AXIS
]
=
Z_RAISE_BEFORE_HOMING
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
// Set destination away from bed
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
/
60
,
active_extruder
,
active_driver
);
feedrate
=
max_feedrate
[
Z_AXIS
];
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
,
active_extruder
,
active_driver
);
st_synchronize
();
st_synchronize
();
current_position
[
X_AXIS
]
=
destination
[
X_AXIS
];
current_position
[
Y_AXIS
]
=
destination
[
Y_AXIS
];
HOMEAXIS
(
Z
);
HOMEAXIS
(
Z
);
}
else
if
(
!
((
axis_known_position
[
X_AXIS
])
&&
(
axis_known_position
[
Y_AXIS
])))
{
LCD_MESSAGEPGM
(
MSG_POSITION_UNKNOWN
);
SERIAL_ECHO_START
;
SERIAL_ECHOLNPGM
(
MSG_POSITION_UNKNOWN
);
}
else
{
LCD_MESSAGEPGM
(
MSG_ZPROBE_OUT
);
SERIAL_ECHO_START
;
SERIAL_ECHOLNPGM
(
MSG_ZPROBE_OUT
);
}
}
}
// Let's see if X and Y are homed and probe is inside bed area.
#endif // Z_SAFE_HOMING
if
(
code_seen
(
axis_codes
[
Z_AXIS
]))
{
#endif // Z_HOME_DIR < 0
if
(
axis_known_position
[
X_AXIS
]
&&
axis_known_position
[
Y_AXIS
])
{
float
cpx
=
current_position
[
X_AXIS
]
+
X_PROBE_OFFSET_FROM_EXTRUDER
,
cpy
=
current_position
[
Y_AXIS
]
+
Y_PROBE_OFFSET_FROM_EXTRUDER
;
if
(
code_seen
(
axis_codes
[
Z_AXIS
]))
{
if
(
cpx
>=
X_MIN_POS
&&
cpx
<=
X_MAX_POS
&&
cpy
>=
Y_MIN_POS
&&
cpy
<=
Y_MAX_POS
)
{
if
(
code_value_long
()
!=
0
)
{
current_position
[
Z_AXIS
]
=
0
;
current_position
[
Z_AXIS
]
=
code_value
()
+
add_homing
[
Z_AXIS
];
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
destination
[
Z_AXIS
]
=
Z_RAISE_BEFORE_HOMING
*
home_dir
(
Z_AXIS
)
*
(
-
1
);
// Set destination away from bed
feedrate
=
max_feedrate
[
Z_AXIS
];
plan_buffer_line
(
destination
[
X_AXIS
],
destination
[
Y_AXIS
],
destination
[
Z_AXIS
],
destination
[
E_AXIS
],
feedrate
,
active_extruder
,
active_driver
);
st_synchronize
();
HOMEAXIS
(
Z
);
}
else
{
LCD_MESSAGEPGM
(
MSG_ZPROBE_OUT
);
SERIAL_ECHO_START
;
SERIAL_ECHOLNPGM
(
MSG_ZPROBE_OUT
);
}
}
else
{
LCD_MESSAGEPGM
(
MSG_POSITION_UNKNOWN
);
SERIAL_ECHO_START
;
SERIAL_ECHOLNPGM
(
MSG_POSITION_UNKNOWN
);
}
}
}
}
#endif // Z_SAFE_HOMING
#ifdef ENABLE_AUTO_BED_LEVELING
#endif // Z_HOME_DIR < 0
if
(
code_seen
(
axis_codes
[
Z_AXIS
])
&&
code_value_long
()
!=
0
)
current_position
[
Z_AXIS
]
=
code_value
()
+
add_homing
[
Z_AXIS
];
#ifdef ENABLE_AUTO_BED_LEVELING
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Z_AXIS
])))
{
if
((
home_all_axis
)
||
(
code_seen
(
axis_codes
[
Z_AXIS
])))
{
current_position
[
Z_AXIS
]
+=
zprobe_zoffset
;
//Add Z_Probe offset (the distance is negative)
current_position
[
Z_AXIS
]
+=
zprobe_zoffset
;
//Add Z_Probe offset (the distance is negative)
}
}
#endif
#endif
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#endif // else DELTA
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#ifdef SCARA
#endif // else DELTA
calculate_delta
(
current_position
);
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#endif SCARA
#ifdef SCARA
#ifdef ENDSTOPS_ONLY_FOR_HOMING
calculate_delta
(
current_position
);
enable_endstops
(
false
);
plan_set_position
(
delta
[
X_AXIS
],
delta
[
Y_AXIS
],
delta
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#endif
#endif SCARA
#ifdef ENDSTOPS_ONLY_FOR_HOMING
feedrate
=
saved_feedrate
;
enable_endstops
(
false
);
feedmultiply
=
saved_feedmultiply
;
#endif
refresh_cmd_timeout
();
endstops_hit_on_purpose
();
}
feedrate
=
saved_feedrate
;
feedmultiply
=
saved_feedmultiply
;
refresh_cmd_timeout
();
endstops_hit_on_purpose
();
break
;
#ifdef ENABLE_AUTO_BED_LEVELING
#ifdef ENABLE_AUTO_BED_LEVELING
case
29
:
// G29 Detailed Z-Probe, probes the bed at 3 or more points.
/**
{
* G29: Detailed Z-Probe, probes the bed at 3 or more points.
#if Z_MIN_PIN == -1
* Will fail if the printer has not been homed with G28.
#error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling feature!!! Z_MIN_PIN must point to a valid hardware pin."
*/
#endif
void
gcode_G29
()
{
float
x_tmp
,
y_tmp
,
z_tmp
,
real_z
;
// Prevent user from running a G29 without first homing in X and Y
#if Z_MIN_PIN == -1
if
(
!
(
axis_known_position
[
X_AXIS
]
&&
axis_known_position
[
Y_AXIS
])
)
{
#error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling feature!!! Z_MIN_PIN must point to a valid hardware pin."
LCD_MESSAGEPGM
(
MSG_POSITION_UNKNOWN
);
#endif
SERIAL_ECHO_START
;
SERIAL_ECHOLNPGM
(
MSG_POSITION_UNKNOWN
);
break
;
// abort G29, since we don't know where we are
}
#ifdef Z_PROBE_SLED
// Prevent user from running a G29 without first homing in X and Y
dock_sled
(
false
);
if
(
!
(
axis_known_position
[
X_AXIS
]
&&
axis_known_position
[
Y_AXIS
])
)
{
#endif // Z_PROBE_SLED
LCD_MESSAGEPGM
(
MSG_POSITION_UNKNOWN
);
SERIAL_ECHO_START
;
SERIAL_ECHOLNPGM
(
MSG_POSITION_UNKNOWN
);
return
;
// abort G29, since we don't know where we are
}
st_synchronize
();
#ifdef Z_PROBE_SLED
// make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
dock_sled
(
false
);
//vector_3 corrected_position = plan_get_position_mm();
#endif // Z_PROBE_SLED
//corrected_position.debug("position before G29");
plan_bed_level_matrix
.
set_to_identity
();
vector_3
uncorrected_position
=
plan_get_position
();
//uncorrected_position.debug("position durring G29");
current_position
[
X_AXIS
]
=
uncorrected_position
.
x
;
current_position
[
Y_AXIS
]
=
uncorrected_position
.
y
;
current_position
[
Z_AXIS
]
=
uncorrected_position
.
z
;
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
setup_for_endstop_move
();
feedrate
=
homing_feedrate
[
Z_AXIS
];
st_synchronize
();
#ifdef AUTO_BED_LEVELING_GRID
// make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
int
r_probe_bed_position
=
RIGHT_PROBE_BED_POSITION
;
//vector_3 corrected_position = plan_get_position_mm();
int
l_probe_bed_position
=
LEFT_PROBE_BED_POSITION
;
//corrected_position.debug("position before G29");
int
f_probe_bed_position
=
FRONT_PROBE_BED_POSITION
;
plan_bed_level_matrix
.
set_to_identity
();
int
b_probe_bed_position
=
BACK_PROBE_BED_POSITION
;
vector_3
uncorrected_position
=
plan_get_position
();
int
a_bed_leveling_points
=
AUTO_BED_LEVELING_GRID_POINTS
;
//uncorrected_position.debug("position durring G29");
current_position
[
X_AXIS
]
=
uncorrected_position
.
x
;
current_position
[
Y_AXIS
]
=
uncorrected_position
.
y
;
current_position
[
Z_AXIS
]
=
uncorrected_position
.
z
;
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
setup_for_endstop_move
();
feedrate
=
homing_feedrate
[
Z_AXIS
];
#ifdef AUTO_BED_LEVELING_GRID
int
r_probe_bed_position
=
RIGHT_PROBE_BED_POSITION
;
int
l_probe_bed_position
=
LEFT_PROBE_BED_POSITION
;
int
f_probe_bed_position
=
FRONT_PROBE_BED_POSITION
;
int
b_probe_bed_position
=
BACK_PROBE_BED_POSITION
;
int
a_bed_leveling_points
=
AUTO_BED_LEVELING_GRID_POINTS
;
if
(
code_seen
(
'R'
))
r_probe_bed_position
=
code_value
();
if
(
code_seen
(
'L'
))
l_probe_bed_position
=
code_value
();
if
(
code_seen
(
'F'
))
f_probe_bed_position
=
code_value
();
if
(
code_seen
(
'B'
))
b_probe_bed_position
=
code_value
();
if
(
code_seen
(
'A'
))
a_bed_leveling_points
=
code_value
();
if
((
f_probe_bed_position
==
b_probe_bed_position
)
||
(
r_probe_bed_position
==
l_probe_bed_position
))
{
SERIAL_ERROR_START
;
SERIAL_ERRORLNPGM
(
MSG_EMPTY_PLANE
);
return
;
}
if
(
code_seen
(
'R'
))
// probe at the points of a lattice grid
{
int
xGridSpacing
=
(
r_probe_bed_position
-
l_probe_bed_position
)
/
(
a_bed_leveling_points
-
1
);
r_probe_bed_position
=
code_value
();
int
yGridSpacing
=
(
b_probe_bed_position
-
f_probe_bed_position
)
/
(
a_bed_leveling_points
-
1
);
}
// solve the plane equation ax + by + d = z
// A is the matrix with rows [x y 1] for all the probed points
// B is the vector of the Z positions
// the normal vector to the plane is formed by the coefficients of the plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0
// so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
// "A" matrix of the linear system of equations
double
eqnAMatrix
[
a_bed_leveling_points
*
a_bed_leveling_points
*
3
];
// "B" vector of Z points
double
eqnBVector
[
a_bed_leveling_points
*
a_bed_leveling_points
];
int
probePointCounter
=
0
;
bool
zig
=
true
;
for
(
int
yProbe
=
f_probe_bed_position
;
yProbe
<=
b_probe_bed_position
;
yProbe
+=
yGridSpacing
)
{
int
xProbe
,
xInc
;
if
(
zig
)
{
xProbe
=
l_probe_bed_position
;
//xEnd = RIGHT_PROBE_BED_POSITION;
xInc
=
xGridSpacing
;
zig
=
false
;
}
else
// zag
{
xProbe
=
r_probe_bed_position
;
//xEnd = LEFT_PROBE_BED_POSITION;
xInc
=
-
xGridSpacing
;
zig
=
true
;
}
if
(
code_seen
(
'L'
))
for
(
int
xCount
=
0
;
xCount
<
a_bed_leveling_points
;
xCount
++
)
{
{
float
z_before
;
l_probe_bed_position
=
code_value
();
if
(
probePointCounter
==
0
)
{
// raise before probing
z_before
=
Z_RAISE_BEFORE_PROBING
;
}
else
{
// raise extruder
z_before
=
current_position
[
Z_AXIS
]
+
Z_RAISE_BETWEEN_PROBINGS
;
}
}
if
(
code_seen
(
'F'
))
float
measured_z
=
probe_pt
(
xProbe
,
yProbe
,
z_before
);
{
eqnBVector
[
probePointCounter
]
=
measured_z
;
f_probe_bed_position
=
code_value
();
eqnAMatrix
[
probePointCounter
+
0
*
a_bed_leveling_points
*
a_bed_leveling_points
]
=
xProbe
;
}
eqnAMatrix
[
probePointCounter
+
1
*
a_bed_leveling_points
*
a_bed_leveling_points
]
=
yProbe
;
eqnAMatrix
[
probePointCounter
+
2
*
a_bed_leveling_points
*
a_bed_leveling_points
]
=
1
;
probePointCounter
++
;
xProbe
+=
xInc
;
}
}
clean_up_after_endstop_move
();
if
(
code_seen
(
'B'
))
// solve lsq problem
{
double
*
plane_equation_coefficients
=
qr_solve
(
a_bed_leveling_points
*
a_bed_leveling_points
,
3
,
eqnAMatrix
,
eqnBVector
);
b_probe_bed_position
=
code_value
();
}
if
(
code_seen
(
'A'
))
SERIAL_PROTOCOLPGM
(
"Eqn coefficients: a: "
);
{
SERIAL_PROTOCOL
(
plane_equation_coefficients
[
0
]);
a_bed_leveling_points
=
code_value
();
SERIAL_PROTOCOLPGM
(
" b: "
);
}
SERIAL_PROTOCOL
(
plane_equation_coefficients
[
1
]);
SERIAL_PROTOCOLPGM
(
" d: "
);
SERIAL_PROTOCOLLN
(
plane_equation_coefficients
[
2
]);
if
((
f_probe_bed_position
==
b_probe_bed_position
)
||
(
r_probe_bed_position
==
l_probe_bed_position
))
set_bed_level_equation_lsq
(
plane_equation_coefficients
);
{
free
(
plane_equation_coefficients
);
SERIAL_ERROR_START
;
SERIAL_ERRORLNPGM
(
MSG_EMPTY_PLANE
);
break
;
return
;
}
// probe at the points of a lattice gri
d
#else // AUTO_BED_LEVELING_GRID not define
d
int
xGridSpacing
=
(
r_probe_bed_position
-
l_probe_bed_position
)
/
(
a_bed_leveling_points
-
1
);
// Probe at 3 arbitrary points
int
yGridSpacing
=
(
b_probe_bed_position
-
f_probe_bed_position
)
/
(
a_bed_leveling_points
-
1
);
// probe 1
float
z_at_pt_1
=
probe_pt
(
ABL_PROBE_PT_1_X
,
ABL_PROBE_PT_1_Y
,
Z_RAISE_BEFORE_PROBING
);
// solve the plane equation ax + by + d = z
// probe 2
// A is the matrix with rows [x y 1] for all the probed points
float
z_at_pt_2
=
probe_pt
(
ABL_PROBE_PT_2_X
,
ABL_PROBE_PT_2_Y
,
current_position
[
Z_AXIS
]
+
Z_RAISE_BETWEEN_PROBINGS
);
// B is the vector of the Z positions
// the normal vector to the plane is formed by the coefficients of the plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0
// so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
// "A" matrix of the linear system of equations
// probe 3
double
eqnAMatrix
[
a_bed_leveling_points
*
a_bed_leveling_points
*
3
];
float
z_at_pt_3
=
probe_pt
(
ABL_PROBE_PT_3_X
,
ABL_PROBE_PT_3_Y
,
current_position
[
Z_AXIS
]
+
Z_RAISE_BETWEEN_PROBINGS
);
// "B" vector of Z points
double
eqnBVector
[
a_bed_leveling_points
*
a_bed_leveling_points
];
int
probePointCounter
=
0
;
clean_up_after_endstop_move
()
;
bool
zig
=
true
;
set_bed_level_equation_3pts
(
z_at_pt_1
,
z_at_pt_2
,
z_at_pt_3
)
;
for
(
int
yProbe
=
f_probe_bed_position
;
yProbe
<=
b_probe_bed_position
;
yProbe
+=
yGridSpacing
)
#endif // AUTO_BED_LEVELING_GRID
{
int
xProbe
,
xInc
;
if
(
zig
)
{
xProbe
=
l_probe_bed_position
;
//xEnd = RIGHT_PROBE_BED_POSITION;
xInc
=
xGridSpacing
;
zig
=
false
;
}
else
// zag
{
xProbe
=
r_probe_bed_position
;
//xEnd = LEFT_PROBE_BED_POSITION;
xInc
=
-
xGridSpacing
;
zig
=
true
;
}
for
(
int
xCount
=
0
;
xCount
<
a_bed_leveling_points
;
xCount
++
)
st_synchronize
();
{
float
z_before
;
if
(
probePointCounter
==
0
)
{
// raise before probing
z_before
=
Z_RAISE_BEFORE_PROBING
;
}
else
{
// raise extruder
z_before
=
current_position
[
Z_AXIS
]
+
Z_RAISE_BETWEEN_PROBINGS
;
}
float
measured_z
=
probe_pt
(
xProbe
,
yProbe
,
z_before
);
// The following code correct the Z height difference from z-probe position and hotend tip position.
// The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
// When the bed is uneven, this height must be corrected.
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)
x_tmp
=
current_position
[
X_AXIS
]
+
X_PROBE_OFFSET_FROM_EXTRUDER
;
y_tmp
=
current_position
[
Y_AXIS
]
+
Y_PROBE_OFFSET_FROM_EXTRUDER
;
z_tmp
=
current_position
[
Z_AXIS
];
eqnBVector
[
probePointCounter
]
=
measured_z
;
apply_rotation_xyz
(
plan_bed_level_matrix
,
x_tmp
,
y_tmp
,
z_tmp
);
//Apply the correction sending the probe offset
current_position
[
Z_AXIS
]
=
z_tmp
-
real_z
+
current_position
[
Z_AXIS
];
//The difference is added to current position and sent to planner.
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
#ifdef Z_PROBE_SLED
dock_sled
(
true
,
-
SLED_DOCKING_OFFSET
);
// correct for over travel.
#endif // Z_PROBE_SLED
}
eqnAMatrix
[
probePointCounter
+
0
*
a_bed_leveling_points
*
a_bed_leveling_points
]
=
xProbe
;
#ifndef Z_PROBE_SLED
eqnAMatrix
[
probePointCounter
+
1
*
a_bed_leveling_points
*
a_bed_leveling_points
]
=
yProbe
;
void
gcode_G30
()
{
eqnAMatrix
[
probePointCounter
+
2
*
a_bed_leveling_points
*
a_bed_leveling_points
]
=
1
;
engage_z_probe
();
// Engage Z Servo endstop if available
probePointCounter
++
;
st_synchronize
();
xProbe
+=
xInc
;
// TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly
}
setup_for_endstop_move
();
}
clean_up_after_endstop_move
();
// solve lsq problem
feedrate
=
homing_feedrate
[
Z_AXIS
];
double
*
plane_equation_coefficients
=
qr_solve
(
a_bed_leveling_points
*
a_bed_leveling_points
,
3
,
eqnAMatrix
,
eqnBVector
);
SERIAL_PROTOCOLPGM
(
"Eqn coefficients: a: "
);
run_z_probe
();
SERIAL_PROTOCOL
(
plane_equation_coefficients
[
0
]);
SERIAL_PROTOCOLPGM
(
MSG_BED
);
SERIAL_PROTOCOLPGM
(
" b: "
);
SERIAL_PROTOCOLPGM
(
" X: "
);
SERIAL_PROTOCOL
(
plane_equation_coefficients
[
1
]);
SERIAL_PROTOCOL
(
current_position
[
X_AXIS
]);
SERIAL_PROTOCOLPGM
(
" d: "
);
SERIAL_PROTOCOLPGM
(
" Y: "
);
SERIAL_PROTOCOLLN
(
plane_equation_coefficients
[
2
]);
SERIAL_PROTOCOL
(
current_position
[
Y_AXIS
]);
SERIAL_PROTOCOLPGM
(
" Z: "
);
SERIAL_PROTOCOL
(
current_position
[
Z_AXIS
]);
SERIAL_PROTOCOLPGM
(
"
\n
"
);
clean_up_after_endstop_move
();
retract_z_probe
();
// Retract Z Servo endstop if available
}
#endif // Z_PROBE_SLED
#endif // ENABLE_AUTO_BED_LEVELING
set_bed_level_equation_lsq
(
plane_equation_coefficients
);
free
(
plane_equation_coefficients
);
#ifdef DELTA
/**
* G29: Detailed Z-Probe, probes the bed at more points.
*/
void
gcode_G29
()
{
if
(
code_seen
(
'D'
)){
SERIAL_ECHOLN
(
"Current bed level array values:"
);
SERIAL_ECHOLN
(
""
);
for
(
int
y
=
0
;
y
<
7
;
y
++
){
for
(
int
x
=
0
;
x
<
7
;
x
++
){
SERIAL_PROTOCOL_F
(
bed_level
[
x
][
y
],
3
);
SERIAL_PROTOCOLPGM
(
" "
);
}
SERIAL_ECHOLN
(
""
);
}
return
;
}
saved_feedrate
=
feedrate
;
saved_feedmultiply
=
feedmultiply
;
feedmultiply
=
100
;
#else // AUTO_BED_LEVELING_GRID not defined
deploy_z_probe
();
calibrate_print_surface
(
z_probe_offset
[
Z_AXIS
]
+
(
code_seen
(
axis_codes
[
Z_AXIS
])
?
code_value
()
:
0.0
));
retract_z_probe
();
// Probe at 3 arbitrary points
feedrate
=
saved_feedrate
;
// probe 1
feedmultiply
=
saved_feedmultiply
;
float
z_at_pt_1
=
probe_pt
(
ABL_PROBE_PT_1_X
,
ABL_PROBE_PT_1_Y
,
Z_RAISE_BEFORE_PROBING
);
refresh_cmd_timeout
();
endstops_hit_on_purpose
();
}
// probe 2
/**
float
z_at_pt_2
=
probe_pt
(
ABL_PROBE_PT_2_X
,
ABL_PROBE_PT_2_Y
,
current_position
[
Z_AXIS
]
+
Z_RAISE_BETWEEN_PROBINGS
);
* G30: Delta AutoCalibration
*/
void
gcode_G30
()
{
int
iterations
;
// probe 3
//Zero the bed level array
float
z_at_pt_3
=
probe_pt
(
ABL_PROBE_PT_3_X
,
ABL_PROBE_PT_3_Y
,
current_position
[
Z_AXIS
]
+
Z_RAISE_BETWEEN_PROBINGS
);
for
(
int
y
=
0
;
y
<
7
;
y
++
)
{
for
(
int
x
=
0
;
x
<
7
;
x
++
)
{
bed_level
[
x
][
y
]
=
0.0
;
}
}
clean_up_after_endstop_move
();
if
(
code_seen
(
'C'
))
{
//Show carriage positions
SERIAL_ECHOLN
(
"Carriage Positions for last scan:"
);
for
(
int8_t
i
=
0
;
i
<
7
;
i
++
)
{
SERIAL_ECHO
(
"["
);
SERIAL_ECHO
(
saved_positions
[
i
][
X_AXIS
]);
SERIAL_ECHO
(
", "
);
SERIAL_ECHO
(
saved_positions
[
i
][
Y_AXIS
]);
SERIAL_ECHO
(
", "
);
SERIAL_ECHO
(
saved_positions
[
i
][
Z_AXIS
]);
SERIAL_ECHOLN
(
"]"
);
}
return
;
}
if
(
code_seen
(
'F'
))
{
probing_feedrate
=
code_value
();
}
if
(
code_seen
(
'X'
)
and
code_seen
(
'Y'
))
{
//Probe specified X,Y point
float
x
=
code_seen
(
'X'
)
?
code_value
()
:
0.00
;
float
y
=
code_seen
(
'Y'
)
?
code_value
()
:
0.00
;
float
probe_value
;
deploy_z_probe
();
probe_value
=
probe_bed
(
x
,
y
);
SERIAL_ECHO
(
"Bed Z-Height at X:"
);
SERIAL_ECHO
(
x
);
SERIAL_ECHO
(
" Y:"
);
SERIAL_ECHO
(
y
);
SERIAL_ECHO
(
" = "
);
SERIAL_PROTOCOL_F
(
probe_value
,
4
);
SERIAL_ECHOLN
(
""
);
set_bed_level_equation_3pts
(
z_at_pt_1
,
z_at_pt_2
,
z_at_pt_3
);
SERIAL_ECHO
(
"Carriage Positions: ["
);
SERIAL_ECHO
(
saved_position
[
X_AXIS
]);
SERIAL_ECHO
(
", "
);
SERIAL_ECHO
(
saved_position
[
Y_AXIS
]);
SERIAL_ECHO
(
", "
);
SERIAL_ECHO
(
saved_position
[
Z_AXIS
]);
SERIAL_ECHOLN
(
"]"
);
retract_z_probe
();
return
;
}
#endif // AUTO_BED_LEVELING_GRID
saved_feedrate
=
feedrate
;
st_synchronize
();
saved_feedmultiply
=
feedmultiply
;
feedmultiply
=
100
;
// The following code correct the Z height difference from z-probe position and hotend tip position.
if
(
code_seen
(
'A'
))
{
// The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
SERIAL_ECHOLN
(
"Starting Auto Calibration.."
);
// When the bed is uneven, this height must be corrected.
LCD_MESSAGEPGM
(
"Auto Calibration..."
);
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)
if
(
code_value
()
!=
0
)
ac_prec
=
code_value
();
x_tmp
=
current_position
[
X_AXIS
]
+
X_PROBE_OFFSET_FROM_EXTRUDER
;
SERIAL_ECHO
(
"Calibration precision: +/-"
)
;
y_tmp
=
current_position
[
Y_AXIS
]
+
Y_PROBE_OFFSET_FROM_EXTRUDER
;
SERIAL_PROTOCOL_F
(
ac_prec
,
3
)
;
z_tmp
=
current_position
[
Z_AXIS
]
;
SERIAL_ECHOLN
(
"mm"
)
;
apply_rotation_xyz
(
plan_bed_level_matrix
,
x_tmp
,
y_tmp
,
z_tmp
);
//Apply the correction sending the probe offset
//Zero the bedlevel array in case this affects bed probing
current_position
[
Z_AXIS
]
=
z_tmp
-
real_z
+
current_position
[
Z_AXIS
];
//The difference is added to current position and sent to planner.
for
(
int
y
=
0
;
y
>=
6
;
y
++
)
{
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
for
(
int
x
=
0
;
x
>=
6
;
y
++
)
{
#ifdef Z_PROBE_SLED
bed_level
[
x
][
y
]
=
0.0
;
dock_sled
(
true
,
-
SLED_DOCKING_OFFSET
);
// correct for over travel.
}
#endif // Z_PROBE_SLED
}
}
}
break
;
#ifndef Z_PROBE_SLED
home_delta_axis
();
case
30
:
// G30 Single Z Probe
deploy_z_probe
();
{
engage_z_probe
();
// Engage Z Servo endstop if available
//Probe all points
st_synchronize
();
bed_probe_all
();
// TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly
setup_for_endstop_move
();
//Show calibration report
calibration_report
();
if
(
code_seen
(
'A'
))
{
iterations
=
100
;
//Maximum number of iterations
int
loopcount
=
1
;
float
adj_r_target
,
adj_dr_target
;
float
adj_r_target_delta
=
0
,
adj_dr_target_delta
=
0
;
float
adj_AlphaA
,
adj_AlphaB
,
adj_AlphaC
;
float
adj_RadiusA
,
adj_RadiusB
,
adj_RadiusC
;
float
radiusErrorA
,
radiusErrorB
,
radiusErrorC
;
float
adj_r
=
0
,
adj_dr
=
0
;
boolean
equalAB
,
equalBC
,
equalCA
;
boolean
adj_r_done
,
adj_dr_done
,
adj_tower_done
;
boolean
adj_dr_allowed
=
true
;
float
h_endstop
=
-
100
,
l_endstop
=
100
;
float
probe_error
,
ftemp
;
if
(
code_seen
(
'D'
))
{
delta_diagonal_rod
=
code_value
();
adj_dr_allowed
=
false
;
SERIAL_ECHOPAIR
(
"Using diagional rod length: "
,
delta_diagonal_rod
);
SERIAL_ECHOLN
(
"mm (will not be adjusted)"
);
}
//Check that endstops are within limits
if
(
bed_level_x
+
endstop_adj
[
0
]
>
h_endstop
)
h_endstop
=
bed_level_x
+
endstop_adj
[
0
];
if
(
bed_level_x
+
endstop_adj
[
0
]
<
l_endstop
)
l_endstop
=
bed_level_x
+
endstop_adj
[
0
];
if
(
bed_level_y
+
endstop_adj
[
1
]
>
h_endstop
)
h_endstop
=
bed_level_y
+
endstop_adj
[
1
];
if
(
bed_level_y
+
endstop_adj
[
1
]
<
l_endstop
)
l_endstop
=
bed_level_y
+
endstop_adj
[
1
];
if
(
bed_level_z
+
endstop_adj
[
2
]
>
h_endstop
)
h_endstop
=
bed_level_z
+
endstop_adj
[
2
];
if
(
bed_level_z
+
endstop_adj
[
2
]
<
l_endstop
)
l_endstop
=
bed_level_z
+
endstop_adj
[
2
];
if
(
h_endstop
-
l_endstop
>
3
)
{
SERIAL_ECHOLN
(
"The position of the endstop switches on this printer are not within limits"
);
SERIAL_ECHOLN
(
"Adjust endstop switches so that they are within 3mm Z-height of each other"
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"Current Endstop Positions - X: "
,
bed_level_x
+
endstop_adj
[
0
]);
SERIAL_ECHOPAIR
(
" Y: "
,
bed_level_y
+
endstop_adj
[
1
]);
SERIAL_ECHOPAIR
(
" Z: "
,
bed_level_z
+
endstop_adj
[
2
]);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOLN
(
"Autocalibration aborted"
);
feedrate
=
homing_feedrate
[
Z_AXIS
]
;
retract_z_probe
()
;
run_z_probe
();
//Restore saved variables
SERIAL_PROTOCOLPGM
(
MSG_BED
);
feedrate
=
saved_feedrate
;
SERIAL_PROTOCOLPGM
(
" X: "
);
feedmultiply
=
saved_feedmultiply
;
SERIAL_PROTOCOL
(
current_position
[
X_AXIS
]);
return
;
SERIAL_PROTOCOLPGM
(
" Y: "
);
}
SERIAL_PROTOCOL
(
current_position
[
Y_AXIS
]);
SERIAL_PROTOCOLPGM
(
" Z: "
);
SERIAL_PROTOCOL
(
current_position
[
Z_AXIS
]);
SERIAL_PROTOCOLPGM
(
"
\n
"
);
clean_up_after_endstop_move
();
if
(
code_seen
(
'D'
))
{
retract_z_probe
();
// Retract Z Servo endstop if available
//Fix diagonal rod at specified length (do not adjust)
}
delta_diagonal_rod
=
code_value
();
break
;
adj_dr_allowed
=
false
;
#else
}
case
31
:
// G31 - dock the sled
dock_sled
(
true
);
break
;
case
32
:
// G32 - undock the sled
do
{
dock_sled
(
false
);
SERIAL_ECHO
(
"Iteration: "
);
break
;
SERIAL_ECHO
(
loopcount
);
#endif // Z_PROBE_SLED
SERIAL_ECHOLN
(
""
);
#endif // ENABLE_AUTO_BED_LEVELING
#ifdef DELTA
if
((
bed_level_c
>
3
)
or
(
bed_level_c
<
-
3
))
{
case
29
:
// G29 Calibrate print surface with automatic Z probe.
//Build height is not set correctly ..
if
(
code_seen
(
'D'
)){
max_pos
[
Z_AXIS
]
-=
bed_level_c
+
2
;
SERIAL_ECHOLN
(
"Current bed level array values:"
);
set_delta_constants
();
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"Adjusting Z-Height to: "
,
max_pos
[
Z_AXIS
]);
for
(
int
y
=
0
;
y
<
7
;
y
++
){
SERIAL_ECHOLN
(
" mm.."
);
for
(
int
x
=
0
;
x
<
7
;
x
++
){
}
SERIAL_PROTOCOL_F
(
bed_level
[
x
][
y
],
3
);
else
{
SERIAL_PROTOCOLPGM
(
" "
);
if
((
bed_level_x
<
-
ac_prec
)
or
(
bed_level_x
>
ac_prec
)
or
(
bed_level_y
<
-
ac_prec
)
or
(
bed_level_y
>
ac_prec
)
or
(
bed_level_z
<
-
ac_prec
)
or
(
bed_level_z
>
ac_prec
))
{
//Endstops req adjustment
SERIAL_ECHOLN
(
"Adjusting Endstops.."
);
endstop_adj
[
0
]
+=
bed_level_x
/
1.05
;
endstop_adj
[
1
]
+=
bed_level_y
/
1.05
;
endstop_adj
[
2
]
+=
bed_level_z
/
1.05
;
//Check that no endstop adj values are > 0 (not allowed).. if they are, reduce the build height to compensate.
h_endstop
=
0
;
for
(
int
x
=
0
;
x
<
3
;
x
++
)
{
if
(
endstop_adj
[
x
]
>
h_endstop
)
h_endstop
=
endstop_adj
[
x
];
}
}
SERIAL_ECHOLN
(
""
);
if
(
h_endstop
>
0
)
{
}
//Reduce build height and adjust endstops
break
;
for
(
int
x
=
0
;
x
<
3
;
x
++
)
{
}
endstop_adj
[
x
]
-=
h_endstop
+
2
;
saved_feedrate
=
feedrate
;
}
saved_feedmultiply
=
feedmultiply
;
max_pos
[
Z_AXIS
]
-=
h_endstop
+
2
;
feedmultiply
=
100
;
set_delta_constants
();
SERIAL_ECHOPAIR
(
"Adjusting Z-Height to: "
,
max_pos
[
Z_AXIS
]);
SERIAL_ECHOLN
(
" mm.."
);
}
}
else
{
SERIAL_ECHOLN
(
"Endstops: OK"
);
adj_r_target
=
(
bed_level_x
+
bed_level_y
+
bed_level_z
)
/
3
;
adj_dr_target
=
(
bed_level_ox
+
bed_level_oy
+
bed_level_oz
)
/
3
;
//Determine which parameters require adjustment
if
((
bed_level_c
>=
adj_r_target
-
ac_prec
)
and
(
bed_level_c
<=
adj_r_target
+
ac_prec
))
adj_r_done
=
true
;
else
adj_r_done
=
false
;
if
((
adj_dr_target
>=
adj_r_target
-
ac_prec
)
and
(
adj_dr_target
<=
adj_r_target
+
ac_prec
))
adj_dr_done
=
true
;
else
adj_dr_done
=
false
;
if
((
bed_level_x
!=
bed_level_ox
)
or
(
bed_level_y
!=
bed_level_oy
)
or
(
bed_level_z
!=
bed_level_oz
))
adj_tower_done
=
false
;
else
adj_tower_done
=
true
;
if
((
adj_r_done
==
false
)
or
(
adj_dr_done
==
false
)
or
(
adj_tower_done
==
false
))
{
//delta geometry adjustment required
SERIAL_ECHOLN
(
"Adjusting Delta Geometry.."
);
//set inital direction and magnitude for delta radius & diagonal rod adjustment
if
(
adj_r
==
0
)
{
if
(
adj_r_target
>
bed_level_c
)
adj_r
=
1
;
else
adj_r
=
-
1
;
}
deploy_z_probe
();
if
(
adj_dr
==
0
)
{
calibrate_print_surface
(
z_probe_offset
[
Z_AXIS
]
+
if
(
adj_r_target
>
adj_dr_target
)
adj_dr
=
1
;
(
code_seen
(
axis_codes
[
Z_AXIS
])
?
code_value
()
:
0.0
));
else
adj_dr
=
-
1
;
}
retract_z_probe
();
//Don't adjust tower positions on first iteration
adj_AlphaA
=
adj_AlphaB
=
adj_AlphaC
=
0
;
adj_RadiusA
=
adj_RadiusB
=
adj_RadiusC
=
0
;
do
{
//Apply adjustments
if
(
adj_r_done
==
false
)
{
SERIAL_ECHOPAIR
(
"Adjusting Delta Radius ("
,
delta_radius
);
SERIAL_ECHOPAIR
(
" -> "
,
delta_radius
+
adj_r
);
SERIAL_ECHOLN
(
")"
);
delta_radius
+=
adj_r
;
}
feedrate
=
saved_feedrate
;
if
(
adj_dr_allowed
==
false
)
adj_dr_done
=
true
;
feedmultiply
=
saved_feedmultiply
;
if
(
adj_dr_done
==
false
)
{
refresh_cmd_timeout
();
SERIAL_ECHOPAIR
(
"Adjusting Diag Rod Length ("
,
delta_diagonal_rod
);
endstops_hit_on_purpose
();
SERIAL_ECHOPAIR
(
" -> "
,
delta_diagonal_rod
+
adj_dr
);
break
;
SERIAL_ECHOLN
(
")"
);
delta_diagonal_rod
+=
adj_dr
;
}
case
30
:
//G30 Delta AutoCalibration
tower_adj
[
0
]
-=
adj_AlphaA
;
int
iterations
;
tower_adj
[
1
]
-=
adj_AlphaB
;
tower_adj
[
2
]
-=
adj_AlphaC
;
tower_adj
[
3
]
+=
adj_RadiusA
;
tower_adj
[
4
]
+=
adj_RadiusB
;
tower_adj
[
5
]
+=
adj_RadiusC
;
set_delta_constants
();
bed_probe_all
();
calibration_report
();
//Check to see if autocal is complete to within limits..
if
(
adj_dr_allowed
==
true
)
{
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
)
and
(
bed_level_ox
>=
-
ac_prec
)
and
(
bed_level_ox
<=
ac_prec
)
and
(
bed_level_oy
>=
-
ac_prec
)
and
(
bed_level_oy
<=
ac_prec
)
and
(
bed_level_oz
>=
-
ac_prec
)
and
(
bed_level_oz
<=
ac_prec
))
loopcount
=
iterations
;
}
else
{
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
))
loopcount
=
iterations
;
}
//Zero the bed level array
//set delta radius and diag rod targets
for
(
int
y
=
0
;
y
<
7
;
y
++
)
{
adj_r_target
=
(
bed_level_x
+
bed_level_y
+
bed_level_z
)
/
3
;
for
(
int
x
=
0
;
x
<
7
;
x
++
)
{
adj_dr_target
=
(
bed_level_ox
+
bed_level_oy
+
bed_level_oz
)
/
3
;
bed_level
[
x
][
y
]
=
0.0
;
}
}
if
(
code_seen
(
'C'
))
{
//set Tower position adjustment values
//Show carriage positions
adj_AlphaA
=
bed_level_oy
-
bed_level_oz
;
SERIAL_ECHOLN
(
"Carriage Positions for last scan:"
);
adj_AlphaB
=
bed_level_oz
-
bed_level_ox
;
for
(
int8_t
i
=
0
;
i
<
7
;
i
++
)
{
adj_AlphaC
=
bed_level_ox
-
bed_level_oy
;
SERIAL_ECHO
(
"["
);
SERIAL_ECHO
(
saved_positions
[
i
][
X_AXIS
]);
//set tower radius errors
SERIAL_ECHO
(
", "
);
radiusErrorA
=
bed_level_x
-
bed_level_ox
;
SERIAL_ECHO
(
saved_positions
[
i
][
Y_AXIS
]);
radiusErrorB
=
bed_level_y
-
bed_level_oy
;
SERIAL_ECHO
(
", "
);
radiusErrorC
=
bed_level_z
-
bed_level_oz
;
SERIAL_ECHO
(
saved_positions
[
i
][
Z_AXIS
]);
SERIAL_ECHOLN
(
"]"
);
if
((
radiusErrorA
>=
(
radiusErrorB
-
0.02
))
and
(
radiusErrorA
<=
(
radiusErrorB
+
0.02
)))
equalAB
=
true
;
}
else
equalAB
=
false
;
break
;
if
((
radiusErrorB
>=
(
radiusErrorC
-
0.02
))
and
(
radiusErrorB
<=
(
radiusErrorC
+
0.02
)))
equalBC
=
true
;
}
else
equalBC
=
false
;
if
(
code_seen
(
'F'
))
{
if
((
radiusErrorC
>=
(
radiusErrorA
-
0.02
))
and
(
radiusErrorC
<=
(
radiusErrorA
+
0.02
)))
equalCA
=
true
;
probing_feedrate
=
code_value
();
else
equalCA
=
false
;
}
if
(
code_seen
(
'X'
)
and
code_seen
(
'Y'
))
{
#ifdef DEBUG_MESSAGES
//Probe specified X,Y point
if
(
equalAB
==
true
)
{
float
x
=
code_seen
(
'X'
)
?
code_value
()
:
0.00
;
SERIAL_ECHOPAIR
(
"Tower AB Equal (A="
,
radiusErrorA
);
float
y
=
code_seen
(
'Y'
)
?
code_value
()
:
0.00
;
SERIAL_ECHOPAIR
(
" B="
,
radiusErrorB
);
float
probe_value
;
SERIAL_ECHOLN
(
")"
);
}
deploy_z_probe
();
else
SERIAL_ECHOLN
(
"equalAB=false"
);
probe_value
=
probe_bed
(
x
,
y
);
SERIAL_ECHO
(
"Bed Z-Height at X:"
);
SERIAL_ECHO
(
x
);
SERIAL_ECHO
(
" Y:"
);
SERIAL_ECHO
(
y
);
SERIAL_ECHO
(
" = "
);
SERIAL_PROTOCOL_F
(
probe_value
,
4
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHO
(
"Carriage Positions: ["
);
if
(
equalBC
==
true
)
{
SERIAL_ECHO
(
saved_position
[
X_AXIS
]);
SERIAL_ECHOPAIR
(
"Tower BC Equal (B="
,
radiusErrorB
);
SERIAL_ECHO
(
", "
);
SERIAL_ECHOPAIR
(
" C="
,
radiusErrorC
);
SERIAL_ECHO
(
saved_position
[
Y_AXIS
]);
SERIAL_ECHOLN
(
")"
);
SERIAL_ECHO
(
", "
);
}
SERIAL_ECHO
(
saved_position
[
Z_AXIS
]);
else
SERIAL_ECHOLN
(
"equalBC=false"
);
SERIAL_ECHOLN
(
"]"
);
retract_z_probe
();
break
;
}
saved_feedrate
=
feedrate
;
if
(
equalCA
==
true
)
{
saved_feedmultiply
=
feedmultiply
;
SERIAL_ECHOPAIR
(
"Tower CA Equal (C="
,
radiusErrorC
);
feedmultiply
=
100
;
SERIAL_ECHOPAIR
(
" A="
,
radiusErrorA
);
SERIAL_ECHOLN
(
")"
);
}
else
SERIAL_ECHOLN
(
"equalCA=false"
);
#endif // DEBUG_MESSAGES
if
((
equalAB
==
true
)
and
(
equalBC
==
true
)
and
(
equalCA
==
true
))
{
// all tower radius out by the same amount (within 0.02) - allow adjustment with delta rod length
#ifdef DEBUG_MESSAGES
SERIAL_ECHOLN
(
"All tower radius errors equal"
);
#endif
adj_RadiusA
=
adj_RadiusB
=
adj_RadiusC
=
0
;
}
if
(
code_seen
(
'A'
))
{
if
((
equalAB
==
true
)
and
(
equalBC
==
false
)
and
(
equalCA
==
false
))
{
SERIAL_ECHOLN
(
"Starting Auto Calibration.."
);
//Tower C radius error.. adjust it
LCD_MESSAGEPGM
(
"Auto Calibration..."
);
SERIAL_ECHOLN
(
"TowerC Radius error - adjusting"
);
if
(
code_value
()
!=
0
)
ac_prec
=
code_value
();
if
(
adj_RadiusC
==
0
)
{
SERIAL_ECHO
(
"Calibration precision: +/-"
);
if
(
bed_level_z
<
bed_level_oz
)
adj_RadiusC
=
0.5
;
SERIAL_PROTOCOL_F
(
ac_prec
,
3
);
if
(
bed_level_z
>
bed_level_oz
)
adj_RadiusC
=
-
0.5
;
SERIAL_ECHOLN
(
"mm"
);
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"adj_RadiusC set to "
,
adj_RadiusC
);
//Zero the bedlevel array in case this affects bed probing
SERIAL_ECHOLN
(
""
);
for
(
int
y
=
0
;
y
>=
6
;
y
++
)
{
#endif
for
(
int
x
=
0
;
x
>=
6
;
y
++
)
{
}
bed_level
[
x
][
y
]
=
0.0
;
}
if
((
equalBC
==
true
)
and
(
equalAB
==
false
)
and
(
equalCA
==
false
))
{
//Tower A radius error .. adjust it
SERIAL_ECHOLN
(
"TowerA Radius error - adjusting"
);
if
(
adj_RadiusA
==
0
)
{
if
(
bed_level_x
<
bed_level_ox
)
adj_RadiusA
=
0.5
;
if
(
bed_level_x
>
bed_level_ox
)
adj_RadiusA
=
-
0.5
;
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"adj_RadiusA set to "
,
adj_RadiusA
);
SERIAL_ECHOLN
(
""
);
#endif
}
}
if
((
equalCA
==
true
)
and
(
equalAB
==
false
)
and
(
equalBC
==
false
))
{
//Tower B radius error .. adjust it
SERIAL_ECHOLN
(
"TowerB Radius error - adjusting"
);
if
(
adj_RadiusB
==
0
)
{
if
(
bed_level_y
<
bed_level_oy
)
adj_RadiusB
=
0.5
;
if
(
bed_level_y
>
bed_level_oy
)
adj_RadiusB
=
-
0.5
;
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"adj_RadiusB set to "
,
adj_RadiusB
);
SERIAL_ECHOLN
(
""
);
#endif
}
}
if
(((
adj_r
>
0
)
and
(
bed_level_c
>
adj_r_target
))
or
((
adj_r
<
0
)
and
(
bed_level_c
<
adj_r_target
)))
{
//overshot target .. reverse & scale down
adj_r
=
-
(
adj_r
/
2
);
}
if
(((
adj_dr
>
0
)
and
(
adj_dr_target
>
adj_r_target
))
or
((
adj_dr
<
0
)
and
(
adj_dr_target
<
adj_r_target
)))
{
//overshot target .. reverse & scale down
adj_dr
=
-
(
adj_dr
/
2
);
}
//Tower radius overshot targets?
if
(((
adj_RadiusA
>
0
)
and
(
bed_level_x
>
bed_level_ox
))
or
((
adj_RadiusA
<
0
)
and
(
bed_level_x
<
bed_level_ox
)))
adj_RadiusA
=
-
(
adj_RadiusA
/
2
);
if
(((
adj_RadiusB
>
0
)
and
(
bed_level_y
>
bed_level_oy
))
or
((
adj_RadiusB
<
0
)
and
(
bed_level_y
<
bed_level_oy
)))
adj_RadiusB
=
-
(
adj_RadiusB
/
2
);
if
(((
adj_RadiusC
>
0
)
and
(
bed_level_z
>
bed_level_oz
))
or
((
adj_RadiusC
<
0
)
and
(
bed_level_z
<
bed_level_oz
)))
adj_RadiusC
=
-
(
adj_RadiusC
/
2
);
//Delta radius adjustment complete?
if
((
bed_level_c
>=
(
adj_r_target
-
ac_prec
))
and
(
bed_level_c
<=
(
adj_r_target
+
ac_prec
)))
adj_r_done
=
true
;
else
adj_r_done
=
false
;
//Diag Rod adjustment complete?
if
((
adj_dr_target
>=
(
adj_r_target
-
ac_prec
))
and
(
adj_dr_target
<=
(
adj_r_target
+
ac_prec
)))
adj_dr_done
=
true
;
else
adj_dr_done
=
false
;
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"c: "
,
bed_level_c
);
SERIAL_ECHOPAIR
(
" x: "
,
bed_level_x
);
SERIAL_ECHOPAIR
(
" y: "
,
bed_level_y
);
SERIAL_ECHOPAIR
(
" z: "
,
bed_level_z
);
SERIAL_ECHOPAIR
(
" ox: "
,
bed_level_ox
);
SERIAL_ECHOPAIR
(
" oy: "
,
bed_level_oy
);
SERIAL_ECHOPAIR
(
" oz: "
,
bed_level_oz
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHO
(
"radius:"
);
SERIAL_PROTOCOL_F
(
delta_radius
,
4
);
SERIAL_ECHO
(
" diagrod:"
);
SERIAL_PROTOCOL_F
(
delta_diagonal_rod
,
4
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHO
(
"Radius Adj Complete: "
);
if
(
adj_r_done
==
true
)
SERIAL_ECHO
(
"Yes"
);
else
SERIAL_ECHO
(
"No"
);
SERIAL_ECHO
(
" DiagRod Adj Complete: "
);
if
(
adj_dr_done
==
true
)
SERIAL_ECHO
(
"Yes"
);
else
SERIAL_ECHO
(
"No"
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"RadiusA Error: "
,
radiusErrorA
);
SERIAL_ECHOPAIR
(
" (adjust: "
,
adj_RadiusA
);
SERIAL_ECHOLN
(
")"
);
SERIAL_ECHOPAIR
(
"RadiusB Error: "
,
radiusErrorB
);
SERIAL_ECHOPAIR
(
" (adjust: "
,
adj_RadiusB
);
SERIAL_ECHOLN
(
")"
);
SERIAL_ECHOPAIR
(
"RadiusC Error: "
,
radiusErrorC
);
SERIAL_ECHOPAIR
(
" (adjust: "
,
adj_RadiusC
);
SERIAL_ECHOLN
(
")"
);
SERIAL_ECHOPAIR
(
"DeltaAlphaA: "
,
adj_AlphaA
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"DeltaAlphaB: "
,
adj_AlphaB
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"DeltaAlphaC: "
,
adj_AlphaC
);
SERIAL_ECHOLN
(
""
);
#endif
}
while
(((
adj_r_done
==
false
)
or
(
adj_dr_done
=
false
))
and
(
loopcount
<
iterations
));
}
else
{
SERIAL_ECHOLN
(
"Delta Geometry: OK"
);
}
}
}
}
}
}
home_delta_axis
();
if
(
loopcount
<
iterations
)
{
deploy_z_probe
();
home_delta_axis
();
//Probe all points
//probe bed and display report
bed_probe_all
();
bed_probe_all
();
calibration_report
();
//Show calibration report
//Check to see if autocal is complete to within limits..
calibration_report
();
if
(
adj_dr_allowed
==
true
)
{
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
if
(
code_seen
(
'A'
))
{
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
iterations
=
100
;
//Maximum number of iterations
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
int
loopcount
=
1
;
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
)
float
adj_r_target
,
adj_dr_target
;
and
(
bed_level_ox
>=
-
ac_prec
)
and
(
bed_level_ox
<=
ac_prec
)
float
adj_r_target_delta
=
0
,
adj_dr_target_delta
=
0
;
and
(
bed_level_oy
>=
-
ac_prec
)
and
(
bed_level_oy
<=
ac_prec
)
float
adj_AlphaA
,
adj_AlphaB
,
adj_AlphaC
;
and
(
bed_level_oz
>=
-
ac_prec
)
and
(
bed_level_oz
<=
ac_prec
))
loopcount
=
iterations
;
float
adj_RadiusA
,
adj_RadiusB
,
adj_RadiusC
;
}
float
radiusErrorA
,
radiusErrorB
,
radiusErrorC
;
else
{
float
adj_r
=
0
,
adj_dr
=
0
;
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
boolean
equalAB
,
equalBC
,
equalCA
;
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
boolean
adj_r_done
,
adj_dr_done
,
adj_tower_done
;
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
boolean
adj_dr_allowed
=
true
;
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
))
loopcount
=
iterations
;
float
h_endstop
=
-
100
,
l_endstop
=
100
;
float
probe_error
,
ftemp
;
if
(
code_seen
(
'D'
))
{
delta_diagonal_rod
=
code_value
();
adj_dr_allowed
=
false
;
SERIAL_ECHOPAIR
(
"Using diagional rod length: "
,
delta_diagonal_rod
);
SERIAL_ECHOLN
(
"mm (will not be adjusted)"
);
}
//Check that endstops are within limits
if
(
bed_level_x
+
endstop_adj
[
0
]
>
h_endstop
)
h_endstop
=
bed_level_x
+
endstop_adj
[
0
];
if
(
bed_level_x
+
endstop_adj
[
0
]
<
l_endstop
)
l_endstop
=
bed_level_x
+
endstop_adj
[
0
];
if
(
bed_level_y
+
endstop_adj
[
1
]
>
h_endstop
)
h_endstop
=
bed_level_y
+
endstop_adj
[
1
];
if
(
bed_level_y
+
endstop_adj
[
1
]
<
l_endstop
)
l_endstop
=
bed_level_y
+
endstop_adj
[
1
];
if
(
bed_level_z
+
endstop_adj
[
2
]
>
h_endstop
)
h_endstop
=
bed_level_z
+
endstop_adj
[
2
];
if
(
bed_level_z
+
endstop_adj
[
2
]
<
l_endstop
)
l_endstop
=
bed_level_z
+
endstop_adj
[
2
];
if
(
h_endstop
-
l_endstop
>
3
)
{
SERIAL_ECHOLN
(
"The position of the endstop switches on this printer are not within limits"
);
SERIAL_ECHOLN
(
"Adjust endstop switches so that they are within 3mm Z-height of each other"
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"Current Endstop Positions - X: "
,
bed_level_x
+
endstop_adj
[
0
]);
SERIAL_ECHOPAIR
(
" Y: "
,
bed_level_y
+
endstop_adj
[
1
]);
SERIAL_ECHOPAIR
(
" Z: "
,
bed_level_z
+
endstop_adj
[
2
]);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOLN
(
"Autocalibration aborted"
);
retract_z_probe
();
//Restore saved variables
feedrate
=
saved_feedrate
;
feedmultiply
=
saved_feedmultiply
;
break
;
}
}
}
loopcount
++
;
}
while
(
loopcount
<
iterations
);
SERIAL_ECHOLN
(
"Auto Calibration Complete"
);
LCD_MESSAGEPGM
(
"Complete"
);
SERIAL_ECHOLN
(
"Issue M500 Command to save calibration settings to EPROM (if enabled)"
);
/*
if ((abs(delta_diagonal_rod - saved_delta_diagonal_rod) > 1) and (adj_dr_allowed == true)) {
SERIAL_ECHOLN("");
SERIAL_ECHOPAIR("WARNING: The length of diagonal rods specified (", saved_delta_diagonal_rod);
SERIAL_ECHOLN(" mm) appears to be incorrect");
SERIAL_ECHOLN("If you have measured your rods and you believe that this value is correct, this could indicate");
SERIAL_ECHOLN("excessive twisting movement of carriages and/or loose screws/joints on carriages or end effector");
}
*/
}
if
(
code_seen
(
'D'
))
{
retract_z_probe
();
//Fix diagonal rod at specified length (do not adjust)
delta_diagonal_rod
=
code_value
();
adj_dr_allowed
=
false
;
}
do
{
//Restore saved variables
SERIAL_ECHO
(
"Iteration: "
);
feedrate
=
saved_feedrate
;
SERIAL_ECHO
(
loopcount
);
feedmultiply
=
saved_feedmultiply
;
SERIAL_ECHOLN
(
""
);
}
#endif // DELTA
if
((
bed_level_c
>
3
)
or
(
bed_level_c
<
-
3
))
{
//Build height is not set correctly ..
max_pos
[
Z_AXIS
]
-=
bed_level_c
+
2
;
set_delta_constants
();
SERIAL_ECHOPAIR
(
"Adjusting Z-Height to: "
,
max_pos
[
Z_AXIS
]);
SERIAL_ECHOLN
(
" mm.."
);
}
else
{
if
((
bed_level_x
<
-
ac_prec
)
or
(
bed_level_x
>
ac_prec
)
or
(
bed_level_y
<
-
ac_prec
)
or
(
bed_level_y
>
ac_prec
)
or
(
bed_level_z
<
-
ac_prec
)
or
(
bed_level_z
>
ac_prec
))
{
//Endstops req adjustment
SERIAL_ECHOLN
(
"Adjusting Endstops.."
);
endstop_adj
[
0
]
+=
bed_level_x
/
1.05
;
endstop_adj
[
1
]
+=
bed_level_y
/
1.05
;
endstop_adj
[
2
]
+=
bed_level_z
/
1.05
;
//Check that no endstop adj values are > 0 (not allowed).. if they are, reduce the build height to compensate.
h_endstop
=
0
;
for
(
int
x
=
0
;
x
<
3
;
x
++
)
{
if
(
endstop_adj
[
x
]
>
h_endstop
)
h_endstop
=
endstop_adj
[
x
];
}
if
(
h_endstop
>
0
)
{
//Reduce build height and adjust endstops
for
(
int
x
=
0
;
x
<
3
;
x
++
)
{
endstop_adj
[
x
]
-=
h_endstop
+
2
;
}
max_pos
[
Z_AXIS
]
-=
h_endstop
+
2
;
set_delta_constants
();
SERIAL_ECHOPAIR
(
"Adjusting Z-Height to: "
,
max_pos
[
Z_AXIS
]);
SERIAL_ECHOLN
(
" mm.."
);
}
}
else
{
SERIAL_ECHOLN
(
"Endstops: OK"
);
adj_r_target
=
(
bed_level_x
+
bed_level_y
+
bed_level_z
)
/
3
;
/**
adj_dr_target
=
(
bed_level_ox
+
bed_level_oy
+
bed_level_oz
)
/
3
;
* G60: Store in memory actual position
*/
void
gcode_G60
()
{
lastpos
[
X_AXIS
]
=
current_position
[
X_AXIS
];
lastpos
[
Y_AXIS
]
=
current_position
[
Y_AXIS
];
lastpos
[
Z_AXIS
]
=
current_position
[
Z_AXIS
];
lastpos
[
E_AXIS
]
=
current_position
[
E_AXIS
];
//SERIAL_ECHOPAIR(" Lastpos X: ", lastpos[X_AXIS]);
//SERIAL_ECHOPAIR(" Lastpos Y: ", lastpos[Y_AXIS]);
//SERIAL_ECHOPAIR(" Lastpos Z: ", lastpos[Z_AXIS]);
//SERIAL_ECHOPAIR(" Lastpos E: ", lastpos[E_AXIS]);
//SERIAL_ECHOLN("");
}
//Determine which parameters require adjustment
/**
if
((
bed_level_c
>=
adj_r_target
-
ac_prec
)
and
(
bed_level_c
<=
adj_r_target
+
ac_prec
))
adj_r_done
=
true
;
* G61: move to X Y Z in memory
else
adj_r_done
=
false
;
*/
if
((
adj_dr_target
>=
adj_r_target
-
ac_prec
)
and
(
adj_dr_target
<=
adj_r_target
+
ac_prec
))
adj_dr_done
=
true
;
void
gcode_G61
()
{
else
adj_dr_done
=
false
;
for
(
int8_t
i
=
0
;
i
<
NUM_AXIS
;
i
++
)
{
if
((
bed_level_x
!=
bed_level_ox
)
or
(
bed_level_y
!=
bed_level_oy
)
or
(
bed_level_z
!=
bed_level_oz
))
adj_tower_done
=
false
;
if
(
code_seen
(
axis_codes
[
i
]))
{
else
adj_tower_done
=
true
;
destination
[
i
]
=
(
float
)
code_value
()
+
lastpos
[
i
];
if
((
adj_r_done
==
false
)
or
(
adj_dr_done
==
false
)
or
(
adj_tower_done
==
false
))
{
}
//delta geometry adjustment required
else
{
SERIAL_ECHOLN
(
"Adjusting Delta Geometry.."
);
destination
[
i
]
=
current_position
[
i
];
}
//set inital direction and magnitude for delta radius & diagonal rod adjustment
}
if
(
adj_r
==
0
)
{
//SERIAL_ECHOPAIR(" Move to X: ", destination[X_AXIS]);
if
(
adj_r_target
>
bed_level_c
)
adj_r
=
1
;
//SERIAL_ECHOPAIR(" Move to Y: ", destination[Y_AXIS]);
else
adj_r
=
-
1
;
//SERIAL_ECHOPAIR(" Move to Z: ", destination[Z_AXIS]);
}
//SERIAL_ECHOPAIR(" Move to E: ", destination[E_AXIS]);
//SERIAL_ECHOLN("");
if
(
adj_dr
==
0
)
{
if
(
code_seen
(
'F'
)
)
{
if
(
adj_r_target
>
adj_dr_target
)
adj_dr
=
1
;
next_feedrate
=
code_value
();
else
adj_dr
=
-
1
;
if
(
next_feedrate
>
0.0
)
feedrate
=
next_feedrate
;
}
}
//Don't adjust tower positions on first iteration
//finish moves
adj_AlphaA
=
adj_AlphaB
=
adj_AlphaC
=
0
;
prepare_move
();
adj_RadiusA
=
adj_RadiusB
=
adj_RadiusC
=
0
;
}
do
{
/**
//Apply adjustments
* G92: Set current position to given X Y Z E
if
(
adj_r_done
==
false
)
{
*/
SERIAL_ECHOPAIR
(
"Adjusting Delta Radius ("
,
delta_radius
);
void
gcode_G92
()
{
SERIAL_ECHOPAIR
(
" -> "
,
delta_radius
+
adj_r
);
if
(
!
code_seen
(
axis_codes
[
E_AXIS
]))
SERIAL_ECHOLN
(
")"
);
st_synchronize
();
delta_radius
+=
adj_r
;
}
if
(
adj_dr_allowed
==
false
)
adj_dr_done
=
true
;
for
(
int
i
=
0
;
i
<
NUM_AXIS
;
i
++
)
{
if
(
adj_dr_done
==
false
)
{
if
(
code_seen
(
axis_codes
[
i
]))
{
SERIAL_ECHOPAIR
(
"Adjusting Diag Rod Length ("
,
delta_diagonal_rod
);
if
(
i
==
E_AXIS
)
{
SERIAL_ECHOPAIR
(
" -> "
,
delta_diagonal_rod
+
adj_dr
);
current_position
[
i
]
=
code_value
();
SERIAL_ECHOLN
(
")"
);
plan_set_e_position
(
current_position
[
E_AXIS
]);
delta_diagonal_rod
+=
adj_dr
;
}
}
else
{
current_position
[
i
]
=
code_value
()
+
#ifdef SCARA
((
i
!=
X_AXIS
&&
i
!=
Y_AXIS
)
?
add_homing
[
i
]
:
0
)
#else
add_homing
[
i
]
#endif
;
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
}
}
}
}
tower_adj
[
0
]
-=
adj_AlphaA
;
tower_adj
[
1
]
-=
adj_AlphaB
;
tower_adj
[
2
]
-=
adj_AlphaC
;
tower_adj
[
3
]
+=
adj_RadiusA
;
tower_adj
[
4
]
+=
adj_RadiusB
;
tower_adj
[
5
]
+=
adj_RadiusC
;
set_delta_constants
();
bed_probe_all
();
calibration_report
();
//Check to see if autocal is complete to within limits..
if
(
adj_dr_allowed
==
true
)
{
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
)
and
(
bed_level_ox
>=
-
ac_prec
)
and
(
bed_level_ox
<=
ac_prec
)
and
(
bed_level_oy
>=
-
ac_prec
)
and
(
bed_level_oy
<=
ac_prec
)
and
(
bed_level_oz
>=
-
ac_prec
)
and
(
bed_level_oz
<=
ac_prec
))
loopcount
=
iterations
;
}
else
{
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
))
loopcount
=
iterations
;
}
//set delta radius and diag rod targets
/**
adj_r_target
=
(
bed_level_x
+
bed_level_y
+
bed_level_z
)
/
3
;
* Process Commands and dispatch them to handlers
adj_dr_target
=
(
bed_level_ox
+
bed_level_oy
+
bed_level_oz
)
/
3
;
*/
void
process_commands
()
{
//set Tower position adjustment values
unsigned
long
codenum
;
//throw away variable
adj_AlphaA
=
bed_level_oy
-
bed_level_oz
;
char
*
starpos
=
NULL
;
adj_AlphaB
=
bed_level_oz
-
bed_level_ox
;
adj_AlphaC
=
bed_level_ox
-
bed_level_oy
;
//set tower radius errors
radiusErrorA
=
bed_level_x
-
bed_level_ox
;
radiusErrorB
=
bed_level_y
-
bed_level_oy
;
radiusErrorC
=
bed_level_z
-
bed_level_oz
;
if
((
radiusErrorA
>=
(
radiusErrorB
-
0.02
))
and
(
radiusErrorA
<=
(
radiusErrorB
+
0.02
)))
equalAB
=
true
;
else
equalAB
=
false
;
if
((
radiusErrorB
>=
(
radiusErrorC
-
0.02
))
and
(
radiusErrorB
<=
(
radiusErrorC
+
0.02
)))
equalBC
=
true
;
else
equalBC
=
false
;
if
((
radiusErrorC
>=
(
radiusErrorA
-
0.02
))
and
(
radiusErrorC
<=
(
radiusErrorA
+
0.02
)))
equalCA
=
true
;
else
equalCA
=
false
;
#ifdef DEBUG_MESSAGES
if
(
equalAB
==
true
)
{
SERIAL_ECHOPAIR
(
"Tower AB Equal (A="
,
radiusErrorA
);
SERIAL_ECHOPAIR
(
" B="
,
radiusErrorB
);
SERIAL_ECHOLN
(
")"
);
}
else
SERIAL_ECHOLN
(
"equalAB=false"
);
if
(
equalBC
==
true
)
{
SERIAL_ECHOPAIR
(
"Tower BC Equal (B="
,
radiusErrorB
);
SERIAL_ECHOPAIR
(
" C="
,
radiusErrorC
);
SERIAL_ECHOLN
(
")"
);
}
else
SERIAL_ECHOLN
(
"equalBC=false"
);
if
(
equalCA
==
true
)
{
SERIAL_ECHOPAIR
(
"Tower CA Equal (C="
,
radiusErrorC
);
SERIAL_ECHOPAIR
(
" A="
,
radiusErrorA
);
SERIAL_ECHOLN
(
")"
);
}
else
SERIAL_ECHOLN
(
"equalCA=false"
);
#endif // DEBUG_MESSAGES
if
((
equalAB
==
true
)
and
(
equalBC
==
true
)
and
(
equalCA
==
true
))
{
// all tower radius out by the same amount (within 0.02) - allow adjustment with delta rod length
#ifdef DEBUG_MESSAGES
SERIAL_ECHOLN
(
"All tower radius errors equal"
);
#endif
adj_RadiusA
=
adj_RadiusB
=
adj_RadiusC
=
0
;
}
if
((
equalAB
==
true
)
and
(
equalBC
==
false
)
and
(
equalCA
==
false
))
{
if
(
code_seen
(
'G'
))
{
//Tower C radius error.. adjust it
SERIAL_ECHOLN
(
"TowerC Radius error - adjusting"
);
if
(
adj_RadiusC
==
0
)
{
if
(
bed_level_z
<
bed_level_oz
)
adj_RadiusC
=
0.5
;
if
(
bed_level_z
>
bed_level_oz
)
adj_RadiusC
=
-
0.5
;
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"adj_RadiusC set to "
,
adj_RadiusC
);
SERIAL_ECHOLN
(
""
);
#endif
}
}
if
((
equalBC
==
true
)
and
(
equalAB
==
false
)
and
(
equalCA
==
false
))
{
//Tower A radius error .. adjust it
SERIAL_ECHOLN
(
"TowerA Radius error - adjusting"
);
if
(
adj_RadiusA
==
0
)
{
if
(
bed_level_x
<
bed_level_ox
)
adj_RadiusA
=
0.5
;
if
(
bed_level_x
>
bed_level_ox
)
adj_RadiusA
=
-
0.5
;
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"adj_RadiusA set to "
,
adj_RadiusA
);
SERIAL_ECHOLN
(
""
);
#endif
}
}
if
((
equalCA
==
true
)
and
(
equalAB
==
false
)
and
(
equalBC
==
false
))
{
//Tower B radius error .. adjust it
SERIAL_ECHOLN
(
"TowerB Radius error - adjusting"
);
if
(
adj_RadiusB
==
0
)
{
if
(
bed_level_y
<
bed_level_oy
)
adj_RadiusB
=
0.5
;
if
(
bed_level_y
>
bed_level_oy
)
adj_RadiusB
=
-
0.5
;
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"adj_RadiusB set to "
,
adj_RadiusB
);
SERIAL_ECHOLN
(
""
);
#endif
}
}
if
(((
adj_r
>
0
)
and
(
bed_level_c
>
adj_r_target
))
or
((
adj_r
<
0
)
and
(
bed_level_c
<
adj_r_target
)))
{
switch
((
int
)
code_value
())
{
//overshot target .. reverse & scale down
adj_r
=
-
(
adj_r
/
2
);
}
if
(((
adj_dr
>
0
)
and
(
adj_dr_target
>
adj_r_target
))
or
((
adj_dr
<
0
)
and
(
adj_dr_target
<
adj_r_target
)))
{
// G0 -> G1
//overshot target .. reverse & scale down
case
0
:
adj_dr
=
-
(
adj_dr
/
2
);
case
1
:
}
gcode_G0_G1
();
break
;
//Tower radius overshot targets?
// G2, G3
if
(((
adj_RadiusA
>
0
)
and
(
bed_level_x
>
bed_level_ox
))
or
((
adj_RadiusA
<
0
)
and
(
bed_level_x
<
bed_level_ox
)))
adj_RadiusA
=
-
(
adj_RadiusA
/
2
);
#ifndef SCARA
if
(((
adj_RadiusB
>
0
)
and
(
bed_level_y
>
bed_level_oy
))
or
((
adj_RadiusB
<
0
)
and
(
bed_level_y
<
bed_level_oy
)))
adj_RadiusB
=
-
(
adj_RadiusB
/
2
);
case
2
:
// G2 - CW ARC
if
(((
adj_RadiusC
>
0
)
and
(
bed_level_z
>
bed_level_oz
))
or
((
adj_RadiusC
<
0
)
and
(
bed_level_z
<
bed_level_oz
)))
adj_RadiusC
=
-
(
adj_RadiusC
/
2
);
gcode_G2_G3
(
true
);
break
;
//Delta radius adjustment complete?
case
3
:
// G3 - CCW ARC
if
((
bed_level_c
>=
(
adj_r_target
-
ac_prec
))
and
(
bed_level_c
<=
(
adj_r_target
+
ac_prec
)))
adj_r_done
=
true
;
gcode_G2_G3
(
false
);
else
adj_r_done
=
false
;
break
;
#endif
//Diag Rod adjustment complete?
if
((
adj_dr_target
>=
(
adj_r_target
-
ac_prec
))
and
(
adj_dr_target
<=
(
adj_r_target
+
ac_prec
)))
adj_dr_done
=
true
;
else
adj_dr_done
=
false
;
#ifdef DEBUG_MESSAGES
SERIAL_ECHOPAIR
(
"c: "
,
bed_level_c
);
SERIAL_ECHOPAIR
(
" x: "
,
bed_level_x
);
SERIAL_ECHOPAIR
(
" y: "
,
bed_level_y
);
SERIAL_ECHOPAIR
(
" z: "
,
bed_level_z
);
SERIAL_ECHOPAIR
(
" ox: "
,
bed_level_ox
);
SERIAL_ECHOPAIR
(
" oy: "
,
bed_level_oy
);
SERIAL_ECHOPAIR
(
" oz: "
,
bed_level_oz
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHO
(
"radius:"
);
SERIAL_PROTOCOL_F
(
delta_radius
,
4
);
SERIAL_ECHO
(
" diagrod:"
);
SERIAL_PROTOCOL_F
(
delta_diagonal_rod
,
4
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHO
(
"Radius Adj Complete: "
);
if
(
adj_r_done
==
true
)
SERIAL_ECHO
(
"Yes"
);
else
SERIAL_ECHO
(
"No"
);
SERIAL_ECHO
(
" DiagRod Adj Complete: "
);
if
(
adj_dr_done
==
true
)
SERIAL_ECHO
(
"Yes"
);
else
SERIAL_ECHO
(
"No"
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"RadiusA Error: "
,
radiusErrorA
);
SERIAL_ECHOPAIR
(
" (adjust: "
,
adj_RadiusA
);
SERIAL_ECHOLN
(
")"
);
SERIAL_ECHOPAIR
(
"RadiusB Error: "
,
radiusErrorB
);
SERIAL_ECHOPAIR
(
" (adjust: "
,
adj_RadiusB
);
SERIAL_ECHOLN
(
")"
);
SERIAL_ECHOPAIR
(
"RadiusC Error: "
,
radiusErrorC
);
SERIAL_ECHOPAIR
(
" (adjust: "
,
adj_RadiusC
);
SERIAL_ECHOLN
(
")"
);
SERIAL_ECHOPAIR
(
"DeltaAlphaA: "
,
adj_AlphaA
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"DeltaAlphaB: "
,
adj_AlphaB
);
SERIAL_ECHOLN
(
""
);
SERIAL_ECHOPAIR
(
"DeltaAlphaC: "
,
adj_AlphaC
);
SERIAL_ECHOLN
(
""
);
#endif
}
// G4 Dwell
while
(((
adj_r_done
==
false
)
or
(
adj_dr_done
=
false
))
and
(
loopcount
<
iterations
));
case
4
:
}
gcode_G4
();
else
{
break
;
SERIAL_ECHOLN
(
"Delta Geometry: OK"
);
}
}
}
if
(
loopcount
<
iterations
)
{
#ifdef FWRETRACT
home_delta_axis
();
//probe bed and display report
bed_probe_all
();
calibration_report
();
//Check to see if autocal is complete to within limits..
if
(
adj_dr_allowed
==
true
)
{
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
)
and
(
bed_level_ox
>=
-
ac_prec
)
and
(
bed_level_ox
<=
ac_prec
)
and
(
bed_level_oy
>=
-
ac_prec
)
and
(
bed_level_oy
<=
ac_prec
)
and
(
bed_level_oz
>=
-
ac_prec
)
and
(
bed_level_oz
<=
ac_prec
))
loopcount
=
iterations
;
}
else
{
if
((
bed_level_x
>=
-
ac_prec
)
and
(
bed_level_x
<=
ac_prec
)
and
(
bed_level_y
>=
-
ac_prec
)
and
(
bed_level_y
<=
ac_prec
)
and
(
bed_level_z
>=
-
ac_prec
)
and
(
bed_level_z
<=
ac_prec
)
and
(
bed_level_c
>=
-
ac_prec
)
and
(
bed_level_c
<=
ac_prec
))
loopcount
=
iterations
;
}
}
loopcount
++
;
case
10
:
// G10: retract
}
gcode_G10_G11
(
true
);
while
(
loopcount
<
iterations
);
break
;
SERIAL_ECHOLN
(
"Auto Calibration Complete"
);
LCD_MESSAGEPGM
(
"Complete"
);
SERIAL_ECHOLN
(
"Issue M500 Command to save calibration settings to EPROM (if enabled)"
);
/*
if ((abs(delta_diagonal_rod - saved_delta_diagonal_rod) > 1) and (adj_dr_allowed == true)) {
SERIAL_ECHOLN("");
SERIAL_ECHOPAIR("WARNING: The length of diagonal rods specified (", saved_delta_diagonal_rod);
SERIAL_ECHOLN(" mm) appears to be incorrect");
SERIAL_ECHOLN("If you have measured your rods and you believe that this value is correct, this could indicate");
SERIAL_ECHOLN("excessive twisting movement of carriages and/or loose screws/joints on carriages or end effector");
}
*/
}
retract_z_probe
();
case
11
:
// G11: retract_recover
gcode_G10_G11
(
false
);
break
;
//Restore saved variables
#endif //FWRETRACT
feedrate
=
saved_feedrate
;
feedmultiply
=
saved_feedmultiply
;
case
28
:
// G28: Home all axes, one at a time
gcode_G28
();
break
;
break
;
#endif // DELTA
case
60
:
// G60 Memory actual position
#ifdef ENABLE_AUTO_BED_LEVELING
lastpos
[
X_AXIS
]
=
current_position
[
X_AXIS
];
case
29
:
// G29 Detailed Z-Probe, probes the bed at 3 or more points.
lastpos
[
Y_AXIS
]
=
current_position
[
Y_AXIS
];
gcode_G29
();
lastpos
[
Z_AXIS
]
=
current_position
[
Z_AXIS
];
break
;
lastpos
[
E_AXIS
]
=
current_position
[
E_AXIS
];
//SERIAL_ECHOPAIR(" Lastpos X: ", lastpos[X_AXIS]);
#ifndef Z_PROBE_SLED
//SERIAL_ECHOPAIR(" Lastpos Y: ", lastpos[Y_AXIS]);
case
30
:
// G30 Single Z Probe
//SERIAL_ECHOPAIR(" Lastpos Z: ", lastpos[Z_AXIS]);
gcode_G30
();
//SERIAL_ECHOPAIR(" Lastpos E: ", lastpos[E_AXIS]);
break
;
//SERIAL_ECHOLN("");
#else // Z_PROBE_SLED
case
31
:
// G31: dock the sled
dock_sled
(
true
);
break
;
case
32
:
// G32: undock the sled
dock_sled
(
false
);
break
;
#endif // Z_PROBE_SLED
#endif // ENABLE_AUTO_BED_LEVELING
#ifdef DELTA
case
29
:
// G29 Detailed Z-Probe, probes the bed at more points.
gcode_G29
();
break
;
case
30
:
// G30 Delta AutoCalibration
gcode_G30
();
break
;
#endif //DELTA
case
60
:
// G60 Store in memory actual position
gcode_G60
();
break
;
break
;
case
61
:
// G61 move to X Y Z in memory
case
61
:
// G61 move to X Y Z in memory
{
gcode_G61
();
for
(
int8_t
i
=
0
;
i
<
NUM_AXIS
;
i
++
)
{
if
(
code_seen
(
axis_codes
[
i
]))
{
destination
[
i
]
=
(
float
)
code_value
()
+
lastpos
[
i
];
}
else
{
destination
[
i
]
=
current_position
[
i
];
}
}
//SERIAL_ECHOPAIR(" Move to X: ", destination[X_AXIS]);
//SERIAL_ECHOPAIR(" Move to Y: ", destination[Y_AXIS]);
//SERIAL_ECHOPAIR(" Move to Z: ", destination[Z_AXIS]);
//SERIAL_ECHOPAIR(" Move to E: ", destination[E_AXIS]);
//SERIAL_ECHOLN("");
if
(
code_seen
(
'F'
))
{
next_feedrate
=
code_value
();
if
(
next_feedrate
>
0.0
)
feedrate
=
next_feedrate
;
}
//finish moves
prepare_move
();
}
break
;
break
;
case
90
:
// G90
case
90
:
// G90
relative_mode
=
false
;
relative_mode
=
false
;
...
@@ -3034,34 +3099,12 @@ void process_commands()
...
@@ -3034,34 +3099,12 @@ void process_commands()
relative_mode
=
true
;
relative_mode
=
true
;
break
;
break
;
case
92
:
// G92
case
92
:
// G92
if
(
!
code_seen
(
axis_codes
[
E_AXIS
]))
gcode_G92
();
st_synchronize
();
for
(
int8_t
i
=
0
;
i
<
NUM_AXIS
;
i
++
)
{
if
(
code_seen
(
axis_codes
[
i
]))
{
if
(
i
==
E_AXIS
)
{
current_position
[
i
]
=
code_value
();
plan_set_e_position
(
current_position
[
E_AXIS
]);
}
else
{
#ifdef SCARA
if
(
i
==
X_AXIS
||
i
==
Y_AXIS
)
{
current_position
[
i
]
=
code_value
();
}
else
{
current_position
[
i
]
=
code_value
()
+
add_homing
[
i
];
}
#else
current_position
[
i
]
=
code_value
()
+
add_homing
[
i
];
#endif
plan_set_position
(
current_position
[
X_AXIS
],
current_position
[
Y_AXIS
],
current_position
[
Z_AXIS
],
current_position
[
E_AXIS
]);
}
}
}
break
;
break
;
}
}
}
}
else
if
(
code_seen
(
'M'
)){
else
if
(
code_seen
(
'M'
))
{
switch
((
int
)
code_value
()){
switch
((
int
)
code_value
())
{
#ifdef ULTIPANEL
#ifdef ULTIPANEL
case
0
:
// M0 - Unconditional stop - Wait for user button press on LCD
case
0
:
// M0 - Unconditional stop - Wait for user button press on LCD
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment