1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-08-31 01:59:54 +02:00

Fixed some limit bugs. Homing works in some simple cases now.

This commit is contained in:
Mitch Bradley
2021-07-20 07:49:34 -10:00
parent 03ef840927
commit 43160b048a
6 changed files with 175 additions and 13 deletions

View File

@@ -197,7 +197,7 @@ static void limits_go_home(uint8_t cycle_mask, uint32_t n_locate_cycles) {
}
homing_rate = float(sqrt(homing_rate)); // Magnitude of homing rate vector
sys.homing_axis_lock = axislock;
config->_axes->release_all_motors();
// Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle.
pl_data->feed_rate = homing_rate;
@@ -209,8 +209,9 @@ static void limits_go_home(uint8_t cycle_mask, uint32_t n_locate_cycles) {
do {
if (approach) {
// Check limit state. Lock out cycle axes when they change.
bit_false(axislock, limits_check(axislock));
sys.homing_axis_lock = axislock;
uint32_t limitedAxes = limits_check(axislock);
config->_axes->stop_motors(limitedAxes);
bit_false(axislock, limitedAxes);
}
Stepper::prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us.

View File

@@ -79,7 +79,8 @@ namespace Machine {
// use this to tell all the motors what the current homing mode is
// They can use this to setup things like Stall
uint8_t Axes::set_homing_mode(uint8_t homing_mask, bool isHoming) {
uint32_t Axes::set_homing_mode(uint8_t homing_mask, bool isHoming) {
release_all_motors(); // On homing transitions, cancel all motor lockouts
uint8_t can_home = 0;
for (uint8_t axis = X_AXIS; axis < _numberAxis; axis++) {
@@ -103,7 +104,13 @@ namespace Machine {
return can_home;
}
void Axes::release_all_motors() { _motorLockoutMask = 0xffffffff; }
void Axes::stop_motors(uint32_t mask) { bit_false(_motorLockoutMask, mask); }
void IRAM_ATTR Axes::step(uint8_t step_mask, uint8_t dir_mask) {
// Do not step motors that are locked out during homing
step_mask &= _motorLockoutMask;
auto n_axis = _numberAxis;
//log_info("motors_set_direction_pins:0x%02X", onMask);

View File

@@ -31,6 +31,10 @@ namespace Machine {
bool _switchedStepper = false;
// During homing, this is used to stop stepping on motors that have
// reached their limit switches, by clearing bits in the mask.
uint32_t _motorLockoutMask = 0;
public:
Axes();
@@ -82,12 +86,16 @@ namespace Machine {
void init();
void read_settings(); // more like 'after read settings, before init'. Oh well...
// These are used during homing cycles.
// The return value is a bitmask of axes that can home
uint8_t set_homing_mode(uint8_t homing_mask, bool isHoming);
void set_disable(int axis, bool disable);
void set_disable(bool disable);
void step(uint8_t step_mask, uint8_t dir_mask);
void unstep();
uint32_t set_homing_mode(uint8_t homing_mask, bool isHoming);
void release_all_motors();
void stop_motors(uint32_t motor_mask);
void set_disable(int axis, bool disable);
void set_disable(bool disable);
void step(uint8_t step_mask, uint8_t dir_mask);
void unstep();
// Configuration helpers:
void group(Configuration::HandlerBase& handler) override;

View File

@@ -0,0 +1,114 @@
#include "LimitPin.h"
#include "Axes.h"
#include "MachineConfig.h" // config
#include "../NutsBolts.h" // bitnum_true etc
#include "../MotionControl.h" // mc_reset
#include "../Limits.h"
#include "../System.h" // sys_rt_exec_alarm
namespace Machine {
LimitPin::LimitPin(Pin& pin, int axis, int gang, int direction, bool& pHardLimits) :
_axis(axis), _gang(gang), _value(false), _pHardLimits(pHardLimits), _pin(pin) {
String sDir;
// Select one or two bitmask variables to receive the switch data
switch (direction) {
case 1:
_posLimits = &Axes::posLimitMask;
_negLimits = nullptr;
sDir = "Pos";
break;
case -1:
_posLimits = nullptr;
_negLimits = &Axes::negLimitMask;
sDir = "Neg";
break;
case 0:
_posLimits = &Axes::posLimitMask;
_negLimits = &Axes::negLimitMask;
sDir = "All";
break;
default: // invalid
_negLimits = nullptr;
_posLimits = nullptr;
_pHardLimits = false;
break;
}
// Set a bitmap with bits to represent the axis and which motors are affected,
// and construct a legend string like "Y Axis Limit" or "Y Axis Gang0 Limit".
// The bitmap looks like CBAZYXcbazyx where gang0 motors are in the lower
// bits and gang1 in the upper bits. If both gangs are affected, there is
// a bit set in both the upper and lower groups.
switch (gang) {
case 0:
_bitmask = 1; // Set bit as for x axis gang 0
_legend = " Gang0";
break;
case 1:
_bitmask = 1 << MAX_N_AXIS; // Set bit as for X axis gang 1
_legend = " Gang1";
break;
case -1: // Axis level switch - set both bits
_bitmask = (1 << MAX_N_AXIS) | 1;
_legend = "";
break;
default:
break;
}
_bitmask <<= axis; // Shift the bits into position
_legend = String(config->_axes->axisName(axis)) + " Axis" + _legend + " " + sDir + " Limit";
}
void IRAM_ATTR LimitPin::handleISR() {
bool pinState = _pin.read();
_value = _pin.read();
if (_value) {
if (_posLimits != nullptr) {
bit_true(*_posLimits, _bitmask);
}
if (_negLimits != nullptr) {
bit_true(*_negLimits, _bitmask);
}
} else {
if (_posLimits != nullptr) {
bit_false(*_posLimits, _bitmask);
}
if (_negLimits != nullptr) {
bit_false(*_negLimits, _bitmask);
}
}
if (sys.state != State::Alarm && sys.state != State::ConfigAlarm && sys.state != State::Homing) {
if (_pHardLimits && sys_rt_exec_alarm == ExecAlarm::None) {
#if 0
if (config->_softwareDebounceMs) {
// send a message to wakeup the task that rechecks the switches after a small delay
int evt;
xQueueSendFromISR(limit_sw_queue, &evt, NULL);
return;
}
#endif
// log_debug("Hard limits"); // This might not work from ISR context
mc_reset(); // Initiate system kill.
sys_rt_exec_alarm = ExecAlarm::HardLimit; // Indicate hard limit critical event
}
}
}
void LimitPin::init() {
if (_pin.undefined()) {
return;
}
bitnum_true(Axes::limitMask, _axis);
_pin.report(_legend.c_str());
auto attr = Pin::Attr::Input | Pin::Attr::ISR;
if (_pin.capabilities().has(Pins::PinCapabilities::PullUp)) {
attr = attr | Pin::Attr::PullUp;
}
_pin.setAttr(attr);
_pin.attachInterrupt<LimitPin, &LimitPin::handleISR>(this, CHANGE);
}
LimitPin::~LimitPin() { _pin.detachInterrupt(); }
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include "../Pin.h"
#include <esp_attr.h> // IRAM_ATTR
namespace Machine {
class LimitPin {
private:
int _axis;
int _gang;
bool _value = 0;
uint32_t _bitmask = 0;
// _pHardLimits is a reference so the shared variable at the
// Endstops level can be changed at runtime to control the
// limit behavior dynamically.
bool& _pHardLimits;
volatile uint32_t* _posLimits = nullptr;
volatile uint32_t* _negLimits = nullptr;
void IRAM_ATTR handleISR();
public:
LimitPin(Pin& pin, int axis, int gang, int direction, bool& phardLimits);
Pin& _pin;
String _legend;
void init();
bool get() { return _value; }
~LimitPin();
};
}

View File

@@ -269,10 +269,6 @@ void IRAM_ATTR Stepper::pulse_func() {
}
}
// During a homing cycle, lock out and prevent desired axes from moving.
if (sys.state == State::Homing) {
st.step_outbits &= sys.homing_axis_lock;
}
st.step_count--; // Decrement step events count
if (st.step_count == 0) {
// Segment is complete. Discard current segment and advance segment indexing.