From 04fa9d4f47b6af7a55b80369950cd8ac15f3a793 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Mon, 21 Mar 2016 18:10:08 -0700
Subject: [PATCH] Make Autotune options into Menu Edit Items

---
 Marlin/Marlin.h        |  1 +
 Marlin/Marlin_main.cpp | 17 ++++++++---
 Marlin/cardreader.cpp  |  2 +-
 Marlin/temperature.cpp |  5 +--
 Marlin/temperature.h   |  2 +-
 Marlin/ultralcd.cpp    | 69 ++++++++++++++++++++++++++++++------------
 6 files changed, 68 insertions(+), 28 deletions(-)

diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 414aeb3289..35ab606d2d 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -228,6 +228,7 @@ inline bool IsRunning() { return  Running; }
 inline bool IsStopped() { return !Running; }
 
 bool enqueue_and_echo_command(const char* cmd, bool say_ok=false); //put a single ASCII command at the end of the current buffer or return false when it is full
+void enqueue_and_echo_command_now(const char* cmd); // enqueue now, only return when the command has been enqueued
 void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
 
 void prepare_arc_move(char isclockwise);
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 9a21803da3..bb5ab23f10 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -549,6 +549,10 @@ inline bool _enqueuecommand(const char* cmd, bool say_ok=false) {
   return true;
 }
 
+void enqueue_and_echo_command_now(const char* cmd) {
+  while (!enqueue_and_echo_command(cmd)) idle();
+}
+
 /**
  * Enqueue with Serial Echo
  */
@@ -5135,9 +5139,11 @@ inline void gcode_M226() {
 
 /**
  * M303: PID relay autotune
- *       S<temperature> sets the target temperature. (default target temperature = 150C)
- *       E<extruder> (-1 for the bed)
+ *
+ *       S<temperature> sets the target temperature. (default 150C)
+ *       E<extruder> (-1 for the bed) (default 0)
  *       C<cycles>
+ *       U<bool> with a non-zero value will apply the result to current settings
  */
 inline void gcode_M303() {
   int e = code_seen('E') ? code_value_short() : 0;
@@ -5146,11 +5152,14 @@ inline void gcode_M303() {
   
   float temp = code_seen('S') ? code_value() : (e < 0 ? 70.0 : 150.0);
 
-  if (e >=0 && e < EXTRUDERS)
+  if (e >= 0 && e < EXTRUDERS)
     target_extruder = e;
 
-  KEEPALIVE_STATE(NOT_BUSY);
+  KEEPALIVE_STATE(NOT_BUSY); // don't send "busy: processing" messages during autotune output
+
   PID_autotune(temp, e, c, u);
+
+  KEEPALIVE_STATE(IN_HANDLER);
 }
 
 #if ENABLED(SCARA)
diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp
index e508190c41..c3585e31e2 100644
--- a/Marlin/cardreader.cpp
+++ b/Marlin/cardreader.cpp
@@ -247,7 +247,7 @@ void CardReader::openAndPrintFile(const char *name) {
   char cmd[4 + (FILENAME_LENGTH + 1) * MAX_DIR_DEPTH + 2]; // Room for "M23 ", names with slashes, a null, and one extra
   sprintf_P(cmd, PSTR("M23 %s"), name);
   for (char *c = &cmd[4]; *c; c++) *c = tolower(*c);
-  enqueue_and_echo_command(cmd);
+  enqueue_and_echo_command_now(cmd);
   enqueue_and_echo_commands_P(PSTR("M24"));
 }
 
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index a0ee3e8f5f..4df22333d9 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -199,7 +199,7 @@ static void updateTemperaturesFromRawValues();
 //================================ Functions ================================
 //===========================================================================
 
-void PID_autotune(float temp, int extruder, int ncycles, bool set_result /* = false */) {
+void PID_autotune(float temp, int extruder, int ncycles, bool set_result/*=false*/) {
   float input = 0.0;
   int cycles = 0;
   bool heating = true;
@@ -346,7 +346,8 @@ void PID_autotune(float temp, int extruder, int ncycles, bool set_result /* = fa
       SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kp "); SERIAL_PROTOCOLLN(Kp);
       SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Ki "); SERIAL_PROTOCOLLN(Ki);
       SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kd "); SERIAL_PROTOCOLLN(Kd);
-      //Uses the result if set_result is true
+
+      // Use the result? (As with "M303 U1")
       if (set_result) {
         if (extruder < 0) {
           #if ENABLED(PIDTEMPBED)
diff --git a/Marlin/temperature.h b/Marlin/temperature.h
index 06c732f656..1a4d648f31 100644
--- a/Marlin/temperature.h
+++ b/Marlin/temperature.h
@@ -141,7 +141,7 @@ int getHeaterPower(int heater);
 void disable_all_heaters();
 void updatePID();
 
-void PID_autotune(float temp, int extruder, int ncycles, bool set_result = false);
+void PID_autotune(float temp, int extruder, int ncycles, bool set_result=false);
 
 void setExtruderAutoFanState(int pin, bool state);
 void checkExtruderAutoFans();
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 1f76b1397b..43f112e8c8 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1067,6 +1067,33 @@ static void lcd_control_menu() {
  *
  */
 
+#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
+
+  #if ENABLED(PIDTEMP)
+    int autotune_temp[EXTRUDERS] = { 150 };
+    const int heater_maxtemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP);
+  #endif
+
+  #if ENABLED(PIDTEMPBED)
+    int autotune_temp_bed = 70;
+  #endif
+
+  static void _lcd_autotune(int e) {
+    char cmd[30];
+    sprintf_P(cmd, PSTR("M303 U1 E%d S%d"), e,
+      #if ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED)
+        e < 0 ? autotune_temp_bed : autotune_temp[e]
+      #elif ENABLED(PIDTEMPBED)
+        autotune_temp_bed
+      #else
+        autotune_temp[e]
+      #endif
+    );
+    enqueue_and_echo_command_now(cmd);
+  }
+
+#endif PIDTEMP || PIDTEMPBED
+
 #if ENABLED(PIDTEMP)
 
   // Helpers for editing PID Ki & Kd values
@@ -1079,18 +1106,19 @@ static void lcd_control_menu() {
     PID_PARAM(Kd, e) = scalePID_d(raw_Kd);
     updatePID();
   }
-  #define COPY_AND_SCALE(eindex) \
+  #define _PIDTEMP_FUNCTIONS(eindex) \
     void copy_and_scalePID_i_E ## eindex() { copy_and_scalePID_i(eindex); } \
-    void copy_and_scalePID_d_E ## eindex() { copy_and_scalePID_d(eindex); }
+    void copy_and_scalePID_d_E ## eindex() { copy_and_scalePID_d(eindex); } \
+    void lcd_autotune_callback_E ## eindex() { _lcd_autotune(eindex); }
 
-  COPY_AND_SCALE(0);
+  _PIDTEMP_FUNCTIONS(0);
   #if ENABLED(PID_PARAMS_PER_EXTRUDER)
     #if EXTRUDERS > 1
-      COPY_AND_SCALE(1);
+      _PIDTEMP_FUNCTIONS(1);
       #if EXTRUDERS > 2
-        COPY_AND_SCALE(2);
+        _PIDTEMP_FUNCTIONS(2);
         #if EXTRUDERS > 3
-          COPY_AND_SCALE(3);
+          _PIDTEMP_FUNCTIONS(3);
         #endif //EXTRUDERS > 3
       #endif //EXTRUDERS > 2
     #endif //EXTRUDERS > 1
@@ -1184,35 +1212,36 @@ static void lcd_control_temperature_menu() {
   //
   #if ENABLED(PIDTEMP)
 
-    #define _PID_MENU_ITEMS(ELABEL, eindex) \
+    #define _PID_BASE_MENU_ITEMS(ELABEL, eindex) \
       raw_Ki = unscalePID_i(PID_PARAM(Ki, eindex)); \
       raw_Kd = unscalePID_d(PID_PARAM(Kd, eindex)); \
       MENU_ITEM_EDIT(float52, MSG_PID_P ELABEL, &PID_PARAM(Kp, eindex), 1, 9990); \
       MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I ELABEL, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_E ## eindex); \
       MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D ELABEL, &raw_Kd, 1, 9990, copy_and_scalePID_d_E ## eindex)
-      
+
     #if ENABLED(PID_ADD_EXTRUSION_RATE)
-      #define PID_MENU_ITEMS(ELABEL, eindex, AUTOTUNE_CMD) \
-        _PID_MENU_ITEMS(ELABEL, eindex); \
-        MENU_ITEM_EDIT(float3, MSG_PID_C ELABEL, &PID_PARAM(Kc, eindex), 1, 9990); \
-        MENU_ITEM(gcode, MSG_PID_AUTOTUNE ELABEL, PSTR(AUTOTUNE_CMD))
+      #define _PID_MENU_ITEMS(ELABEL, eindex) \
+        _PID_BASE_MENU_ITEMS(ELABEL, eindex); \
+        MENU_ITEM_EDIT(float3, MSG_PID_C ELABEL, &PID_PARAM(Kc, eindex), 1, 9990)
     #else
-      #define PID_MENU_ITEMS(ELABEL, eindex, AUTOTUNE_CMD) \
-        _PID_MENU_ITEMS(ELABEL, eindex); \
-        MENU_ITEM(gcode, MSG_PID_AUTOTUNE ELABEL, PSTR(AUTOTUNE_CMD))
+      #define _PID_MENU_ITEMS(ELABEL, eindex) _PID_BASE_MENU_ITEMS(ELABEL, eindex)
     #endif
 
+    #define PID_MENU_ITEMS(ELABEL, eindex) \
+      _PID_MENU_ITEMS(ELABEL, eindex); \
+      MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_PID_AUTOTUNE ELABEL, &autotune_temp[eindex], 150, heater_maxtemp[eindex] - 15, lcd_autotune_callback_E ## eindex)
+
     #if ENABLED(PID_PARAMS_PER_EXTRUDER) && EXTRUDERS > 1
-      PID_MENU_ITEMS(MSG_E1, 0, "M303 U1");
-      PID_MENU_ITEMS(MSG_E2, 1, "M303 U1 E1");
+      PID_MENU_ITEMS(MSG_E1, 0);
+      PID_MENU_ITEMS(MSG_E2, 1);
       #if EXTRUDERS > 2
-        PID_MENU_ITEMS(MSG_E3, 2, "M303 U1 E2");
+        PID_MENU_ITEMS(MSG_E3, 2);
         #if EXTRUDERS > 3
-          PID_MENU_ITEMS(MSG_E4, 3, "M303 U1 E3");
+          PID_MENU_ITEMS(MSG_E4, 3);
         #endif //EXTRUDERS > 3
       #endif //EXTRUDERS > 2
     #else //!PID_PARAMS_PER_EXTRUDER || EXTRUDERS == 1
-      PID_MENU_ITEMS("", 0, "M303 U1");
+      PID_MENU_ITEMS("", 0);
     #endif //!PID_PARAMS_PER_EXTRUDER || EXTRUDERS == 1
 
   #endif //PIDTEMP
-- 
GitLab