Homing and limit updates. Minor bug fixes.
- Updated new homing cycle to error out when a pull-off motion detects the limit is still active. - Created a limits_get_state() function to centralize it. It reports state as a bit-wise booleans according to axis numbering. - Updated the print uint8 functions. Generalized it to allow both base2 and base10 printouts, while allowing base2 prints with N_AXIS digits for limit state status reports. Doing this saved about 100bytes of flash as well. - Applied CoreXY status reporting bug fix by @phd0. Thanks!
This commit is contained in:
parent
e704862f11
commit
f85c481ded
@ -1,3 +1,84 @@
|
||||
----------------
|
||||
Date: 2015-05-22
|
||||
Author: Sonny Jeon
|
||||
Subject: Merge pull request #702 from ashelly/default-split
|
||||
|
||||
Moving defaults to individual files in subdirectory
|
||||
|
||||
----------------
|
||||
Date: 2015-05-22
|
||||
Author: ashelly
|
||||
Subject: Moving defaults to individual files in subdirectory
|
||||
|
||||
|
||||
----------------
|
||||
Date: 2015-05-22
|
||||
Author: Sonny Jeon
|
||||
Subject: Merge pull request #700 from ashelly/header-split
|
||||
|
||||
Header split
|
||||
|
||||
----------------
|
||||
Date: 2015-05-22
|
||||
Author: ashelly
|
||||
Subject: Fixing up comment blocks in headers
|
||||
|
||||
|
||||
----------------
|
||||
Date: 2015-05-22
|
||||
Author: ashelly
|
||||
Subject: Splitting Cpu map into separate files.
|
||||
|
||||
Makes comparison, addition of new ones easier
|
||||
|
||||
|
||||
----------------
|
||||
Date: 2015-05-17
|
||||
Author: Sonny Jeon
|
||||
Subject: Critical M0/2/30 fix. Homing updates.
|
||||
|
||||
- Critical fix for M0 program pause. Due to its recent change, it would
|
||||
cause Grbl to suspend but wouldn’t notify the user of why Grbl was not
|
||||
doing anything. The state would show IDLE and a cycle start would
|
||||
resume it. Grbl now enters a HOLD state to better indicate the state
|
||||
change.
|
||||
|
||||
- Critical fix for M2 and M30 program end. As with M0, the state
|
||||
previously would show IDLE while suspended. Grbl now does not suspend
|
||||
upon program end and leaves job control to the GUI. Grbl simply reports
|
||||
a `[Pgm End]` as a feedback message and resets certain g-code modes.
|
||||
|
||||
- M2/30 g-code reseting fix. Previously Grbl would soft-reset after an
|
||||
M2/30, but this was not complaint to the (linuxcnc) g-code standard. It
|
||||
simply resets [G1,G17,G90,G94,G40,G54,M5,M9,M48] and keeps all other
|
||||
modes the same.
|
||||
|
||||
- M0/M2/M30 check-mode fix. It now does not suspend the machine during
|
||||
check-mode.
|
||||
|
||||
- Minor bug fix related to commands similar to G90.1, but not G90.1,
|
||||
not reporting an unsupported command.
|
||||
|
||||
- Homing cycle refactoring. To help reduce the chance of users
|
||||
misunderstanding their limit switch wiring, Grbl only moves a short
|
||||
distance for the locate cycles only. In addition, the homing cycle
|
||||
pulls-off the limit switch by the pull-off distance to re-engage and
|
||||
locate home. This should improve its accuracy.
|
||||
|
||||
- HOMING_FORCE_ORIGIN now sets the origin to the pull-off location,
|
||||
rather than where the limit switch was triggered.
|
||||
|
||||
- Updated default junction deviation to 0.01mm. Recent tests showed
|
||||
that this improves Grbl’s cornering behavior a bit.
|
||||
|
||||
- Added the ShapeOko3 defaults.
|
||||
|
||||
- Added new feedback message `[Pgm End]` for M2/30 notification.
|
||||
|
||||
- Limit pin reporting is now a $10 status report option. Requested by
|
||||
OEMs to help simplify support troubleshooting.
|
||||
|
||||
|
||||
----------------
|
||||
Date: 2015-03-29
|
||||
Author: Sonny Jeon
|
||||
|
@ -26,7 +26,9 @@
|
||||
Ensure one and only one of these DEFAULTS_XXX values is defined in config.h */
|
||||
|
||||
#ifndef defaults_h
|
||||
// Don't #define defaults_h here, let the selected file do it. Prevents incuding more than one.
|
||||
|
||||
// Only define the DEFAULT_XXX with where to find the corresponding default_XXX.h file.
|
||||
// Don't #define defaults_h here, let the selected file do it. Prevents including more than one.
|
||||
|
||||
#ifdef DEFAULTS_GENERIC
|
||||
// Grbl generic default settings. Should work across different machines.
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
// Grbl versioning system
|
||||
#define GRBL_VERSION "0.9i"
|
||||
#define GRBL_VERSION_BUILD "20150516"
|
||||
#define GRBL_VERSION_BUILD "20150523"
|
||||
|
||||
// Define standard libraries used by Grbl.
|
||||
#include <avr/io.h>
|
||||
|
@ -55,6 +55,7 @@ void limits_init()
|
||||
}
|
||||
|
||||
|
||||
// Disables hard limits.
|
||||
void limits_disable()
|
||||
{
|
||||
LIMIT_PCMSK &= ~LIMIT_MASK; // Disable specific pins of the Pin Change Interrupt
|
||||
@ -62,6 +63,24 @@ void limits_disable()
|
||||
}
|
||||
|
||||
|
||||
// Returns limit state as a bit-wise uint8 variable. Each bit indicates an axis limit, where
|
||||
// triggered is 1 and not triggered is 0. Invert mask is applied. Axes are defined by their
|
||||
// number in bit position, i.e. Z_AXIS is (1<<2) or bit 2, and Y_AXIS is (1<<1) or bit 1.
|
||||
uint8_t limits_get_state()
|
||||
{
|
||||
uint8_t limit_state = 0;
|
||||
uint8_t pin = (LIMIT_PIN & LIMIT_MASK);
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; }
|
||||
if (pin) {
|
||||
uint8_t idx;
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
if (pin & get_limit_pin_mask(idx)) { limit_state |= (1 << idx); }
|
||||
}
|
||||
}
|
||||
return(limit_state);
|
||||
}
|
||||
|
||||
|
||||
// This is the Limit Pin Change Interrupt, which handles the hard limit feature. A bouncing
|
||||
// limit switch can cause a lot of problems, like false readings and multiple interrupt calls.
|
||||
// If a switch is triggered at all, something bad has happened and treat it as such, regardless
|
||||
@ -84,10 +103,8 @@ void limits_disable()
|
||||
if (sys.state != STATE_ALARM) {
|
||||
if (!(sys.rt_exec_alarm)) {
|
||||
#ifdef HARD_LIMIT_FORCE_STATE_CHECK
|
||||
uint8_t bits = (LIMIT_PIN & LIMIT_MASK);
|
||||
// Check limit pin state.
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
|
||||
if (bits) {
|
||||
if (limits_get_state()) {
|
||||
mc_reset(); // Initiate system kill.
|
||||
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event
|
||||
}
|
||||
@ -106,10 +123,8 @@ void limits_disable()
|
||||
WDTCSR &= ~(1<<WDIE); // Disable watchdog timer.
|
||||
if (sys.state != STATE_ALARM) { // Ignore if already in alarm state.
|
||||
if (!(sys.rt_exec_alarm)) {
|
||||
uint8_t bits = (LIMIT_PIN & LIMIT_MASK);
|
||||
// Check limit pin state.
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
|
||||
if (bits) {
|
||||
if (limits_get_state()) {
|
||||
mc_reset(); // Initiate system kill.
|
||||
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event
|
||||
}
|
||||
@ -118,7 +133,7 @@ void limits_disable()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Homes the specified cycle axes, sets the machine position, and performs a pull-off motion after
|
||||
// completing. Homing is a special motion case, which involves rapid uncontrolled stops to locate
|
||||
// the trigger point of the limit switches. The rapid stops are handled by a system level axis lock
|
||||
@ -132,13 +147,12 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
|
||||
// Initialize
|
||||
uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
|
||||
uint8_t limit_pin[N_AXIS], step_pin[N_AXIS];
|
||||
uint8_t step_pin[N_AXIS];
|
||||
float target[N_AXIS];
|
||||
float max_travel = 0.0;
|
||||
uint8_t idx;
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
// Initialize limit and step pin masks
|
||||
limit_pin[idx] = get_limit_pin_mask(idx);
|
||||
// Initialize step pin masks
|
||||
step_pin[idx] = get_step_pin_mask(idx);
|
||||
#ifdef COREXY
|
||||
if ((idx==A_MOTOR)||(idx==B_MOTOR)) { step_pin[idx] = (get_step_pin_mask(X_AXIS)|get_step_pin_mask(Y_AXIS)); }
|
||||
@ -199,11 +213,10 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
do {
|
||||
if (approach) {
|
||||
// Check limit state. Lock out cycle axes when they change.
|
||||
limit_state = LIMIT_PIN;
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; }
|
||||
limit_state = limits_get_state();
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
if (axislock & step_pin[idx]) {
|
||||
if (limit_state & limit_pin[idx]) { axislock &= ~(step_pin[idx]); }
|
||||
if (limit_state & (1 << idx)) { axislock &= ~(step_pin[idx]); }
|
||||
}
|
||||
}
|
||||
sys.homing_axis_lock = axislock;
|
||||
@ -211,16 +224,18 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
|
||||
st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us.
|
||||
|
||||
// Exit routines: User abort homing and alarm upon safety door or no limit switch found.
|
||||
// No time to run protocol_execute_realtime() in this loop.
|
||||
// Exit routines: No time to run protocol_execute_realtime() in this loop.
|
||||
if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) {
|
||||
if ((sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) ||
|
||||
((approach) && (sys.rt_exec_state & EXEC_CYCLE_STOP))) {
|
||||
mc_reset();
|
||||
// Homing failure: Limit switches are still engaged after pull-off motion
|
||||
if ( (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) || // Safety door or reset issued
|
||||
(!approach && (limits_get_state() & cycle_mask)) || // Limit switch still engaged after pull-off motion
|
||||
( approach && (sys.rt_exec_state & EXEC_CYCLE_STOP)) ) { // Limit switch not found during approach.
|
||||
mc_reset(); // Stop motors, if they are running.
|
||||
protocol_execute_realtime();
|
||||
return;
|
||||
} else {
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP);
|
||||
// Pull-off motion complete. Disable CYCLE_STOP from executing.
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -245,7 +260,7 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
}
|
||||
|
||||
} while (n_cycle-- > 0);
|
||||
|
||||
|
||||
// The active cycle axes should now be homed and machine limits have been located. By
|
||||
// default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches
|
||||
// can be on either side of an axes, check and set axes machine zero appropriately. Also,
|
||||
@ -289,9 +304,8 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
}
|
||||
}
|
||||
plan_sync_position(); // Sync planner position to homed machine position.
|
||||
|
||||
// Set system state to homing before returning.
|
||||
sys.state = STATE_HOMING;
|
||||
|
||||
// sys.state = STATE_HOMING; // Ensure system state set as homing before returning.
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,8 +26,12 @@
|
||||
// Initialize the limits module
|
||||
void limits_init();
|
||||
|
||||
// Disables hard limits.
|
||||
void limits_disable();
|
||||
|
||||
// Returns limit state as a bit-wise uint8 variable.
|
||||
uint8_t limits_get_state();
|
||||
|
||||
// Perform one portion of the homing cycle based on the input settings.
|
||||
void limits_go_home(uint8_t cycle_mask);
|
||||
|
||||
|
@ -225,9 +225,7 @@ void mc_homing_cycle()
|
||||
// with machines with limits wired on both ends of travel to one limit pin.
|
||||
// TODO: Move the pin-specific LIMIT_PIN call to limits.c as a function.
|
||||
#ifdef LIMITS_TWO_SWITCHES_ON_AXES
|
||||
uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK);
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; }
|
||||
if (limit_state) {
|
||||
if (limits_get_state()) {
|
||||
mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
|
||||
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT));
|
||||
return;
|
||||
@ -256,7 +254,7 @@ void mc_homing_cycle()
|
||||
|
||||
// Gcode parser position was circumvented by the limits_go_home() routine, so sync position now.
|
||||
gc_sync_position();
|
||||
|
||||
|
||||
// If hard limits feature enabled, re-enable hard limits pin change register after homing cycle.
|
||||
limits_init();
|
||||
}
|
||||
|
71
grbl/print.c
71
grbl/print.c
@ -60,38 +60,36 @@ void printPgmString(const char *s)
|
||||
// }
|
||||
|
||||
|
||||
void print_uint8_base2(uint8_t n)
|
||||
// Prints an uint8 variable with base and number of desired digits.
|
||||
void print_unsigned_int8(uint8_t n, uint8_t base, uint8_t digits)
|
||||
{
|
||||
unsigned char buf[8];
|
||||
uint8_t i = 0;
|
||||
|
||||
for (; i < 8; i++) {
|
||||
buf[i] = n & 1;
|
||||
n >>= 1;
|
||||
}
|
||||
|
||||
for (; i > 0; i--)
|
||||
serial_write('0' + buf[i - 1]);
|
||||
}
|
||||
|
||||
|
||||
void print_uint8_base10(uint8_t n)
|
||||
{
|
||||
if (n == 0) {
|
||||
serial_write('0');
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char buf[3];
|
||||
unsigned char buf[digits];
|
||||
uint8_t i = 0;
|
||||
|
||||
while (n > 0) {
|
||||
buf[i++] = n % 10 + '0';
|
||||
n /= 10;
|
||||
for (; i < digits; i++) {
|
||||
buf[i] = n % base ;
|
||||
n /= base;
|
||||
}
|
||||
|
||||
for (; i > 0; i--)
|
||||
serial_write(buf[i - 1]);
|
||||
serial_write('0' + buf[i - 1]);
|
||||
}
|
||||
|
||||
|
||||
// Prints an uint8 variable in base 2.
|
||||
void print_uint8_base2(uint8_t n) {
|
||||
print_unsigned_int8(n,2,8);
|
||||
}
|
||||
|
||||
|
||||
// Prints an uint8 variable in base 10.
|
||||
void print_uint8_base10(uint8_t n)
|
||||
{
|
||||
uint8_t digits;
|
||||
if (n < 10) { digits = 1; }
|
||||
else if (n < 100) { digits = 2; }
|
||||
else { digits = 3; }
|
||||
print_unsigned_int8(n,10,digits);
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +117,7 @@ void printInteger(long n)
|
||||
{
|
||||
if (n < 0) {
|
||||
serial_write('-');
|
||||
print_uint32_base10((-n));
|
||||
print_uint32_base10(-n);
|
||||
} else {
|
||||
print_uint32_base10(n);
|
||||
}
|
||||
@ -194,12 +192,13 @@ void printFloat_RateValue(float n) {
|
||||
void printFloat_SettingValue(float n) { printFloat(n,N_DECIMAL_SETTINGVALUE); }
|
||||
|
||||
|
||||
// Debug tool to print free memory in bytes at the called point. Not used otherwise.
|
||||
void printFreeMemory()
|
||||
{
|
||||
extern int __heap_start, *__brkval;
|
||||
uint16_t free; // Up to 64k values.
|
||||
free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
printInteger((int32_t)free);
|
||||
printString(" ");
|
||||
}
|
||||
// Debug tool to print free memory in bytes at the called point.
|
||||
// NOTE: Keep commented unless using. Part of this function always gets compiled in.
|
||||
// void printFreeMemory()
|
||||
// {
|
||||
// extern int __heap_start, *__brkval;
|
||||
// uint16_t free; // Up to 64k values.
|
||||
// free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
// printInteger((int32_t)free);
|
||||
// printString(" ");
|
||||
// }
|
||||
|
@ -31,8 +31,13 @@ void printInteger(long n);
|
||||
|
||||
void print_uint32_base10(uint32_t n);
|
||||
|
||||
// Prints uint8 variable with base and number of desired digits.
|
||||
void print_unsigned_int8(uint8_t n, uint8_t base, uint8_t digits);
|
||||
|
||||
// Prints an uint8 variable in base 2.
|
||||
void print_uint8_base2(uint8_t n);
|
||||
|
||||
// Prints an uint8 variable in base 10.
|
||||
void print_uint8_base10(uint8_t n);
|
||||
|
||||
void printFloat(float n, uint8_t decimal_places);
|
||||
|
@ -496,10 +496,7 @@ void report_realtime_status()
|
||||
|
||||
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) {
|
||||
printPgmString(PSTR(",Lim:"));
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
if (LIMIT_PIN & get_limit_pin_mask(idx)) { printPgmString(PSTR("1")); }
|
||||
else { printPgmString(PSTR("0")); }
|
||||
}
|
||||
print_unsigned_int8(limits_get_state(),2,N_AXIS);
|
||||
}
|
||||
|
||||
#ifdef REPORT_CONTROL_PIN_STATE
|
||||
|
@ -252,8 +252,10 @@ float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx)
|
||||
#ifdef COREXY
|
||||
if (idx==A_MOTOR) {
|
||||
pos = 0.5*((steps[A_MOTOR] + steps[B_MOTOR])/settings.steps_per_mm[idx]);
|
||||
} else { // (idx==B_MOTOR)
|
||||
} else if (idx==B_MOTOR) {
|
||||
pos = 0.5*((steps[A_MOTOR] - steps[B_MOTOR])/settings.steps_per_mm[idx]);
|
||||
} else {
|
||||
pos = steps[idx]/settings.steps_per_mm[idx];
|
||||
}
|
||||
#else
|
||||
pos = steps[idx]/settings.steps_per_mm[idx];
|
||||
|
Loading…
Reference in New Issue
Block a user