#include "FilamentDetector.h"
#include "utils.h"
#include "Gcode.h"
+#include "ExtruderPublicAccess.h"
#include "InterruptIn.h" // mbed
#include "us_ticker_api.h" // mbed
{
suspended= false;
filament_out_alarm= false;
+ bulge_detected= false;
active= true;
e_last_moved= NAN;
}
Pin dummy_pin;
dummy_pin.from_string( THEKERNEL->config->value(filament_detector_checksum, encoder_pin_checksum)->by_default("nc" )->as_string());
this->encoder_pin= dummy_pin.interrupt_pin();
- if(this->encoder_pin == nullptr) {
- // was not a valid interrupt pin
- delete this;
- return;
- }
-
- // set interrupt on rising edge
- this->encoder_pin->rise(this, &FilamentDetector::on_pin_rise);
- NVIC_SetPriority(EINT3_IRQn, 16); // set to low priority
// optional bulge detector
bulge_pin.from_string( THEKERNEL->config->value(filament_detector_checksum, bulge_pin_checksum)->by_default("nc" )->as_string())->as_input();
THEKERNEL->slow_ticker->attach( 100, this, &FilamentDetector::button_tick);
}
+ //Valid configurations contain an encoder pin, a bulge pin or both.
+ //free the module if not a valid configuration
+ if(this->encoder_pin == nullptr && !bulge_pin.connected()) {
+ delete this;
+ return;
+ }
+
+ //only monitor the encoder if we are using the encodeer.
+ if (this->encoder_pin != nullptr) {
+ // set interrupt on rising edge
+ this->encoder_pin->rise(this, &FilamentDetector::on_pin_rise);
+ NVIC_SetPriority(EINT3_IRQn, 16); // set to low priority
+ }
+
+
// how many seconds between checks, must be long enough for several pulses to be detected, but not too long
seconds_per_check= THEKERNEL->config->value(filament_detector_checksum, seconds_per_check_checksum)->by_default(2)->as_number();
pulses_per_mm= THEKERNEL->config->value(filament_detector_checksum, pulses_per_mm_checksum)->by_default(1)->as_number();
// register event-handlers
- register_for_event(ON_SECOND_TICK);
+ if (this->encoder_pin != nullptr) {
+ //This event is only valid if we are using the encodeer.
+ register_for_event(ON_SECOND_TICK);
+ }
+
register_for_event(ON_MAIN_LOOP);
register_for_event(ON_CONSOLE_LINE_RECEIVED);
this->register_for_event(ON_GCODE_RECEIVED);
}
+
void FilamentDetector::send_command(std::string msg, StreamOutput *stream)
{
struct SerialMessage message;
SerialMessage new_message = *static_cast<SerialMessage *>(argument);
string possible_command = new_message.message;
string cmd = shift_parameter(possible_command);
- if(cmd == "resume") {
+ if(cmd == "resume" || cmd == "M601") {
+ this->pulses= 0;
+ e_last_moved= NAN;
suspended= false;
}
}
+float FilamentDetector::get_emove()
+{
+ pad_extruder_t rd;
+ if(PublicData::get_value( extruder_checksum, (void *)&rd )) return rd.current_position;
+ return NAN;
+}
+
void FilamentDetector::on_gcode_received(void *argument)
{
Gcode *gcode = static_cast<Gcode *>(argument);
if (gcode->has_m) {
- if (gcode->m == 405) { // diable filament detector
+ if (gcode->m == 404) { // set filament detector parameters S seconds per check, P pulses per mm
+ if(gcode->has_letter('S')){
+ seconds_per_check= gcode->get_value('S');
+ seconds_passed= 0;
+ }
+ if(gcode->has_letter('P')){
+ pulses_per_mm= gcode->get_value('P');
+ }
+ gcode->stream->printf("// pulses per mm: %f, seconds per check: %d\n", pulses_per_mm, seconds_per_check);
+
+ } else if (gcode->m == 405) { // disable filament detector
active= false;
+ e_last_moved= get_emove();
}else if (gcode->m == 406) { // enable filament detector
this->pulses= 0;
- e_last_moved= NAN;
+ e_last_moved= get_emove();
active= true;
}else if (gcode->m == 407) { // display filament detector pulses and status
- float *rd;
- if(!PublicData::get_value( extruder_checksum, (void **)&rd )) {
- float e_moved= *(rd+5); // current position for extruder in mm
+ float e_moved= get_emove();
+ if(!isnan(e_moved)) {
float delta= e_moved - e_last_moved;
gcode->stream->printf("Extruder moved: %f mm\n", delta);
}
{
if (active && this->filament_out_alarm) {
this->filament_out_alarm = false;
- THEKERNEL->streams->printf("// Filament Detector has detected a filament jam\n");
- this->suspended= true;
- // fire suspend command
- this->send_command( "M600", &(StreamOutput::NullStream) );
+ if(bulge_detected){
+ THEKERNEL->streams->printf("// Filament Detector has detected a bulge in the filament\n");
+ bulge_detected= false;
+ }else{
+ THEKERNEL->streams->printf("// Filament Detector has detected a filament jam\n");
+ }
+
+ if(!suspended) {
+ this->suspended= true;
+ // fire suspend command
+ this->send_command( "M600", &(StreamOutput::NullStream) );
+ }
}
}
void FilamentDetector::check_encoder()
{
- uint32_t pulse_cnt= this->pulses.exchange(0); // atomic load and reset
if(suspended) return; // already suspended
+ if(!active) return; // not enabled
+
+ uint32_t pulse_cnt= this->pulses.exchange(0); // atomic load and reset
// get number of E steps taken and make sure we have seen enough pulses to cover that
- float *rd;
- if(!PublicData::get_value( extruder_checksum, (void **)&rd )) return;
- float e_moved= *(rd+5); // current position for extruder in mm
+ float e_moved= get_emove();
if(isnan(e_last_moved)) {
e_last_moved= e_moved;
return;
float delta= e_moved - e_last_moved;
e_last_moved= e_moved;
+ if(delta < 0) {
+ // we ignore retracts for the purposes of jam detection
+ return;
+ }
// figure out how many pulses need to have happened to cover that e move
uint32_t needed_pulses= floorf(delta*pulses_per_mm);
uint32_t FilamentDetector::button_tick(uint32_t dummy)
{
- if(!bulge_pin.connected()) return 0;
+ if(!bulge_pin.connected() || suspended || !active) return 0;
if(bulge_pin.get()) {
// we got a trigger from the bulge detector
this->filament_out_alarm= true;
+ this->bulge_detected= true;
}
return 0;