Unified the volumetric_multiplier with extrusion_multiply to improve

numeric accuracy and to reduce compuatitonal load. With this commit,
the numeric rounding is fixed not only for the M221 G-code
(as implemented by the preceding commit), but also for the volumetric
extrusion in general.

Removed the old FILAMENT_SENSOR code, which served the purpose
to modulate the volumetric multiplayer in real time depending
on the measured filament diameter. This feature will certainly not be
used by Prusa Research in the near future as we know of no sensor,
which would offer sufficient accuracy for a reasonable price.
This commit is contained in:
bubnikv 2018-02-21 11:25:21 +01:00 committed by PavelSindler
parent 4e3ea41ba4
commit cff7b9b396
7 changed files with 32 additions and 266 deletions

View File

@ -789,34 +789,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
// //
//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command
/**********************************************************************\ #define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm). Used by the volumetric extrusion.
* Support for a filament diameter sensor
* Also allows adjustment of diameter at print time (vs at slicing)
* Single extruder only at this point (extruder 0)
*
* Motherboards
* 34 - RAMPS1.4 - uses Analog input 5 on the AUX2 connector
* 81 - Printrboard - Uses Analog input 2 on the Exp1 connector (version B,C,D,E)
* 301 - Rambo - uses Analog input 3
* Note may require analog pins to be defined for different motherboards
**********************************************************************/
// Uncomment below to enable
//#define FILAMENT_SENSOR
#define FILAMENT_SENSOR_EXTRUDER_NUM 0 //The number of the extruder that has the filament sensor (0,1,2)
#define MEASUREMENT_DELAY_CM 14 //measurement delay in cm. This is the distance from filament sensor to middle of barrel
#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm) - this is then used in the slicer software. Used for sensor reading validation
#define MEASURED_UPPER_LIMIT 3.30 //upper limit factor used for sensor reading validation in mm
#define MEASURED_LOWER_LIMIT 1.90 //lower limit factor for sensor reading validation in mm
#define MAX_MEASUREMENT_DELAY 20 //delay buffer size in bytes (1 byte = 1cm)- limits maximum measurement delay allowable (must be larger than MEASUREMENT_DELAY_CM and lower number saves RAM)
//defines used in the code
#define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA //set measured to nominal initially
//When using an LCD, uncomment the line below to display the Filament sensor data on the last line instead of status. Status will appear for 5 sec.
//#define FILAMENT_LCD_DISPLAY
// Calibration status of the machine, to be stored into the EEPROM, // Calibration status of the machine, to be stored into the EEPROM,
// (unsigned char*)EEPROM_CALIBRATION_STATUS // (unsigned char*)EEPROM_CALIBRATION_STATUS

View File

@ -472,7 +472,7 @@ void Config_ResetDefault()
filament_size[2] = DEFAULT_NOMINAL_FILAMENT_DIA; filament_size[2] = DEFAULT_NOMINAL_FILAMENT_DIA;
#endif #endif
#endif #endif
calculate_volumetric_multipliers(); calculate_extruder_multipliers();
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded");

View File

@ -283,17 +283,6 @@ extern void homeaxis(int axis);
extern unsigned char fanSpeedSoftPwm; extern unsigned char fanSpeedSoftPwm;
#endif #endif
#ifdef FILAMENT_SENSOR
extern float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75
extern bool filament_sensor; //indicates that filament sensor readings should control extrusion
extern float filament_width_meas; //holds the filament diameter as accurately measured
extern signed char measurement_delay[]; //ring buffer to delay measurement
extern int delay_index1, delay_index2; //index into ring buffer
extern float delay_dist; //delay distance counter
extern int meas_delay_cm; //delay distance
#endif
#ifdef FWRETRACT #ifdef FWRETRACT
extern bool autoretract_enabled; extern bool autoretract_enabled;
extern bool retracted[EXTRUDERS]; extern bool retracted[EXTRUDERS];
@ -358,7 +347,7 @@ extern bool sortAlpha;
extern char dir_names[3][9]; extern char dir_names[3][9];
extern void calculate_volumetric_multipliers(); extern void calculate_extruder_multipliers();
// Similar to the default Arduino delay function, // Similar to the default Arduino delay function,
// but it keeps the background tasks running. // but it keeps the background tasks running.

View File

@ -334,7 +334,7 @@ float filament_size[EXTRUDERS] = { DEFAULT_NOMINAL_FILAMENT_DIA
#endif #endif
#endif #endif
}; };
float volumetric_multiplier[EXTRUDERS] = {1.0 float extruder_multiplier[EXTRUDERS] = {1.0
#if EXTRUDERS > 1 #if EXTRUDERS > 1
, 1.0 , 1.0
#if EXTRUDERS > 2 #if EXTRUDERS > 2
@ -411,18 +411,6 @@ bool cancel_heatup = false ;
#define KEEPALIVE_STATE(n); #define KEEPALIVE_STATE(n);
#endif #endif
#ifdef FILAMENT_SENSOR
//Variables for Filament Sensor input
float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404
bool filament_sensor=false; //M405 turns on filament_sensor control, M406 turns it off
float filament_width_meas=DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter
signed char measurement_delay[MAX_MEASUREMENT_DELAY+1]; //ring buffer to delay measurement store extruder factor after subtracting 100
int delay_index1=0; //index into ring buffer
int delay_index2=-1; //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized
float delay_dist=0; //delay distance counter
int meas_delay_cm = MEASUREMENT_DELAY_CM; //distance delay setting
#endif
const char errormagic[] PROGMEM = "Error:"; const char errormagic[] PROGMEM = "Error:";
const char echomagic[] PROGMEM = "echo:"; const char echomagic[] PROGMEM = "echo:";
@ -1971,11 +1959,7 @@ void refresh_cmd_timeout(void)
destination[Y_AXIS]=current_position[Y_AXIS]; destination[Y_AXIS]=current_position[Y_AXIS];
destination[Z_AXIS]=current_position[Z_AXIS]; destination[Z_AXIS]=current_position[Z_AXIS];
destination[E_AXIS]=current_position[E_AXIS]; destination[E_AXIS]=current_position[E_AXIS];
if (swapretract) { current_position[E_AXIS]+=(swapretract?retract_length_swap:retract_length)*float(extrudemultiply)*0.01f;
current_position[E_AXIS]+=retract_length_swap/volumetric_multiplier[active_extruder];
} else {
current_position[E_AXIS]+=retract_length/volumetric_multiplier[active_extruder];
}
plan_set_e_position(current_position[E_AXIS]); plan_set_e_position(current_position[E_AXIS]);
float oldFeedrate = feedrate; float oldFeedrate = feedrate;
feedrate=retract_feedrate*60; feedrate=retract_feedrate*60;
@ -1992,12 +1976,7 @@ void refresh_cmd_timeout(void)
destination[E_AXIS]=current_position[E_AXIS]; destination[E_AXIS]=current_position[E_AXIS];
current_position[Z_AXIS]+=retract_zlift; current_position[Z_AXIS]+=retract_zlift;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
//prepare_move(); current_position[E_AXIS]-=(swapretract?(retract_length_swap+retract_recover_length_swap):(retract_length+retract_recover_length))*float(extrudemultiply)*0.01f;
if (swapretract) {
current_position[E_AXIS]-=(retract_length_swap+retract_recover_length_swap)/volumetric_multiplier[active_extruder];
} else {
current_position[E_AXIS]-=(retract_length+retract_recover_length)/volumetric_multiplier[active_extruder];
}
plan_set_e_position(current_position[E_AXIS]); plan_set_e_position(current_position[E_AXIS]);
float oldFeedrate = feedrate; float oldFeedrate = feedrate;
feedrate=retract_recover_feedrate*60; feedrate=retract_recover_feedrate*60;
@ -5066,7 +5045,7 @@ Sigma_Exit:
//reserved for setting filament diameter via UFID or filament measuring device //reserved for setting filament diameter via UFID or filament measuring device
break; break;
} }
calculate_volumetric_multipliers(); calculate_extruder_multipliers();
} }
break; break;
case 201: // M201 case 201: // M201
@ -5234,6 +5213,7 @@ Sigma_Exit:
extrudemultiply = tmp_code ; extrudemultiply = tmp_code ;
} }
} }
calculate_extruder_multipliers();
} }
break; break;
@ -5472,69 +5452,6 @@ Sigma_Exit:
} }
break; break;
#ifdef FILAMENT_SENSOR
case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width
{
#if (FILWIDTH_PIN > -1)
if(code_seen('N')) filament_width_nominal=code_value();
else{
SERIAL_PROTOCOLPGM("Filament dia (nominal mm):");
SERIAL_PROTOCOLLN(filament_width_nominal);
}
#endif
}
break;
case 405: //M405 Turn on filament sensor for control
{
if(code_seen('D')) meas_delay_cm=code_value();
if(meas_delay_cm> MAX_MEASUREMENT_DELAY)
meas_delay_cm = MAX_MEASUREMENT_DELAY;
if(delay_index2 == -1) //initialize the ring buffer if it has not been done since startup
{
int temp_ratio = widthFil_to_size_ratio();
for (delay_index1=0; delay_index1<(MAX_MEASUREMENT_DELAY+1); ++delay_index1 ){
measurement_delay[delay_index1]=temp_ratio-100; //subtract 100 to scale within a signed byte
}
delay_index1=0;
delay_index2=0;
}
filament_sensor = true ;
//SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
//SERIAL_PROTOCOL(filament_width_meas);
//SERIAL_PROTOCOLPGM("Extrusion ratio(%):");
//SERIAL_PROTOCOL(extrudemultiply);
}
break;
case 406: //M406 Turn off filament sensor for control
{
filament_sensor = false ;
}
break;
case 407: //M407 Display measured filament diameter
{
SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
SERIAL_PROTOCOLLN(filament_width_meas);
}
break;
#endif
case 500: // M500 Store settings in EEPROM case 500: // M500 Store settings in EEPROM
{ {
Config_StoreSettings(EEPROM_OFFSET); Config_StoreSettings(EEPROM_OFFSET);
@ -6527,10 +6444,19 @@ void get_coordinates()
for(int8_t i=0; i < NUM_AXIS; i++) { for(int8_t i=0; i < NUM_AXIS; i++) {
if(code_seen(axis_codes[i])) if(code_seen(axis_codes[i]))
{ {
bool relative = axis_relative_modes[i] || relative_mode;
destination[i] = (float)code_value(); destination[i] = (float)code_value();
if (i == E_AXIS && extrudemultiply != 100) if (i == E_AXIS) {
destination[i] *= (extrudemultiply * 0.01f); float emult = extruder_multiplier[active_extruder];
if (axis_relative_modes[i] || relative_mode) if (emult != 1.) {
if (! relative) {
destination[i] -= current_position[i];
relative = true;
}
destination[i] *= emult;
}
}
if (relative)
destination[i] += current_position[i]; destination[i] += current_position[i];
seen[i]=true; seen[i]=true;
} }
@ -7047,27 +6973,20 @@ void save_statistics(unsigned long _total_filament_used, unsigned long _total_pr
} }
float calculate_volumetric_multiplier(float diameter) { float calculate_extruder_multiplier(float diameter) {
float area = .0; bool enabled = volumetric_enabled && diameter > 0;
float radius = .0; float area = enabled ? (M_PI * pow(diameter * .5, 2)) : 0;
return (extrudemultiply == 100) ?
radius = diameter * .5; (enabled ? (1.f / area) : 1.f) :
if (! volumetric_enabled || radius == 0) { (enabled ? ((float(extrudemultiply) * 0.01f) / area) : 1.f);
area = 1;
}
else {
area = M_PI * pow(radius, 2);
}
return 1.0 / area;
} }
void calculate_volumetric_multipliers() { void calculate_extruder_multipliers() {
volumetric_multiplier[0] = calculate_volumetric_multiplier(filament_size[0]); extruder_multiplier[0] = calculate_extruder_multiplier(filament_size[0]);
#if EXTRUDERS > 1 #if EXTRUDERS > 1
volumetric_multiplier[1] = calculate_volumetric_multiplier(filament_size[1]); extruder_multiplier[1] = calculate_extruder_multiplier(filament_size[1]);
#if EXTRUDERS > 2 #if EXTRUDERS > 2
volumetric_multiplier[2] = calculate_volumetric_multiplier(filament_size[2]); extruder_multiplier[2] = calculate_extruder_multiplier(filament_size[2]);
#endif #endif
#endif #endif
} }

View File

@ -126,10 +126,6 @@ static uint8_t g_cntr_planner_queue_min = 0;
float extrude_min_temp=EXTRUDE_MINTEMP; float extrude_min_temp=EXTRUDE_MINTEMP;
#endif #endif
#ifdef FILAMENT_SENSOR
static char meas_sample; //temporary variable to hold filament measurement sample
#endif
#ifdef LIN_ADVANCE #ifdef LIN_ADVANCE
float extruder_advance_k = LIN_ADVANCE_K, float extruder_advance_k = LIN_ADVANCE_K,
advance_ed_ratio = LIN_ADVANCE_E_D_RATIO, advance_ed_ratio = LIN_ADVANCE_E_D_RATIO,
@ -782,8 +778,6 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
#endif #endif
block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]); block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]);
block->steps_e = labs(target[E_AXIS]-position[E_AXIS]); block->steps_e = labs(target[E_AXIS]-position[E_AXIS]);
if (volumetric_multiplier[active_extruder] != 1.f)
block->steps_e *= volumetric_multiplier[active_extruder];
block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e))); block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e)));
// Bail if this is a zero-length block // Bail if this is a zero-length block
@ -915,7 +909,7 @@ Having the real displacement of the head, we can calculate the total movement le
delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[Y_AXIS]; delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[Y_AXIS];
#endif #endif
delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS]; delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS];
delta_mm[E_AXIS] = ((target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS])*volumetric_multiplier[active_extruder]; delta_mm[E_AXIS] = (target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS];
if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments ) if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments )
{ {
block->millimeters = fabs(delta_mm[E_AXIS]); block->millimeters = fabs(delta_mm[E_AXIS]);
@ -951,49 +945,6 @@ Having the real displacement of the head, we can calculate the total movement le
block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0 block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0
block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0 block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0
#ifdef FILAMENT_SENSOR
//FMM update ring buffer used for delay with filament measurements
if((extruder==FILAMENT_SENSOR_EXTRUDER_NUM) && (delay_index2 > -1)) //only for extruder with filament sensor and if ring buffer is initialized
{
delay_dist = delay_dist + delta_mm[E_AXIS]; //increment counter with next move in e axis
while (delay_dist >= (10*(MAX_MEASUREMENT_DELAY+1))) //check if counter is over max buffer size in mm
delay_dist = delay_dist - 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer
while (delay_dist<0)
delay_dist = delay_dist + 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer
delay_index1=delay_dist/10.0; //calculate index
//ensure the number is within range of the array after converting from floating point
if(delay_index1<0)
delay_index1=0;
else if (delay_index1>MAX_MEASUREMENT_DELAY)
delay_index1=MAX_MEASUREMENT_DELAY;
if(delay_index1 != delay_index2) //moved index
{
meas_sample=widthFil_to_size_ratio()-100; //subtract off 100 to reduce magnitude - to store in a signed char
}
while( delay_index1 != delay_index2)
{
delay_index2 = delay_index2 + 1;
if(delay_index2>MAX_MEASUREMENT_DELAY)
delay_index2=delay_index2-(MAX_MEASUREMENT_DELAY+1); //loop around buffer when incrementing
if(delay_index2<0)
delay_index2=0;
else if (delay_index2>MAX_MEASUREMENT_DELAY)
delay_index2=MAX_MEASUREMENT_DELAY;
measurement_delay[delay_index2]=meas_sample;
}
}
#endif
// Calculate and limit speed in mm/sec for each axis // Calculate and limit speed in mm/sec for each axis
float current_speed[4]; float current_speed[4];
float speed_factor = 1.0; //factor <=1 do decrease speed float speed_factor = 1.0; //factor <=1 do decrease speed

View File

@ -104,9 +104,6 @@ unsigned char soft_pwm_bed;
volatile int babystepsTodo[3]={0,0,0}; volatile int babystepsTodo[3]={0,0,0};
#endif #endif
#ifdef FILAMENT_SENSOR
int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
#endif
//=========================================================================== //===========================================================================
//=============================private variables============================ //=============================private variables============================
//=========================================================================== //===========================================================================
@ -204,9 +201,6 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
#define SOFT_PWM_SCALE 0 #define SOFT_PWM_SCALE 0
#endif #endif
#ifdef FILAMENT_SENSOR
static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor
#endif
//=========================================================================== //===========================================================================
//============================= functions ============================ //============================= functions ============================
//=========================================================================== //===========================================================================
@ -810,27 +804,6 @@ void manage_heater()
#endif #endif
#endif #endif
//code for controlling the extruder rate based on the width sensor
#ifdef FILAMENT_SENSOR
if(filament_sensor)
{
meas_shift_index=delay_index1-meas_delay_cm;
if(meas_shift_index<0)
meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed
//get the delayed info and add 100 to reconstitute to a percent of the nominal filament diameter
//then square it to get an area
if(meas_shift_index<0)
meas_shift_index=0;
else if (meas_shift_index>MAX_MEASUREMENT_DELAY)
meas_shift_index=MAX_MEASUREMENT_DELAY;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/100.0,2);
if (volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] <0.01)
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01;
}
#endif
#ifdef HOST_KEEPALIVE_FEATURE #ifdef HOST_KEEPALIVE_FEATURE
host_keepalive(); host_keepalive();
#endif #endif
@ -985,9 +958,7 @@ static void updateTemperaturesFromRawValues()
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature = analog2temp(redundant_temperature_raw, 1); redundant_temperature = analog2temp(redundant_temperature_raw, 1);
#endif #endif
#if defined (FILAMENT_SENSOR) && (FILWIDTH_PIN > -1) //check if a sensor is supported
filament_width_meas = analog2widthFil();
#endif
//Reset the watchdog after we know we have a temperature measurement. //Reset the watchdog after we know we have a temperature measurement.
watchdog_reset(); watchdog_reset();
@ -997,35 +968,6 @@ static void updateTemperaturesFromRawValues()
} }
// For converting raw Filament Width to milimeters
#ifdef FILAMENT_SENSOR
float analog2widthFil() {
return current_raw_filwidth/16383.0*5.0;
//return current_raw_filwidth;
}
// For converting raw Filament Width to a ratio
int widthFil_to_size_ratio() {
float temp;
temp=filament_width_meas;
if(filament_width_meas<MEASURED_LOWER_LIMIT)
temp=filament_width_nominal; //assume sensor cut out
else if (filament_width_meas>MEASURED_UPPER_LIMIT)
temp= MEASURED_UPPER_LIMIT;
return(filament_width_nominal/temp*100);
}
#endif
void tp_init() void tp_init()
{ {
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))

View File

@ -31,14 +31,6 @@
void tp_init(); //initialize the heating void tp_init(); //initialize the heating
void manage_heater(); //it is critical that this is called periodically. void manage_heater(); //it is critical that this is called periodically.
#ifdef FILAMENT_SENSOR
// For converting raw Filament Width to milimeters
float analog2widthFil();
// For converting raw Filament Width to an extrusion ratio
int widthFil_to_size_ratio();
#endif
// low level conversion routines // low level conversion routines
// do not use these routines and variables outside of temperature.cpp // do not use these routines and variables outside of temperature.cpp
extern int target_temperature[EXTRUDERS]; extern int target_temperature[EXTRUDERS];