Hard limits code minor updates.

- Fixed a bug that would not disable the steppers if a user issues a
system abort during a homing cycle.

- Updated the hard limit interrupt to be more correct and to issue a
shutdown for the right situations when the switch has been triggered.

- Added a status message to indicate to the user what happened and what
to do upon a hard limit trigger.
This commit is contained in:
Sonny Jeon 2012-10-18 21:29:07 -06:00
parent df5bb70b25
commit 39e11b696f
7 changed files with 26 additions and 17 deletions

View File

@ -46,9 +46,9 @@
#define X_LIMIT_BIT 1 // Uno Digital Pin 9
#define Y_LIMIT_BIT 2 // Uno Digital Pin 10
#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
#define LIMIT_INT PCIE0 // Pin change interrupt settings
#define LIMIT_INT_vect PCINT0_vect
#define LIMIT_PCMSK PCMSK0
#define LIMIT_INT PCIE0 // Pin change interrupt enable pin
#define LIMIT_INT_vect PCINT0_vect
#define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
#define SPINDLE_ENABLE_DDR DDRB
#define SPINDLE_ENABLE_PORT PORTB

View File

@ -39,27 +39,34 @@ void limits_init()
LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins
LIMIT_PORT |= (LIMIT_MASK); // Enable internal pull-up resistors. Normal high operation.
if bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE) {
MCUCR = (1<<ISC01) | (0<<ISC00); //1 0 triggers at a falling edge.
if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) {
LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt
PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt
}
}
// This is the Limit Pin Change Interrupt, which handles the hard limit feature. This is
// called when Grbl detects a falling edge on a limit pin.
// This is the Limit Pin Change Interrupt, which handles the hard limit feature.
// NOTE: Do not attach an e-stop to the limit pins, because this interrupt is disabled during
// homing cycles and will not respond correctly. Upon user request or need, there may be a
// special pinout for an e-stop, but it is generally recommended to just directly connect
// your e-stop switch to the Arduino reset pin, since it is the most correct way to do this.
ISR(LIMIT_INT_vect)
{
// Kill all processes upon hard limit event.
st_go_idle(); // Immediately stop stepper motion
spindle_stop(); // Stop spindle
sys.auto_start = false; // Disable auto cycle start.
sys.execute |= EXEC_ALARM;
// TODO: When Grbl system status is installed, update here to indicate loss of position.
// Only enter if the system alarm is not active.
if (bit_isfalse(sys.execute,EXEC_ALARM)) {
// Kill all processes upon hard limit event.
if ((LIMIT_PIN & LIMIT_MASK) ^ LIMIT_MASK) {
st_go_idle(); // Immediately stop stepper motion
spindle_stop(); // Stop spindle
sys.auto_start = false; // Disable auto cycle start.
sys.execute |= EXEC_ALARM;
// TODO: When Grbl system status is installed, update here to indicate loss of position.
}
// else {
// TODO: When leaving a switch, this interrupt can be activated upon detecting a pin
// change to high. If so, need to start a countdown timer to check the pin again after
// a debounce period to not falsely re-engage the alarm.
}
}

View File

@ -217,7 +217,7 @@ void mc_go_home()
if (bit_istrue(settings.homing_dir_mask,bit(Z_DIRECTION_BIT))) { z_dir = -1; }
mc_line(x_dir*settings.homing_pulloff, y_dir*settings.homing_pulloff,
z_dir*settings.homing_pulloff, settings.homing_feed_rate, false);
st_cycle_start(); // Nothing should be in the buffer except this motion.
st_cycle_start(); // Move it. Nothing should be in the buffer except this motion.
plan_synchronize(); // Make sure the motion completes.
gc_set_current_position(sys.position[X_AXIS],sys.position[Y_AXIS],sys.position[Z_AXIS]);
PCICR |= (1 << LIMIT_INT); // Re-enable hard limits.

View File

@ -80,8 +80,6 @@ typedef struct {
uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume.
uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings.
uint8_t alarm; // Alarm mode. Causes all functions to immediately cease until a system abort
// is issued by the user.
// uint8_t switches; // Switches state bitflag variable. For settings not governed by g-code.
int32_t position[3]; // Real-time machine (aka home) position vector in steps.

View File

@ -57,6 +57,8 @@ void protocol_status_message(int8_t status_code)
printPgmString(PSTR("Invalid command\r\n")); break;
case STATUS_SETTING_DISABLED:
printPgmString(PSTR("Grbl setting disabled\r\n")); break;
case STATUS_HARD_LIMIT:
printPgmString(PSTR("Limit triggered <Check and Reset>\r\n")); break;
default:
printInteger(status_code);
printPgmString(PSTR("\r\n"));
@ -141,6 +143,7 @@ void protocol_execute_runtime()
// System alarm. Something has gone wrong. Disable everything until system reset.
if (rt_exec & EXEC_ALARM) {
protocol_status_message(STATUS_HARD_LIMIT);
while (bit_isfalse(sys.execute,EXEC_RESET)) { sleep_mode(); }
bit_false(sys.execute,EXEC_ALARM);
}

View File

@ -29,6 +29,7 @@
#define STATUS_MODAL_GROUP_VIOLATION 5
#define STATUS_INVALID_COMMAND 6
#define STATUS_SETTING_DISABLED 7
#define STATUS_HARD_LIMIT 8
#define LINE_BUFFER_SIZE 50

View File

@ -166,7 +166,7 @@ ISR(USART_RX_vect)
case CMD_CYCLE_START: sys.execute |= EXEC_CYCLE_START; break; // Set as true
case CMD_FEED_HOLD: sys.execute |= EXEC_FEED_HOLD; break; // Set as true
case CMD_RESET:
sys.alarm |= EXEC_ALARM; // Set alarm to allow subsystem disable for certain settings.
sys.execute |= EXEC_ALARM; // Set alarm to allow subsystem disable for certain settings.
// TODO: When Grbl system status is installed, set position lost state if the cycle is active.