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<dia in mm> 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<delay in cm> 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_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;
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];