Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MMU improved fsensor handling #3885

Open
wants to merge 8 commits into
base: MK3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 60 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)))
leptun marked this conversation as resolved.
Show resolved Hide resolved
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,25 @@ 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
|| printJobOngoing()
|| (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 +469,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