From af9395ac2ec8d9ede37028720af953e56821120b Mon Sep 17 00:00:00 2001
From: Jim Morris <morris@wolfman.com>
Date: Mon, 17 Feb 2014 20:50:59 -0800
Subject: [PATCH] Add M605 to dynamically set delta configuration Save above
 configs in eeprom fix docs in createTemperatureLookupMarlin.py add missing
 azteegX3pro digipot settings in delta example config

---
 Marlin/ConfigurationStore.cpp                 | 25 ++++++--
 Marlin/Marlin.h                               |  4 ++
 Marlin/Marlin_main.cpp                        | 63 +++++++++++++++----
 Marlin/createTemperatureLookupMarlin.py       |  9 +--
 .../delta/Configuration.h                     | 13 +---
 .../delta/Configuration_adv.h                 |  6 ++
 6 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp
index 3409ade705..80dce5df06 100644
--- a/Marlin/ConfigurationStore.cpp
+++ b/Marlin/ConfigurationStore.cpp
@@ -37,7 +37,7 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size)
 // the default values are used whenever there is a change to the data, to prevent
 // wrong data being written to the variables.
 // ALSO:  always make sure the variables in the Store and retrieve sections are in the same order.
-#define EEPROM_VERSION "V10"
+#define EEPROM_VERSION "V11"
 
 #ifdef EEPROM_SETTINGS
 void Config_StoreSettings() 
@@ -59,6 +59,9 @@ void Config_StoreSettings()
   EEPROM_WRITE_VAR(i,add_homeing);
   #ifdef DELTA
   EEPROM_WRITE_VAR(i,endstop_adj);
+  EEPROM_WRITE_VAR(i,delta_radius);
+  EEPROM_WRITE_VAR(i,delta_diagonal_rod);
+  EEPROM_WRITE_VAR(i,delta_segments_per_second);
   #endif
   #ifndef ULTIPANEL
   int plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP, plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP, plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED;
@@ -156,7 +159,14 @@ void Config_PrintSettings()
     SERIAL_ECHOPAIR("  M666 X",endstop_adj[0] );
     SERIAL_ECHOPAIR(" Y" ,endstop_adj[1] );
     SERIAL_ECHOPAIR(" Z" ,endstop_adj[2] );
-    SERIAL_ECHOLN("");
+	SERIAL_ECHOLN("");
+	SERIAL_ECHO_START;
+	SERIAL_ECHOLNPGM("Delta settings: L=delta_diagonal_rod, R=delta_radius, S=delta_segments_per_second");
+	SERIAL_ECHO_START;
+	SERIAL_ECHOPAIR("  M665 L",delta_diagonal_rod );
+	SERIAL_ECHOPAIR(" R" ,delta_radius );
+	SERIAL_ECHOPAIR(" S" ,delta_segments_per_second );
+	SERIAL_ECHOLN("");
 #endif
 #ifdef PIDTEMP
     SERIAL_ECHO_START;
@@ -199,7 +209,10 @@ void Config_RetrieveSettings()
         EEPROM_READ_VAR(i,max_e_jerk);
         EEPROM_READ_VAR(i,add_homeing);
         #ifdef DELTA
-        EEPROM_READ_VAR(i,endstop_adj);
+		EEPROM_READ_VAR(i,endstop_adj);
+		EEPROM_READ_VAR(i,delta_radius);
+		EEPROM_READ_VAR(i,delta_diagonal_rod);
+		EEPROM_READ_VAR(i,delta_segments_per_second);
         #endif
         #ifndef ULTIPANEL
         int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
@@ -264,7 +277,11 @@ void Config_ResetDefault()
     max_e_jerk=DEFAULT_EJERK;
     add_homeing[0] = add_homeing[1] = add_homeing[2] = 0;
 #ifdef DELTA
-    endstop_adj[0] = endstop_adj[1] = endstop_adj[2] = 0;
+	endstop_adj[0] = endstop_adj[1] = endstop_adj[2] = 0;
+	delta_radius= DELTA_RADIUS;
+	delta_diagonal_rod= DELTA_DIAGONAL_ROD;
+	delta_segments_per_second= DELTA_SEGMENTS_PER_SECOND;
+	recalc_delta_settings(delta_radius, delta_diagonal_rod);
 #endif
 #ifdef ULTIPANEL
     plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP;
diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 7a4b864fde..d79fc019fb 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -209,6 +209,10 @@ extern float current_position[NUM_AXIS] ;
 extern float add_homeing[3];
 #ifdef DELTA
 extern float endstop_adj[3];
+extern float delta_radius;
+extern float delta_diagonal_rod;
+extern float delta_segments_per_second;
+void recalc_delta_settings(float radius, float diagonal_rod);
 #endif
 extern float min_pos[3];
 extern float max_pos[3];
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 0023279d8b..d8a105dc3f 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -161,6 +161,7 @@
 // M503 - print the current settings (from memory not from eeprom)
 // M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
 // M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
+// M665 - set delta configurations
 // M666 - set delta endstop adjustemnt
 // M605 - Set dual x-carriage movement mode: S<mode> [ X<duplication x-offset> R<duplication temp offset> ]
 // M907 - Set digital trimpot motor current using axis codes.
@@ -246,9 +247,21 @@ int EtoPPressure=0;
 #endif
 
 #ifdef DELTA
-float delta[3] = {0.0, 0.0, 0.0};
-#endif
-
+  float delta[3] = {0.0, 0.0, 0.0};
+  #define SIN_60 0.8660254037844386
+  #define COS_60 0.5
+  // these are the default values, can be overriden with M665
+  float delta_radius= DELTA_RADIUS;
+  float delta_tower1_x= -SIN_60*delta_radius; // front left tower
+  float delta_tower1_y= -COS_60*delta_radius;	   
+  float delta_tower2_x=  SIN_60*delta_radius; // front right tower
+  float delta_tower2_y= -COS_60*delta_radius;	   
+  float delta_tower3_x= 0.0;                  // back middle tower
+  float delta_tower3_y= delta_radius;
+  float delta_diagonal_rod= DELTA_DIAGONAL_ROD;
+  float delta_diagonal_rod_2= sq(delta_diagonal_rod);
+  float delta_segments_per_second= DELTA_SEGMENTS_PER_SECOND;
+#endif					
 
 //===========================================================================
 //=============================private variables=============================
@@ -2267,6 +2280,19 @@ void process_commands()
       }
       break;
     #ifdef DELTA
+	case 665: // M665 set delta configurations L<diagonal_rod> R<delta_radius> S<segments_per_sec>
+		if(code_seen('L')) {
+			delta_diagonal_rod= code_value();
+		}
+		if(code_seen('R')) {
+			delta_radius= code_value();
+		}
+		if(code_seen('S')) {
+			delta_segments_per_second= code_value();
+		}
+		
+		recalc_delta_settings(delta_radius, delta_diagonal_rod);
+		break;
     case 666: // M666 set delta endstop adjustemnt
       for(int8_t i=0; i < 3; i++)
       {
@@ -3101,19 +3127,30 @@ void clamp_to_software_endstops(float target[3])
 }
 
 #ifdef DELTA
+void recalc_delta_settings(float radius, float diagonal_rod)
+{
+	 delta_tower1_x= -SIN_60*radius; // front left tower
+	 delta_tower1_y= -COS_60*radius;	   
+	 delta_tower2_x=  SIN_60*radius; // front right tower
+	 delta_tower2_y= -COS_60*radius;	   
+	 delta_tower3_x= 0.0;                  // back middle tower
+	 delta_tower3_y= radius;
+	 delta_diagonal_rod_2= sq(diagonal_rod);
+}
+
 void calculate_delta(float cartesian[3])
 {
-  delta[X_AXIS] = sqrt(DELTA_DIAGONAL_ROD_2
-                       - sq(DELTA_TOWER1_X-cartesian[X_AXIS])
-                       - sq(DELTA_TOWER1_Y-cartesian[Y_AXIS])
+  delta[X_AXIS] = sqrt(delta_diagonal_rod_2
+                       - sq(delta_tower1_x-cartesian[X_AXIS])
+                       - sq(delta_tower1_y-cartesian[Y_AXIS])
                        ) + cartesian[Z_AXIS];
-  delta[Y_AXIS] = sqrt(DELTA_DIAGONAL_ROD_2
-                       - sq(DELTA_TOWER2_X-cartesian[X_AXIS])
-                       - sq(DELTA_TOWER2_Y-cartesian[Y_AXIS])
+  delta[Y_AXIS] = sqrt(delta_diagonal_rod_2
+                       - sq(delta_tower2_x-cartesian[X_AXIS])
+                       - sq(delta_tower2_y-cartesian[Y_AXIS])
                        ) + cartesian[Z_AXIS];
-  delta[Z_AXIS] = sqrt(DELTA_DIAGONAL_ROD_2
-                       - sq(DELTA_TOWER3_X-cartesian[X_AXIS])
-                       - sq(DELTA_TOWER3_Y-cartesian[Y_AXIS])
+  delta[Z_AXIS] = sqrt(delta_diagonal_rod_2
+                       - sq(delta_tower3_x-cartesian[X_AXIS])
+                       - sq(delta_tower3_y-cartesian[Y_AXIS])
                        ) + cartesian[Z_AXIS];
   /*
   SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]);
@@ -3143,7 +3180,7 @@ void prepare_move()
   if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
   if (cartesian_mm < 0.000001) { return; }
   float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
-  int steps = max(1, int(DELTA_SEGMENTS_PER_SECOND * seconds));
+  int steps = max(1, int(delta_segments_per_second * seconds));
   // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
   // SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
   // SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
diff --git a/Marlin/createTemperatureLookupMarlin.py b/Marlin/createTemperatureLookupMarlin.py
index 77187b8099..01c602dffa 100755
--- a/Marlin/createTemperatureLookupMarlin.py
+++ b/Marlin/createTemperatureLookupMarlin.py
@@ -16,9 +16,9 @@ Usage: python createTemperatureLookup.py [options]
 Options:
   -h, --help        show this help
   --rp=...          pull-up resistor
-  --t0=ttt:rrr      low temperature temperature:resistance point (around 25C)
-  --t1=ttt:rrr      middle temperature temperature:resistance point (around 150C)
-  --t2=ttt:rrr      high temperature temperature:resistance point (around 250C)
+  --t1=ttt:rrr      low temperature temperature:resistance point (around 25C)
+  --t2=ttt:rrr      middle temperature temperature:resistance point (around 150C)
+  --t3=ttt:rrr      high temperature temperature:resistance point (around 250C)
   --num-temps=...   the number of temperature points to calculate (default: 20)
 """
 
@@ -98,7 +98,8 @@ def main(argv):
     
     try:
         opts, args = getopt.getopt(argv, "h", ["help", "rp=", "t1=", "t2=", "t3=", "num-temps="])
-    except getopt.GetoptError:
+    except getopt.GetoptError as err:
+        print  str(err)
         usage()
         sys.exit(2)
         
diff --git a/Marlin/example_configurations/delta/Configuration.h b/Marlin/example_configurations/delta/Configuration.h
index 0d232d372f..c724484bd9 100644
--- a/Marlin/example_configurations/delta/Configuration.h
+++ b/Marlin/example_configurations/delta/Configuration.h
@@ -51,6 +51,7 @@
 // 65 = Azteeg X1
 // 66 = Melzi with ATmega1284 (MaKr3d version)
 // 67 = Azteeg X3
+// 68 = Azteeg X3 Pro
 // 7  = Ultimaker
 // 71 = Ultimaker (Older electronics. Pre 1.5.4. This is rare)
 // 77 = 3Drag Controller
@@ -119,18 +120,6 @@
 // Effective horizontal distance bridged by diagonal push rods.
 #define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-DELTA_EFFECTOR_OFFSET-DELTA_CARRIAGE_OFFSET)
 
-#define DELTA_DIAGONAL_ROD_2 sq(DELTA_DIAGONAL_ROD)
-
-// Effective X/Y positions of the three vertical towers.
-#define SIN_60 0.8660254037844386
-#define COS_60 0.5
-#define DELTA_TOWER1_X -SIN_60*DELTA_RADIUS // front left tower
-#define DELTA_TOWER1_Y -COS_60*DELTA_RADIUS
-#define DELTA_TOWER2_X SIN_60*DELTA_RADIUS // front right tower
-#define DELTA_TOWER2_Y -COS_60*DELTA_RADIUS
-#define DELTA_TOWER3_X 0.0 // back middle tower
-#define DELTA_TOWER3_Y DELTA_RADIUS
-
 //===========================================================================
 //=============================Thermal Settings  ============================
 //===========================================================================
diff --git a/Marlin/example_configurations/delta/Configuration_adv.h b/Marlin/example_configurations/delta/Configuration_adv.h
index fcf6ff570f..4d6e78b4d9 100644
--- a/Marlin/example_configurations/delta/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/Configuration_adv.h
@@ -270,6 +270,12 @@
 // Motor Current setting (Only functional when motor driver current ref pins are connected to a digital trimpot on supported boards)
 #define DIGIPOT_MOTOR_CURRENT {135,135,135,135,135} // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
 
+// uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro
+//#define DIGIPOT_I2C
+// Number of channels available for I2C digipot, For Azteeg X3 Pro we have 8
+#define DIGIPOT_I2C_NUM_CHANNELS 8
+// actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS
+#define DIGIPOT_I2C_MOTOR_CURRENTS {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}
 
 //===========================================================================
 //=============================Additional Features===========================