fix the public data for extruder that the panel uses
[clinton/Smoothieware.git] / src / modules / tools / filamentdetector / FilamentDetector.cpp
index e3015f7..327443e 100644 (file)
@@ -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<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);
             }
@@ -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;