Skip to content

Commit

Permalink
MMU jam detection with pat9125
Browse files Browse the repository at this point in the history
  • Loading branch information
leptun authored and gudnimg committed Apr 29, 2023
1 parent a354aad commit e5edc9b
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 84 deletions.
126 changes: 61 additions & 65 deletions Firmware/Filament_sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@

#ifdef FILAMENT_SENSOR
FSensorBlockRunout::FSensorBlockRunout() {
fsensor.setRunoutEnabled(false); //suppress filament runouts while loading filament.
fsensor.setAutoLoadEnabled(false); //suppress filament autoloads while loading filament.
#if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
fsensor.setJamDetectionEnabled(false); //suppress filament jam detection while loading filament.
#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
oldSuppressionStatus = fsensor.getSuppressionStatus();
fsensor.setSuppressionStatus(true);
// SERIAL_ECHOLNPGM("FSBlockRunout");
}

FSensorBlockRunout::~FSensorBlockRunout() {
fsensor.settings_init(); // restore filament runout state.
fsensor.setSuppressionStatus(oldSuppressionStatus);
// SERIAL_ECHOLNPGM("FSUnBlockRunout");
}

Expand All @@ -48,14 +45,12 @@ void Filament_sensor::setEnabled(bool enabled) {
}

void Filament_sensor::setAutoLoadEnabled(bool state, bool updateEEPROM) {
autoLoadEnabled = state;
if (updateEEPROM) {
eeprom_update_byte((uint8_t *)EEPROM_FSENS_AUTOLOAD_ENABLED, state);
}
}

void Filament_sensor::setRunoutEnabled(bool state, bool updateEEPROM) {
runoutEnabled = state;
if (updateEEPROM) {
eeprom_update_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED, state);
}
Expand All @@ -74,40 +69,38 @@ void Filament_sensor::settings_init_common() {
state = enabled ? State::initializing : State::disabled;
}

autoLoadEnabled = eeprom_read_byte((uint8_t *)EEPROM_FSENS_AUTOLOAD_ENABLED);
runoutEnabled = eeprom_read_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED);
sensorActionOnError = (SensorActionOnError)eeprom_read_byte((uint8_t *)EEPROM_FSENSOR_ACTION_NA);
if (sensorActionOnError == SensorActionOnError::_Undef) {
sensorActionOnError = SensorActionOnError::_Continue;
}
}

bool Filament_sensor::checkFilamentEvents() {
if (state != State::ready)
return false;
if (eventBlankingTimer.running() && !eventBlankingTimer.expired(100)) { // event blanking for 100ms
return false;
}
void Filament_sensor::checkFilamentEvents() {
if ((state != State::ready) || (eventBlankingTimer.running() && !eventBlankingTimer.expired(100)))
return;

bool newFilamentPresent = fsensor.getFilamentPresent();
if (oldFilamentPresent != newFilamentPresent) {
oldFilamentPresent = newFilamentPresent;
eventBlankingTimer.start();
if (newFilamentPresent) { // filament insertion
// puts_P(PSTR("filament inserted"));
if (getAutoLoadEnabled()) {
setEvent(Events::autoload);
}
triggerFilamentInserted();
postponedLoadEvent = true;
} else { // filament removal
// puts_P(PSTR("filament removed"));
if (getRunoutEnabled()) {
setEvent(Events::runout);
}
triggerFilamentRemoved();
}
return true;
}
return false;
}

void Filament_sensor::triggerFilamentInserted() {
if (autoLoadEnabled
if (!suppressed
&& (eFilamentAction == FilamentAction::None)
&& !(
MMU2::mmu2.Enabled() // quick and dirty hack to prevent spurious runouts while the MMU is in charge
Expand All @@ -123,7 +116,7 @@ void Filament_sensor::triggerFilamentInserted() {

void Filament_sensor::triggerFilamentRemoved() {
// SERIAL_ECHOLNPGM("triggerFilamentRemoved");
if (runoutEnabled
if (!suppressed
&& (eFilamentAction == FilamentAction::None)
&& (
moves_planned() != 0
Expand All @@ -146,8 +139,6 @@ void Filament_sensor::triggerFilamentRemoved() {

void Filament_sensor::filRunout() {
// SERIAL_ECHOLNPGM("filRunout");
runoutEnabled = false;
autoLoadEnabled = false;
stop_and_save_print_to_ram(0, 0);
restore_print_from_ram_and_continue(0);
eeprom_increment_byte((uint8_t *)EEPROM_FERROR_COUNT);
Expand Down Expand Up @@ -180,23 +171,20 @@ void IR_sensor::deinit() {
state = State::disabled;
}

bool IR_sensor::update() {
void IR_sensor::update() {
switch (state) {
case State::initializing:
state = State::ready; // the IR sensor gets ready instantly as it's just a gpio read operation.
// initialize the current filament state so that we don't create a switching event right after the sensor is ready.
oldFilamentPresent = fsensor.getFilamentPresent();
[[fallthrough]];
case State::ready: {
postponedLoadEvent = false;
return checkFilamentEvents();
checkFilamentEvents();
} break;
case State::disabled:
case State::error:
default:
return false;
break;
}
return false;
}


Expand All @@ -214,8 +202,8 @@ void IR_sensor_analog::init() {
sensorRevision = (SensorRevision)eeprom_read_byte((uint8_t *)EEPROM_FSENSOR_PCB);
}

bool IR_sensor_analog::update() {
bool event = IR_sensor::update();
void IR_sensor_analog::update() {
IR_sensor::update();
if (state == State::ready) {
if (getVoltReady()) {
clearVoltReady();
Expand Down Expand Up @@ -257,8 +245,6 @@ bool IR_sensor_analog::update() {
}

; //

return event;
}

void IR_sensor_analog::voltUpdate(uint16_t raw) { // to be called from the ADC ISR when a cycle is finished
Expand Down Expand Up @@ -398,7 +384,7 @@ void PAT9125_sensor::deinit() {
filter = 0;
}

bool PAT9125_sensor::update() {
void PAT9125_sensor::update() {
switch (state) {
case State::initializing:
if (!updatePAT9125()) {
Expand All @@ -411,19 +397,12 @@ bool PAT9125_sensor::update() {
break;
case State::ready: {
updatePAT9125();
postponedLoadEvent = false;
bool event = checkFilamentEvents();

; //

return event;
checkFilamentEvents();
} break;
case State::disabled:
case State::error:
default:
return false;
break;
}
return false;
}

#ifdef FSENSOR_PROBING
Expand All @@ -439,7 +418,6 @@ bool PAT9125_sensor::probeOtherType() {
#endif

void PAT9125_sensor::setJamDetectionEnabled(bool state, bool updateEEPROM) {
jamDetection = state;
oldPos = pat9125_y;
resetStepCount();
jamErrCnt = 0;
Expand All @@ -464,10 +442,26 @@ void PAT9125_sensor::resetStepCount() {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { stepCount = 0; }
}

void PAT9125_sensor::triggerFilamentJam() {
// SERIAL_ECHOLNPGM("triggerFilamentJam");
if (!suppressed
&& (! MMU2::mmu2.Enabled() ) // quick and dirty hack to prevent spurious runouts just before the toolchange
&& (eFilamentAction == FilamentAction::None)
&& !saved_printing
&& (
moves_planned() != 0
|| IS_SD_PRINTING
|| usb_timer.running()
|| (lcd_commands_type == LcdCommands::Layer1Cal)
|| eeprom_read_byte((uint8_t *)EEPROM_WIZARD_ACTIVE)
)
) {
filJam();
}
}

void PAT9125_sensor::filJam() {
runoutEnabled = false;
autoLoadEnabled = false;
jamDetection = false;
// puts_P(PSTR("filJam()"));
stop_and_save_print_to_ram(0, 0);
restore_print_from_ram_and_continue(0);
eeprom_increment_byte((uint8_t *)EEPROM_FERROR_COUNT);
Expand All @@ -476,26 +470,28 @@ void PAT9125_sensor::filJam() {
}

bool PAT9125_sensor::updatePAT9125() {
if (jamDetection) {
int16_t _stepCount = getStepCount();
if (abs(_stepCount) >= chunkSteps) { // end of chunk. Check distance
resetStepCount();
if (!pat9125_update()) { // get up to date data. reinit on error.
init(); // try to reinit.
}
bool fsDir = (pat9125_y - oldPos) > 0;
bool stDir = _stepCount > 0;
if (fsDir != stDir) {
jamErrCnt++;
} else if (jamErrCnt) {
jamErrCnt--;
}
oldPos = pat9125_y;

int16_t _stepCount = getStepCount();
if (abs(_stepCount) >= chunkSteps) { // end of chunk. Check distance
resetStepCount();
if (!pat9125_update()) { // get up to date data. reinit on error.
init(); // try to reinit.
}
if (jamErrCnt > 10) {
jamErrCnt = 0;
filJam();
bool fsDir = (pat9125_y - oldPos) > 0;
bool stDir = _stepCount > 0;
if (fsDir != stDir) {
jamErrCnt++;
} else if (jamErrCnt) {
jamErrCnt--;
}
oldPos = pat9125_y;
}
if (jamErrCnt > 10) {
jamErrCnt = 0;
if (getJamDetectionEnabled()) {
setEvent(Events::jam);
}
triggerFilamentJam();
}

if (pollingTimer.expired_cont(pollingPeriod)) {
Expand Down
39 changes: 26 additions & 13 deletions Firmware/Filament_sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class FSensorBlockRunout {
public:
FSensorBlockRunout();
~FSensorBlockRunout();
private:
bool oldSuppressionStatus;
};

/// Base class Filament sensor
Expand All @@ -43,19 +45,30 @@ class Filament_sensor {
_Pause = 1,
_Undef = EEPROM_EMPTY_VALUE
};

enum class Events : uint8_t {
runout = 0,
autoload,
jam,
};

static void setEnabled(bool enabled);

void setAutoLoadEnabled(bool state, bool updateEEPROM = false);
bool getAutoLoadEnabled() const { return autoLoadEnabled; }
bool getAutoLoadEnabled() const { return eeprom_read_byte((uint8_t *)EEPROM_FSENS_AUTOLOAD_ENABLED); }

void setRunoutEnabled(bool state, bool updateEEPROM = false);
bool getRunoutEnabled() const { return runoutEnabled; }
bool getRunoutEnabled() const { return eeprom_read_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED); }

void setActionOnError(SensorActionOnError state, bool updateEEPROM = false);
SensorActionOnError getActionOnError() const { return sensorActionOnError; }

bool getFilamentLoadEvent() const { return postponedLoadEvent; }
void setEvent(Events e) { eventFlags |= _BV((uint8_t)e); }
void clearEvent(Events e) { eventFlags &= ~_BV((uint8_t)e); }
bool getEvent(Events e) const { return eventFlags & _BV((uint8_t)e); }

bool getSuppressionStatus() const { return suppressed; }
void setSuppressionStatus(bool s) { suppressed = s; }

bool isError() const { return state == State::error; }
bool isReady() const { return state == State::ready; }
Expand All @@ -64,7 +77,7 @@ class Filament_sensor {
protected:
void settings_init_common();

bool checkFilamentEvents();
void checkFilamentEvents();

void triggerFilamentInserted();

Expand All @@ -75,10 +88,9 @@ class Filament_sensor {
void triggerError();

State state;
bool autoLoadEnabled;
bool runoutEnabled;
bool oldFilamentPresent; //for creating filament presence switching events.
bool postponedLoadEvent; //this event lasts exactly one update cycle. It is long enough to be able to do polling for load event.
uint8_t eventFlags;
bool suppressed;
ShortTimer eventBlankingTimer;
SensorActionOnError sensorActionOnError;
};
Expand All @@ -88,7 +100,7 @@ class IR_sensor: public Filament_sensor {
public:
void init();
void deinit();
bool update();
void update();
bool getFilamentPresent() const { return !READ(IR_SENSOR_PIN); }
#ifdef FSENSOR_PROBING
static bool probeOtherType(); //checks if the wrong fsensor type is detected.
Expand All @@ -107,7 +119,7 @@ constexpr static float Raw2Voltage(uint16_t raw) {
class IR_sensor_analog: public IR_sensor {
public:
void init();
bool update();
void update();
void voltUpdate(uint16_t raw);

uint16_t __attribute__((noinline)) getVoltRaw();
Expand Down Expand Up @@ -160,14 +172,14 @@ class PAT9125_sensor: public Filament_sensor {
public:
void init();
void deinit();
bool update();
void update();
bool getFilamentPresent() const { return filterFilPresent; }
#ifdef FSENSOR_PROBING
bool probeOtherType(); //checks if the wrong fsensor type is detected.
#endif

void setJamDetectionEnabled(bool state, bool updateEEPROM = false);
bool getJamDetectionEnabled() const { return jamDetection; }
bool getJamDetectionEnabled() const { return eeprom_read_byte((uint8_t *)EEPROM_FSENSOR_JAM_DETECTION); }

void stStep(bool rev) { //from stepper isr
stepCount += rev ? -1 : 1;
Expand All @@ -180,8 +192,7 @@ class PAT9125_sensor: public Filament_sensor {
ShortTimer pollingTimer;
uint8_t filter;
uint8_t filterFilPresent;

bool jamDetection;

int16_t oldPos;
int16_t stepCount;
int16_t chunkSteps;
Expand All @@ -195,6 +206,8 @@ class PAT9125_sensor: public Filament_sensor {

void resetStepCount();

void triggerFilamentJam();

void filJam();

bool updatePAT9125();
Expand Down
Loading

0 comments on commit e5edc9b

Please sign in to comment.