Преглед на файлове

Merge pull request #1405 from MagoKimbra/4th-extruders

All the additions look proper. I can't think of any other extruder-count-related items that you might have missed. So, with some optimism, I will merge this for testing.
Scott Lahteine преди 9 години
родител
ревизия
865ca0ef04
променени са 14 файла, в които са добавени 599 реда и са изтрити 201 реда
  1. 26
    12
      Marlin/ConfigurationStore.cpp
  2. 15
    3
      Marlin/Configuration_adv.h
  3. 7
    0
      Marlin/Marlin.h
  4. 70
    43
      Marlin/Marlin_main.cpp
  5. 12
    2
      Marlin/language_en.h
  6. 13
    3
      Marlin/language_it.h
  7. 13
    3
      Marlin/pins.h
  8. 18
    4
      Marlin/planner.cpp
  9. 37
    5
      Marlin/stepper.cpp
  10. 5
    1
      Marlin/stepper.h
  11. 227
    48
      Marlin/temperature.cpp
  12. 23
    15
      Marlin/temperature.h
  13. 48
    21
      Marlin/thermistortables.h
  14. 85
    41
      Marlin/ultralcd.cpp

+ 26
- 12
Marlin/ConfigurationStore.cpp Целия файл

@@ -77,7 +77,7 @@ void Config_StoreSettings()
77 77
   EEPROM_WRITE_VAR(i,zprobe_zoffset);
78 78
   #ifdef PIDTEMP
79 79
     float dummy = 0.0f;
80
-    for (int e = 0; e < 3; e++)
80
+    for (int e = 0; e < 4; e++)
81 81
 	{
82 82
 	  if (e < EXTRUDERS)
83 83
 	  {
@@ -132,12 +132,15 @@ void Config_StoreSettings()
132 132
   // Save filament sizes
133 133
   EEPROM_WRITE_VAR(i, volumetric_enabled);
134 134
   EEPROM_WRITE_VAR(i, filament_size[0]);
135
-  #if EXTRUDERS > 1
135
+#if EXTRUDERS > 1
136 136
   EEPROM_WRITE_VAR(i, filament_size[1]);
137
-  #if EXTRUDERS > 2
137
+#if EXTRUDERS > 2
138 138
   EEPROM_WRITE_VAR(i, filament_size[2]);
139
-  #endif//EXTRUDERS > 2
140
-  #endif//EXTRUDERS > 1
139
+#if EXTRUDERS > 3
140
+  EEPROM_WRITE_VAR(i, filament_size[3]);
141
+#endif //EXTRUDERS > 3
142
+#endif //EXTRUDERS > 2
143
+#endif //EXTRUDERS > 1
141 144
   
142 145
   char ver2[4]=EEPROM_VERSION;
143 146
   i=EEPROM_OFFSET;
@@ -280,8 +283,13 @@ SERIAL_ECHOLNPGM("Scaling factors:");
280 283
 		SERIAL_ECHO_START;
281 284
         SERIAL_ECHOPAIR("   M200 T2 D", filament_size[2]);
282 285
 		SERIAL_ECHOLN("");
283
-#endif//EXTRUDERS > 2
284
-#endif//EXTRUDERS > 1
286
+#if EXTRUDERS > 3
287
+        SERIAL_ECHO_START;
288
+        SERIAL_ECHOPAIR("   M200 T3 D", filament_size[3]);
289
+        SERIAL_ECHOLN("");
290
+#endif //EXTRUDERS > 3
291
+#endif //EXTRUDERS > 2
292
+#endif //EXTRUDERS > 1
285 293
     } else {
286 294
         SERIAL_ECHOLNPGM("Filament settings: Disabled");
287 295
     }
@@ -345,7 +353,7 @@ void Config_RetrieveSettings()
345 353
         EEPROM_READ_VAR(i,zprobe_zoffset);
346 354
         #ifdef PIDTEMP
347 355
 		float dummy = 0.0f;
348
-		for (int e = 0; e < 3; e++) // 3 = max extruders supported by marlin
356
+		for (int e = 0; e < 4; e++) // 4 = max extruders supported by marlin
349 357
 		{
350 358
 		  if (e < EXTRUDERS)
351 359
 		  {
@@ -412,8 +420,11 @@ void Config_RetrieveSettings()
412 420
 		EEPROM_READ_VAR(i, filament_size[1]);
413 421
 #if EXTRUDERS > 2
414 422
 		EEPROM_READ_VAR(i, filament_size[2]);
415
-#endif//EXTRUDERS > 2
416
-#endif//EXTRUDERS > 1
423
+#if EXTRUDERS > 3
424
+    EEPROM_READ_VAR(i, filament_size[3]);
425
+#endif //EXTRUDERS > 3
426
+#endif //EXTRUDERS > 2
427
+#endif //EXTRUDERS > 1
417 428
 		calculate_volumetric_multipliers();
418 429
 		// Call updatePID (similar to when we have processed M301)
419 430
 		updatePID();
@@ -517,8 +528,11 @@ void Config_ResetDefault()
517 528
 	filament_size[1] = DEFAULT_NOMINAL_FILAMENT_DIA;
518 529
 #if EXTRUDERS > 2
519 530
 	filament_size[2] = DEFAULT_NOMINAL_FILAMENT_DIA;
520
-#endif//EXTRUDERS > 2
521
-#endif//EXTRUDERS > 1
531
+#if EXTRUDERS > 3
532
+  filament_size[3] = DEFAULT_NOMINAL_FILAMENT_DIA;
533
+#endif //EXTRUDERS > 3
534
+#endif //EXTRUDERS > 2
535
+#endif //EXTRUDERS > 1
522 536
 	calculate_volumetric_multipliers();
523 537
 
524 538
 SERIAL_ECHO_START;

+ 15
- 3
Marlin/Configuration_adv.h Целия файл

@@ -75,9 +75,10 @@
75 75
 // extruder temperature is above/below EXTRUDER_AUTO_FAN_TEMPERATURE.
76 76
 // Multiple extruders can be assigned to the same pin in which case
77 77
 // the fan will turn on when any selected extruder is above the threshold.
78
-#define EXTRUDER_0_AUTO_FAN_PIN   -1
79
-#define EXTRUDER_1_AUTO_FAN_PIN   -1
80
-#define EXTRUDER_2_AUTO_FAN_PIN   -1
78
+#define EXTRUDER_0_AUTO_FAN_PIN -1
79
+#define EXTRUDER_1_AUTO_FAN_PIN -1
80
+#define EXTRUDER_2_AUTO_FAN_PIN -1
81
+#define EXTRUDER_3_AUTO_FAN_PIN -1
81 82
 #define EXTRUDER_AUTO_FAN_TEMPERATURE 50
82 83
 #define EXTRUDER_AUTO_FAN_SPEED   255  // == full speed
83 84
 
@@ -483,6 +484,10 @@ const unsigned int dropsegments=5; //everything with less than this number of st
483 484
   #define THERMISTORHEATER_2 TEMP_SENSOR_2
484 485
   #define HEATER_2_USES_THERMISTOR
485 486
 #endif
487
+#if TEMP_SENSOR_3 > 0
488
+  #define THERMISTORHEATER_3 TEMP_SENSOR_3
489
+  #define HEATER_3_USES_THERMISTOR
490
+#endif
486 491
 #if TEMP_SENSOR_BED > 0
487 492
   #define THERMISTORBED TEMP_SENSOR_BED
488 493
   #define BED_USES_THERMISTOR
@@ -496,6 +501,9 @@ const unsigned int dropsegments=5; //everything with less than this number of st
496 501
 #if TEMP_SENSOR_2 == -1
497 502
   #define HEATER_2_USES_AD595
498 503
 #endif
504
+#if TEMP_SENSOR_3 == -1
505
+  #define HEATER_3_USES_AD595
506
+#endif
499 507
 #if TEMP_SENSOR_BED == -1
500 508
   #define BED_USES_AD595
501 509
 #endif
@@ -514,6 +522,10 @@ const unsigned int dropsegments=5; //everything with less than this number of st
514 522
   #undef HEATER_2_MINTEMP
515 523
   #undef HEATER_2_MAXTEMP
516 524
 #endif
525
+#if TEMP_SENSOR_3 == 0
526
+  #undef HEATER_3_MINTEMP
527
+  #undef HEATER_3_MAXTEMP
528
+#endif
517 529
 #if TEMP_SENSOR_BED == 0
518 530
   #undef BED_MINTEMP
519 531
   #undef BED_MAXTEMP

+ 7
- 0
Marlin/Marlin.h Целия файл

@@ -170,6 +170,13 @@ void manage_inactivity(bool ignore_stepper_queue=false);
170 170
   #define disable_e2() /* nothing */
171 171
 #endif
172 172
 
173
+#if (EXTRUDERS > 3) && defined(E3_ENABLE_PIN) && (E3_ENABLE_PIN > -1)
174
+  #define enable_e3() WRITE(E3_ENABLE_PIN, E_ENABLE_ON)
175
+  #define disable_e3() WRITE(E3_ENABLE_PIN,!E_ENABLE_ON)
176
+#else
177
+  #define enable_e3()  /* nothing */
178
+  #define disable_e3() /* nothing */
179
+#endif
173 180
 
174 181
 enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5};
175 182
 

+ 70
- 43
Marlin/Marlin_main.cpp Целия файл

@@ -212,6 +212,9 @@ int extruder_multiply[EXTRUDERS] = {100
212 212
     , 100
213 213
     #if EXTRUDERS > 2
214 214
       , 100
215
+	    #if EXTRUDERS > 3
216
+      	, 100
217
+	    #endif
215 218
     #endif
216 219
   #endif
217 220
 };
@@ -221,6 +224,9 @@ float filament_size[EXTRUDERS] = { DEFAULT_NOMINAL_FILAMENT_DIA
221 224
       , DEFAULT_NOMINAL_FILAMENT_DIA
222 225
     #if EXTRUDERS > 2
223 226
        , DEFAULT_NOMINAL_FILAMENT_DIA
227
+      #if EXTRUDERS > 3
228
+        , DEFAULT_NOMINAL_FILAMENT_DIA
229
+      #endif
224 230
     #endif
225 231
   #endif
226 232
 };
@@ -229,6 +235,9 @@ float volumetric_multiplier[EXTRUDERS] = {1.0
229 235
     , 1.0
230 236
     #if EXTRUDERS > 2
231 237
       , 1.0
238
+      #if EXTRUDERS > 3
239
+        , 1.0
240
+      #endif
232 241
     #endif
233 242
   #endif
234 243
 };
@@ -271,19 +280,25 @@ int EtoPPressure=0;
271 280
   bool autoretract_enabled=false;
272 281
   bool retracted[EXTRUDERS]={false
273 282
     #if EXTRUDERS > 1
274
-    , false
275
-     #if EXTRUDERS > 2
276 283
       , false
277
-     #endif
278
-  #endif
284
+      #if EXTRUDERS > 2
285
+        , false
286
+        #if EXTRUDERS > 3
287
+       	  , false
288
+      	#endif
289
+      #endif
290
+    #endif
279 291
   };
280 292
   bool retracted_swap[EXTRUDERS]={false
281 293
     #if EXTRUDERS > 1
282
-    , false
283
-     #if EXTRUDERS > 2
284 294
       , false
285
-     #endif
286
-  #endif
295
+      #if EXTRUDERS > 2
296
+        , false
297
+        #if EXTRUDERS > 3
298
+       	  , false
299
+      	#endif
300
+      #endif
301
+    #endif
287 302
   };
288 303
 
289 304
   float retract_length = RETRACT_LENGTH;
@@ -293,7 +308,7 @@ int EtoPPressure=0;
293 308
   float retract_recover_length = RETRACT_RECOVER_LENGTH;
294 309
   float retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP;
295 310
   float retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE;
296
-#endif
311
+#endif // FWRETRACT
297 312
 
298 313
 #ifdef ULTIPANEL
299 314
   #ifdef PS_DEFAULT_OFF
@@ -582,8 +597,8 @@ void setup()
582 597
       SERIAL_ECHOLNPGM(STRING_CONFIG_H_AUTHOR);
583 598
       SERIAL_ECHOPGM("Compiled: ");
584 599
       SERIAL_ECHOLNPGM(__DATE__);
585
-    #endif
586
-  #endif
600
+    #endif // STRING_CONFIG_H_AUTHOR
601
+  #endif // STRING_VERSION_CONFIG_H
587 602
   SERIAL_ECHO_START;
588 603
   SERIAL_ECHOPGM(MSG_FREE_MEMORY);
589 604
   SERIAL_ECHO(freeMemory());
@@ -2881,29 +2896,32 @@ Sigma_Exit:
2881 2896
 
2882 2897
         float area = .0;
2883 2898
         if(code_seen('D')) {
2884
-		  float diameter = (float)code_value();
2885
-		  if (diameter == 0.0) {
2886
-			// setting any extruder filament size disables volumetric on the assumption that
2887
-			// slicers either generate in extruder values as cubic mm or as as filament feeds
2888
-			// for all extruders
2889
-		    volumetric_enabled = false;
2890
-		  } else {
2899
+          float diameter = (float)code_value();
2900
+          if (diameter == 0.0) {
2901
+            // setting any extruder filament size disables volumetric on the assumption that
2902
+            // slicers either generate in extruder values as cubic mm or as as filament feeds
2903
+            // for all extruders
2904
+            volumetric_enabled = false;
2905
+          } else {
2891 2906
             filament_size[tmp_extruder] = (float)code_value();
2892
-			// make sure all extruders have some sane value for the filament size
2893
-			filament_size[0] = (filament_size[0] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[0]);
2894
-            #if EXTRUDERS > 1
2895
-			filament_size[1] = (filament_size[1] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[1]);
2896
-            #if EXTRUDERS > 2
2897
-			filament_size[2] = (filament_size[2] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[2]);
2898
-            #endif
2899
-            #endif
2900
-			volumetric_enabled = true;
2901
-		  }
2907
+            // make sure all extruders have some sane value for the filament size
2908
+            filament_size[0] = (filament_size[0] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[0]);
2909
+#if EXTRUDERS > 1
2910
+            filament_size[1] = (filament_size[1] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[1]);
2911
+#if EXTRUDERS > 2
2912
+            filament_size[2] = (filament_size[2] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[2]);
2913
+#if EXTRUDERS > 3
2914
+            filament_size[3] = (filament_size[3] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[3]);
2915
+#endif //EXTRUDERS > 3
2916
+#endif //EXTRUDERS > 2
2917
+#endif //EXTRUDERS > 1
2918
+            volumetric_enabled = true;
2919
+          }
2902 2920
         } else {
2903 2921
           //reserved for setting filament diameter via UFID or filament measuring device
2904 2922
           break;
2905 2923
         }
2906
-		calculate_volumetric_multipliers();
2924
+        calculate_volumetric_multipliers();
2907 2925
       }
2908 2926
       break;
2909 2927
     case 201: // M201
@@ -3020,23 +3038,29 @@ Sigma_Exit:
3020 3038
           {
3021 3039
             autoretract_enabled=false;
3022 3040
             retracted[0]=false;
3023
-            #if EXTRUDERS > 1
3024
-              retracted[1]=false;
3025
-            #endif
3026
-            #if EXTRUDERS > 2
3027
-              retracted[2]=false;
3028
-            #endif
3041
+#if EXTRUDERS > 1
3042
+            retracted[1]=false;
3043
+#endif
3044
+#if EXTRUDERS > 2
3045
+            retracted[2]=false;
3046
+#endif
3047
+#if EXTRUDERS > 3
3048
+            retracted[3]=false;
3049
+#endif
3029 3050
           }break;
3030 3051
           case 1: 
3031 3052
           {
3032 3053
             autoretract_enabled=true;
3033 3054
             retracted[0]=false;
3034
-            #if EXTRUDERS > 1
3035
-              retracted[1]=false;
3036
-            #endif
3037
-            #if EXTRUDERS > 2
3038
-              retracted[2]=false;
3039
-            #endif
3055
+#if EXTRUDERS > 1
3056
+            retracted[1]=false;
3057
+#endif
3058
+#if EXTRUDERS > 2
3059
+            retracted[2]=false;
3060
+#endif
3061
+#if EXTRUDERS > 3
3062
+            retracted[3]=false;
3063
+#endif
3040 3064
           }break;
3041 3065
           default:
3042 3066
             SERIAL_ECHO_START;
@@ -4680,7 +4704,10 @@ void calculate_volumetric_multipliers() {
4680 4704
 	volumetric_multiplier[1] = calculate_volumetric_multiplier(filament_size[1]);
4681 4705
 #if EXTRUDERS > 2
4682 4706
 	volumetric_multiplier[2] = calculate_volumetric_multiplier(filament_size[2]);
4683
-#endif
4684
-#endif
4707
+#if EXTRUDERS > 3
4708
+	volumetric_multiplier[3] = calculate_volumetric_multiplier(filament_size[3]);
4709
+#endif //EXTRUDERS > 3
4710
+#endif //EXTRUDERS > 2
4711
+#endif //EXTRUDERS > 1
4685 4712
 }
4686 4713
 

+ 12
- 2
Marlin/language_en.h Целия файл

@@ -21,14 +21,16 @@
21 21
 #define MSG_PREHEAT_PLA0                    "Preheat PLA 1"
22 22
 #define MSG_PREHEAT_PLA1                    "Preheat PLA 2"
23 23
 #define MSG_PREHEAT_PLA2                    "Preheat PLA 3"
24
-#define MSG_PREHEAT_PLA012                  "Preheat PLA All"
24
+#define MSG_PREHEAT_PLA3                    "Preheat PLA 4"
25
+#define MSG_PREHEAT_PLA0123                 "Preheat PLA All"
25 26
 #define MSG_PREHEAT_PLA_BEDONLY             "Preheat PLA Bed"
26 27
 #define MSG_PREHEAT_PLA_SETTINGS            "Preheat PLA conf"
27 28
 #define MSG_PREHEAT_ABS                     "Preheat ABS"
28 29
 #define MSG_PREHEAT_ABS0                    "Preheat ABS 1"
29 30
 #define MSG_PREHEAT_ABS1                    "Preheat ABS 2"
30 31
 #define MSG_PREHEAT_ABS2                    "Preheat ABS 3"
31
-#define MSG_PREHEAT_ABS012                  "Preheat ABS All"
32
+#define MSG_PREHEAT_ABS3                    "Preheat ABS 4"
33
+#define MSG_PREHEAT_ABS0123                 "Preheat ABS All"
32 34
 #define MSG_PREHEAT_ABS_BEDONLY             "Preheat ABS Bed"
33 35
 #define MSG_PREHEAT_ABS_SETTINGS            "Preheat ABS conf"
34 36
 #define MSG_COOLDOWN                        "Cooldown"
@@ -43,6 +45,7 @@
43 45
 #define MSG_MOVE_E                          "Extruder"
44 46
 #define MSG_MOVE_E1                         "Extruder2"
45 47
 #define MSG_MOVE_E2                         "Extruder3"
48
+#define MSG_MOVE_E3                         "Extruder4"
46 49
 #define MSG_MOVE_01MM                       "Move 0.1mm"
47 50
 #define MSG_MOVE_1MM                        "Move 1mm"
48 51
 #define MSG_MOVE_10MM                       "Move 10mm"
@@ -50,12 +53,14 @@
50 53
 #define MSG_NOZZLE                          "Nozzle"
51 54
 #define MSG_NOZZLE1                         "Nozzle2"
52 55
 #define MSG_NOZZLE2                         "Nozzle3"
56
+#define MSG_NOZZLE3                         "Nozzle4"
53 57
 #define MSG_BED                             "Bed"
54 58
 #define MSG_FAN_SPEED                       "Fan speed"
55 59
 #define MSG_FLOW                            "Flow"
56 60
 #define MSG_FLOW0                           "Flow 0"
57 61
 #define MSG_FLOW1                           "Flow 1"
58 62
 #define MSG_FLOW2                           "Flow 2"
63
+#define MSG_FLOW3                           "Flow 3"
59 64
 #define MSG_CONTROL                         "Control"
60 65
 #define MSG_MIN                             " \002 Min"
61 66
 #define MSG_MAX                             " \002 Max"
@@ -75,6 +80,10 @@
75 80
 #define MSG_PID_I2                          "PID-I E3"
76 81
 #define MSG_PID_D2                          "PID-D E3"
77 82
 #define MSG_PID_C2                          "PID-C E3"
83
+#define MSG_PID_P3                          "PID-P E4"
84
+#define MSG_PID_I3                          "PID-I E4"
85
+#define MSG_PID_D3                          "PID-D E4"
86
+#define MSG_PID_C3                          "PID-C E4"
78 87
 #define MSG_ACC                             "Accel"
79 88
 #define MSG_VXY_JERK                        "Vxy-jerk"
80 89
 #define MSG_VZ_JERK                         "Vz-jerk"
@@ -99,6 +108,7 @@
99 108
 #define MSG_FILAMENT_SIZE_EXTRUDER_0        "Fil. Dia. 1"
100 109
 #define MSG_FILAMENT_SIZE_EXTRUDER_1        "Fil. Dia. 2"
101 110
 #define MSG_FILAMENT_SIZE_EXTRUDER_2        "Fil. Dia. 3"
111
+#define MSG_FILAMENT_SIZE_EXTRUDER_3        "Fil. Dia. 4"
102 112
 #define MSG_CONTRAST                        "LCD contrast"
103 113
 #define MSG_STORE_EPROM                     "Store memory"
104 114
 #define MSG_LOAD_EPROM                      "Load memory"

+ 13
- 3
Marlin/language_it.h Целия файл

@@ -21,14 +21,16 @@
21 21
 #define MSG_PREHEAT_PLA0                    "Preriscalda PLA 1"
22 22
 #define MSG_PREHEAT_PLA1                    "Preriscalda PLA 2"
23 23
 #define MSG_PREHEAT_PLA2                    "Preriscalda PLA 3"
24
-#define MSG_PREHEAT_PLA012                  "Prer. PLA Tutto"
24
+#define MSG_PREHEAT_PLA3                    "Preriscalda PLA 4"
25
+#define MSG_PREHEAT_PLA0123                 "Prer. PLA Tutto"
25 26
 #define MSG_PREHEAT_PLA_BEDONLY             "Prer. PLA Piatto"
26 27
 #define MSG_PREHEAT_PLA_SETTINGS            "Config. prer. PLA"
27 28
 #define MSG_PREHEAT_ABS                     "Preriscalda ABS"
28 29
 #define MSG_PREHEAT_ABS0                    "Preriscalda ABS 1"
29 30
 #define MSG_PREHEAT_ABS1                    "Preriscalda ABS 2"
30 31
 #define MSG_PREHEAT_ABS2                    "Preriscalda ABS 3"
31
-#define MSG_PREHEAT_ABS012                  "Prer. ABS Tutto"
32
+#define MSG_PREHEAT_ABS3                    "Preriscalda ABS 4"
33
+#define MSG_PREHEAT_ABS0123                 "Prer. ABS Tutto"
32 34
 #define MSG_PREHEAT_ABS_BEDONLY             "Prer. ABS Piatto"
33 35
 #define MSG_PREHEAT_ABS_SETTINGS            "Config. prer. ABS"
34 36
 #define MSG_COOLDOWN                        "Raffredda"
@@ -43,6 +45,7 @@
43 45
 #define MSG_MOVE_E                          "Estrusore"
44 46
 #define MSG_MOVE_E1                         "Estrusore 2"
45 47
 #define MSG_MOVE_E2                         "Estrusore 3"
48
+#define MSG_MOVE_E3                         "Estrusore 4"
46 49
 #define MSG_MOVE_01MM                       "Muovi di 0.1mm"
47 50
 #define MSG_MOVE_1MM                        "Muovi di   1mm"
48 51
 #define MSG_MOVE_10MM                       "Muovi di  10mm"
@@ -50,12 +53,14 @@
50 53
 #define MSG_NOZZLE                          "Ugello"
51 54
 #define MSG_NOZZLE1                         "Ugello2"
52 55
 #define MSG_NOZZLE2                         "Ugello3"
56
+#define MSG_NOZZLE3                         "Ugello4"
53 57
 #define MSG_BED                             "Piatto"
54 58
 #define MSG_FAN_SPEED                       "Ventola"
55 59
 #define MSG_FLOW                            "Flusso"
56 60
 #define MSG_FLOW0                           "Flusso 0"
57 61
 #define MSG_FLOW1                           "Flusso 1"
58 62
 #define MSG_FLOW2                           "Flusso 2"
63
+#define MSG_FLOW3                           "Flusso 3"
59 64
 #define MSG_CONTROL                         "Controllo"
60 65
 #define MSG_MIN                             " \002 Min:"
61 66
 #define MSG_MAX                             " \002 Max:"
@@ -75,6 +80,10 @@
75 80
 #define MSG_PID_I2                          "PID-I E3"
76 81
 #define MSG_PID_D2                          "PID-D E3"
77 82
 #define MSG_PID_C2                          "PID-C E3"
83
+#define MSG_PID_P3                          "PID-P E4"
84
+#define MSG_PID_I3                          "PID-I E4"
85
+#define MSG_PID_D3                          "PID-D E4"
86
+#define MSG_PID_C3                          "PID-C E4"
78 87
 #define MSG_ACC                             "Accel."
79 88
 #define MSG_VXY_JERK                        "Vxy-jerk"
80 89
 #define MSG_VZ_JERK                         "Vz-jerk"
@@ -95,10 +104,11 @@
95 104
 #define MSG_TEMPERATURE                     "Temperatura"
96 105
 #define MSG_MOTION                          "Movimento"
97 106
 #define MSG_VOLUMETRIC                      "Filament"
98
-#define MSG_VOLUMETRIC_ENABLED		        "E in mm³"
107
+#define MSG_VOLUMETRIC_ENABLED		          "E in mm³"
99 108
 #define MSG_FILAMENT_SIZE_EXTRUDER_0        "Diam. filo 1"
100 109
 #define MSG_FILAMENT_SIZE_EXTRUDER_1        "Diam. filo 2"
101 110
 #define MSG_FILAMENT_SIZE_EXTRUDER_2        "Diam. filo 3"
111
+#define MSG_FILAMENT_SIZE_EXTRUDER_3        "Diam. filo 4"
102 112
 #define MSG_CONTRAST                        "Contrasto LCD"
103 113
 #define MSG_STORE_EPROM                     "Salva in EEPROM"
104 114
 #define MSG_LOAD_EPROM                      "Carica da EEPROM"

+ 13
- 3
Marlin/pins.h Целия файл

@@ -2947,6 +2947,12 @@ Fan_2 2
2947 2947
 #endif // CHEAPTRONIC
2948 2948
 
2949 2949
 
2950
+#ifndef HEATER_3_PIN
2951
+  #define HEATER_3_PIN -1
2952
+#endif
2953
+#ifndef TEMP_3_PIN
2954
+  #define TEMP_3_PIN -1
2955
+#endif
2950 2956
 
2951 2957
 #ifndef KNOWN_BOARD
2952 2958
 #error Unknown MOTHERBOARD value in configuration.h
@@ -2964,6 +2970,11 @@ Fan_2 2
2964 2970
 #else
2965 2971
   #define _E2_PINS
2966 2972
 #endif
2973
+#if EXTRUDERS > 3
2974
+  #define _E3_PINS E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, HEATER_3_PIN,
2975
+#else
2976
+  #define _E3_PINS
2977
+#endif
2967 2978
 
2968 2979
 #ifdef X_STOP_PIN
2969 2980
   #if X_HOME_DIR < 0
@@ -3009,7 +3020,6 @@ Fan_2 2
3009 3020
 
3010 3021
 #define SENSITIVE_PINS {0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, PS_ON_PIN, \
3011 3022
                         HEATER_BED_PIN, FAN_PIN,                  \
3012
-                        _E0_PINS _E1_PINS _E2_PINS             \
3013
-                        analogInputToDigitalPin(TEMP_0_PIN), analogInputToDigitalPin(TEMP_1_PIN), analogInputToDigitalPin(TEMP_2_PIN), analogInputToDigitalPin(TEMP_BED_PIN) }
3014
-
3023
+                        _E0_PINS _E1_PINS _E2_PINS _E3_PINS           \
3024
+                        analogInputToDigitalPin(TEMP_0_PIN), analogInputToDigitalPin(TEMP_1_PIN), analogInputToDigitalPin(TEMP_2_PIN), analogInputToDigitalPin(TEMP_3_PIN), analogInputToDigitalPin(TEMP_BED_PIN) }
3015 3025
 #endif //__PINS_H

+ 18
- 4
Marlin/planner.cpp Целия файл

@@ -80,7 +80,7 @@ unsigned long axis_steps_per_sqr_second[NUM_AXIS];
80 80
 matrix_3x3 plan_bed_level_matrix = {
81 81
 	1.0, 0.0, 0.0,
82 82
 	0.0, 1.0, 0.0,
83
-	0.0, 0.0, 1.0,
83
+	0.0, 0.0, 1.0
84 84
 };
85 85
 #endif // #ifdef ENABLE_AUTO_BED_LEVELING
86 86
 
@@ -96,7 +96,7 @@ float autotemp_factor=0.1;
96 96
 bool autotemp_enabled=false;
97 97
 #endif
98 98
 
99
-unsigned char g_uc_extruder_last_move[3] = {0,0,0};
99
+unsigned char g_uc_extruder_last_move[4] = {0,0,0,0};
100 100
 
101 101
 //===========================================================================
102 102
 //=================semi-private variables, used in inline  functions    =====
@@ -486,6 +486,7 @@ void check_axes_activity()
486 486
     disable_e0();
487 487
     disable_e1();
488 488
     disable_e2(); 
489
+    disable_e3();
489 490
   }
490 491
 #if defined(FAN_PIN) && FAN_PIN > -1
491 492
   #ifdef FAN_KICKSTART_TIME
@@ -672,6 +673,7 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
672 673
       if(g_uc_extruder_last_move[0] > 0) g_uc_extruder_last_move[0]--;
673 674
       if(g_uc_extruder_last_move[1] > 0) g_uc_extruder_last_move[1]--;
674 675
       if(g_uc_extruder_last_move[2] > 0) g_uc_extruder_last_move[2]--;
676
+      if(g_uc_extruder_last_move[3] > 0) g_uc_extruder_last_move[3]--;
675 677
       
676 678
       switch(extruder)
677 679
       {
@@ -681,6 +683,7 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
681 683
           
682 684
           if(g_uc_extruder_last_move[1] == 0) disable_e1(); 
683 685
           if(g_uc_extruder_last_move[2] == 0) disable_e2(); 
686
+          if(g_uc_extruder_last_move[3] == 0) disable_e3(); 
684 687
         break;
685 688
         case 1:
686 689
           enable_e1(); 
@@ -688,6 +691,7 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
688 691
           
689 692
           if(g_uc_extruder_last_move[0] == 0) disable_e0(); 
690 693
           if(g_uc_extruder_last_move[2] == 0) disable_e2(); 
694
+          if(g_uc_extruder_last_move[3] == 0) disable_e3(); 
691 695
         break;
692 696
         case 2:
693 697
           enable_e2(); 
@@ -695,6 +699,15 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
695 699
           
696 700
           if(g_uc_extruder_last_move[0] == 0) disable_e0(); 
697 701
           if(g_uc_extruder_last_move[1] == 0) disable_e1(); 
702
+          if(g_uc_extruder_last_move[3] == 0) disable_e3(); 
703
+        break;        
704
+        case 3:
705
+          enable_e3(); 
706
+          g_uc_extruder_last_move[3] = BLOCK_BUFFER_SIZE*2;
707
+          
708
+          if(g_uc_extruder_last_move[0] == 0) disable_e0(); 
709
+          if(g_uc_extruder_last_move[1] == 0) disable_e1(); 
710
+          if(g_uc_extruder_last_move[2] == 0) disable_e2(); 
698 711
         break;        
699 712
       }
700 713
     }
@@ -702,7 +715,8 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
702 715
     {
703 716
       enable_e0();
704 717
       enable_e1();
705
-      enable_e2(); 
718
+      enable_e2();
719
+      enable_e3();
706 720
     }
707 721
   }
708 722
 
@@ -866,7 +880,7 @@ Having the real displacement of the head, we can calculate the total movement le
866 880
   long min_xy_segment_time =min(max_x_segment_time, max_y_segment_time);
867 881
   if(min_xy_segment_time < MAX_FREQ_TIME)
868 882
     speed_factor = min(speed_factor, speed_factor * (float)min_xy_segment_time / (float)MAX_FREQ_TIME);
869
-#endif
883
+#endif // XY_FREQUENCY_LIMIT
870 884
 
871 885
   // Correct the speed  
872 886
   if( speed_factor < 1.0)

+ 37
- 5
Marlin/stepper.cpp Целия файл

@@ -55,7 +55,7 @@ volatile static unsigned long step_events_completed; // The number of step event
55 55
 #ifdef ADVANCE
56 56
   static long advance_rate, advance, final_advance = 0;
57 57
   static long old_advance = 0;
58
-  static long e_steps[3];
58
+  static long e_steps[4];
59 59
 #endif
60 60
 static long acceleration_time, deceleration_time;
61 61
 //static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
@@ -200,6 +200,8 @@ void checkHitEndstops()
200 200
      setTargetHotend0(0);
201 201
      setTargetHotend1(0);
202 202
      setTargetHotend2(0);
203
+     setTargetHotend3(0);
204
+     setTargetBed(0);
203 205
    }
204 206
 #endif
205 207
  }
@@ -298,7 +300,7 @@ FORCE_INLINE void trapezoid_generator_reset() {
298 300
 //    SERIAL_ECHOPGM("advance rate :");
299 301
 //    SERIAL_ECHO(current_block->advance_rate/256.0);
300 302
 //    SERIAL_ECHOPGM("initial advance :");
301
-//  SERIAL_ECHO(current_block->initial_advance/256.0);
303
+//    SERIAL_ECHO(current_block->initial_advance/256.0);
302 304
 //    SERIAL_ECHOPGM("final advance :");
303 305
 //    SERIAL_ECHOLN(current_block->final_advance/256.0);
304 306
 
@@ -552,8 +554,8 @@ ISR(TIMER1_COMPA_vect)
552 554
       }
553 555
       #endif //ADVANCE
554 556
 
555
-        counter_x += current_block->steps_x;
556
-        #ifdef CONFIG_STEPPERS_TOSHIBA
557
+      counter_x += current_block->steps_x;
558
+#ifdef CONFIG_STEPPERS_TOSHIBA
557 559
 	/* The toshiba stepper controller require much longer pulses
558 560
 	 * tjerfore we 'stage' decompose the pulses between high, and
559 561
 	 * low instead of doing each in turn. The extra tests add enough
@@ -681,7 +683,7 @@ ISR(TIMER1_COMPA_vect)
681 683
           WRITE_E_STEP(INVERT_E_STEP_PIN);
682 684
         }
683 685
       #endif //!ADVANCE
684
-      #endif
686
+#endif // CONFIG_STEPPERS_TOSHIBA
685 687
       step_events_completed += 1;
686 688
       if(step_events_completed >= current_block->step_event_count) break;
687 689
     }
@@ -807,6 +809,22 @@ ISR(TIMER1_COMPA_vect)
807 809
         }
808 810
       }
809 811
  #endif
812
+ #if EXTRUDERS > 3
813
+      if (e_steps[3] != 0) {
814
+        WRITE(E3_STEP_PIN, INVERT_E_STEP_PIN);
815
+        if (e_steps[3] < 0) {
816
+          WRITE(E3_DIR_PIN, INVERT_E3_DIR);
817
+          e_steps[3]++;
818
+          WRITE(E3_STEP_PIN, !INVERT_E_STEP_PIN);
819
+        }
820
+        else if (e_steps[3] > 0) {
821
+          WRITE(E3_DIR_PIN, !INVERT_E3_DIR);
822
+          e_steps[3]--;
823
+          WRITE(E3_STEP_PIN, !INVERT_E_STEP_PIN);
824
+        }
825
+      }
826
+ #endif
827
+
810 828
     }
811 829
   }
812 830
 #endif // ADVANCE
@@ -846,6 +864,9 @@ void st_init()
846 864
   #if defined(E2_DIR_PIN) && (E2_DIR_PIN > -1)
847 865
     SET_OUTPUT(E2_DIR_PIN);
848 866
   #endif
867
+  #if defined(E3_DIR_PIN) && (E3_DIR_PIN > -1)
868
+    SET_OUTPUT(E3_DIR_PIN);
869
+  #endif
849 870
 
850 871
   //Initialize Enable Pins - steppers default to disabled.
851 872
 
@@ -887,6 +908,10 @@ void st_init()
887 908
     SET_OUTPUT(E2_ENABLE_PIN);
888 909
     if(!E_ENABLE_ON) WRITE(E2_ENABLE_PIN,HIGH);
889 910
   #endif
911
+  #if defined(E3_ENABLE_PIN) && (E3_ENABLE_PIN > -1)
912
+    SET_OUTPUT(E3_ENABLE_PIN);
913
+    if(!E_ENABLE_ON) WRITE(E3_ENABLE_PIN,HIGH);
914
+  #endif
890 915
 
891 916
   //endstops and pullups
892 917
 
@@ -977,6 +1002,11 @@ void st_init()
977 1002
     WRITE(E2_STEP_PIN,INVERT_E_STEP_PIN);
978 1003
     disable_e2();
979 1004
   #endif
1005
+  #if defined(E3_STEP_PIN) && (E3_STEP_PIN > -1)
1006
+    SET_OUTPUT(E3_STEP_PIN);
1007
+    WRITE(E3_STEP_PIN,INVERT_E_STEP_PIN);
1008
+    disable_e3();
1009
+  #endif
980 1010
 
981 1011
   // waveform generation = 0100 = CTC
982 1012
   TCCR1B &= ~(1<<WGM13);
@@ -1007,6 +1037,7 @@ void st_init()
1007 1037
     e_steps[0] = 0;
1008 1038
     e_steps[1] = 0;
1009 1039
     e_steps[2] = 0;
1040
+    e_steps[3] = 0;
1010 1041
     TIMSK0 |= (1<<OCIE0A);
1011 1042
   #endif //ADVANCE
1012 1043
 
@@ -1068,6 +1099,7 @@ void finishAndDisableSteppers()
1068 1099
   disable_e0();
1069 1100
   disable_e1();
1070 1101
   disable_e2();
1102
+  disable_e3();
1071 1103
 }
1072 1104
 
1073 1105
 void quickStop()

+ 5
- 1
Marlin/stepper.h Целия файл

@@ -23,7 +23,11 @@
23 23
 
24 24
 #include "planner.h"
25 25
 
26
-#if EXTRUDERS > 2
26
+#if EXTRUDERS > 3
27
+  #define WRITE_E_STEP(v) { if(current_block->active_extruder == 3) { WRITE(E3_STEP_PIN, v); } else { if(current_block->active_extruder == 2) { WRITE(E2_STEP_PIN, v); } else { if(current_block->active_extruder == 1) { WRITE(E1_STEP_PIN, v); } else { WRITE(E0_STEP_PIN, v); }}}}
28
+  #define NORM_E_DIR() { if(current_block->active_extruder == 3) { WRITE(E3_DIR_PIN, !INVERT_E3_DIR); } else { if(current_block->active_extruder == 2) { WRITE(E2_DIR_PIN, !INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, !INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); }}}}
29
+  #define REV_E_DIR() { if(current_block->active_extruder == 3) { WRITE(E3_DIR_PIN, INVERT_E3_DIR); } else { if(current_block->active_extruder == 2) { WRITE(E2_DIR_PIN, INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, INVERT_E0_DIR); }}}}
30
+#elif EXTRUDERS > 2
27 31
   #define WRITE_E_STEP(v) { if(current_block->active_extruder == 2) { WRITE(E2_STEP_PIN, v); } else { if(current_block->active_extruder == 1) { WRITE(E1_STEP_PIN, v); } else { WRITE(E0_STEP_PIN, v); }}}
28 32
   #define NORM_E_DIR() { if(current_block->active_extruder == 2) { WRITE(E2_DIR_PIN, !INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, !INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); }}}
29 33
   #define REV_E_DIR() { if(current_block->active_extruder == 2) { WRITE(E2_DIR_PIN, INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, INVERT_E0_DIR); }}}

+ 227
- 48
Marlin/temperature.cpp Целия файл

@@ -38,8 +38,15 @@
38 38
 
39 39
 
40 40
 //===========================================================================
41
-//=============================public variables============================
41
+//============================= public variables ============================
42 42
 //===========================================================================
43
+
44
+// Sampling period of the temperature routine
45
+#ifdef PID_dT
46
+  #undef PID_dT
47
+#endif
48
+#define PID_dT ((OVERSAMPLENR * 12.0)/(F_CPU / 64.0 / 256.0))
49
+
43 50
 int target_temperature[EXTRUDERS] = { 0 };
44 51
 int target_temperature_bed = 0;
45 52
 int current_temperature_raw[EXTRUDERS] = { 0 };
@@ -115,14 +122,16 @@ static volatile bool temp_meas_ready = false;
115 122
   static unsigned long extruder_autofan_last_check;
116 123
 #endif  
117 124
 
118
-#if EXTRUDERS > 3
125
+#if EXTRUDERS > 4
119 126
   # error Unsupported number of extruders
127
+#elif EXTRUDERS > 3
128
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3, v4 }
120 129
 #elif EXTRUDERS > 2
121
-  # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2, v3 }
130
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3 }
122 131
 #elif EXTRUDERS > 1
123
-  # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2 }
132
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2 }
124 133
 #else
125
-  # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
134
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1 }
126 135
 #endif
127 136
 
128 137
 #ifdef PIDTEMP
@@ -144,10 +153,10 @@ static volatile bool temp_meas_ready = false;
144 153
 #endif //PIDTEMP
145 154
 
146 155
 // Init min and max temp with extreme values to prevent false errors during startup
147
-static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
148
-static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
149
-static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0 );
150
-static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383 );
156
+static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP, HEATER_3_RAW_LO_TEMP);
157
+static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP, HEATER_3_RAW_HI_TEMP);
158
+static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0, 0 );
159
+static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383, 16383 );
151 160
 //static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */
152 161
 #ifdef BED_MAXTEMP
153 162
 static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
@@ -157,8 +166,8 @@ static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
157 166
   static void *heater_ttbl_map[2] = {(void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE };
158 167
   static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN };
159 168
 #else
160
-  static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE );
161
-  static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN );
169
+  static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE, (void *)HEATER_3_TEMPTABLE );
170
+  static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN, HEATER_3_TEMPTABLE_LEN );
162 171
 #endif
163 172
 
164 173
 static float analog2temp(int raw, uint8_t e);
@@ -166,8 +175,8 @@ static float analog2tempBed(int raw);
166 175
 static void updateTemperaturesFromRawValues();
167 176
 
168 177
 #ifdef WATCH_TEMP_PERIOD
169
-int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
170
-unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
178
+int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0);
179
+unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0);
171 180
 #endif //WATCH_TEMP_PERIOD
172 181
 
173 182
 #ifndef SOFT_PWM_SCALE
@@ -205,7 +214,8 @@ void PID_autotune(float temp, int extruder, int ncycles)
205 214
 
206 215
 #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
207 216
     (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
208
-    (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
217
+    (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) || \
218
+    (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1)
209 219
   unsigned long extruder_autofan_last_check = millis();
210 220
 #endif
211 221
 
@@ -248,7 +258,8 @@ void PID_autotune(float temp, int extruder, int ncycles)
248 258
 
249 259
       #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
250 260
           (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
251
-          (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
261
+          (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) || \
262
+          (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1)
252 263
       if(millis() - extruder_autofan_last_check > 2500) {
253 264
         checkExtruderAutoFans();
254 265
         extruder_autofan_last_check = millis();
@@ -425,6 +436,19 @@ void checkExtruderAutoFans()
425 436
         fanState |= 4;
426 437
     }
427 438
   #endif
439
+  #if defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1
440
+    if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) 
441
+    {
442
+      if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) 
443
+        fanState |= 1;
444
+      else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN) 
445
+        fanState |= 2;
446
+      else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN) 
447
+        fanState |= 4;
448
+      else
449
+        fanState |= 8;
450
+    }
451
+  #endif
428 452
   
429 453
   // update extruder auto fan states
430 454
   #if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
@@ -438,7 +462,13 @@ void checkExtruderAutoFans()
438 462
     if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN 
439 463
         && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
440 464
       setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
441
-  #endif 
465
+  #endif
466
+  #if defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1
467
+    if (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN 
468
+        && EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
469
+        && EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
470
+      setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0);
471
+  #endif
442 472
 }
443 473
 
444 474
 #endif // any extruder auto fan pins set
@@ -606,13 +636,13 @@ void manage_heater()
606 636
 		  temp_dState_bed = pid_input;
607 637
 
608 638
 		  pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
609
-          	  if (pid_output > MAX_BED_POWER) {
610
-            	    if (pid_error_bed > 0 )  temp_iState_bed -= pid_error_bed; // conditional un-integration
611
-                    pid_output=MAX_BED_POWER;
612
-          	  } else if (pid_output < 0){
613
-            	    if (pid_error_bed < 0 )  temp_iState_bed -= pid_error_bed; // conditional un-integration
614
-                    pid_output=0;
615
-                  }
639
+      if (pid_output > MAX_BED_POWER) {
640
+        if (pid_error_bed > 0 )  temp_iState_bed -= pid_error_bed; // conditional un-integration
641
+        pid_output=MAX_BED_POWER;
642
+      } else if (pid_output < 0){
643
+        if (pid_error_bed < 0 )  temp_iState_bed -= pid_error_bed; // conditional un-integration
644
+        pid_output=0;
645
+      }
616 646
 
617 647
     #else 
618 648
       pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
@@ -847,13 +877,16 @@ void tp_init()
847 877
 
848 878
   #if defined(HEATER_0_PIN) && (HEATER_0_PIN > -1) 
849 879
     SET_OUTPUT(HEATER_0_PIN);
850
-  #endif  
880
+  #endif
851 881
   #if defined(HEATER_1_PIN) && (HEATER_1_PIN > -1) 
852 882
     SET_OUTPUT(HEATER_1_PIN);
853 883
   #endif
854 884
   #if defined(HEATER_2_PIN) && (HEATER_2_PIN > -1) 
855 885
     SET_OUTPUT(HEATER_2_PIN);
856
-  #endif  
886
+  #endif
887
+  #if defined(HEATER_3_PIN) && (HEATER_3_PIN > -1) 
888
+    SET_OUTPUT(HEATER_3_PIN);
889
+  #endif
857 890
   #if defined(HEATER_BED_PIN) && (HEATER_BED_PIN > -1) 
858 891
     SET_OUTPUT(HEATER_BED_PIN);
859 892
   #endif  
@@ -903,16 +936,23 @@ void tp_init()
903 936
   #endif
904 937
   #if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
905 938
     #if TEMP_1_PIN < 8
906
-       DIDR0 |= 1<<TEMP_1_PIN; 
939
+      DIDR0 |= 1<<TEMP_1_PIN; 
907 940
     #else
908
-       DIDR2 |= 1<<(TEMP_1_PIN - 8); 
941
+    	DIDR2 |= 1<<(TEMP_1_PIN - 8); 
909 942
     #endif
910 943
   #endif
911 944
   #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
912 945
     #if TEMP_2_PIN < 8
913
-       DIDR0 |= 1 << TEMP_2_PIN; 
946
+      DIDR0 |= 1 << TEMP_2_PIN; 
914 947
     #else
915
-       DIDR2 |= 1<<(TEMP_2_PIN - 8); 
948
+      DIDR2 |= 1<<(TEMP_2_PIN - 8); 
949
+    #endif
950
+  #endif
951
+  #if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
952
+    #if TEMP_3_PIN < 8
953
+      DIDR0 |= 1 << TEMP_3_PIN; 
954
+    #else
955
+      DIDR2 |= 1<<(TEMP_3_PIN - 8); 
916 956
     #endif
917 957
   #endif
918 958
   #if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
@@ -925,13 +965,13 @@ void tp_init()
925 965
   
926 966
   //Added for Filament Sensor 
927 967
   #ifdef FILAMENT_SENSOR
928
-   #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1) 
929
-	#if FILWIDTH_PIN < 8 
930
-       	   DIDR0 |= 1<<FILWIDTH_PIN;  
931
-	#else 
932
-       	   DIDR2 |= 1<<(FILWIDTH_PIN - 8);  
933
-	#endif 
934
-   #endif
968
+    #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1) 
969
+      #if FILWIDTH_PIN < 8 
970
+        DIDR0 |= 1<<FILWIDTH_PIN;  
971
+      #else
972
+        DIDR2 |= 1<<(FILWIDTH_PIN - 8);  
973
+      #endif 
974
+    #endif
935 975
   #endif
936 976
   
937 977
   // Use timer0 for temperature measurement
@@ -1005,6 +1045,28 @@ void tp_init()
1005 1045
   }
1006 1046
 #endif //MAXTEMP 2
1007 1047
 
1048
+#if (EXTRUDERS > 3) && defined(HEATER_3_MINTEMP)
1049
+  minttemp[3] = HEATER_3_MINTEMP;
1050
+  while(analog2temp(minttemp_raw[3], 3) < HEATER_3_MINTEMP) {
1051
+#if HEATER_3_RAW_LO_TEMP < HEATER_3_RAW_HI_TEMP
1052
+    minttemp_raw[3] += OVERSAMPLENR;
1053
+#else
1054
+    minttemp_raw[3] -= OVERSAMPLENR;
1055
+#endif
1056
+  }
1057
+#endif //MINTEMP 3
1058
+#if (EXTRUDERS > 3) && defined(HEATER_3_MAXTEMP)
1059
+  maxttemp[3] = HEATER_3_MAXTEMP;
1060
+  while(analog2temp(maxttemp_raw[3], 3) > HEATER_3_MAXTEMP) {
1061
+#if HEATER_3_RAW_LO_TEMP < HEATER_3_RAW_HI_TEMP
1062
+    maxttemp_raw[3] -= OVERSAMPLENR;
1063
+#else
1064
+    maxttemp_raw[3] += OVERSAMPLENR;
1065
+#endif
1066
+  }
1067
+#endif // MAXTEMP 3
1068
+
1069
+
1008 1070
 #ifdef BED_MINTEMP
1009 1071
   /* No bed MINTEMP error implemented?!? */ /*
1010 1072
   while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
@@ -1093,6 +1155,7 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
1093 1155
           disable_e0();
1094 1156
           disable_e1();
1095 1157
           disable_e2();
1158
+          disable_e3();
1096 1159
           manage_heater();
1097 1160
           lcd_update();
1098 1161
         }
@@ -1129,8 +1192,17 @@ void disable_heater()
1129 1192
     #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1  
1130 1193
       WRITE(HEATER_2_PIN,LOW);
1131 1194
     #endif
1195
+  #endif
1196
+
1197
+  #if defined(TEMP_3_PIN) && TEMP_3_PIN > -1 && EXTRUDERS > 3
1198
+    target_temperature[3]=0;
1199
+    soft_pwm[3]=0;
1200
+    #if defined(HEATER_3_PIN) && HEATER_3_PIN > -1  
1201
+      WRITE(HEATER_3_PIN,LOW);
1202
+    #endif
1132 1203
   #endif 
1133 1204
 
1205
+
1134 1206
   #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
1135 1207
     target_temperature_bed=0;
1136 1208
     soft_pwm_bed=0;
@@ -1246,8 +1318,9 @@ ISR(TIMER0_COMPB_vect)
1246 1318
   static unsigned long raw_temp_0_value = 0;
1247 1319
   static unsigned long raw_temp_1_value = 0;
1248 1320
   static unsigned long raw_temp_2_value = 0;
1321
+  static unsigned long raw_temp_3_value = 0;
1249 1322
   static unsigned long raw_temp_bed_value = 0;
1250
-  static unsigned char temp_state = 10;
1323
+  static unsigned char temp_state = 12;
1251 1324
   static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
1252 1325
   static unsigned char soft_pwm_0;
1253 1326
 #ifdef SLOW_PWM_HEATERS
@@ -1255,6 +1328,7 @@ ISR(TIMER0_COMPB_vect)
1255 1328
   static unsigned char state_heater_0 = 0;
1256 1329
   static unsigned char state_timer_heater_0 = 0;
1257 1330
 #endif 
1331
+
1258 1332
 #if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
1259 1333
   static unsigned char soft_pwm_1;
1260 1334
 #ifdef SLOW_PWM_HEATERS
@@ -1269,6 +1343,14 @@ ISR(TIMER0_COMPB_vect)
1269 1343
   static unsigned char state_timer_heater_2 = 0;
1270 1344
 #endif 
1271 1345
 #endif
1346
+#if EXTRUDERS > 3
1347
+  static unsigned char soft_pwm_3;
1348
+#ifdef SLOW_PWM_HEATERS
1349
+  static unsigned char state_heater_3 = 0;
1350
+  static unsigned char state_timer_heater_3 = 0;
1351
+#endif
1352
+#endif
1353
+
1272 1354
 #if HEATER_BED_PIN > -1
1273 1355
   static unsigned char soft_pwm_b;
1274 1356
 #ifdef SLOW_PWM_HEATERS
@@ -1293,7 +1375,7 @@ ISR(TIMER0_COMPB_vect)
1293 1375
       WRITE(HEATER_1_PIN,1);
1294 1376
 #endif
1295 1377
     } else WRITE(HEATER_0_PIN,0);
1296
-    
1378
+
1297 1379
 #if EXTRUDERS > 1
1298 1380
     soft_pwm_1 = soft_pwm[1];
1299 1381
     if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0);
@@ -1302,6 +1384,12 @@ ISR(TIMER0_COMPB_vect)
1302 1384
     soft_pwm_2 = soft_pwm[2];
1303 1385
     if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0);
1304 1386
 #endif
1387
+#if EXTRUDERS > 3
1388
+    soft_pwm_3 = soft_pwm[3];
1389
+    if(soft_pwm_3 > 0) WRITE(HEATER_3_PIN,1); else WRITE(HEATER_3_PIN,0);
1390
+#endif
1391
+
1392
+
1305 1393
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1306 1394
     soft_pwm_b = soft_pwm_bed;
1307 1395
     if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
@@ -1317,12 +1405,17 @@ ISR(TIMER0_COMPB_vect)
1317 1405
     WRITE(HEATER_1_PIN,0);
1318 1406
 #endif
1319 1407
   }
1408
+
1320 1409
 #if EXTRUDERS > 1
1321 1410
   if(soft_pwm_1 < pwm_count) WRITE(HEATER_1_PIN,0);
1322 1411
 #endif
1323 1412
 #if EXTRUDERS > 2
1324 1413
   if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
1325 1414
 #endif
1415
+#if EXTRUDERS > 3
1416
+  if(soft_pwm_3 < pwm_count) WRITE(HEATER_3_PIN,0);
1417
+#endif
1418
+
1326 1419
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1327 1420
   if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0);
1328 1421
 #endif
@@ -1424,7 +1517,33 @@ ISR(TIMER0_COMPB_vect)
1424 1517
       }
1425 1518
     }
1426 1519
 #endif
1427
-    
1520
+
1521
+#if EXTRUDERS > 3
1522
+    // EXTRUDER 3
1523
+    soft_pwm_3 = soft_pwm[3];
1524
+    if (soft_pwm_3 > 0) {
1525
+      // turn ON heather only if the minimum time is up 
1526
+      if (state_timer_heater_3 == 0) { 
1527
+	// if change state set timer 
1528
+	if (state_heater_3 == 0) {
1529
+	  state_timer_heater_3 = MIN_STATE_TIME;
1530
+	}
1531
+	state_heater_3 = 1;
1532
+	WRITE(HEATER_3_PIN, 1);
1533
+      }
1534
+    } else {
1535
+      // turn OFF heather only if the minimum time is up 
1536
+      if (state_timer_heater_3 == 0) {
1537
+	// if change state set timer 
1538
+	if (state_heater_3 == 1) {
1539
+	  state_timer_heater_3 = MIN_STATE_TIME;
1540
+	}
1541
+	state_heater_3 = 0;
1542
+	WRITE(HEATER_3_PIN, 0);
1543
+      }
1544
+    }
1545
+#endif
1546
+
1428 1547
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1429 1548
     // BED
1430 1549
     soft_pwm_b = soft_pwm_bed;
@@ -1497,6 +1616,21 @@ ISR(TIMER0_COMPB_vect)
1497 1616
     }
1498 1617
   }
1499 1618
 #endif
1619
+
1620
+#if EXTRUDERS > 3
1621
+  // EXTRUDER 3
1622
+  if (soft_pwm_3 < slow_pwm_count) {
1623
+    // turn OFF heather only if the minimum time is up 
1624
+    if (state_timer_heater_3 == 0) { 
1625
+      // if change state set timer 
1626
+      if (state_heater_3 == 1) {
1627
+	state_timer_heater_3 = MIN_STATE_TIME;
1628
+      }
1629
+      state_heater_3 = 0;
1630
+      WRITE(HEATER_3_PIN, 0);
1631
+    }
1632
+  }
1633
+#endif
1500 1634
   
1501 1635
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1502 1636
   // BED
@@ -1545,6 +1679,12 @@ ISR(TIMER0_COMPB_vect)
1545 1679
     if (state_timer_heater_2 > 0) 
1546 1680
       state_timer_heater_2--;
1547 1681
 #endif
1682
+
1683
+#if EXTRUDERS > 3
1684
+    // Extruder 3
1685
+    if (state_timer_heater_3 > 0) 
1686
+      state_timer_heater_3--;
1687
+#endif
1548 1688
     
1549 1689
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1550 1690
     // Bed   
@@ -1630,10 +1770,28 @@ ISR(TIMER0_COMPB_vect)
1630 1770
       #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
1631 1771
         raw_temp_2_value += ADC;
1632 1772
       #endif
1633
-      temp_state = 8;//change so that Filament Width is also measured
1634
-      
1773
+      temp_state = 8;
1635 1774
       break;
1636
-    case 8: //Prepare FILWIDTH 
1775
+    case 8: // Prepare TEMP_3
1776
+      #if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
1777
+        #if TEMP_3_PIN > 7
1778
+          ADCSRB = 1<<MUX5;
1779
+        #else
1780
+          ADCSRB = 0;
1781
+        #endif
1782
+        ADMUX = ((1 << REFS0) | (TEMP_3_PIN & 0x07));
1783
+        ADCSRA |= 1<<ADSC; // Start conversion
1784
+      #endif
1785
+      lcd_buttons_update();
1786
+      temp_state = 9;
1787
+      break;
1788
+    case 9: // Measure TEMP_3
1789
+      #if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
1790
+        raw_temp_3_value += ADC;
1791
+      #endif
1792
+      temp_state = 10; //change so that Filament Width is also measured
1793
+      break;
1794
+    case 10: //Prepare FILWIDTH 
1637 1795
      #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1) 
1638 1796
       #if FILWIDTH_PIN>7 
1639 1797
          ADCSRB = 1<<MUX5;
@@ -1644,9 +1802,9 @@ ISR(TIMER0_COMPB_vect)
1644 1802
       ADCSRA |= 1<<ADSC; // Start conversion 
1645 1803
      #endif 
1646 1804
      lcd_buttons_update();       
1647
-     temp_state = 9; 
1805
+     temp_state = 11; 
1648 1806
      break; 
1649
-    case 9:   //Measure FILWIDTH 
1807
+    case 11:   //Measure FILWIDTH 
1650 1808
      #if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1) 
1651 1809
      //raw_filwidth_value += ADC;  //remove to use an IIR filter approach 
1652 1810
       if(ADC>102)  //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
@@ -1662,7 +1820,7 @@ ISR(TIMER0_COMPB_vect)
1662 1820
      break;      
1663 1821
       
1664 1822
       
1665
-    case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
1823
+    case 12: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
1666 1824
       temp_state = 0;
1667 1825
       break;
1668 1826
 //    default:
@@ -1687,6 +1845,9 @@ ISR(TIMER0_COMPB_vect)
1687 1845
 #if EXTRUDERS > 2
1688 1846
       current_temperature_raw[2] = raw_temp_2_value;
1689 1847
 #endif
1848
+#if EXTRUDERS > 3
1849
+      current_temperature_raw[3] = raw_temp_3_value;
1850
+#endif
1690 1851
       current_temperature_bed_raw = raw_temp_bed_value;
1691 1852
     }
1692 1853
 
@@ -1701,6 +1862,7 @@ ISR(TIMER0_COMPB_vect)
1701 1862
     raw_temp_0_value = 0;
1702 1863
     raw_temp_1_value = 0;
1703 1864
     raw_temp_2_value = 0;
1865
+    raw_temp_3_value = 0;
1704 1866
     raw_temp_bed_value = 0;
1705 1867
 
1706 1868
 #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
@@ -1721,6 +1883,8 @@ ISR(TIMER0_COMPB_vect)
1721 1883
         min_temp_error(0);
1722 1884
 #endif
1723 1885
     }
1886
+
1887
+
1724 1888
 #if EXTRUDERS > 1
1725 1889
 #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
1726 1890
     if(current_temperature_raw[1] <= maxttemp_raw[1]) {
@@ -1753,7 +1917,24 @@ ISR(TIMER0_COMPB_vect)
1753 1917
         min_temp_error(2);
1754 1918
     }
1755 1919
 #endif
1756
-  
1920
+#if EXTRUDERS > 3
1921
+#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
1922
+    if(current_temperature_raw[3] <= maxttemp_raw[3]) {
1923
+#else
1924
+    if(current_temperature_raw[3] >= maxttemp_raw[3]) {
1925
+#endif
1926
+        max_temp_error(3);
1927
+    }
1928
+#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
1929
+    if(current_temperature_raw[3] >= minttemp_raw[3]) {
1930
+#else
1931
+    if(current_temperature_raw[3] <= minttemp_raw[3]) {
1932
+#endif
1933
+        min_temp_error(3);
1934
+    }
1935
+#endif
1936
+
1937
+
1757 1938
   /* No bed MINTEMP error? */
1758 1939
 #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
1759 1940
 # if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
@@ -1812,5 +1993,3 @@ float unscalePID_d(float d)
1812 1993
 }
1813 1994
 
1814 1995
 #endif //PIDTEMP
1815
-
1816
-

+ 23
- 15
Marlin/temperature.h Целия файл

@@ -159,6 +159,15 @@ FORCE_INLINE bool isCoolingBed() {
159 159
 #define setTargetHotend2(_celsius) do{}while(0)
160 160
 #endif
161 161
 #if EXTRUDERS > 3
162
+#define degHotend3() degHotend(3)
163
+#define degTargetHotend3() degTargetHotend(3)
164
+#define setTargetHotend3(_celsius) setTargetHotend((_celsius), 3)
165
+#define isHeatingHotend3() isHeatingHotend(3)
166
+#define isCoolingHotend3() isCoolingHotend(3)
167
+#else
168
+#define setTargetHotend3(_celsius) do{}while(0)
169
+#endif
170
+#if EXTRUDERS > 4
162 171
 #error Invalid number of extruders
163 172
 #endif
164 173
 
@@ -171,24 +180,24 @@ void updatePID();
171 180
 
172 181
 #if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
173 182
 void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
174
-static int thermal_runaway_state_machine[3]; // = {0,0,0};
175
-static unsigned long thermal_runaway_timer[3]; // = {0,0,0};
183
+static int thermal_runaway_state_machine[4]; // = {0,0,0,0};
184
+static unsigned long thermal_runaway_timer[4]; // = {0,0,0,0};
176 185
 static bool thermal_runaway = false;
177
-  #if TEMP_SENSOR_BED != 0
178
-    static int thermal_runaway_bed_state_machine;
179
-    static unsigned long thermal_runaway_bed_timer;
180
-  #endif
186
+#if TEMP_SENSOR_BED != 0
187
+  static int thermal_runaway_bed_state_machine;
188
+  static unsigned long thermal_runaway_bed_timer;
189
+#endif
181 190
 #endif
182 191
 
183 192
 FORCE_INLINE void autotempShutdown(){
184
- #ifdef AUTOTEMP
185
- if(autotemp_enabled)
186
- {
187
-  autotemp_enabled=false;
188
-  if(degTargetHotend(active_extruder)>autotemp_min)
189
-    setTargetHotend(0,active_extruder);
190
- }
191
- #endif
193
+#ifdef AUTOTEMP
194
+  if(autotemp_enabled)
195
+  {
196
+    autotemp_enabled=false;
197
+    if(degTargetHotend(active_extruder)>autotemp_min)
198
+      setTargetHotend(0,active_extruder);
199
+  }
200
+#endif
192 201
 }
193 202
 
194 203
 void PID_autotune(float temp, int extruder, int ncycles);
@@ -197,4 +206,3 @@ void setExtruderAutoFanState(int pin, bool state);
197 206
 void checkExtruderAutoFans();
198 207
 
199 208
 #endif
200
-

+ 48
- 21
Marlin/thermistortables.h Целия файл

@@ -5,7 +5,7 @@
5 5
 
6 6
 #define OVERSAMPLENR 16
7 7
 
8
-#if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1)  || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor
8
+#if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1)  || (THERMISTORHEATER_2 == 1) || (THERMISTORHEATER_3 == 1) || (THERMISTORBED == 1) //100k bed thermistor
9 9
 
10 10
 const short temptable_1[][2] PROGMEM = {
11 11
 {       23*OVERSAMPLENR ,       300     },
@@ -71,7 +71,7 @@ const short temptable_1[][2] PROGMEM = {
71 71
 {       1008*OVERSAMPLENR       ,       0       } //safety
72 72
 };
73 73
 #endif
74
-#if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor
74
+#if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORHEATER_3 == 2) || (THERMISTORBED == 2) //200k bed thermistor
75 75
 const short temptable_2[][2] PROGMEM = {
76 76
 //200k ATC Semitec 204GT-2
77 77
 //Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
@@ -111,7 +111,7 @@ const short temptable_2[][2] PROGMEM = {
111 111
 };
112 112
 
113 113
 #endif
114
-#if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORBED == 3) //mendel-parts
114
+#if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORHEATER_3 == 3) || (THERMISTORBED == 3) //mendel-parts
115 115
 const short temptable_3[][2] PROGMEM = {
116 116
                 {1*OVERSAMPLENR,864},
117 117
                 {21*OVERSAMPLENR,300},
@@ -144,7 +144,7 @@ const short temptable_3[][2] PROGMEM = {
144 144
         };
145 145
 
146 146
 #endif
147
-#if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor
147
+#if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORHEATER_3 == 4) || (THERMISTORBED == 4) //10k thermistor
148 148
 const short temptable_4[][2] PROGMEM = {
149 149
    {1*OVERSAMPLENR, 430},
150 150
    {54*OVERSAMPLENR, 137},
@@ -169,7 +169,7 @@ const short temptable_4[][2] PROGMEM = {
169 169
 };
170 170
 #endif
171 171
 
172
-#if (THERMISTORHEATER_0 == 5) || (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)
172
+#if (THERMISTORHEATER_0 == 5) || (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORHEATER_3 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)
173 173
 const short temptable_5[][2] PROGMEM = {
174 174
 // ATC Semitec 104GT-2 (Used in ParCan)
175 175
 // Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
@@ -209,7 +209,7 @@ const short temptable_5[][2] PROGMEM = {
209 209
 };
210 210
 #endif
211 211
 
212
-#if (THERMISTORHEATER_0 == 6) || (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor
212
+#if (THERMISTORHEATER_0 == 6) || (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORHEATER_3 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor
213 213
 const short temptable_6[][2] PROGMEM = {
214 214
    {1*OVERSAMPLENR, 350},
215 215
    {28*OVERSAMPLENR, 250}, //top rating 250C
@@ -252,7 +252,7 @@ const short temptable_6[][2] PROGMEM = {
252 252
 };
253 253
 #endif
254 254
 
255
-#if (THERMISTORHEATER_0 == 7) || (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01
255
+#if (THERMISTORHEATER_0 == 7) || (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORHEATER_3 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01
256 256
 const short temptable_7[][2] PROGMEM = {
257 257
    {1*OVERSAMPLENR, 941},
258 258
    {19*OVERSAMPLENR, 362},
@@ -315,7 +315,7 @@ const short temptable_7[][2] PROGMEM = {
315 315
 };
316 316
 #endif
317 317
 
318
-#if (THERMISTORHEATER_0 == 71) || (THERMISTORHEATER_1 == 71) || (THERMISTORHEATER_2 == 71) || (THERMISTORBED == 71) // 100k Honeywell 135-104LAF-J01
318
+#if (THERMISTORHEATER_0 == 71) || (THERMISTORHEATER_1 == 71) || (THERMISTORHEATER_2 == 71) || (THERMISTORHEATER_3 == 71) || (THERMISTORBED == 71) // 100k Honeywell 135-104LAF-J01
319 319
 // R0 = 100000 Ohm
320 320
 // T0 = 25 °C
321 321
 // Beta = 3974
@@ -466,7 +466,7 @@ const short temptable_71[][2] PROGMEM = {
466 466
 };
467 467
 #endif
468 468
 
469
-#if (THERMISTORHEATER_0 == 8) || (THERMISTORHEATER_1 == 8) || (THERMISTORHEATER_2 == 8) || (THERMISTORBED == 8)
469
+#if (THERMISTORHEATER_0 == 8) || (THERMISTORHEATER_1 == 8) || (THERMISTORHEATER_2 == 8) || (THERMISTORHEATER_3 == 8) || (THERMISTORBED == 8)
470 470
 // 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
471 471
 const short temptable_8[][2] PROGMEM = {
472 472
    {1*OVERSAMPLENR, 704},
@@ -491,7 +491,7 @@ const short temptable_8[][2] PROGMEM = {
491 491
    {1008*OVERSAMPLENR, 0}
492 492
 };
493 493
 #endif
494
-#if (THERMISTORHEATER_0 == 9) || (THERMISTORHEATER_1 == 9) || (THERMISTORHEATER_2 == 9) || (THERMISTORBED == 9)
494
+#if (THERMISTORHEATER_0 == 9) || (THERMISTORHEATER_1 == 9) || (THERMISTORHEATER_2 == 9) || (THERMISTORHEATER_3 == 9) || (THERMISTORBED == 9)
495 495
 // 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
496 496
 const short temptable_9[][2] PROGMEM = {
497 497
 	{1*OVERSAMPLENR, 936},
@@ -527,7 +527,7 @@ const short temptable_9[][2] PROGMEM = {
527 527
 	{1016*OVERSAMPLENR, 0}
528 528
 };
529 529
 #endif
530
-#if (THERMISTORHEATER_0 == 10) || (THERMISTORHEATER_1 == 10) || (THERMISTORHEATER_2 == 10) || (THERMISTORBED == 10)
530
+#if (THERMISTORHEATER_0 == 10) || (THERMISTORHEATER_1 == 10) || (THERMISTORHEATER_2 == 10) || (THERMISTORHEATER_3 == 10) || (THERMISTORBED == 10)
531 531
 // 100k RS thermistor 198-961 (4.7k pullup)
532 532
 const short temptable_10[][2] PROGMEM = {
533 533
    {1*OVERSAMPLENR, 929},
@@ -564,7 +564,7 @@ const short temptable_10[][2] PROGMEM = {
564 564
 };
565 565
 #endif
566 566
 
567
-#if (THERMISTORHEATER_0 == 11) || (THERMISTORHEATER_1 == 11) || (THERMISTORHEATER_2 == 11) || (THERMISTORBED == 11) 
567
+#if (THERMISTORHEATER_0 == 11) || (THERMISTORHEATER_1 == 11) || (THERMISTORHEATER_2 == 11) || (THERMISTORHEATER_3 == 11) || (THERMISTORBED == 11) 
568 568
 // QU-BD silicone bed QWG-104F-3950 thermistor
569 569
 
570 570
 const short temptable_11[][2] PROGMEM = {
@@ -621,7 +621,7 @@ const short temptable_11[][2] PROGMEM = {
621 621
 };
622 622
 #endif
623 623
 
624
-#if (THERMISTORHEATER_0 == 13) || (THERMISTORHEATER_1 == 13) || (THERMISTORHEATER_2 == 13) || (THERMISTORBED == 13)
624
+#if (THERMISTORHEATER_0 == 13) || (THERMISTORHEATER_1 == 13) || (THERMISTORHEATER_2 == 13) || (THERMISTORHEATER_3 == 13) || (THERMISTORBED == 13)
625 625
 // Hisens thermistor B25/50 =3950 +/-1%
626 626
 
627 627
 const short temptable_13[][2] PROGMEM = {
@@ -705,6 +705,10 @@ This does not match the normal thermistor behaviour so we need to set the follow
705 705
 # define HEATER_2_RAW_HI_TEMP 16383
706 706
 # define HEATER_2_RAW_LO_TEMP 0
707 707
 #endif
708
+#if (THERMISTORHEATER_3 == 20)
709
+# define HEATER_3_RAW_HI_TEMP 16383
710
+# define HEATER_3_RAW_LO_TEMP 0
711
+#endif
708 712
 #if (THERMISTORBED == 20)
709 713
 # define HEATER_BED_RAW_HI_TEMP 16383
710 714
 # define HEATER_BED_RAW_LO_TEMP 0
@@ -762,7 +766,7 @@ const short temptable_20[][2] PROGMEM = {
762 766
 };
763 767
 #endif
764 768
 
765
-#if (THERMISTORHEATER_0 == 51) || (THERMISTORHEATER_1 == 51) || (THERMISTORHEATER_2 == 51) || (THERMISTORBED == 51)
769
+#if (THERMISTORHEATER_0 == 51) || (THERMISTORHEATER_1 == 51) || (THERMISTORHEATER_2 == 51) || (THERMISTORHEATER_3 == 51) || (THERMISTORBED == 51)
766 770
 // 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
767 771
 // Verified by linagee.
768 772
 // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
@@ -824,7 +828,7 @@ const short temptable_51[][2] PROGMEM = {
824 828
 };
825 829
 #endif
826 830
 
827
-#if (THERMISTORHEATER_0 == 52) || (THERMISTORHEATER_1 == 52) || (THERMISTORHEATER_2 == 52) || (THERMISTORBED == 52) 
831
+#if (THERMISTORHEATER_0 == 52) || (THERMISTORHEATER_1 == 52) || (THERMISTORHEATER_2 == 52) || (THERMISTORHEATER_3 == 52) || (THERMISTORBED == 52) 
828 832
 // 200k ATC Semitec 204GT-2 (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
829 833
 // Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
830 834
 // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
@@ -865,7 +869,7 @@ const short temptable_52[][2] PROGMEM = {
865 869
 };
866 870
 #endif
867 871
 
868
-#if (THERMISTORHEATER_0 == 55) || (THERMISTORHEATER_1 == 55) || (THERMISTORHEATER_2 == 55) || (THERMISTORBED == 55) 
872
+#if (THERMISTORHEATER_0 == 55) || (THERMISTORHEATER_1 == 55) || (THERMISTORHEATER_2 == 55) || (THERMISTORHEATER_3 == 55) || (THERMISTORBED == 55) 
869 873
 // 100k ATC Semitec 104GT-2 (Used on ParCan) (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
870 874
 // Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
871 875
 // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
@@ -906,7 +910,7 @@ const short temptable_55[][2] PROGMEM = {
906 910
 };
907 911
 #endif
908 912
 
909
-#if (THERMISTORHEATER_0 == 60) || (THERMISTORHEATER_1 == 60) || (THERMISTORHEATER_2 == 60) || (THERMISTORBED == 60) // Maker's Tool Works Kapton Bed Thermister
913
+#if (THERMISTORHEATER_0 == 60) || (THERMISTORHEATER_1 == 60) || (THERMISTORHEATER_2 == 60) || (THERMISTORHEATER_3 == 60) || (THERMISTORBED == 60) // Maker's Tool Works Kapton Bed Thermister
910 914
 // ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=3950 
911 915
 // r0: 100000
912 916
 // t0: 25
@@ -1037,7 +1041,7 @@ const short temptable_12[][2] PROGMEM = {
1037 1041
 #define PtAdVal(T,R0,Rup) (short)(1024/(Rup/PtRt(T,R0)+1))
1038 1042
 #define PtLine(T,R0,Rup) { PtAdVal(T,R0,Rup)*OVERSAMPLENR, T },
1039 1043
 
1040
-#if (THERMISTORHEATER_0 == 110) || (THERMISTORHEATER_1 == 110) || (THERMISTORHEATER_2 == 110) || (THERMISTORBED == 110) // Pt100 with 1k0 pullup
1044
+#if (THERMISTORHEATER_0 == 110) || (THERMISTORHEATER_1 == 110) || (THERMISTORHEATER_2 == 110) || (THERMISTORHEATER_3 == 110) || (THERMISTORBED == 110) // Pt100 with 1k0 pullup
1041 1045
 const short temptable_110[][2] PROGMEM = {
1042 1046
 // only few values are needed as the curve is very flat  
1043 1047
   PtLine(0,100,1000)
@@ -1049,7 +1053,7 @@ const short temptable_110[][2] PROGMEM = {
1049 1053
   PtLine(300,100,1000)
1050 1054
 };
1051 1055
 #endif
1052
-#if (THERMISTORHEATER_0 == 147) || (THERMISTORHEATER_1 == 147) || (THERMISTORHEATER_2 == 147) || (THERMISTORBED == 147) // Pt100 with 4k7 pullup
1056
+#if (THERMISTORHEATER_0 == 147) || (THERMISTORHEATER_1 == 147) || (THERMISTORHEATER_2 == 147) || (THERMISTORHEATER_3 == 147) || (THERMISTORBED == 147) // Pt100 with 4k7 pullup
1053 1057
 const short temptable_147[][2] PROGMEM = {
1054 1058
 // only few values are needed as the curve is very flat  
1055 1059
   PtLine(0,100,4700)
@@ -1061,7 +1065,7 @@ const short temptable_147[][2] PROGMEM = {
1061 1065
   PtLine(300,100,4700)
1062 1066
 };
1063 1067
 #endif
1064
-#if (THERMISTORHEATER_0 == 1010) || (THERMISTORHEATER_1 == 1010) || (THERMISTORHEATER_2 == 1010) || (THERMISTORBED == 1010) // Pt1000 with 1k0 pullup
1068
+#if (THERMISTORHEATER_0 == 1010) || (THERMISTORHEATER_1 == 1010) || (THERMISTORHEATER_2 == 1010) || (THERMISTORHEATER_3 == 1010) || (THERMISTORBED == 1010) // Pt1000 with 1k0 pullup
1065 1069
 const short temptable_1010[][2] PROGMEM = {
1066 1070
   PtLine(0,1000,1000)
1067 1071
   PtLine(25,1000,1000)
@@ -1078,7 +1082,7 @@ const short temptable_1010[][2] PROGMEM = {
1078 1082
   PtLine(300,1000,1000)
1079 1083
 };
1080 1084
 #endif
1081
-#if (THERMISTORHEATER_0 == 1047) || (THERMISTORHEATER_1 == 1047) || (THERMISTORHEATER_2 == 1047) || (THERMISTORBED == 1047) // Pt1000 with 4k7 pullup
1085
+#if (THERMISTORHEATER_0 == 1047) || (THERMISTORHEATER_1 == 1047) || (THERMISTORHEATER_2 == 1047) || (THERMISTORHEATER_3 == 1047) || (THERMISTORBED == 1047) // Pt1000 with 4k7 pullup
1082 1086
 const short temptable_1047[][2] PROGMEM = {
1083 1087
 // only few values are needed as the curve is very flat  
1084 1088
   PtLine(0,1000,4700)
@@ -1163,6 +1167,29 @@ const short temptable_1047[][2] PROGMEM = {
1163 1167
 # endif
1164 1168
 #endif
1165 1169
 
1170
+#ifdef THERMISTORHEATER_3
1171
+# define HEATER_3_TEMPTABLE TT_NAME(THERMISTORHEATER_3)
1172
+# define HEATER_3_TEMPTABLE_LEN (sizeof(HEATER_3_TEMPTABLE)/sizeof(*HEATER_3_TEMPTABLE))
1173
+#else
1174
+# ifdef HEATER_3_USES_THERMISTOR
1175
+#  error No heater 3 thermistor table specified
1176
+# else  // HEATER_3_USES_THERMISTOR
1177
+#  define HEATER_3_TEMPTABLE NULL
1178
+#  define HEATER_3_TEMPTABLE_LEN 0
1179
+# endif // HEATER_3_USES_THERMISTOR
1180
+#endif
1181
+
1182
+//Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature
1183
+#ifndef HEATER_3_RAW_HI_TEMP
1184
+# ifdef HEATER_3_USES_THERMISTOR   //In case of a thermistor the highest temperature results in the lowest ADC value
1185
+#  define HEATER_3_RAW_HI_TEMP 0
1186
+#  define HEATER_3_RAW_LO_TEMP 16383
1187
+# else                          //In case of an thermocouple the highest temperature results in the highest ADC value
1188
+#  define HEATER_3_RAW_HI_TEMP 16383
1189
+#  define HEATER_3_RAW_LO_TEMP 0
1190
+# endif
1191
+#endif
1192
+
1166 1193
 #ifdef THERMISTORBED
1167 1194
 # define BEDTEMPTABLE TT_NAME(THERMISTORBED)
1168 1195
 # define BEDTEMPTABLE_LEN (sizeof(BEDTEMPTABLE)/sizeof(*BEDTEMPTABLE))

+ 85
- 41
Marlin/ultralcd.cpp Целия файл

@@ -431,6 +431,11 @@ static void lcd_tune_menu()
431 431
 #if TEMP_SENSOR_2 != 0
432 432
     MENU_ITEM_EDIT(int3, MSG_NOZZLE2, &target_temperature[2], 0, HEATER_2_MAXTEMP - 15);
433 433
 #endif
434
+#if TEMP_SENSOR_3 != 0
435
+    MENU_ITEM_EDIT(int3, MSG_NOZZLE3, &target_temperature[3], 0, HEATER_3_MAXTEMP - 15);
436
+#endif
437
+
438
+
434 439
 #if TEMP_SENSOR_BED != 0
435 440
     MENU_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
436 441
 #endif
@@ -443,6 +448,10 @@ static void lcd_tune_menu()
443 448
 #if TEMP_SENSOR_2 != 0
444 449
     MENU_ITEM_EDIT(int3, MSG_FLOW2, &extruder_multiply[2], 10, 999);
445 450
 #endif
451
+#if TEMP_SENSOR_3 != 0
452
+    MENU_ITEM_EDIT(int3, MSG_FLOW3, &extruder_multiply[3], 10, 999);
453
+#endif
454
+
446 455
 
447 456
 #ifdef BABYSTEPPING
448 457
     #ifdef BABYSTEP_XY
@@ -515,23 +524,46 @@ void lcd_preheat_abs2()
515 524
 }
516 525
 #endif //3 extruder preheat
517 526
 
518
-#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 //more than one extruder present
519
-void lcd_preheat_pla012()
527
+#if TEMP_SENSOR_3 != 0 //4 extruder preheat
528
+void lcd_preheat_pla3()
529
+{
530
+    setTargetHotend3(plaPreheatHotendTemp);
531
+    setTargetBed(plaPreheatHPBTemp);
532
+    fanSpeed = plaPreheatFanSpeed;
533
+    lcd_return_to_status();
534
+    setWatch(); // heater sanity check timer
535
+}
536
+
537
+void lcd_preheat_abs3()
538
+{
539
+    setTargetHotend3(absPreheatHotendTemp);
540
+    setTargetBed(absPreheatHPBTemp);
541
+    fanSpeed = absPreheatFanSpeed;
542
+    lcd_return_to_status();
543
+    setWatch(); // heater sanity check timer
544
+}
545
+
546
+#endif //4 extruder preheat
547
+
548
+#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 //more than one extruder present
549
+void lcd_preheat_pla0123()
520 550
 {
521 551
     setTargetHotend0(plaPreheatHotendTemp);
522 552
     setTargetHotend1(plaPreheatHotendTemp);
523 553
     setTargetHotend2(plaPreheatHotendTemp);
554
+    setTargetHotend3(plaPreheatHotendTemp);
524 555
     setTargetBed(plaPreheatHPBTemp);
525 556
     fanSpeed = plaPreheatFanSpeed;
526 557
     lcd_return_to_status();
527 558
     setWatch(); // heater sanity check timer
528 559
 }
529 560
 
530
-void lcd_preheat_abs012()
561
+void lcd_preheat_abs0123()
531 562
 {
532 563
     setTargetHotend0(absPreheatHotendTemp);
533 564
     setTargetHotend1(absPreheatHotendTemp);
534 565
     setTargetHotend2(absPreheatHotendTemp);
566
+    setTargetHotend3(absPreheatHotendTemp);
535 567
     setTargetBed(absPreheatHPBTemp);
536 568
     fanSpeed = absPreheatFanSpeed;
537 569
     lcd_return_to_status();
@@ -557,42 +589,49 @@ void lcd_preheat_abs_bedonly()
557 589
 
558 590
 static void lcd_preheat_pla_menu()
559 591
 {
560
-    START_MENU();
561
-    MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu);
562
-    MENU_ITEM(function, MSG_PREHEAT_PLA0, lcd_preheat_pla0);
592
+  START_MENU();
593
+  MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu);
594
+  MENU_ITEM(function, MSG_PREHEAT_PLA0, lcd_preheat_pla0);
563 595
 #if TEMP_SENSOR_1 != 0 //2 extruder preheat
564
-    MENU_ITEM(function, MSG_PREHEAT_PLA1, lcd_preheat_pla1);
596
+  MENU_ITEM(function, MSG_PREHEAT_PLA1, lcd_preheat_pla1);
565 597
 #endif //2 extruder preheat
566 598
 #if TEMP_SENSOR_2 != 0 //3 extruder preheat
567
-    MENU_ITEM(function, MSG_PREHEAT_PLA2, lcd_preheat_pla2);
599
+  MENU_ITEM(function, MSG_PREHEAT_PLA2, lcd_preheat_pla2);
568 600
 #endif //3 extruder preheat
569
-#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 //all extruder preheat
570
-    MENU_ITEM(function, MSG_PREHEAT_PLA012, lcd_preheat_pla012);
571
-#endif //2 extruder preheat
601
+#if TEMP_SENSOR_3 != 0 //4 extruder preheat
602
+  MENU_ITEM(function, MSG_PREHEAT_PLA3, lcd_preheat_pla3);
603
+#endif //4 extruder preheat
604
+#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 //all extruder preheat
605
+  MENU_ITEM(function, MSG_PREHEAT_PLA0123, lcd_preheat_pla0123);
606
+#endif //all extruder preheat
572 607
 #if TEMP_SENSOR_BED != 0
573
-    MENU_ITEM(function, MSG_PREHEAT_PLA_BEDONLY, lcd_preheat_pla_bedonly);
608
+  MENU_ITEM(function, MSG_PREHEAT_PLA_BEDONLY, lcd_preheat_pla_bedonly);
574 609
 #endif
575
-    END_MENU();
610
+  END_MENU();
576 611
 }
577 612
 
578 613
 static void lcd_preheat_abs_menu()
579 614
 {
580
-    START_MENU();
581
-    MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu);
582
-    MENU_ITEM(function, MSG_PREHEAT_ABS0, lcd_preheat_abs0);
615
+  START_MENU();
616
+  MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu);
617
+  MENU_ITEM(function, MSG_PREHEAT_ABS0, lcd_preheat_abs0);
583 618
 #if TEMP_SENSOR_1 != 0 //2 extruder preheat
584
-    MENU_ITEM(function, MSG_PREHEAT_ABS1, lcd_preheat_abs1);
619
+	MENU_ITEM(function, MSG_PREHEAT_ABS1, lcd_preheat_abs1);
585 620
 #endif //2 extruder preheat
586 621
 #if TEMP_SENSOR_2 != 0 //3 extruder preheat
587
-    MENU_ITEM(function, MSG_PREHEAT_ABS2, lcd_preheat_abs2);
622
+  MENU_ITEM(function, MSG_PREHEAT_ABS2, lcd_preheat_abs2);
588 623
 #endif //3 extruder preheat
589
-#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 //all extruder preheat
590
-    MENU_ITEM(function, MSG_PREHEAT_ABS012, lcd_preheat_abs012);
591
-#endif //2 extruder preheat
624
+#if TEMP_SENSOR_3 != 0 //4 extruder preheat
625
+  MENU_ITEM(function, MSG_PREHEAT_ABS3, lcd_preheat_abs3);
626
+#endif //4 extruder preheat
627
+#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 //all extruder preheat
628
+  MENU_ITEM(function, MSG_PREHEAT_ABS0123, lcd_preheat_abs0123);
629
+#endif //all extruder preheat
630
+
592 631
 #if TEMP_SENSOR_BED != 0
593
-    MENU_ITEM(function, MSG_PREHEAT_ABS_BEDONLY, lcd_preheat_abs_bedonly);
632
+ MENU_ITEM(function, MSG_PREHEAT_ABS_BEDONLY, lcd_preheat_abs_bedonly);
594 633
 #endif
595
-    END_MENU();
634
+  END_MENU();
596 635
 }
597 636
 
598 637
 void lcd_cooldown()
@@ -600,6 +639,7 @@ void lcd_cooldown()
600 639
     setTargetHotend0(0);
601 640
     setTargetHotend1(0);
602 641
     setTargetHotend2(0);
642
+    setTargetHotend3(0);
603 643
     setTargetBed(0);
604 644
     fanSpeed = 0;
605 645
     lcd_return_to_status();
@@ -747,7 +787,7 @@ static void lcd_control_menu()
747 787
     MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
748 788
     MENU_ITEM(submenu, MSG_TEMPERATURE, lcd_control_temperature_menu);
749 789
     MENU_ITEM(submenu, MSG_MOTION, lcd_control_motion_menu);
750
-	MENU_ITEM(submenu, MSG_VOLUMETRIC, lcd_control_volumetric_menu);
790
+    MENU_ITEM(submenu, MSG_VOLUMETRIC, lcd_control_volumetric_menu);
751 791
 
752 792
 #ifdef DOGLCD
753 793
 //    MENU_ITEM_EDIT(int3, MSG_CONTRAST, &lcd_contrast, 0, 63);
@@ -766,26 +806,29 @@ static void lcd_control_menu()
766 806
 
767 807
 static void lcd_control_temperature_menu()
768 808
 {
769
-    START_MENU();
770
-    MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
809
+  START_MENU();
810
+  MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
771 811
 #if TEMP_SENSOR_0 != 0
772
-    MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15);
812
+  MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15);
773 813
 #endif
774 814
 #if TEMP_SENSOR_1 != 0
775
-    MENU_ITEM_EDIT(int3, MSG_NOZZLE1, &target_temperature[1], 0, HEATER_1_MAXTEMP - 15);
815
+  MENU_ITEM_EDIT(int3, MSG_NOZZLE1, &target_temperature[1], 0, HEATER_1_MAXTEMP - 15);
776 816
 #endif
777 817
 #if TEMP_SENSOR_2 != 0
778
-    MENU_ITEM_EDIT(int3, MSG_NOZZLE2, &target_temperature[2], 0, HEATER_2_MAXTEMP - 15);
818
+  MENU_ITEM_EDIT(int3, MSG_NOZZLE2, &target_temperature[2], 0, HEATER_2_MAXTEMP - 15);
819
+#endif
820
+#if TEMP_SENSOR_3 != 0
821
+  MENU_ITEM_EDIT(int3, MSG_NOZZLE3, &target_temperature[3], 0, HEATER_3_MAXTEMP - 15);
779 822
 #endif
780 823
 #if TEMP_SENSOR_BED != 0
781
-    MENU_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
824
+  MENU_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
782 825
 #endif
783
-    MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
826
+  MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
784 827
 #if defined AUTOTEMP && (TEMP_SENSOR_0 != 0)
785
-    MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &autotemp_enabled);
786
-    MENU_ITEM_EDIT(float3, MSG_MIN, &autotemp_min, 0, HEATER_0_MAXTEMP - 15);
787
-    MENU_ITEM_EDIT(float3, MSG_MAX, &autotemp_max, 0, HEATER_0_MAXTEMP - 15);
788
-    MENU_ITEM_EDIT(float32, MSG_FACTOR, &autotemp_factor, 0.0, 1.0);
828
+  MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &autotemp_enabled);
829
+  MENU_ITEM_EDIT(float3, MSG_MIN, &autotemp_min, 0, HEATER_0_MAXTEMP - 15);
830
+  MENU_ITEM_EDIT(float3, MSG_MAX, &autotemp_max, 0, HEATER_0_MAXTEMP - 15);
831
+  MENU_ITEM_EDIT(float32, MSG_FACTOR, &autotemp_factor, 0.0, 1.0);
789 832
 #endif
790 833
 #ifdef PIDTEMP
791 834
 	// set up temp variables - undo the default scaling
@@ -916,13 +959,15 @@ static void lcd_control_volumetric_menu()
916 959
 		MENU_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_SIZE_EXTRUDER_1, &filament_size[1], DEFAULT_NOMINAL_FILAMENT_DIA - .5, DEFAULT_NOMINAL_FILAMENT_DIA + .5, calculate_volumetric_multipliers);
917 960
 #if EXTRUDERS > 2
918 961
 		MENU_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_SIZE_EXTRUDER_2, &filament_size[2], DEFAULT_NOMINAL_FILAMENT_DIA - .5, DEFAULT_NOMINAL_FILAMENT_DIA + .5, calculate_volumetric_multipliers);
919
-#endif
920
-#endif
962
+#if EXTRUDERS > 3
963
+		MENU_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_SIZE_EXTRUDER_3, &filament_size[3], DEFAULT_NOMINAL_FILAMENT_DIA - .5, DEFAULT_NOMINAL_FILAMENT_DIA + .5, calculate_volumetric_multipliers);
964
+#endif //EXTRUDERS > 3
965
+#endif //EXTRUDERS > 2
966
+#endif //EXTRUDERS > 1
921 967
 	}
922 968
 
923 969
 	END_MENU();
924 970
 }
925
-
926 971
 #ifdef DOGLCD
927 972
 static void lcd_set_contrast()
928 973
 {
@@ -950,19 +995,18 @@ static void lcd_control_retract_menu()
950 995
     MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
951 996
     MENU_ITEM_EDIT(bool, MSG_AUTORETRACT, &autoretract_enabled);
952 997
     MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT, &retract_length, 0, 100);
953
-	#if EXTRUDERS > 1
998
+    #if EXTRUDERS > 1
954 999
       MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_SWAP, &retract_length_swap, 0, 100);
955 1000
     #endif
956 1001
     MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &retract_feedrate, 1, 999);
957 1002
     MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_ZLIFT, &retract_zlift, 0, 999);
958 1003
     MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER, &retract_recover_length, 0, 100);
959
-	#if EXTRUDERS > 1
1004
+    #if EXTRUDERS > 1
960 1005
       MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &retract_recover_length_swap, 0, 100);
961 1006
     #endif
962 1007
     MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate, 1, 999);
963 1008
     END_MENU();
964 1009
 }
965
-
966 1010
 #endif //FWRETRACT
967 1011
 
968 1012
 #if SDCARDDETECT == -1

Loading…
Отказ
Запис