From cff7b9b39647593fe90de7b73c6199b756c4d97c Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 21 Feb 2018 11:25:21 +0100 Subject: [PATCH] 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. --- Firmware/Configuration.h | 29 +------ Firmware/ConfigurationStore.cpp | 2 +- Firmware/Marlin.h | 13 +-- Firmware/Marlin_main.cpp | 135 +++++++------------------------- Firmware/planner.cpp | 51 +----------- Firmware/temperature.cpp | 60 +------------- Firmware/temperature.h | 8 -- 7 files changed, 32 insertions(+), 266 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index b8669c22..322ea8b2 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -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 -/**********************************************************************\ - * 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 - +#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. // Calibration status of the machine, to be stored into the EEPROM, // (unsigned char*)EEPROM_CALIBRATION_STATUS diff --git a/Firmware/ConfigurationStore.cpp b/Firmware/ConfigurationStore.cpp index 9b0d0e87..253452fe 100644 --- a/Firmware/ConfigurationStore.cpp +++ b/Firmware/ConfigurationStore.cpp @@ -472,7 +472,7 @@ void Config_ResetDefault() filament_size[2] = DEFAULT_NOMINAL_FILAMENT_DIA; #endif #endif - calculate_volumetric_multipliers(); + calculate_extruder_multipliers(); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index f3f13463..a576a1f2 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -283,17 +283,6 @@ extern void homeaxis(int axis); extern unsigned char fanSpeedSoftPwm; #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 extern bool autoretract_enabled; extern bool retracted[EXTRUDERS]; @@ -358,7 +347,7 @@ extern bool sortAlpha; extern char dir_names[3][9]; -extern void calculate_volumetric_multipliers(); +extern void calculate_extruder_multipliers(); // Similar to the default Arduino delay function, // but it keeps the background tasks running. diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a96abe2e..3b51a67c 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -334,7 +334,7 @@ float filament_size[EXTRUDERS] = { DEFAULT_NOMINAL_FILAMENT_DIA #endif #endif }; -float volumetric_multiplier[EXTRUDERS] = {1.0 +float extruder_multiplier[EXTRUDERS] = {1.0 #if EXTRUDERS > 1 , 1.0 #if EXTRUDERS > 2 @@ -411,18 +411,6 @@ bool cancel_heatup = false ; #define KEEPALIVE_STATE(n); #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 echomagic[] PROGMEM = "echo:"; @@ -1971,11 +1959,7 @@ void refresh_cmd_timeout(void) destination[Y_AXIS]=current_position[Y_AXIS]; destination[Z_AXIS]=current_position[Z_AXIS]; destination[E_AXIS]=current_position[E_AXIS]; - if (swapretract) { - current_position[E_AXIS]+=retract_length_swap/volumetric_multiplier[active_extruder]; - } else { - current_position[E_AXIS]+=retract_length/volumetric_multiplier[active_extruder]; - } + current_position[E_AXIS]+=(swapretract?retract_length_swap:retract_length)*float(extrudemultiply)*0.01f; plan_set_e_position(current_position[E_AXIS]); float oldFeedrate = feedrate; feedrate=retract_feedrate*60; @@ -1992,12 +1976,7 @@ void refresh_cmd_timeout(void) destination[E_AXIS]=current_position[E_AXIS]; 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]); - //prepare_move(); - 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]; - } + current_position[E_AXIS]-=(swapretract?(retract_length_swap+retract_recover_length_swap):(retract_length+retract_recover_length))*float(extrudemultiply)*0.01f; plan_set_e_position(current_position[E_AXIS]); float oldFeedrate = feedrate; feedrate=retract_recover_feedrate*60; @@ -5066,7 +5045,7 @@ Sigma_Exit: //reserved for setting filament diameter via UFID or filament measuring device break; } - calculate_volumetric_multipliers(); + calculate_extruder_multipliers(); } break; case 201: // M201 @@ -5234,6 +5213,7 @@ Sigma_Exit: extrudemultiply = tmp_code ; } } + calculate_extruder_multipliers(); } break; @@ -5472,69 +5452,6 @@ Sigma_Exit: } 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 { Config_StoreSettings(EEPROM_OFFSET); @@ -6527,10 +6444,19 @@ void get_coordinates() for(int8_t i=0; i < NUM_AXIS; i++) { if(code_seen(axis_codes[i])) { + bool relative = axis_relative_modes[i] || relative_mode; destination[i] = (float)code_value(); - if (i == E_AXIS && extrudemultiply != 100) - destination[i] *= (extrudemultiply * 0.01f); - if (axis_relative_modes[i] || relative_mode) + if (i == E_AXIS) { + float emult = extruder_multiplier[active_extruder]; + if (emult != 1.) { + if (! relative) { + destination[i] -= current_position[i]; + relative = true; + } + destination[i] *= emult; + } + } + if (relative) destination[i] += current_position[i]; 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 area = .0; - float radius = .0; - - radius = diameter * .5; - if (! volumetric_enabled || radius == 0) { - area = 1; - } - else { - area = M_PI * pow(radius, 2); - } - - return 1.0 / area; +float calculate_extruder_multiplier(float diameter) { + bool enabled = volumetric_enabled && diameter > 0; + float area = enabled ? (M_PI * pow(diameter * .5, 2)) : 0; + return (extrudemultiply == 100) ? + (enabled ? (1.f / area) : 1.f) : + (enabled ? ((float(extrudemultiply) * 0.01f) / area) : 1.f); } -void calculate_volumetric_multipliers() { - volumetric_multiplier[0] = calculate_volumetric_multiplier(filament_size[0]); +void calculate_extruder_multipliers() { + extruder_multiplier[0] = calculate_extruder_multiplier(filament_size[0]); #if EXTRUDERS > 1 - volumetric_multiplier[1] = calculate_volumetric_multiplier(filament_size[1]); + extruder_multiplier[1] = calculate_extruder_multiplier(filament_size[1]); #if EXTRUDERS > 2 - volumetric_multiplier[2] = calculate_volumetric_multiplier(filament_size[2]); + extruder_multiplier[2] = calculate_extruder_multiplier(filament_size[2]); #endif #endif } diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 2f5f358e..b7c22d44 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -126,10 +126,6 @@ static uint8_t g_cntr_planner_queue_min = 0; float extrude_min_temp=EXTRUDE_MINTEMP; #endif -#ifdef FILAMENT_SENSOR - static char meas_sample; //temporary variable to hold filament measurement sample -#endif - #ifdef LIN_ADVANCE float extruder_advance_k = LIN_ADVANCE_K, 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 block->steps_z = labs(target[Z_AXIS]-position[Z_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))); // 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]; #endif 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 ) { 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_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 float current_speed[4]; float speed_factor = 1.0; //factor <=1 do decrease speed diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 5e7704b8..870e60e9 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -104,9 +104,6 @@ unsigned char soft_pwm_bed; volatile int babystepsTodo[3]={0,0,0}; #endif -#ifdef FILAMENT_SENSOR - int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only -#endif //=========================================================================== //=============================private variables============================ //=========================================================================== @@ -204,9 +201,6 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0); #define SOFT_PWM_SCALE 0 #endif -#ifdef FILAMENT_SENSOR - static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor -#endif //=========================================================================== //============================= functions ============================ //=========================================================================== @@ -810,27 +804,6 @@ void manage_heater() #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 host_keepalive(); #endif @@ -985,9 +958,7 @@ static void updateTemperaturesFromRawValues() #ifdef TEMP_SENSOR_1_AS_REDUNDANT redundant_temperature = analog2temp(redundant_temperature_raw, 1); #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. 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_measMEASURED_UPPER_LIMIT) - temp= MEASURED_UPPER_LIMIT; - - -return(filament_width_nominal/temp*100); - - -} -#endif - - - - - void tp_init() { #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 73c503bc..91791c4c 100644 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -31,14 +31,6 @@ void tp_init(); //initialize the heating 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 // do not use these routines and variables outside of temperature.cpp extern int target_temperature[EXTRUDERS];