Prusa MINI Firmware overview
filwidth.h
Go to the documentation of this file.
1 /**
2  * Marlin 3D Printer Firmware
3  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4  *
5  * Based on Sprinter and grbl.
6  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 #pragma once
23 
24 #include "../inc/MarlinConfig.h"
25 #include "../module/planner.h"
26 
28 public:
29  static constexpr int MMD_CM = MAX_MEASUREMENT_DELAY + 1, MMD_MM = MMD_CM * 10;
30  static bool enabled; // (M405-M406) Filament Width Sensor ON/OFF.
31  static uint32_t accum; // ADC accumulator
32  static uint16_t raw; // Measured filament diameter - one extruder only
33  static float nominal_mm, // (M104) Nominal filament width
34  measured_mm, // Measured filament diameter
36  static uint8_t meas_delay_cm; // Distance delay setting
37  static int8_t ratios[MMD_CM], // Ring buffer to delay measurement. (Extruder factor minus 100)
38  index_r, index_w; // Indexes into ring buffer
39 
41  static void init();
42 
43  static inline void enable(const bool ena) { enabled = ena; }
44 
45  static inline void set_delay_cm(const uint8_t cm) {
46  meas_delay_cm = _MIN(cm, MAX_MEASUREMENT_DELAY);
47  }
48 
49  /**
50  * Convert Filament Width (mm) to an extrusion ratio
51  * and reduce to an 8 bit value.
52  *
53  * A nominal width of 1.75 and measured width of 1.73
54  * gives (100 * 1.75 / 1.73) for a ratio of 101 and
55  * a return value of 1.
56  */
57  static int8_t sample_to_size_ratio() {
58  return ABS(nominal_mm - measured_mm) <= FILWIDTH_ERROR_MARGIN
59  ? int(100.0f * nominal_mm / measured_mm) - 100 : 0;
60  }
61 
62  // Apply a single ADC reading to the raw value
63  static void accumulate(const uint16_t adc) {
64  if (adc > 102) // Ignore ADC under 0.5 volts
65  accum += (uint32_t(adc) << 7) - (accum >> 7);
66  }
67 
68  // Convert raw measurement to mm
69  static inline float raw_to_mm(const uint16_t v) { return v * 5.0f * RECIPROCAL(16383.0f); }
70  static inline float raw_to_mm() { return raw_to_mm(raw); }
71 
72  // A scaled reading is ready
73  // Divide to get to 0-16384 range since we used 1/128 IIR filter approach
74  static inline void reading_ready() { raw = accum >> 10; }
75 
76  // Update mm from the raw measurement
77  static inline void update_measured_mm() { measured_mm = raw_to_mm(); }
78 
79  // Update ring buffer used to delay filament measurements
80  static inline void advance_e(const float &e_move) {
81 
82  // Increment counters with the E distance
83  e_count += e_move;
84  delay_dist += e_move;
85 
86  // Only get new measurements on forward E movement
87  if (!UNEAR_ZERO(e_count)) {
88 
89  // Loop the delay distance counter (modulus by the mm length)
90  while (delay_dist >= MMD_MM) delay_dist -= MMD_MM;
91 
92  // Convert into an index (cm) into the measurement array
93  index_r = int8_t(delay_dist * 0.1f);
94 
95  // If the ring buffer is not full...
96  if (index_r != index_w) {
97  e_count = 0; // Reset the E movement counter
98  const int8_t meas_sample = sample_to_size_ratio();
99  do {
100  if (++index_w >= MMD_CM) index_w = 0; // The next unused slot
101  ratios[index_w] = meas_sample; // Store the measurement
102  } while (index_r != index_w); // More slots to fill?
103  }
104  }
105  }
106 
107  // Dynamically set the volumetric multiplier based on the delayed width measurement.
108  static inline void update_volumetric() {
109  if (enabled) {
110  int8_t read_index = index_r - meas_delay_cm;
111  if (read_index < 0) read_index += MMD_CM; // Loop around buffer if needed
112  LIMIT(read_index, 0, MAX_MEASUREMENT_DELAY);
113  planner.apply_filament_width_sensor(ratios[read_index]);
114  }
115  }
116 
117 };
118 
FilamentWidthSensor::enable
static void enable(const bool ena)
Definition: filwidth.h:43
FilamentWidthSensor
Definition: filwidth.h:27
FilamentWidthSensor::index_w
static int8_t index_w
Definition: filwidth.h:37
FilamentWidthSensor::raw_to_mm
static float raw_to_mm(const uint16_t v)
Definition: filwidth.h:69
FilamentWidthSensor::raw_to_mm
static float raw_to_mm()
Definition: filwidth.h:70
FilamentWidthSensor::accum
static uint32_t accum
Definition: filwidth.h:31
RECIPROCAL
#define RECIPROCAL(x)
Definition: macros.h:273
UNEAR_ZERO
#define UNEAR_ZERO(x)
Definition: macros.h:269
FilamentWidthSensor::advance_e
static void advance_e(const float &e_move)
Definition: filwidth.h:80
i
uint8_t i
Definition: screen_test_graph.c:72
_MIN
#define _MIN(V...)
Definition: macros.h:333
FilamentWidthSensor::meas_delay_cm
static uint8_t meas_delay_cm
Definition: filwidth.h:36
LIMIT
#define LIMIT(v, n1, n2)
Definition: macros.h:139
FilamentWidthSensor::index_r
static int8_t index_r
Definition: filwidth.h:37
ABS
#define ABS(a)
Definition: macros.h:266
FilamentWidthSensor::enabled
static bool enabled
Definition: filwidth.h:30
COUNT
#define COUNT(a)
Definition: macros.h:200
filwidth
FilamentWidthSensor filwidth
FilamentWidthSensor::nominal_mm
static float nominal_mm
Definition: filwidth.h:33
FilamentWidthSensor::MMD_CM
static constexpr int MMD_CM
Definition: filwidth.h:29
FilamentWidthSensor::update_volumetric
static void update_volumetric()
Definition: filwidth.h:108
FilamentWidthSensor::accumulate
static void accumulate(const uint16_t adc)
Definition: filwidth.h:63
uint8_t
const uint8_t[]
Definition: 404_html.c:3
FilamentWidthSensor::sample_to_size_ratio
static int8_t sample_to_size_ratio()
Definition: filwidth.h:57
FilamentWidthSensor::reading_ready
static void reading_ready()
Definition: filwidth.h:74
DEFAULT_NOMINAL_FILAMENT_DIA
#define DEFAULT_NOMINAL_FILAMENT_DIA
Definition: Configuration_A3ides_2209_MINI.h:151
FilamentWidthSensor::e_count
static float e_count
Definition: filwidth.h:33
FilamentWidthSensor::set_delay_cm
static void set_delay_cm(const uint8_t cm)
Definition: filwidth.h:45
FilamentWidthSensor::MMD_MM
static constexpr int MMD_MM
Definition: filwidth.h:29
FilamentWidthSensor::init
static void init()
FilamentWidthSensor::FilamentWidthSensor
FilamentWidthSensor()
Definition: filwidth.h:40
createSpeedLookupTable.int
int
Definition: createSpeedLookupTable.py:15
FilamentWidthSensor::update_measured_mm
static void update_measured_mm()
Definition: filwidth.h:77
FilamentWidthSensor::delay_dist
static float delay_dist
Definition: filwidth.h:33
FilamentWidthSensor::raw
static uint16_t raw
Definition: filwidth.h:32
filwidth.h
FilamentWidthSensor::ratios
static int8_t ratios[MMD_CM]
Definition: filwidth.h:37
FilamentWidthSensor::measured_mm
static float measured_mm
Definition: filwidth.h:33
planner
Planner planner
Definition: planner.cpp:111