Browse Source

Comment, fix filament width sensor

Scott Lahteine 6 years ago
parent
commit
cf2193c07f

+ 1
- 6
Marlin/src/gcode/feature/filwidth/M404-M407.cpp View File

@@ -56,7 +56,7 @@ void GcodeSuite::M405() {
56 56
   }
57 57
 
58 58
   if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup
59
-    const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio() - 100; // -100 to scale within a signed byte
59
+    const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio();
60 60
 
61 61
     for (uint8_t i = 0; i < COUNT(measurement_delay); ++i)
62 62
       measurement_delay[i] = temp_ratio;
@@ -65,11 +65,6 @@ void GcodeSuite::M405() {
65 65
   }
66 66
 
67 67
   filament_sensor = true;
68
-
69
-  //SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
70
-  //SERIAL_PROTOCOL(filament_width_meas);
71
-  //SERIAL_PROTOCOLPGM("Extrusion ratio(%):");
72
-  //SERIAL_PROTOCOL(planner.flow_percentage[active_extruder]);
73 68
 }
74 69
 
75 70
 /**

+ 6
- 4
Marlin/src/lcd/ultralcd_impl_DOGM.h View File

@@ -660,10 +660,12 @@ static void lcd_implementation_status_screen() {
660 660
     strcpy(zstring, ftostr52sp(FIXFLOAT(LOGICAL_Z_POSITION(current_position[Z_AXIS]))));
661 661
     #if ENABLED(FILAMENT_LCD_DISPLAY)
662 662
       strcpy(wstring, ftostr12ns(filament_width_meas));
663
-      if (parser.volumetric_enabled)
664
-        strcpy(mstring, itostr3(100.0 * planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
665
-      else
666
-        strcpy_P(mstring, PSTR("---"));
663
+      strcpy(mstring, itostr3(100.0 * (
664
+          parser.volumetric_enabled
665
+            ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
666
+            : planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
667
+        )
668
+      ));
667 669
     #endif
668 670
   }
669 671
 

+ 7
- 6
Marlin/src/lcd/ultralcd_impl_HD44780.h View File

@@ -884,12 +884,13 @@ static void lcd_implementation_status_screen() {
884 884
       lcd_printPGM(PSTR("Dia "));
885 885
       lcd.print(ftostr12ns(filament_width_meas));
886 886
       lcd_printPGM(PSTR(" V"));
887
-      if (parser.volumetric_enabled) {
888
-        lcd.print(itostr3(100.0 * planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
889
-        lcd.write('%');
890
-      }
891
-      else
892
-        lcd_printPGM(PSTR("--- "));
887
+      lcd.print(itostr3(100.0 * (
888
+          parser.volumetric_enabled
889
+            ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
890
+            : planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
891
+        )
892
+      ));
893
+      lcd.write('%');
893 894
       return;
894 895
     }
895 896
 

+ 29
- 1
Marlin/src/module/planner.cpp View File

@@ -561,10 +561,19 @@ void Planner::check_axes_activity() {
561 561
   #endif
562 562
 }
563 563
 
564
+/**
565
+ * Get a volumetric multiplier from a filament diameter.
566
+ * This is the reciprocal of the circular cross-section area.
567
+ * Return 1.0 with volumetric off or a diameter of 0.0.
568
+ */
564 569
 inline float calculate_volumetric_multiplier(const float &diameter) {
565 570
   return (parser.volumetric_enabled && diameter) ? 1.0 / CIRCLE_AREA(diameter * 0.5) : 1.0;
566 571
 }
567 572
 
573
+/**
574
+ * Convert the filament sizes into volumetric multipliers.
575
+ * The multiplier converts a given E value into a length.
576
+ */
568 577
 void Planner::calculate_volumetric_multipliers() {
569 578
   for (uint8_t i = 0; i < COUNT(filament_size); i++) {
570 579
     volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]);
@@ -572,6 +581,25 @@ void Planner::calculate_volumetric_multipliers() {
572 581
   }
573 582
 }
574 583
 
584
+#if ENABLED(FILAMENT_WIDTH_SENSOR)
585
+  /**
586
+   * Convert the ratio value given by the filament width sensor
587
+   * into a volumetric multiplier. Conversion differs when using
588
+   * linear extrusion vs volumetric extrusion.
589
+   */
590
+  void Planner::calculate_volumetric_for_width_sensor(const int8_t encoded_ratio) {
591
+    // Reconstitute the nominal/measured ratio
592
+    const float nom_meas_ratio = 1.0 + 0.01 * encoded_ratio,
593
+                ratio_2 = sq(nom_meas_ratio);
594
+
595
+    volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = parser.volumetric_enabled
596
+      ? ratio_2 / CIRCLE_AREA(filament_width_nominal * 0.5) // Volumetric uses a true volumetric multiplier
597
+      : ratio_2;                                            // Linear squares the ratio, which scales the volume
598
+
599
+    refresh_e_factor(FILAMENT_SENSOR_EXTRUDER_NUM);
600
+  }
601
+#endif
602
+
575 603
 #if PLANNER_LEVELING
576 604
   /**
577 605
    * rx, ry, rz - Cartesian positions in mm
@@ -1057,7 +1085,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
1057 1085
         // If the index has changed (must have gone forward)...
1058 1086
         if (filwidth_delay_index[0] != filwidth_delay_index[1]) {
1059 1087
           filwidth_e_count = 0; // Reset the E movement counter
1060
-          const uint8_t meas_sample = thermalManager.widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char
1088
+          const uint8_t meas_sample = thermalManager.widthFil_to_size_ratio();
1061 1089
           do {
1062 1090
             filwidth_delay_index[1] = (filwidth_delay_index[1] + 1) % MMD_CM; // The next unused slot
1063 1091
             measurement_delay[filwidth_delay_index[1]] = meas_sample;         // Store the measurement

+ 4
- 0
Marlin/src/module/planner.h View File

@@ -293,6 +293,10 @@ class Planner {
293 293
     // Update multipliers based on new diameter measurements
294 294
     static void calculate_volumetric_multipliers();
295 295
 
296
+    #if ENABLED(FILAMENT_WIDTH_SENSOR)
297
+      void calculate_volumetric_for_width_sensor(const int8_t encoded_ratio);
298
+    #endif
299
+
296 300
     FORCE_INLINE static void set_filament_size(const uint8_t e, const float &v) {
297 301
       filament_size[e] = v;
298 302
       // make sure all extruders have some sane value for the filament size

+ 3
- 3
Marlin/src/module/stepper.cpp View File

@@ -688,7 +688,7 @@ void Stepper::isr() {
688 688
     // step_rate to timer interval
689 689
     const hal_timer_t interval = calc_timer_interval(acc_step_rate);
690 690
 
691
-    SPLIT(interval);  // split step into multiple ISRs if larger than  ENDSTOP_NOMINAL_OCR_VAL
691
+    SPLIT(interval);  // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
692 692
     _NEXT_ISR(ocr_val);
693 693
 
694 694
     acceleration_time += interval;
@@ -725,7 +725,7 @@ void Stepper::isr() {
725 725
     // step_rate to timer interval
726 726
     const hal_timer_t interval = calc_timer_interval(step_rate);
727 727
 
728
-    SPLIT(interval);  // split step into multiple ISRs if larger than  ENDSTOP_NOMINAL_OCR_VAL
728
+    SPLIT(interval);  // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
729 729
     _NEXT_ISR(ocr_val);
730 730
     deceleration_time += interval;
731 731
 
@@ -754,7 +754,7 @@ void Stepper::isr() {
754 754
 
755 755
     #endif
756 756
 
757
-    SPLIT(OCR1A_nominal);  // split step into multiple ISRs if larger than  ENDSTOP_NOMINAL_OCR_VAL
757
+    SPLIT(OCR1A_nominal);  // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
758 758
     _NEXT_ISR(ocr_val);
759 759
     // ensure we're running at the correct step rate, even if we just came off an acceleration
760 760
     step_loops = step_loops_nominal;

+ 17
- 24
Marlin/src/module/temperature.cpp View File

@@ -740,17 +740,6 @@ float Temperature::get_pid_output(const int8_t e) {
740 740
  *  - Apply filament width to the extrusion rate (may move)
741 741
  *  - Update the heated bed PID output value
742 742
  */
743
-
744
-/**
745
- * The following line SOMETIMES results in the dreaded "unable to find a register to spill in class 'POINTER_REGS'"
746
- * compile error.
747
- *    thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS);
748
- *
749
- * This is due to a bug in the C++ compiler used by the Arduino IDE from 1.6.10 to at least 1.8.1.
750
- *
751
- * The work around is to add the compiler flag "__attribute__((__optimize__("O2")))" to the declaration for manage_heater()
752
- */
753
-//void Temperature::manage_heater()  __attribute__((__optimize__("O2")));
754 743
 void Temperature::manage_heater() {
755 744
 
756 745
   if (!temp_meas_ready) return;
@@ -805,18 +794,16 @@ void Temperature::manage_heater() {
805 794
     }
806 795
   #endif
807 796
 
808
-  // Control the extruder rate based on the width sensor
809 797
   #if ENABLED(FILAMENT_WIDTH_SENSOR)
798
+    /**
799
+     * Filament Width Sensor dynamically sets the volumetric multiplier
800
+     * based on a delayed measurement of the filament diameter.
801
+     */
810 802
     if (filament_sensor) {
811 803
       meas_shift_index = filwidth_delay_index[0] - meas_delay_cm;
812 804
       if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1;  //loop around buffer if needed
813 805
       meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
814
-
815
-      // Get the delayed info and add 100 to reconstitute to a percent of
816
-      // the nominal filament diameter then square it to get an area
817
-      const float vmroot = measurement_delay[meas_shift_index] * 0.01 + 1.0;
818
-      planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vmroot <= 0.1 ? 0.01 : sq(vmroot);
819
-      planner.refresh_e_factor(FILAMENT_SENSOR_EXTRUDER_NUM);
806
+      calculate_volumetric_for_width_sensor(measurement_delay[meas_shift_index])
820 807
     }
821 808
   #endif // FILAMENT_WIDTH_SENSOR
822 809
 
@@ -1004,12 +991,18 @@ void Temperature::updateTemperaturesFromRawValues() {
1004 991
     return current_raw_filwidth * 5.0 * (1.0 / 16383.0);
1005 992
   }
1006 993
 
1007
-  // Convert raw Filament Width to a ratio
1008
-  int Temperature::widthFil_to_size_ratio() {
1009
-    float temp = filament_width_meas;
1010
-    if (temp < MEASURED_LOWER_LIMIT) temp = filament_width_nominal;  // Assume a bad sensor reading
1011
-    else NOMORE(temp, MEASURED_UPPER_LIMIT);
1012
-    return filament_width_nominal / temp * 100;
994
+  /**
995
+   * Convert Filament Width (mm) to a simple ratio
996
+   * and reduce to an 8 bit value.
997
+   *
998
+   * A nominal width of 1.75 and measured width of 1.73
999
+   * gives (100 * 1.75 / 1.73) for a ratio of 101 and
1000
+   * a return value of 1.
1001
+   */
1002
+  int8_t Temperature::widthFil_to_size_ratio() {
1003
+    if (WITHIN(filament_width_meas, MEASURED_LOWER_LIMIT, MEASURED_UPPER_LIMIT))
1004
+      return int(100.0 * filament_width_nominal / filament_width_meas) - 100;
1005
+    return 0;
1013 1006
   }
1014 1007
 
1015 1008
 #endif

+ 2
- 3
Marlin/src/module/temperature.h View File

@@ -325,11 +325,10 @@ class Temperature {
325 325
     #endif
326 326
 
327 327
     #if ENABLED(FILAMENT_WIDTH_SENSOR)
328
-      static float analog2widthFil(); // Convert raw Filament Width to millimeters
329
-      static int widthFil_to_size_ratio(); // Convert raw Filament Width to an extrusion ratio
328
+      static float analog2widthFil();         // Convert raw Filament Width to millimeters
329
+      static int8_t widthFil_to_size_ratio(); // Convert Filament Width (mm) to an extrusion ratio
330 330
     #endif
331 331
 
332
-
333 332
     //high level conversion routines, for use outside of temperature.cpp
334 333
     //inline so that there is no performance decrease.
335 334
     //deg=degreeCelsius

Loading…
Cancel
Save