Real-time filament diameter measurement and control
This feature allows the printer to read the filament diameter automatically and adjust the printer in real time. Added code to read an analog voltage that represents a filament diameter measurement. This measurement is delayed in a ring buffer to compensate for sensors that are a distance away from the extruder. The measurement is used to adjust the volumetric_multiplier for the extruder. Some additional g codes (M404, M405, M406, M407) are used to set parameters and turn on/off the control. g code M221 is updated. Pins for RAMPS1.4, RAMBO, and Printrboard are identified for analog input. The configuration file is updated with relevant user parameters.
This commit is contained in:
@ -71,7 +71,10 @@ unsigned char soft_pwm_bed;
|
||||
#ifdef BABYSTEPPING
|
||||
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============================
|
||||
//===========================================================================
|
||||
@ -158,6 +161,9 @@ 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 ============================
|
||||
//===========================================================================
|
||||
@ -601,6 +607,21 @@ 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 adjust as a factor to the Standard Diameter (has an area of 1mm squared)
|
||||
//then square it to get an area
|
||||
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/filament_width_nominal*STANDARD_DIA/100.0,2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define PGM_RD_W(x) (short)pgm_read_word(&x)
|
||||
@ -702,6 +723,40 @@ static void updateTemperaturesFromRawValues()
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
|
||||
// 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 an volumetric ratio
|
||||
int widthFil_to_size_ratio() {
|
||||
|
||||
float temp;
|
||||
|
||||
#if (FILWIDTH_PIN > -1) //check if a sensor is supported
|
||||
filament_width_meas=current_raw_filwidth/16383.0*5.0;
|
||||
#endif
|
||||
|
||||
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()
|
||||
{
|
||||
#if (MOTHERBOARD == 80) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
|
||||
@ -797,6 +852,17 @@ void tp_init()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Added for Filament Sensor
|
||||
#ifdef FILAMENT_SENSOR
|
||||
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1)
|
||||
#if FILWIDTH_PIN < 8
|
||||
DIDR0 |= 1<<FILWIDTH_PIN;
|
||||
#else
|
||||
DIDR2 |= 1<<(FILWIDTH_PIN - 8);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Use timer0 for temperature measurement
|
||||
// Interleave temperature interrupt with millies interrupt
|
||||
OCR0B = 128;
|
||||
@ -1109,7 +1175,7 @@ ISR(TIMER0_COMPB_vect)
|
||||
static unsigned long raw_temp_1_value = 0;
|
||||
static unsigned long raw_temp_2_value = 0;
|
||||
static unsigned long raw_temp_bed_value = 0;
|
||||
static unsigned char temp_state = 8;
|
||||
static unsigned char temp_state = 10;
|
||||
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
|
||||
static unsigned char soft_pwm_0;
|
||||
#if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
|
||||
@ -1122,6 +1188,10 @@ ISR(TIMER0_COMPB_vect)
|
||||
static unsigned char soft_pwm_b;
|
||||
#endif
|
||||
|
||||
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
|
||||
static unsigned long raw_filwidth_value = 0; //added for filament width sensor
|
||||
#endif
|
||||
|
||||
if(pwm_count == 0){
|
||||
soft_pwm_0 = soft_pwm[0];
|
||||
if(soft_pwm_0 > 0) {
|
||||
@ -1248,10 +1318,39 @@ ISR(TIMER0_COMPB_vect)
|
||||
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
|
||||
raw_temp_2_value += ADC;
|
||||
#endif
|
||||
temp_state = 0;
|
||||
temp_count++;
|
||||
temp_state = 8;//change so that Filament Width is also measured
|
||||
|
||||
break;
|
||||
case 8: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
|
||||
case 8: //Prepare FILWIDTH
|
||||
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1)
|
||||
#if FILWIDTH_PIN>7
|
||||
ADCSRB = 1<<MUX5;
|
||||
#else
|
||||
ADCSRB = 0;
|
||||
#endif
|
||||
ADMUX = ((1 << REFS0) | (FILWIDTH_PIN & 0x07));
|
||||
ADCSRA |= 1<<ADSC; // Start conversion
|
||||
#endif
|
||||
lcd_buttons_update();
|
||||
temp_state = 9;
|
||||
break;
|
||||
case 9: //Measure FILWIDTH
|
||||
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
|
||||
//raw_filwidth_value += ADC; //remove to use an IIR filter approach
|
||||
if(ADC>102) //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
|
||||
{
|
||||
raw_filwidth_value= raw_filwidth_value-(raw_filwidth_value>>7); //multipliy raw_filwidth_value by 127/128
|
||||
|
||||
raw_filwidth_value= raw_filwidth_value + ((unsigned long)ADC<<7); //add new ADC reading
|
||||
}
|
||||
#endif
|
||||
temp_state = 0;
|
||||
|
||||
temp_count++;
|
||||
break;
|
||||
|
||||
|
||||
case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
|
||||
temp_state = 0;
|
||||
break;
|
||||
// default:
|
||||
@ -1260,7 +1359,7 @@ ISR(TIMER0_COMPB_vect)
|
||||
// break;
|
||||
}
|
||||
|
||||
if(temp_count >= OVERSAMPLENR) // 8 * 16 * 1/(16000000/64/256) = 131ms.
|
||||
if(temp_count >= OVERSAMPLENR) // 10 * 16 * 1/(16000000/64/256) = 164ms.
|
||||
{
|
||||
if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
|
||||
{
|
||||
@ -1276,6 +1375,12 @@ ISR(TIMER0_COMPB_vect)
|
||||
#endif
|
||||
current_temperature_bed_raw = raw_temp_bed_value;
|
||||
}
|
||||
|
||||
//Add similar code for Filament Sensor - can be read any time since IIR filtering is used
|
||||
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
|
||||
current_raw_filwidth = raw_filwidth_value>>10; //need to divide to get to 0-16384 range since we used 1/128 IIR filter approach
|
||||
#endif
|
||||
|
||||
|
||||
temp_meas_ready = true;
|
||||
temp_count = 0;
|
||||
|
Reference in New Issue
Block a user