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:
@@ -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.
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
114
Grbl_Esp32/src/Machine/LimitPin.cpp
Normal file
114
Grbl_Esp32/src/Machine/LimitPin.cpp
Normal 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(); }
|
||||
}
|
36
Grbl_Esp32/src/Machine/LimitPin.h
Normal file
36
Grbl_Esp32/src/Machine/LimitPin.h
Normal 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();
|
||||
};
|
||||
}
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user