X-Git-Url: http://git.hcoop.net/clinton/Smoothieware.git/blobdiff_plain/b5b5a2e7aa2a16f04da83e62afe645f0c0407c29..ed68c716ff7ed08874c2deced74783d1c7a14379:/src/modules/tools/filamentdetector/FilamentDetector.cpp diff --git a/src/modules/tools/filamentdetector/FilamentDetector.cpp b/src/modules/tools/filamentdetector/FilamentDetector.cpp index e3015f73..327443e4 100644 --- a/src/modules/tools/filamentdetector/FilamentDetector.cpp +++ b/src/modules/tools/filamentdetector/FilamentDetector.cpp @@ -18,6 +18,7 @@ #include "FilamentDetector.h" #include "utils.h" #include "Gcode.h" +#include "ExtruderPublicAccess.h" #include "InterruptIn.h" // mbed #include "us_ticker_api.h" // mbed @@ -35,6 +36,7 @@ FilamentDetector::FilamentDetector() { suspended= false; filament_out_alarm= false; + bulge_detected= false; active= true; e_last_moved= NAN; } @@ -57,15 +59,6 @@ void FilamentDetector::on_module_loaded() 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(); @@ -74,6 +67,21 @@ void FilamentDetector::on_module_loaded() 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(); @@ -81,12 +89,17 @@ void FilamentDetector::on_module_loaded() 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; @@ -103,27 +116,46 @@ void FilamentDetector::on_console_line_received( void *argument ) SerialMessage new_message = *static_cast(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(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); } @@ -139,10 +171,18 @@ void FilamentDetector::on_main_loop(void *argument) { 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) ); + } } } @@ -162,13 +202,13 @@ void FilamentDetector::on_pin_rise() 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; @@ -176,6 +216,10 @@ void FilamentDetector::check_encoder() 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); @@ -190,11 +234,12 @@ void FilamentDetector::check_encoder() 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;