From 1d0fe035f3aeb4af0e686fcb13c9a720248db462 Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Mon, 4 Aug 2014 21:44:04 -0500 Subject: [PATCH 1/7] Change pinMode to SET_INPUT or SET_OUTPUT Original code is using WRITE from fastio, but original used pinMode to set pin direction and did not use the fastio SET_INPUT or SET_OUTPUT. This caused an issue with the rotary encoder interface to boards based on teensyduino, since for teensyduino pin numbers for fastio and the usual Arduino IO are different. --- Marlin/ultralcd.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 9797b0bff1..e6774108ac 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -1133,30 +1133,30 @@ void lcd_init() lcd_implementation_init(); #ifdef NEWPANEL - pinMode(BTN_EN1,INPUT); - pinMode(BTN_EN2,INPUT); + SET_INPUT(BTN_EN1); + SET_INPUT(BTN_EN2); WRITE(BTN_EN1,HIGH); WRITE(BTN_EN2,HIGH); #if BTN_ENC > 0 - pinMode(BTN_ENC,INPUT); + SET_INPUT(BTN_ENC); WRITE(BTN_ENC,HIGH); #endif #ifdef REPRAPWORLD_KEYPAD - pinMode(SHIFT_CLK,OUTPUT); - pinMode(SHIFT_LD,OUTPUT); - pinMode(SHIFT_OUT,INPUT); + SET_OUTPUT(SHIFT_CLK); + SET_OUTPUT(SHIFT_LD); + SET_INPUT(SHIFT_OUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); #endif #else // Not NEWPANEL #ifdef SR_LCD_2W_NL // Non latching 2 wire shift register - pinMode (SR_DATA_PIN, OUTPUT); - pinMode (SR_CLK_PIN, OUTPUT); + SET_OUTPUT(SR_DATA_PIN); + SET_OUTPUT(SR_CLK_PIN); #elif defined(SHIFT_CLK) - pinMode(SHIFT_CLK,OUTPUT); - pinMode(SHIFT_LD,OUTPUT); - pinMode(SHIFT_EN,OUTPUT); - pinMode(SHIFT_OUT,INPUT); + SET_OUTPUT(SHIFT_CLK); + SET_OUTPUT(SHIFT_LD); + SET_OUTPUT(SHIFT_EN); + SET_INPUT(SHIFT_OUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); WRITE(SHIFT_EN,LOW); @@ -1168,7 +1168,7 @@ void lcd_init() #endif//!NEWPANEL #if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0) - pinMode(SDCARDDETECT,INPUT); + SET_INPUT(SDCARDDETECT); WRITE(SDCARDDETECT, HIGH); lcd_oldcardstatus = IS_SD_INSERTED; #endif//(SDCARDDETECT > 0) From 85649a4549bc0a3613f675149997210ad5ab26da Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Wed, 6 Aug 2014 19:30:57 -0500 Subject: [PATCH 2/7] 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. --- Marlin/Configuration.h | 30 +++++++++++ Marlin/Marlin.h | 10 ++++ Marlin/Marlin_main.cpp | 84 ++++++++++++++++++++++++++++- Marlin/pins.h | 16 ++++++ Marlin/planner.cpp | 31 +++++++++++ Marlin/temperature.cpp | 117 ++++++++++++++++++++++++++++++++++++++--- Marlin/temperature.h | 8 +++ 7 files changed, 289 insertions(+), 7 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 46d6b96dd1..45c6ea4864 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -755,6 +755,36 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of //#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1 //#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 70,0} // X,Y,Z Axis Extend and Retract angles +/**********************************************************************\ + * 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 Aux 2 connector + * 301 - Rambo - uses Analog input 3 + * Note may require analog pins to be defined for different motherboards + **********************************************************************/ +#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). 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 +#define STANDARD_DIA 1.12837915 //The diameter of filament that has a cross sectional area of 1 square mm. This dia should be used in the slicer software settings + + + + + + + #include "Configuration_adv.h" #include "thermistortables.h" diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 062b6d43c4..3fb6ec5531 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -229,6 +229,16 @@ extern int EtoPPressure; extern unsigned char fanSpeedSoftPwm; #endif +#ifdef FILAMENT_SENSOR + extern volatile float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75 + extern volatile 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]; diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index b373e22137..48d867c833 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -157,6 +157,10 @@ // M400 - Finish all moves // M401 - Lower z-probe if present // M402 - Raise z-probe if present +// M404 - N Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters +// M405 - Turn on Filament Sensor extrusion control. Optional D to set delay in centimeters between sensor and extruder +// M406 - Turn off Filament Sensor extrusion control +// M407 - Displays measured filament diameter // M500 - stores parameters in EEPROM // M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). // M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. @@ -296,6 +300,18 @@ int EtoPPressure=0; bool cancel_heatup = false ; +#ifdef FILAMENT_SENSOR + //Variables for Filament Sensor input + volatile float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404 + volatile 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; + int delay_index2=0; //index into ring buffer + float delay_dist=0; //delay distance counter + int meas_delay_cm = MEASUREMENT_DELAY_CM; //distance delay setting +#endif + //=========================================================================== //=============================Private Variables============================= //=========================================================================== @@ -2317,7 +2333,13 @@ void process_commands() } } else { //reserved for setting filament diameter via UFID or filament measuring device - break; + if(active_extruder == FILAMENT_SENSOR_EXTRUDER_NUM){ + radius = analog2widthFil() * 0.5; + area = M_PI * pow(radius, 2); + }else{ + area = 1.0; + } + } tmp_extruder = active_extruder; if(code_seen('T')) { @@ -2771,6 +2793,66 @@ void process_commands() } break; #endif + +#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; + + filament_sensor = true ; + 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; + + //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 + { + + filament_width_meas = code_value(); + + SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); + SERIAL_PROTOCOLLN(filament_width_meas); + } + break; + #endif + + + + + case 500: // M500 Store settings in EEPROM { Config_StoreSettings(); diff --git a/Marlin/pins.h b/Marlin/pins.h index c3644a086a..1ec236a074 100644 --- a/Marlin/pins.h +++ b/Marlin/pins.h @@ -558,6 +558,15 @@ #define E1_DIR_PIN 34 #define E1_ENABLE_PIN 30 +#if MOTHERBOARD == 34 //FMM added for Filament Extruder +#ifdef FILAMENT_SENSOR + //define analog pin for the filament width sensor input + //Use the RAMPS 1.4 Analog input 5 on the AUX2 connector + #define FILWIDTH_PIN 5 +#endif +#endif + + #if MOTHERBOARD == 68 #define E2_STEP_PIN 23 #define E2_DIR_PIN 25 @@ -1692,6 +1701,9 @@ #define Z_STOP_PIN 36 #define TEMP_0_PIN 1 // Extruder / Analog pin numbering #define TEMP_BED_PIN 0 // Bed / Analog pin numbering + #ifdef FILAMENT_SENSOR + #define FILWIDTH_PIN 2 + #endif //FILAMENT_SENSOR #endif #define TEMP_1_PIN -1 @@ -2326,6 +2338,10 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a #endif #endif //ULTRA_LCD +#ifdef FILAMENT_SENSOR + //Filip added pin for Filament sensor analog input + #define FILWIDTH_PIN 3 +#endif //FILAMENT_SENSOR #endif diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 5b20f86f99..fefae6e181 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -117,6 +117,10 @@ static long x_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; // Segment times (in static long y_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; #endif +#ifdef FILAMENT_SENSOR + static char meas_sample; //temporary variable to hold filament measurement sample +#endif + // Returns the index of the next block in the ring buffer // NOTE: Removed modulo (%) operator, which uses an expensive divide and multiplication. static int8_t next_block_index(int8_t block_index) { @@ -737,6 +741,33 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi 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(filament_sensor && (extruder==0)) //only for extruder 0 + { + delay_dist = delay_dist + delta_mm[E_AXIS]; //increment counter with next move in e axis + if (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 + if(delay_dist<0) + delay_dist = delay_dist + 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer + delay_index1=delay_dist/10; //calculate index + 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 + 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/Marlin/temperature.cpp b/Marlin/temperature.cpp index a10c255af9..467b6dbdb3 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -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_measMEASURED_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< 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< -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; diff --git a/Marlin/temperature.h b/Marlin/temperature.h index df2b5deacf..ca4efabec1 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -31,6 +31,14 @@ 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]; From 62db9848d3f9ffcfe73e74cc7069fb4fe2b63b64 Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Sat, 16 Aug 2014 06:50:13 -0500 Subject: [PATCH 3/7] Improvements and bug fixes in sensor delay buffer for filament sensor code Improvement to avoid reinitializing delay buffer with every print. Fixed issues in buffer indexing and memory out of bounds due to floating point imprecision. Simplified the code by avoiding conversion to standard diameter and 1cu mm extrusion, which caused complications in determining mm extruded. --- Marlin/Marlin.h | 4 ++-- Marlin/Marlin_main.cpp | 40 +++++++++++++++++++++------------------- Marlin/planner.cpp | 28 ++++++++++++++++++++++------ Marlin/temperature.cpp | 22 ++++++++++++++-------- 4 files changed, 59 insertions(+), 35 deletions(-) diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 3fb6ec5531..7ced062964 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -230,8 +230,8 @@ extern unsigned char fanSpeedSoftPwm; #endif #ifdef FILAMENT_SENSOR - extern volatile float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75 - extern volatile bool filament_sensor; //indicates that filament sensor readings should control extrusion + 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 diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 48d867c833..6ce02d364a 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -302,12 +302,12 @@ bool cancel_heatup = false ; #ifdef FILAMENT_SENSOR //Variables for Filament Sensor input - volatile float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404 - volatile bool filament_sensor=false; //M405 turns on filament_sensor control, M406 turns it off + 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; - int delay_index2=0; //index into ring buffer + 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 @@ -504,6 +504,7 @@ void servo_init() #endif } + void setup() { setup_killpin(); @@ -553,6 +554,7 @@ void setup() st_init(); // Initialize stepper, this enables interrupts! setup_photpin(); servo_init(); + lcd_init(); _delay_ms(1000); // wait 1sec to display the splash screen @@ -2333,12 +2335,8 @@ void process_commands() } } else { //reserved for setting filament diameter via UFID or filament measuring device - if(active_extruder == FILAMENT_SENSOR_EXTRUDER_NUM){ - radius = analog2widthFil() * 0.5; - area = M_PI * pow(radius, 2); - }else{ - area = 1.0; - } + break; + } tmp_extruder = active_extruder; @@ -2816,15 +2814,19 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp if(meas_delay_cm> MAX_MEASUREMENT_DELAY) meas_delay_cm = MAX_MEASUREMENT_DELAY; - filament_sensor = true ; - int temp_ratio = widthFil_to_size_ratio(); + 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 ; - 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; - //SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); //SERIAL_PROTOCOL(filament_width_meas); //SERIAL_PROTOCOLPGM("Extrusion ratio(%):"); @@ -2841,7 +2843,7 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp case 407: //M407 Display measured filament diameter { - filament_width_meas = code_value(); + SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); SERIAL_PROTOCOLLN(filament_width_meas); diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index fefae6e181..aac41faa7b 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -743,15 +743,25 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi #ifdef FILAMENT_SENSOR //FMM update ring buffer used for delay with filament measurements - - if(filament_sensor && (extruder==0)) //only for extruder 0 + + + 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 - if (delay_dist> (10*(MAX_MEASUREMENT_DELAY+1))) //check if counter is over max buffer size in mm + + 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 - if(delay_dist<0) + while (delay_dist<0) delay_dist = delay_dist + 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer - delay_index1=delay_dist/10; //calculate index + + 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 @@ -761,10 +771,16 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi 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 diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 467b6dbdb3..46cdc7cfbb 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -617,9 +617,16 @@ void manage_heater() 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); + + 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 } @@ -715,6 +722,9 @@ static void updateTemperaturesFromRawValues() #ifdef TEMP_SENSOR_1_AS_REDUNDANT redundant_temperature = analog2temp(redundant_temperature_raw, 1); #endif + #ifdef 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(); @@ -731,15 +741,11 @@ return current_raw_filwidth/16383.0*5.0; //return current_raw_filwidth; } -// For converting raw Filament Width to an volumetric ratio +// For converting raw Filament Width to a 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 Date: Sat, 16 Aug 2014 07:08:09 -0500 Subject: [PATCH 4/7] Filament sensor changes to config file Update the config file for improvements and clarifying what diameter to use in the slicer software. --- Marlin/Configuration.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 45c6ea4864..c877eec90a 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -770,14 +770,13 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of #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). Used for sensor reading validation +#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 -#define STANDARD_DIA 1.12837915 //The diameter of filament that has a cross sectional area of 1 square mm. This dia should be used in the slicer software settings From 75b3a68b65c53b1439756ea287158ca1bd63586a Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Sat, 16 Aug 2014 13:26:48 -0500 Subject: [PATCH 5/7] Revert "Change pinMode to SET_INPUT or SET_OUTPUT" This reverts commit 1d0fe035f3aeb4af0e686fcb13c9a720248db462. --- Marlin/ultralcd.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index e6774108ac..9797b0bff1 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -1133,30 +1133,30 @@ void lcd_init() lcd_implementation_init(); #ifdef NEWPANEL - SET_INPUT(BTN_EN1); - SET_INPUT(BTN_EN2); + pinMode(BTN_EN1,INPUT); + pinMode(BTN_EN2,INPUT); WRITE(BTN_EN1,HIGH); WRITE(BTN_EN2,HIGH); #if BTN_ENC > 0 - SET_INPUT(BTN_ENC); + pinMode(BTN_ENC,INPUT); WRITE(BTN_ENC,HIGH); #endif #ifdef REPRAPWORLD_KEYPAD - SET_OUTPUT(SHIFT_CLK); - SET_OUTPUT(SHIFT_LD); - SET_INPUT(SHIFT_OUT); + pinMode(SHIFT_CLK,OUTPUT); + pinMode(SHIFT_LD,OUTPUT); + pinMode(SHIFT_OUT,INPUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); #endif #else // Not NEWPANEL #ifdef SR_LCD_2W_NL // Non latching 2 wire shift register - SET_OUTPUT(SR_DATA_PIN); - SET_OUTPUT(SR_CLK_PIN); + pinMode (SR_DATA_PIN, OUTPUT); + pinMode (SR_CLK_PIN, OUTPUT); #elif defined(SHIFT_CLK) - SET_OUTPUT(SHIFT_CLK); - SET_OUTPUT(SHIFT_LD); - SET_OUTPUT(SHIFT_EN); - SET_INPUT(SHIFT_OUT); + pinMode(SHIFT_CLK,OUTPUT); + pinMode(SHIFT_LD,OUTPUT); + pinMode(SHIFT_EN,OUTPUT); + pinMode(SHIFT_OUT,INPUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); WRITE(SHIFT_EN,LOW); @@ -1168,7 +1168,7 @@ void lcd_init() #endif//!NEWPANEL #if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0) - SET_INPUT(SDCARDDETECT); + pinMode(SDCARDDETECT,INPUT); WRITE(SDCARDDETECT, HIGH); lcd_oldcardstatus = IS_SD_INSERTED; #endif//(SDCARDDETECT > 0) From fe3a09bbcfe2866752df01394fbfcb117f1dc80c Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Mon, 1 Sep 2014 06:26:19 -0500 Subject: [PATCH 6/7] Correct analog sampling time for additional A to D sample Adjusted the #define PID_dT to reflect 10 A to D sample steps, vs original 8. --- Marlin/Configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index c877eec90a..c838d6ceeb 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -185,7 +185,7 @@ // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. #define PID_INTEGRAL_DRIVE_MAX 255 //limit for the integral term #define K1 0.95 //smoothing factor within the PID - #define PID_dT ((OVERSAMPLENR * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine + #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it // Ultimaker From 9bc7aec349ec47bab359357ed38e115fc7af7b44 Mon Sep 17 00:00:00 2001 From: filipmu Date: Sat, 6 Sep 2014 21:55:47 -0500 Subject: [PATCH 7/7] Update README.md Added the new m-codes to this document. --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 17e920ec00..f21883e36d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ========================== Marlin 3D Printer Firmware ========================== -[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224) - +[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224) + Marlin has a GPL license because I believe in open development. Please do not use this code in products (3D printers, CNC etc) that are closed source or are crippled by a patent. @@ -207,15 +207,15 @@ M Codes * M140 - Set bed target temp * M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating * Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling -* M200 D- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters). +* M200 D- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters). * M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) * M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!! * M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec * M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate * M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk * M206 - set additional homeing offset -* M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting -* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min] +* M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting +* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min] * M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction. * M218 - set hotend offset (in mm): T X Y * M220 S- set speed factor override percentage @@ -230,6 +230,10 @@ M Codes * M400 - Finish all moves * M401 - Lower z-probe if present * M402 - Raise z-probe if present +* M404 - N Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters +* M405 - Turn on Filament Sensor extrusion control. Optional D to set delay in centimeters between sensor and extruder +* M406 - Turn off Filament Sensor extrusion control +* M407 - Displays measured filament diameter * M500 - stores paramters in EEPROM * M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). * M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.