Comment, improve filament width sensor

master
Scott Lahteine 7 years ago
parent 7c1adff8ad
commit 8519451161

@ -9553,7 +9553,7 @@ inline void gcode_M400() { stepper.synchronize(); }
} }
if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup
const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio() - 100; // -100 to scale within a signed byte const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio();
for (uint8_t i = 0; i < COUNT(measurement_delay); ++i) for (uint8_t i = 0; i < COUNT(measurement_delay); ++i)
measurement_delay[i] = temp_ratio; measurement_delay[i] = temp_ratio;
@ -9562,11 +9562,6 @@ inline void gcode_M400() { stepper.synchronize(); }
} }
filament_sensor = true; filament_sensor = true;
//SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
//SERIAL_PROTOCOL(filament_width_meas);
//SERIAL_PROTOCOLPGM("Extrusion ratio(%):");
//SERIAL_PROTOCOL(planner.flow_percentage[active_extruder]);
} }
/** /**

@ -550,10 +550,19 @@ void Planner::check_axes_activity() {
#endif #endif
} }
/**
* Get a volumetric multiplier from a filament diameter.
* This is the reciprocal of the circular cross-section area.
* Return 1.0 with volumetric off or a diameter of 0.0.
*/
inline float calculate_volumetric_multiplier(const float &diameter) { inline float calculate_volumetric_multiplier(const float &diameter) {
return (parser.volumetric_enabled && diameter) ? 1.0 / CIRCLE_AREA(diameter * 0.5) : 1.0; return (parser.volumetric_enabled && diameter) ? 1.0 / CIRCLE_AREA(diameter * 0.5) : 1.0;
} }
/**
* Convert the filament sizes into volumetric multipliers.
* The multiplier converts a given E value into a length.
*/
void Planner::calculate_volumetric_multipliers() { void Planner::calculate_volumetric_multipliers() {
for (uint8_t i = 0; i < COUNT(filament_size); i++) { for (uint8_t i = 0; i < COUNT(filament_size); i++) {
volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]);
@ -561,6 +570,25 @@ void Planner::calculate_volumetric_multipliers() {
} }
} }
#if ENABLED(FILAMENT_WIDTH_SENSOR)
/**
* Convert the ratio value given by the filament width sensor
* into a volumetric multiplier. Conversion differs when using
* linear extrusion vs volumetric extrusion.
*/
void Planner::calculate_volumetric_for_width_sensor(const int8_t encoded_ratio) {
// Reconstitute the nominal/measured ratio
const float nom_meas_ratio = 1.0 + 0.01 * encoded_ratio,
ratio_2 = sq(nom_meas_ratio);
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = parser.volumetric_enabled
? ratio_2 / CIRCLE_AREA(filament_width_nominal * 0.5) // Volumetric uses a true volumetric multiplier
: ratio_2; // Linear squares the ratio, which scales the volume
refresh_e_factor(FILAMENT_SENSOR_EXTRUDER_NUM);
}
#endif
#if PLANNER_LEVELING #if PLANNER_LEVELING
/** /**
* rx, ry, rz - Cartesian positions in mm * rx, ry, rz - Cartesian positions in mm
@ -1046,7 +1074,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
// If the index has changed (must have gone forward)... // If the index has changed (must have gone forward)...
if (filwidth_delay_index[0] != filwidth_delay_index[1]) { if (filwidth_delay_index[0] != filwidth_delay_index[1]) {
filwidth_e_count = 0; // Reset the E movement counter filwidth_e_count = 0; // Reset the E movement counter
const uint8_t meas_sample = thermalManager.widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char const uint8_t meas_sample = thermalManager.widthFil_to_size_ratio();
do { do {
filwidth_delay_index[1] = (filwidth_delay_index[1] + 1) % MMD_CM; // The next unused slot filwidth_delay_index[1] = (filwidth_delay_index[1] + 1) % MMD_CM; // The next unused slot
measurement_delay[filwidth_delay_index[1]] = meas_sample; // Store the measurement measurement_delay[filwidth_delay_index[1]] = meas_sample; // Store the measurement

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

@ -723,7 +723,7 @@ void Stepper::isr() {
// step_rate to timer interval // step_rate to timer interval
const uint16_t interval = calc_timer_interval(acc_step_rate); const uint16_t interval = calc_timer_interval(acc_step_rate);
SPLIT(interval); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL SPLIT(interval); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
_NEXT_ISR(ocr_val); _NEXT_ISR(ocr_val);
acceleration_time += interval; acceleration_time += interval;
@ -756,7 +756,7 @@ void Stepper::isr() {
// step_rate to timer interval // step_rate to timer interval
const uint16_t interval = calc_timer_interval(step_rate); const uint16_t interval = calc_timer_interval(step_rate);
SPLIT(interval); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL SPLIT(interval); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
_NEXT_ISR(ocr_val); _NEXT_ISR(ocr_val);
deceleration_time += interval; deceleration_time += interval;
@ -786,7 +786,7 @@ void Stepper::isr() {
#endif #endif
SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
_NEXT_ISR(ocr_val); _NEXT_ISR(ocr_val);
// ensure we're running at the correct step rate, even if we just came off an acceleration // ensure we're running at the correct step rate, even if we just came off an acceleration

@ -736,17 +736,6 @@ float Temperature::get_pid_output(const int8_t e) {
* - Apply filament width to the extrusion rate (may move) * - Apply filament width to the extrusion rate (may move)
* - Update the heated bed PID output value * - Update the heated bed PID output value
*/ */
/**
* The following line SOMETIMES results in the dreaded "unable to find a register to spill in class 'POINTER_REGS'"
* compile error.
* 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);
*
* 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.
*
* The work around is to add the compiler flag "__attribute__((__optimize__("O2")))" to the declaration for manage_heater()
*/
//void Temperature::manage_heater() __attribute__((__optimize__("O2")));
void Temperature::manage_heater() { void Temperature::manage_heater() {
if (!temp_meas_ready) return; if (!temp_meas_ready) return;
@ -801,19 +790,16 @@ void Temperature::manage_heater() {
} }
#endif #endif
// Control the extruder rate based on the width sensor
#if ENABLED(FILAMENT_WIDTH_SENSOR) #if ENABLED(FILAMENT_WIDTH_SENSOR)
/**
* Filament Width Sensor dynamically sets the volumetric multiplier
* based on a delayed measurement of the filament diameter.
*/
if (filament_sensor) { if (filament_sensor) {
meas_shift_index = filwidth_delay_index[0] - meas_delay_cm; meas_shift_index = filwidth_delay_index[0] - meas_delay_cm;
if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed
meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY); meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
calculate_volumetric_for_width_sensor(measurement_delay[meas_shift_index])
// Get the delayed info and add 100 to reconstitute to a percent of
// the nominal filament diameter then square it to get an area
float vmroot = measurement_delay[meas_shift_index] * 0.01 + 1.0;
NOLESS(vmroot, 0.1);
planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = 1.0 / CIRCLE_AREA(vmroot / 2);
planner.refresh_e_factor(FILAMENT_SENSOR_EXTRUDER_NUM);
} }
#endif // FILAMENT_WIDTH_SENSOR #endif // FILAMENT_WIDTH_SENSOR
@ -999,15 +985,20 @@ void Temperature::updateTemperaturesFromRawValues() {
// Convert raw Filament Width to millimeters // Convert raw Filament Width to millimeters
float Temperature::analog2widthFil() { float Temperature::analog2widthFil() {
return current_raw_filwidth * 5.0 * (1.0 / 16383.0); return current_raw_filwidth * 5.0 * (1.0 / 16383.0);
//return current_raw_filwidth;
} }
// Convert raw Filament Width to a ratio /**
int Temperature::widthFil_to_size_ratio() { * Convert Filament Width (mm) to a simple ratio
float temp = filament_width_meas; * and reduce to an 8 bit value.
if (temp < MEASURED_LOWER_LIMIT) temp = filament_width_nominal; //assume sensor cut out *
else NOMORE(temp, MEASURED_UPPER_LIMIT); * A nominal width of 1.75 and measured width of 1.73
return filament_width_nominal / temp * 100; * gives (100 * 1.75 / 1.73) for a ratio of 101 and
* a return value of 1.
*/
int8_t Temperature::widthFil_to_size_ratio() {
if (WITHIN(filament_width_meas, MEASURED_LOWER_LIMIT, MEASURED_UPPER_LIMIT))
return int(100.0 * filament_width_nominal / filament_width_meas) - 100;
return 0;
} }
#endif #endif

@ -333,8 +333,8 @@ class Temperature {
#endif #endif
#if ENABLED(FILAMENT_WIDTH_SENSOR) #if ENABLED(FILAMENT_WIDTH_SENSOR)
static float analog2widthFil(); // Convert raw Filament Width to millimeters static float analog2widthFil(); // Convert raw Filament Width to millimeters
static int widthFil_to_size_ratio(); // Convert raw Filament Width to an extrusion ratio static int8_t widthFil_to_size_ratio(); // Convert Filament Width (mm) to an extrusion ratio
#endif #endif

@ -650,10 +650,12 @@ static void lcd_implementation_status_screen() {
strcpy(zstring, ftostr52sp(FIXFLOAT(LOGICAL_Z_POSITION(current_position[Z_AXIS])))); strcpy(zstring, ftostr52sp(FIXFLOAT(LOGICAL_Z_POSITION(current_position[Z_AXIS]))));
#if ENABLED(FILAMENT_LCD_DISPLAY) #if ENABLED(FILAMENT_LCD_DISPLAY)
strcpy(wstring, ftostr12ns(filament_width_meas)); strcpy(wstring, ftostr12ns(filament_width_meas));
if (parser.volumetric_enabled) strcpy(mstring, itostr3(100.0 * (
strcpy(mstring, itostr3(100.0 * planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); parser.volumetric_enabled
else ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
strcpy_P(mstring, PSTR("---")); : planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
)
));
#endif #endif
} }

@ -881,12 +881,13 @@ static void lcd_implementation_status_screen() {
lcd_printPGM(PSTR("Dia ")); lcd_printPGM(PSTR("Dia "));
lcd.print(ftostr12ns(filament_width_meas)); lcd.print(ftostr12ns(filament_width_meas));
lcd_printPGM(PSTR(" V")); lcd_printPGM(PSTR(" V"));
if (parser.volumetric_enabled) { lcd.print(itostr3(100.0 * (
lcd.print(itostr3(100.0 * planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); parser.volumetric_enabled
lcd.write('%'); ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
} : planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
else )
lcd_printPGM(PSTR("--- ")); ));
lcd.write('%');
return; return;
} }

Loading…
Cancel
Save