diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp
index 6d4777701f429cb8501fee75aa9f1ad2cc0f3547..574c438ad4891bd4cfdee8d5e65bb9f9763736c6 100644
--- a/Marlin/ConfigurationStore.cpp
+++ b/Marlin/ConfigurationStore.cpp
@@ -3,26 +3,26 @@
 #include "temperature.h"
 #include "ultralcd.h"
 #include "ConfigurationStore.h"
-
-void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size)
-{
-    do
-    {
-        eeprom_write_byte((unsigned char*)pos, *value);
-        pos++;
-        value++;
+
+void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size)
+{
+    do
+    {
+        eeprom_write_byte((unsigned char*)pos, *value);
+        pos++;
+        value++;
     }while(--size);
-}
+}
 #define EEPROM_WRITE_VAR(pos, value) _EEPROM_writeData(pos, (uint8_t*)&value, sizeof(value))
-void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size)
-{
-    do
-    {
-        *value = eeprom_read_byte((unsigned char*)pos);
-        pos++;
-        value++;
+void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size)
+{
+    do
+    {
+        *value = eeprom_read_byte((unsigned char*)pos);
+        pos++;
+        value++;
     }while(--size);
-}
+}
 #define EEPROM_READ_VAR(pos, value) _EEPROM_readData(pos, (uint8_t*)&value, sizeof(value))
 //======================================================================================
 
@@ -43,7 +43,7 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size)
 void Config_StoreSettings() 
 {
   char ver[4]= "000";
-  int i=EEPROM_OFFSET;
+  int i=EEPROM_OFFSET;
   EEPROM_WRITE_VAR(i,ver); // invalidate data first 
   EEPROM_WRITE_VAR(i,axis_steps_per_unit);  
   EEPROM_WRITE_VAR(i,max_feedrate);  
@@ -58,8 +58,8 @@ void Config_StoreSettings()
   EEPROM_WRITE_VAR(i,max_e_jerk);
   EEPROM_WRITE_VAR(i,add_homeing);
   #ifndef ULTIPANEL
-  int plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP, plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP, plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED;
-  int absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP, absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP, absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED;
+  int plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP, plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP, plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED;
+  int absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP, absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP, absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED;
   #endif
   EEPROM_WRITE_VAR(i,plaPreheatHotendTemp);
   EEPROM_WRITE_VAR(i,plaPreheatHPBTemp);
@@ -75,7 +75,7 @@ void Config_StoreSettings()
     EEPROM_WRITE_VAR(i,3000);
     EEPROM_WRITE_VAR(i,0);
     EEPROM_WRITE_VAR(i,0);
-  #endif
+  #endif
   char ver2[4]=EEPROM_VERSION;
   i=EEPROM_OFFSET;
   EEPROM_WRITE_VAR(i,ver2); // validate data
@@ -105,7 +105,7 @@ void Config_PrintSettings()
     SERIAL_ECHOPAIR(" Z", max_feedrate[2] ); 
     SERIAL_ECHOPAIR(" E", max_feedrate[3]);
     SERIAL_ECHOLN("");
-
+
     SERIAL_ECHO_START;
     SERIAL_ECHOLNPGM("Maximum Acceleration (mm/s2):");
     SERIAL_ECHO_START;
@@ -120,9 +120,9 @@ void Config_PrintSettings()
     SERIAL_ECHOPAIR("  M204 S",acceleration ); 
     SERIAL_ECHOPAIR(" T" ,retract_acceleration);
     SERIAL_ECHOLN("");
-
+
     SERIAL_ECHO_START;
-    SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s),  Z=maximum Z jerk (mm/s)");
+    SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s),  Z=maximum Z jerk (mm/s),  E=maximum E jerk (mm/s)");
     SERIAL_ECHO_START;
     SERIAL_ECHOPAIR("  M205 S",minimumfeedrate ); 
     SERIAL_ECHOPAIR(" T" ,mintravelfeedrate ); 
@@ -131,7 +131,7 @@ void Config_PrintSettings()
     SERIAL_ECHOPAIR(" Z" ,max_z_jerk);
     SERIAL_ECHOPAIR(" E" ,max_e_jerk);
     SERIAL_ECHOLN(""); 
-
+
     SERIAL_ECHO_START;
     SERIAL_ECHOLNPGM("Home offset (mm):");
     SERIAL_ECHO_START;
@@ -144,8 +144,8 @@ void Config_PrintSettings()
     SERIAL_ECHOLNPGM("PID settings:");
     SERIAL_ECHO_START;
     SERIAL_ECHOPAIR("   M301 P",Kp); 
-    SERIAL_ECHOPAIR(" I" ,Ki/PID_dT); 
-    SERIAL_ECHOPAIR(" D" ,Kd*PID_dT);
+    SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki)); 
+    SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd));
     SERIAL_ECHOLN(""); 
 #endif
 } 
@@ -161,11 +161,15 @@ void Config_RetrieveSettings()
     EEPROM_READ_VAR(i,stored_ver); //read stored version
     //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
     if (strncmp(ver,stored_ver,3) == 0)
-    {
+    {
         // version number match
         EEPROM_READ_VAR(i,axis_steps_per_unit);  
         EEPROM_READ_VAR(i,max_feedrate);  
         EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second);
+        
+        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
+		reset_acceleration_rates();
+        
         EEPROM_READ_VAR(i,acceleration);
         EEPROM_READ_VAR(i,retract_acceleration);
         EEPROM_READ_VAR(i,minimumfeedrate);
@@ -176,36 +180,37 @@ void Config_RetrieveSettings()
         EEPROM_READ_VAR(i,max_e_jerk);
         EEPROM_READ_VAR(i,add_homeing);
         #ifndef ULTIPANEL
-        int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
-        int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
+        int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
+        int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
         #endif
         EEPROM_READ_VAR(i,plaPreheatHotendTemp);
         EEPROM_READ_VAR(i,plaPreheatHPBTemp);
         EEPROM_READ_VAR(i,plaPreheatFanSpeed);
         EEPROM_READ_VAR(i,absPreheatHotendTemp);
         EEPROM_READ_VAR(i,absPreheatHPBTemp);
-        EEPROM_READ_VAR(i,absPreheatFanSpeed);
+        EEPROM_READ_VAR(i,absPreheatFanSpeed);
         #ifndef PIDTEMP
         float Kp,Ki,Kd;
         #endif
+        // do not need to scale PID values as the values in EEPROM are already scaled		
         EEPROM_READ_VAR(i,Kp);
         EEPROM_READ_VAR(i,Ki);
         EEPROM_READ_VAR(i,Kd);
 
+		// Call updatePID (similar to when we have processed M301)
+		updatePID();
         SERIAL_ECHO_START;
-        SERIAL_ECHOLNPGM("Stored settings retreived:");
+        SERIAL_ECHOLNPGM("Stored settings retrieved");
+    }
+    else
+    {
+        Config_ResetDefault();
     }
-    else
-    {
-        Config_ResetDefault();
-        SERIAL_ECHO_START;
-        SERIAL_ECHOLN("Using Default settings:");
-    }
     Config_PrintSettings();
 }
-#endif
-
-void Config_ResetDefault()
+#endif
+
+void Config_ResetDefault()
 {
     float tmp1[]=DEFAULT_AXIS_STEPS_PER_UNIT;
     float tmp2[]=DEFAULT_MAX_FEEDRATE;
@@ -216,6 +221,10 @@ void Config_ResetDefault()
         max_feedrate[i]=tmp2[i];  
         max_acceleration_units_per_sq_second[i]=tmp3[i];
     }
+    
+    // steps per sq second need to be updated to agree with the units per sq second
+    reset_acceleration_rates();
+    
     acceleration=DEFAULT_ACCELERATION;
     retract_acceleration=DEFAULT_RETRACT_ACCELERATION;
     minimumfeedrate=DEFAULT_MINIMUMFEEDRATE;
@@ -234,11 +243,19 @@ void Config_ResetDefault()
     absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED;
 #endif
 #ifdef PIDTEMP
-    Kp = DEFAULT_Kp;
-    Ki = (DEFAULT_Ki*PID_dT);
-    Kd = (DEFAULT_Kd/PID_dT);
+    Kp = DEFAULT_Kp;
+    Ki = scalePID_i(DEFAULT_Ki);
+    Kd = scalePID_d(DEFAULT_Kd);
+    
+    // call updatePID (similar to when we have processed M301)
+    updatePID();
+    
 #ifdef PID_ADD_EXTRUSION_RATE
     Kc = DEFAULT_Kc;
 #endif//PID_ADD_EXTRUSION_RATE
 #endif//PIDTEMP
+
+SERIAL_ECHO_START;
+SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded");
+
 }
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 016a2036e353555e58f893b66d90a45830f39273..a76f321ede9030221b37e5603ee052156e01938c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -363,13 +363,8 @@ void setup()
     fromsd[i] = false;
   }
   
-  Config_RetrieveSettings(); // loads data from EEPROM if available
-
-  for(int8_t i=0; i < NUM_AXIS; i++)
-  {
-    axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i];
-  }
-
+  // loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
+  Config_RetrieveSettings(); 
 
   tp_init();    // Initialize temperature loop 
   plan_init();  // Initialize planner;
@@ -1323,9 +1318,10 @@ void process_commands()
         if(code_seen(axis_codes[i]))
         {
           max_acceleration_units_per_sq_second[i] = code_value();
-          axis_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i];
         }
       }
+      // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
+	  reset_acceleration_rates();
       break;
     #if 0 // Not used for Sprinter/grbl gen6
     case 202: // M202
@@ -1468,22 +1464,25 @@ void process_commands()
     case 301: // M301
       {
         if(code_seen('P')) Kp = code_value();
-        if(code_seen('I')) Ki = code_value()*PID_dT;
-        if(code_seen('D')) Kd = code_value()/PID_dT;
+        if(code_seen('I')) Ki = scalePID_i(code_value());
+        if(code_seen('D')) Kd = scalePID_d(code_value());
+
         #ifdef PID_ADD_EXTRUSION_RATE
         if(code_seen('C')) Kc = code_value();
         #endif
+        
         updatePID();
         SERIAL_PROTOCOL(MSG_OK);
 		SERIAL_PROTOCOL(" p:");
         SERIAL_PROTOCOL(Kp);
         SERIAL_PROTOCOL(" i:");
-        SERIAL_PROTOCOL(Ki/PID_dT);
+        SERIAL_PROTOCOL(unscalePID_i(Ki));
         SERIAL_PROTOCOL(" d:");
-        SERIAL_PROTOCOL(Kd*PID_dT);
+        SERIAL_PROTOCOL(unscalePID_d(Kd));
         #ifdef PID_ADD_EXTRUSION_RATE
         SERIAL_PROTOCOL(" c:");
-        SERIAL_PROTOCOL(Kc*PID_dT);
+        //Kc does not have scaling applied above, or in resetting defaults
+        SERIAL_PROTOCOL(Kc);
         #endif
         SERIAL_PROTOCOLLN("");
       }
@@ -1493,16 +1492,18 @@ void process_commands()
     case 304: // M304
       {
         if(code_seen('P')) bedKp = code_value();
-        if(code_seen('I')) bedKi = code_value()*PID_dT;
-        if(code_seen('D')) bedKd = code_value()/PID_dT;
+        if(code_seen('I')) bedKi = scalePID_i(code_value());
+        if(code_seen('D')) bedKd = scalePID_d(code_value());
+        // Scale the Bed PID values by PID_dT
+        scaleBedPID();
         updatePID();
         SERIAL_PROTOCOL(MSG_OK);
 		SERIAL_PROTOCOL(" p:");
         SERIAL_PROTOCOL(bedKp);
         SERIAL_PROTOCOL(" i:");
-        SERIAL_PROTOCOL(bedKi/PID_dT);
+        SERIAL_PROTOCOL(unscalePID_i(bedKi));
         SERIAL_PROTOCOL(" d:");
-        SERIAL_PROTOCOL(bedKd*PID_dT);
+        SERIAL_PROTOCOL(unscalePID_d(bedKd));
         SERIAL_PROTOCOLLN("");
       }
       break;
diff --git a/Marlin/language.h b/Marlin/language.h
index c3eb71d5ed03e5d7b6851cf59af617bf5a546345..f562ea2824a056f8f642867145429e541b55c599 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -75,7 +75,9 @@
 	#define MSG_PID_D "PID-D"
 	#define MSG_PID_C "PID-C"
 	#define MSG_ACC  "Accel"
-	#define MSG_VXY_JERK "Vxy-jerk"
+	#define MSG_VXY_JERK "Vxy-jerk"
+	#define MSG_VZ_JERK "Vz-jerk"
+	#define MSG_VE_JERK "Ve-jerk"
 	#define MSG_VMAX "Vmax "
 	#define MSG_X "x"
 	#define MSG_Y "y"
@@ -233,6 +235,8 @@
 	#define MSG_PID_C "PID-C"
 	#define MSG_ACC  "Acc"
 	#define MSG_VXY_JERK "Zryw Vxy"
+	#define MSG_VZ_JERK "Zryw Vz"
+	#define MSG_VE_JERK "Zryw Ve"
 	#define MSG_VMAX "Vmax"
 	#define MSG_X "x"
 	#define MSG_Y "y"
@@ -391,7 +395,9 @@
 #define MSG_PID_D " PID-D: "
 #define MSG_PID_C " PID-C: "
 #define MSG_ACC " Acc:"
-#define MSG_VXY_JERK " Vxy-jerk: "
+#define MSG_VXY_JERK "Vxy-jerk"
+#define MSG_VZ_JERK "Vz-jerk"
+#define MSG_VE_JERK "Ve-jerk"
 #define MSG_VMAX " Vmax "
 #define MSG_X "x:"
 #define MSG_Y "y:"
@@ -555,6 +561,8 @@
 	#define MSG_PID_C            "PID-C"
 	#define MSG_ACC              "Acc"
 	#define MSG_VXY_JERK         "Vxy-jerk"
+	#define MSG_VZ_JERK          "Vz-jerk"
+	#define MSG_VE_JERK          "Ve-jerk"
 	#define MSG_VMAX             "Vmax "
 	#define MSG_X                "x"
 	#define MSG_Y                "y"
@@ -713,6 +721,8 @@
 #define MSG_PID_C " PID-C: "
 #define MSG_ACC  " Acc:"
 #define MSG_VXY_JERK " Vxy-jerk: "
+#define MSG_VZ_JERK "Vz-jerk"
+#define MSG_VE_JERK "Ve-jerk"
 #define MSG_VMAX " Vmax "
 #define MSG_X "x:"
 #define MSG_Y "y:"
@@ -871,6 +881,8 @@
 #define MSG_PID_C							" PID-C: "
 #define MSG_ACC								" Acc:"
 #define MSG_VXY_JERK						" Vxy-jerk: "
+#define MSG_VZ_JERK                         "Vz-jerk"
+#define MSG_VE_JERK                         "Ve-jerk"
 #define MSG_VMAX							" Vmax "
 #define MSG_X								"x:"
 #define MSG_Y								"y:"
@@ -1024,6 +1036,8 @@
 	#define MSG_PID_C                "PID-C"
 	#define MSG_ACC                  "Accel"
 	#define MSG_VXY_JERK             "Vxy-jerk"
+	#define MSG_VZ_JERK              "Vz-jerk"
+	#define MSG_VE_JERK              "Ve-jerk"
 	#define MSG_VMAX                 "Vmax"
 	#define MSG_X                    "x"
 	#define MSG_Y                    "y"
@@ -1184,6 +1198,8 @@
 	#define MSG_PID_C " PID-C: "
 	#define MSG_ACC  " Acc:"
 	#define MSG_VXY_JERK " Vxy-jerk: "
+	#define MSG_VZ_JERK "Vz-jerk"
+	#define MSG_VE_JERK "Ve-jerk"
 	#define MSG_VMAX " Vmax "
 	#define MSG_X "x:"
 	#define MSG_Y "y:"
@@ -1350,6 +1366,8 @@
 	#define MSG_PID_C "PID-C"
 	#define MSG_ACC  "Kiihtyv"
 	#define MSG_VXY_JERK "Vxy-jerk"
+	#define MSG_VZ_JERK "Vz-jerk"
+	#define MSG_VE_JERK "Ve-jerk"
 	#define MSG_VMAX "Vmax "
 	#define MSG_X "x"
 	#define MSG_Y "y"
@@ -1465,4 +1483,3 @@
 
 #endif
 #endif // ifndef LANGUAGE_H
-
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index 5101e18219c3d0ba6f763a7fc6f81b99136ca9d1..e45c9d7ff9203bfc35f42ecc44dfeee98ef69025 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -478,7 +478,7 @@ void check_axes_activity()
           tail_fan_speed = 255;
       } else {
         fan_kick_end = 0;
-      }
+      }
     #endif//FAN_KICKSTART_TIME
     analogWrite(FAN_PIN,tail_fan_speed);
   #endif//!FAN_SOFT_PWM
@@ -895,3 +895,11 @@ void allow_cold_extrudes(bool allow)
 #endif
 }
 
+// Calculate the steps/s^2 acceleration rates, based on the mm/s^s
+void reset_acceleration_rates()
+{
+	for(int8_t i=0; i < NUM_AXIS; i++)
+        {
+        axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i];
+        }
+}
diff --git a/Marlin/planner.h b/Marlin/planner.h
index fc0d83c2b8d3a7a0b029a8b7a530dd1c0a62b6a2..9a904e5776f17036dddb9dd241d3b576acd4c419 100644
--- a/Marlin/planner.h
+++ b/Marlin/planner.h
@@ -136,4 +136,6 @@ FORCE_INLINE bool blocks_queued()
 }
 
 void allow_cold_extrudes(bool allow);
+
+void reset_acceleration_rates();
 #endif
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 58c7b60e6fcba6eb82d3b6624802a828760ae4a6..85017750be7e432daf52040340fdb4b2cf9cfbe9 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1128,3 +1128,31 @@ ISR(TIMER0_COMPB_vect)
 #endif
   }  
 }
+
+#ifdef PIDTEMP
+// Apply the scale factors to the PID values
+
+
+float scalePID_i(float i)
+{
+	return i*PID_dT;
+}
+
+float unscalePID_i(float i)
+{
+	return i/PID_dT;
+}
+
+float scalePID_d(float d)
+{
+    return d/PID_dT;
+}
+
+float unscalePID_d(float d)
+{
+	return d*PID_dT;
+}
+
+#endif //PIDTEMP
+
+
diff --git a/Marlin/temperature.h b/Marlin/temperature.h
index feffcbd4149bc3b19ee34e801730ae720ff03d00..7cc62aa529cb2fdf8f2ee07c6839c1fa1aa6fddd 100644
--- a/Marlin/temperature.h
+++ b/Marlin/temperature.h
@@ -31,8 +31,8 @@
 void tp_init();  //initialise the heating
 void manage_heater(); //it is critical that this is called periodically.
 
-//low leven conversion routines
-// do not use this routines and variables outsie of temperature.cpp
+// low level conversion routines
+// do not use these routines and variables outside of temperature.cpp
 extern int target_temperature[EXTRUDERS];  
 extern float current_temperature[EXTRUDERS];
 extern int target_temperature_bed;
@@ -40,6 +40,11 @@ extern float current_temperature_bed;
 
 #ifdef PIDTEMP
   extern float Kp,Ki,Kd,Kc;
+  float scalePID_i(float i);
+  float scalePID_d(float d);
+  float unscalePID_i(float i);
+  float unscalePID_d(float d);
+
 #endif
 #ifdef PIDTEMPBED
   extern float bedKp,bedKi,bedKd;
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 8a017292b99e2bbc2fe9c7655c06e452954a128b..fe0619fb858b58e8b4c30a6981f5b6e6bb27b71a 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -31,6 +31,10 @@ char lcd_status_message[LCD_WIDTH+1] = WELCOME_MSG;
 #endif
 
 /** forward declerations **/
+
+void copy_and_scalePID_i();
+void copy_and_scalePID_d();
+
 /* Different menus */
 static void lcd_status_screen();
 #ifdef ULTIPANEL
@@ -63,6 +67,14 @@ static void menu_action_setting_edit_float5(const char* pstr, float* ptr, float
 static void menu_action_setting_edit_float51(const char* pstr, float* ptr, float minValue, float maxValue);
 static void menu_action_setting_edit_float52(const char* pstr, float* ptr, float minValue, float maxValue);
 static void menu_action_setting_edit_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue);
+static void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, menuFunc_t callbackFunc);
+static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, menuFunc_t callbackFunc);
+static void menu_action_setting_edit_callback_float3(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc);
+static void menu_action_setting_edit_callback_float32(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc);
+static void menu_action_setting_edit_callback_float5(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc);
+static void menu_action_setting_edit_callback_float51(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc);
+static void menu_action_setting_edit_callback_float52(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc);
+static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue, menuFunc_t callbackFunc);
 
 #define ENCODER_STEPS_PER_MENU_ITEM 5
 
@@ -93,6 +105,7 @@ static void menu_action_setting_edit_long5(const char* pstr, unsigned long* ptr,
 } while(0)
 #define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0)
 #define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args )
+#define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args )
 #define END_MENU() \
     if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; \
     if ((uint8_t)(encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
@@ -123,6 +136,10 @@ uint16_t prevEncoderPosition;
 const char* editLabel;
 void* editValue;
 int32_t minEditValue, maxEditValue;
+menuFunc_t callbackFunc;
+
+// placeholders for Ki and Kd edits
+float raw_Ki, raw_Kd;
 
 /* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependend */
 static void lcd_status_screen()
@@ -442,6 +459,10 @@ static void lcd_control_menu()
 
 static void lcd_control_temperature_menu()
 {
+	// set up temp variables - undo the default scaling
+	raw_Ki = unscalePID_i(Ki);
+	raw_Kd = unscalePID_d(Kd);
+	
     START_MENU();
     MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
     MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15);
@@ -463,9 +484,9 @@ static void lcd_control_temperature_menu()
 #endif
 #ifdef PIDTEMP
     MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp, 1, 9990);
-//TODO, I and D should have a PID_dT multiplier (Ki = PID_I * PID_dT, Kd = PID_D / PID_dT)
-    MENU_ITEM_EDIT(float52, MSG_PID_I, &Ki, 1, 9990);
-    MENU_ITEM_EDIT(float52, MSG_PID_D, &Kd, 1, 9990);
+	// i is typically a small value so allows values below 1
+    MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
+    MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d);
 # ifdef PID_ADD_EXTRUSION_RATE
     MENU_ITEM_EDIT(float3, MSG_PID_C, &Kc, 1, 9990);
 # endif//PID_ADD_EXTRUSION_RATE
@@ -511,16 +532,18 @@ static void lcd_control_motion_menu()
     MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
     MENU_ITEM_EDIT(float5, MSG_ACC, &acceleration, 500, 99000);
     MENU_ITEM_EDIT(float3, MSG_VXY_JERK, &max_xy_jerk, 1, 990);
+    MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &max_z_jerk, 0.1, 990);
+    MENU_ITEM_EDIT(float3, MSG_VE_JERK, &max_e_jerk, 1, 990);
     MENU_ITEM_EDIT(float3, MSG_VMAX MSG_X, &max_feedrate[X_AXIS], 1, 999);
     MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Y, &max_feedrate[Y_AXIS], 1, 999);
     MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Z, &max_feedrate[Z_AXIS], 1, 999);
     MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &max_feedrate[E_AXIS], 1, 999);
     MENU_ITEM_EDIT(float3, MSG_VMIN, &minimumfeedrate, 0, 999);
     MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &mintravelfeedrate, 0, 999);
-    MENU_ITEM_EDIT(long5, MSG_AMAX MSG_X, &max_acceleration_units_per_sq_second[X_AXIS], 100, 99000);
-    MENU_ITEM_EDIT(long5, MSG_AMAX MSG_Y, &max_acceleration_units_per_sq_second[Y_AXIS], 100, 99000);
-    MENU_ITEM_EDIT(long5, MSG_AMAX MSG_Z, &max_acceleration_units_per_sq_second[Z_AXIS], 100, 99000);
-    MENU_ITEM_EDIT(long5, MSG_AMAX MSG_E, &max_acceleration_units_per_sq_second[E_AXIS], 100, 99000);
+    MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &max_acceleration_units_per_sq_second[X_AXIS], 100, 99000, reset_acceleration_rates);
+    MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &max_acceleration_units_per_sq_second[Y_AXIS], 100, 99000, reset_acceleration_rates);
+    MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &max_acceleration_units_per_sq_second[Z_AXIS], 100, 99000, reset_acceleration_rates);
+    MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &max_acceleration_units_per_sq_second[E_AXIS], 100, 99000, reset_acceleration_rates);
     MENU_ITEM_EDIT(float5, MSG_A_RETRACT, &retract_acceleration, 100, 99000);
     MENU_ITEM_EDIT(float52, MSG_XSTEPS, &axis_steps_per_unit[X_AXIS], 5, 9999);
     MENU_ITEM_EDIT(float52, MSG_YSTEPS, &axis_steps_per_unit[Y_AXIS], 5, 9999);
@@ -610,6 +633,23 @@ void lcd_sdcard_menu()
             encoderPosition = prevEncoderPosition; \
         } \
     } \
+    void menu_edit_callback_ ## _name () \
+    { \
+        if ((int32_t)encoderPosition < minEditValue) \
+            encoderPosition = minEditValue; \
+        if ((int32_t)encoderPosition > maxEditValue) \
+            encoderPosition = maxEditValue; \
+        if (lcdDrawUpdate) \
+            lcd_implementation_drawedit(editLabel, _strFunc(((_type)encoderPosition) / scale)); \
+        if (LCD_CLICKED) \
+        { \
+            *((_type*)editValue) = ((_type)encoderPosition) / scale; \
+            lcd_quick_feedback(); \
+            currentMenu = prevMenu; \
+            encoderPosition = prevEncoderPosition; \
+            (*callbackFunc)();\
+        } \
+    } \
     static void menu_action_setting_edit_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue) \
     { \
         prevMenu = currentMenu; \
@@ -623,6 +663,21 @@ void lcd_sdcard_menu()
         minEditValue = minValue * scale; \
         maxEditValue = maxValue * scale; \
         encoderPosition = (*ptr) * scale; \
+    }\
+    static void menu_action_setting_edit_callback_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue, menuFunc_t callback) \
+    { \
+        prevMenu = currentMenu; \
+        prevEncoderPosition = encoderPosition; \
+         \
+        lcdDrawUpdate = 2; \
+        currentMenu = menu_edit_callback_ ## _name; \
+         \
+        editLabel = pstr; \
+        editValue = ptr; \
+        minEditValue = minValue * scale; \
+        maxEditValue = maxValue * scale; \
+        encoderPosition = (*ptr) * scale; \
+        callbackFunc = callback;\
     }
 menu_edit_type(int, int3, itostr3, 1)
 menu_edit_type(float, float3, ftostr3, 1)
@@ -1070,4 +1125,20 @@ char *ftostr52(const float &x)
   return conv;
 }
 
+// Callback for after editing PID i value
+// grab the pid i value out of the temp variable; scale it; then update the PID driver
+void copy_and_scalePID_i()
+{
+  Ki = scalePID_i(raw_Ki);
+  updatePID();
+}	
+
+// Callback for after editing PID d value
+// grab the pid d value out of the temp variable; scale it; then update the PID driver
+void copy_and_scalePID_d()
+{
+  Kd = scalePID_d(raw_Kd);
+  updatePID();
+}	
+	
 #endif //ULTRA_LCD
diff --git a/Marlin/ultralcd_implementation_hitachi_HD44780.h b/Marlin/ultralcd_implementation_hitachi_HD44780.h
index 1d19b7718d917cc1418671325d2af578e281a081..88dea492b3edfeee815aad51b9a938479ff616d0 100644
--- a/Marlin/ultralcd_implementation_hitachi_HD44780.h
+++ b/Marlin/ultralcd_implementation_hitachi_HD44780.h
@@ -376,6 +376,26 @@ static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, cons
 #define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
 #define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
 #define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
+
+//Add version for callback functions
+#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
+#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
+#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
+
+
 void lcd_implementation_drawedit(const char* pstr, char* value)
 {
     lcd.setCursor(1, 1);