Browse Source

Add 4th extruder

MagoKimbra 9 years ago
parent
commit
986e723eeb

+ 17
- 13
Marlin/Configuration.h View File

@@ -44,7 +44,7 @@
44 44
 // The following define selects which electronics board you have.
45 45
 // Please choose the name from boards.h that matches your setup
46 46
 #ifndef MOTHERBOARD
47
-  #define MOTHERBOARD BOARD_ULTIMAKER
47
+  #define MOTHERBOARD BOARD_AZTEEG_X3_PRO
48 48
 #endif
49 49
 
50 50
 // Define this to set a custom name for your generic Mendel,
@@ -104,9 +104,10 @@
104 104
 // 147 is Pt100 with 4k7 pullup
105 105
 // 110 is Pt100 with 1k pullup (non standard)
106 106
 
107
-#define TEMP_SENSOR_0 -1
108
-#define TEMP_SENSOR_1 -1
107
+#define TEMP_SENSOR_0 1
108
+#define TEMP_SENSOR_1 0
109 109
 #define TEMP_SENSOR_2 0
110
+#define TEMP_SENSOR_3 0
110 111
 #define TEMP_SENSOR_BED 0
111 112
 
112 113
 // This makes temp sensor 1 a redundant sensor for sensor 0. If the temperatures difference between these sensors is to high the print will be aborted.
@@ -121,20 +122,22 @@
121 122
 // The minimal temperature defines the temperature below which the heater will not be enabled It is used
122 123
 // to check that the wiring to the thermistor is not broken.
123 124
 // Otherwise this would lead to the heater being powered on all the time.
124
-#define HEATER_0_MINTEMP 5
125
-#define HEATER_1_MINTEMP 5
126
-#define HEATER_2_MINTEMP 5
127
-#define BED_MINTEMP 5
125
+#define HEATER_0_MINTEMP 5 // degC
126
+#define HEATER_1_MINTEMP 5 // degC
127
+#define HEATER_2_MINTEMP 5 // degC
128
+#define HEATER_3_MINTEMP 5 // degC
129
+#define BED_MINTEMP      5 // degC
128 130
 
129 131
 // When temperature exceeds max temp, your heater will be switched off.
130 132
 // This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
131 133
 // You should use MINTEMP for thermistor short/failure protection.
132
-#define HEATER_0_MAXTEMP 275
133
-#define HEATER_1_MAXTEMP 275
134
-#define HEATER_2_MAXTEMP 275
135
-#define BED_MAXTEMP 150
134
+#define HEATER_0_MAXTEMP 275 // degC
135
+#define HEATER_1_MAXTEMP 275 // degC
136
+#define HEATER_2_MAXTEMP 275 // degC
137
+#define HEATER_3_MAXTEMP 275 // degC
138
+#define BED_MAXTEMP      150 // degC
136 139
 
137
-// If your bed has low resistance e.g. .6 ohm and throws the fuse you can duty cycle it to reduce the
140
+// If your bed has low resistance e.g. 0.6 ohm and throws the fuse you can duty cycle it to reduce the
138 141
 // average current. The value should be an integer and the heat bed will be turned on for 1 interval of
139 142
 // HEATER_BED_DUTY_CYCLE_DIVIDER intervals.
140 143
 //#define HEATER_BED_DUTY_CYCLE_DIVIDER 4
@@ -221,7 +224,7 @@
221 224
 //if PREVENT_DANGEROUS_EXTRUDE is on, you can still disable (uncomment) very long bits of extrusion separately.
222 225
 #define PREVENT_LENGTHY_EXTRUDE
223 226
 
224
-#define EXTRUDE_MINTEMP 170
227
+#define EXTRUDE_MINTEMP 170 // degC
225 228
 #define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances.
226 229
 
227 230
 /*================== Thermal Runaway Protection ==============================
@@ -325,6 +328,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
325 328
 #define INVERT_E0_DIR false   // for direct drive extruder v9 set to true, for geared extruder set to false
326 329
 #define INVERT_E1_DIR false    // for direct drive extruder v9 set to true, for geared extruder set to false
327 330
 #define INVERT_E2_DIR false   // for direct drive extruder v9 set to true, for geared extruder set to false
331
+#define INVERT_E3_DIR false   // for direct drive extruder v9 set to true, for geared extruder set to false
328 332
 
329 333
 // ENDSTOP SETTINGS:
330 334
 // Sets direction of endstops when homing; 1=MAX, -1=MIN

+ 26
- 12
Marlin/ConfigurationStore.cpp View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -2933,6 +2933,12 @@ Fan_2 2
2933 2933
 #endif // CHEAPTRONIC
2934 2934
 
2935 2935
 
2936
+#ifndef HEATER_3_PIN
2937
+  #define HEATER_3_PIN -1
2938
+#endif
2939
+#ifndef TEMP_3_PIN
2940
+  #define TEMP_3_PIN -1
2941
+#endif
2936 2942
 
2937 2943
 #ifndef KNOWN_BOARD
2938 2944
 #error Unknown MOTHERBOARD value in configuration.h
@@ -2950,6 +2956,11 @@ Fan_2 2
2950 2956
 #else
2951 2957
   #define _E2_PINS
2952 2958
 #endif
2959
+#if EXTRUDERS > 3
2960
+  #define _E3_PINS E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, HEATER_3_PIN,
2961
+#else
2962
+  #define _E3_PINS
2963
+#endif
2953 2964
 
2954 2965
 #ifdef X_STOP_PIN
2955 2966
   #if X_HOME_DIR < 0
@@ -2995,7 +3006,6 @@ Fan_2 2
2995 3006
 
2996 3007
 #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, \
2997 3008
                         HEATER_BED_PIN, FAN_PIN,                  \
2998
-                        _E0_PINS _E1_PINS _E2_PINS             \
2999
-                        analogInputToDigitalPin(TEMP_0_PIN), analogInputToDigitalPin(TEMP_1_PIN), analogInputToDigitalPin(TEMP_2_PIN), analogInputToDigitalPin(TEMP_BED_PIN) }
3000
-
3009
+                        _E0_PINS _E1_PINS _E2_PINS _E3_PINS           \
3010
+                        analogInputToDigitalPin(TEMP_0_PIN), analogInputToDigitalPin(TEMP_1_PIN), analogInputToDigitalPin(TEMP_2_PIN), analogInputToDigitalPin(TEMP_3_PIN), analogInputToDigitalPin(TEMP_BED_PIN) }
3001 3011
 #endif //__PINS_H

+ 18
- 4
Marlin/planner.cpp View File

@@ -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 View File

@@ -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 View File

@@ -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); }}}

+ 219
- 47
Marlin/temperature.cpp View File

@@ -115,14 +115,16 @@ static volatile bool temp_meas_ready = false;
115 115
   static unsigned long extruder_autofan_last_check;
116 116
 #endif  
117 117
 
118
-#if EXTRUDERS > 3
118
+#if EXTRUDERS > 4
119 119
   # error Unsupported number of extruders
120
+#elif EXTRUDERS > 3
121
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3, v4 }
120 122
 #elif EXTRUDERS > 2
121
-  # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2, v3 }
123
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3 }
122 124
 #elif EXTRUDERS > 1
123
-  # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2 }
125
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2 }
124 126
 #else
125
-  # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
127
+  # define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1 }
126 128
 #endif
127 129
 
128 130
 #ifdef PIDTEMP
@@ -144,10 +146,10 @@ static volatile bool temp_meas_ready = false;
144 146
 #endif //PIDTEMP
145 147
 
146 148
 // 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 );
149
+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);
150
+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);
151
+static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0, 0 );
152
+static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383, 16383 );
151 153
 //static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */
152 154
 #ifdef BED_MAXTEMP
153 155
 static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
@@ -157,8 +159,8 @@ static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
157 159
   static void *heater_ttbl_map[2] = {(void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE };
158 160
   static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN };
159 161
 #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 );
162
+  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 );
163
+  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 164
 #endif
163 165
 
164 166
 static float analog2temp(int raw, uint8_t e);
@@ -166,8 +168,8 @@ static float analog2tempBed(int raw);
166 168
 static void updateTemperaturesFromRawValues();
167 169
 
168 170
 #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);
171
+int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0);
172
+unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0);
171 173
 #endif //WATCH_TEMP_PERIOD
172 174
 
173 175
 #ifndef SOFT_PWM_SCALE
@@ -205,7 +207,8 @@ void PID_autotune(float temp, int extruder, int ncycles)
205 207
 
206 208
 #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
207 209
     (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)
210
+    (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) || \
211
+    (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1)
209 212
   unsigned long extruder_autofan_last_check = millis();
210 213
 #endif
211 214
 
@@ -248,7 +251,8 @@ void PID_autotune(float temp, int extruder, int ncycles)
248 251
 
249 252
       #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
250 253
           (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)
254
+          (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) || \
255
+          (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1)
252 256
       if(millis() - extruder_autofan_last_check > 2500) {
253 257
         checkExtruderAutoFans();
254 258
         extruder_autofan_last_check = millis();
@@ -425,6 +429,19 @@ void checkExtruderAutoFans()
425 429
         fanState |= 4;
426 430
     }
427 431
   #endif
432
+  #if defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1
433
+    if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) 
434
+    {
435
+      if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) 
436
+        fanState |= 1;
437
+      else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN) 
438
+        fanState |= 2;
439
+      else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN) 
440
+        fanState |= 4;
441
+      else
442
+        fanState |= 8;
443
+    }
444
+  #endif
428 445
   
429 446
   // update extruder auto fan states
430 447
   #if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
@@ -438,7 +455,13 @@ void checkExtruderAutoFans()
438 455
     if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN 
439 456
         && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
440 457
       setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
441
-  #endif 
458
+  #endif
459
+  #if defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1
460
+    if (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN 
461
+        && EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
462
+        && EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
463
+      setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0);
464
+  #endif
442 465
 }
443 466
 
444 467
 #endif // any extruder auto fan pins set
@@ -606,13 +629,13 @@ void manage_heater()
606 629
 		  temp_dState_bed = pid_input;
607 630
 
608 631
 		  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
-                  }
632
+      if (pid_output > MAX_BED_POWER) {
633
+        if (pid_error_bed > 0 )  temp_iState_bed -= pid_error_bed; // conditional un-integration
634
+        pid_output=MAX_BED_POWER;
635
+      } else if (pid_output < 0){
636
+        if (pid_error_bed < 0 )  temp_iState_bed -= pid_error_bed; // conditional un-integration
637
+        pid_output=0;
638
+      }
616 639
 
617 640
     #else 
618 641
       pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
@@ -847,13 +870,16 @@ void tp_init()
847 870
 
848 871
   #if defined(HEATER_0_PIN) && (HEATER_0_PIN > -1) 
849 872
     SET_OUTPUT(HEATER_0_PIN);
850
-  #endif  
873
+  #endif
851 874
   #if defined(HEATER_1_PIN) && (HEATER_1_PIN > -1) 
852 875
     SET_OUTPUT(HEATER_1_PIN);
853 876
   #endif
854 877
   #if defined(HEATER_2_PIN) && (HEATER_2_PIN > -1) 
855 878
     SET_OUTPUT(HEATER_2_PIN);
856
-  #endif  
879
+  #endif
880
+  #if defined(HEATER_3_PIN) && (HEATER_3_PIN > -1) 
881
+    SET_OUTPUT(HEATER_3_PIN);
882
+  #endif
857 883
   #if defined(HEATER_BED_PIN) && (HEATER_BED_PIN > -1) 
858 884
     SET_OUTPUT(HEATER_BED_PIN);
859 885
   #endif  
@@ -903,16 +929,23 @@ void tp_init()
903 929
   #endif
904 930
   #if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
905 931
     #if TEMP_1_PIN < 8
906
-       DIDR0 |= 1<<TEMP_1_PIN; 
932
+      DIDR0 |= 1<<TEMP_1_PIN; 
907 933
     #else
908
-       DIDR2 |= 1<<(TEMP_1_PIN - 8); 
934
+    	DIDR2 |= 1<<(TEMP_1_PIN - 8); 
909 935
     #endif
910 936
   #endif
911 937
   #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
912 938
     #if TEMP_2_PIN < 8
913
-       DIDR0 |= 1 << TEMP_2_PIN; 
939
+      DIDR0 |= 1 << TEMP_2_PIN; 
940
+    #else
941
+      DIDR2 |= 1<<(TEMP_2_PIN - 8); 
942
+    #endif
943
+  #endif
944
+  #if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
945
+    #if TEMP_3_PIN < 8
946
+      DIDR0 |= 1 << TEMP_3_PIN; 
914 947
     #else
915
-       DIDR2 |= 1<<(TEMP_2_PIN - 8); 
948
+      DIDR2 |= 1<<(TEMP_3_PIN - 8); 
916 949
     #endif
917 950
   #endif
918 951
   #if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
@@ -925,13 +958,13 @@ void tp_init()
925 958
   
926 959
   //Added for Filament Sensor 
927 960
   #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
961
+    #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1) 
962
+      #if FILWIDTH_PIN < 8 
963
+        DIDR0 |= 1<<FILWIDTH_PIN;  
964
+      #else
965
+        DIDR2 |= 1<<(FILWIDTH_PIN - 8);  
966
+      #endif 
967
+    #endif
935 968
   #endif
936 969
   
937 970
   // Use timer0 for temperature measurement
@@ -1005,6 +1038,28 @@ void tp_init()
1005 1038
   }
1006 1039
 #endif //MAXTEMP 2
1007 1040
 
1041
+#if (EXTRUDERS > 3) && defined(HEATER_3_MINTEMP)
1042
+  minttemp[3] = HEATER_3_MINTEMP;
1043
+  while(analog2temp(minttemp_raw[3], 3) < HEATER_3_MINTEMP) {
1044
+#if HEATER_3_RAW_LO_TEMP < HEATER_3_RAW_HI_TEMP
1045
+    minttemp_raw[3] += OVERSAMPLENR;
1046
+#else
1047
+    minttemp_raw[3] -= OVERSAMPLENR;
1048
+#endif
1049
+  }
1050
+#endif //MINTEMP 3
1051
+#if (EXTRUDERS > 3) && defined(HEATER_3_MAXTEMP)
1052
+  maxttemp[3] = HEATER_3_MAXTEMP;
1053
+  while(analog2temp(maxttemp_raw[3], 3) > HEATER_3_MAXTEMP) {
1054
+#if HEATER_3_RAW_LO_TEMP < HEATER_3_RAW_HI_TEMP
1055
+    maxttemp_raw[3] -= OVERSAMPLENR;
1056
+#else
1057
+    maxttemp_raw[3] += OVERSAMPLENR;
1058
+#endif
1059
+  }
1060
+#endif // MAXTEMP 3
1061
+
1062
+
1008 1063
 #ifdef BED_MINTEMP
1009 1064
   /* No bed MINTEMP error implemented?!? */ /*
1010 1065
   while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
@@ -1093,6 +1148,7 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
1093 1148
           disable_e0();
1094 1149
           disable_e1();
1095 1150
           disable_e2();
1151
+          disable_e3();
1096 1152
           manage_heater();
1097 1153
           lcd_update();
1098 1154
         }
@@ -1129,8 +1185,17 @@ void disable_heater()
1129 1185
     #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1  
1130 1186
       WRITE(HEATER_2_PIN,LOW);
1131 1187
     #endif
1188
+  #endif
1189
+
1190
+  #if defined(TEMP_3_PIN) && TEMP_3_PIN > -1 && EXTRUDERS > 3
1191
+    target_temperature[3]=0;
1192
+    soft_pwm[3]=0;
1193
+    #if defined(HEATER_3_PIN) && HEATER_3_PIN > -1  
1194
+      WRITE(HEATER_3_PIN,LOW);
1195
+    #endif
1132 1196
   #endif 
1133 1197
 
1198
+
1134 1199
   #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
1135 1200
     target_temperature_bed=0;
1136 1201
     soft_pwm_bed=0;
@@ -1246,8 +1311,9 @@ ISR(TIMER0_COMPB_vect)
1246 1311
   static unsigned long raw_temp_0_value = 0;
1247 1312
   static unsigned long raw_temp_1_value = 0;
1248 1313
   static unsigned long raw_temp_2_value = 0;
1314
+  static unsigned long raw_temp_3_value = 0;
1249 1315
   static unsigned long raw_temp_bed_value = 0;
1250
-  static unsigned char temp_state = 10;
1316
+  static unsigned char temp_state = 12;
1251 1317
   static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
1252 1318
   static unsigned char soft_pwm_0;
1253 1319
 #ifdef SLOW_PWM_HEATERS
@@ -1255,6 +1321,7 @@ ISR(TIMER0_COMPB_vect)
1255 1321
   static unsigned char state_heater_0 = 0;
1256 1322
   static unsigned char state_timer_heater_0 = 0;
1257 1323
 #endif 
1324
+
1258 1325
 #if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
1259 1326
   static unsigned char soft_pwm_1;
1260 1327
 #ifdef SLOW_PWM_HEATERS
@@ -1269,6 +1336,14 @@ ISR(TIMER0_COMPB_vect)
1269 1336
   static unsigned char state_timer_heater_2 = 0;
1270 1337
 #endif 
1271 1338
 #endif
1339
+#if EXTRUDERS > 3
1340
+  static unsigned char soft_pwm_3;
1341
+#ifdef SLOW_PWM_HEATERS
1342
+  static unsigned char state_heater_3 = 0;
1343
+  static unsigned char state_timer_heater_3 = 0;
1344
+#endif
1345
+#endif
1346
+
1272 1347
 #if HEATER_BED_PIN > -1
1273 1348
   static unsigned char soft_pwm_b;
1274 1349
 #ifdef SLOW_PWM_HEATERS
@@ -1293,7 +1368,7 @@ ISR(TIMER0_COMPB_vect)
1293 1368
       WRITE(HEATER_1_PIN,1);
1294 1369
 #endif
1295 1370
     } else WRITE(HEATER_0_PIN,0);
1296
-    
1371
+
1297 1372
 #if EXTRUDERS > 1
1298 1373
     soft_pwm_1 = soft_pwm[1];
1299 1374
     if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0);
@@ -1302,6 +1377,12 @@ ISR(TIMER0_COMPB_vect)
1302 1377
     soft_pwm_2 = soft_pwm[2];
1303 1378
     if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0);
1304 1379
 #endif
1380
+#if EXTRUDERS > 3
1381
+    soft_pwm_3 = soft_pwm[3];
1382
+    if(soft_pwm_3 > 0) WRITE(HEATER_3_PIN,1); else WRITE(HEATER_3_PIN,0);
1383
+#endif
1384
+
1385
+
1305 1386
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1306 1387
     soft_pwm_b = soft_pwm_bed;
1307 1388
     if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
@@ -1317,12 +1398,17 @@ ISR(TIMER0_COMPB_vect)
1317 1398
     WRITE(HEATER_1_PIN,0);
1318 1399
 #endif
1319 1400
   }
1401
+
1320 1402
 #if EXTRUDERS > 1
1321 1403
   if(soft_pwm_1 < pwm_count) WRITE(HEATER_1_PIN,0);
1322 1404
 #endif
1323 1405
 #if EXTRUDERS > 2
1324 1406
   if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
1325 1407
 #endif
1408
+#if EXTRUDERS > 3
1409
+  if(soft_pwm_3 < pwm_count) WRITE(HEATER_3_PIN,0);
1410
+#endif
1411
+
1326 1412
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1327 1413
   if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0);
1328 1414
 #endif
@@ -1424,7 +1510,33 @@ ISR(TIMER0_COMPB_vect)
1424 1510
       }
1425 1511
     }
1426 1512
 #endif
1427
-    
1513
+
1514
+#if EXTRUDERS > 3
1515
+    // EXTRUDER 3
1516
+    soft_pwm_3 = soft_pwm[3];
1517
+    if (soft_pwm_3 > 0) {
1518
+      // turn ON heather only if the minimum time is up 
1519
+      if (state_timer_heater_3 == 0) { 
1520
+	// if change state set timer 
1521
+	if (state_heater_3 == 0) {
1522
+	  state_timer_heater_3 = MIN_STATE_TIME;
1523
+	}
1524
+	state_heater_3 = 1;
1525
+	WRITE(HEATER_3_PIN, 1);
1526
+      }
1527
+    } else {
1528
+      // turn OFF heather only if the minimum time is up 
1529
+      if (state_timer_heater_3 == 0) {
1530
+	// if change state set timer 
1531
+	if (state_heater_3 == 1) {
1532
+	  state_timer_heater_3 = MIN_STATE_TIME;
1533
+	}
1534
+	state_heater_3 = 0;
1535
+	WRITE(HEATER_3_PIN, 0);
1536
+      }
1537
+    }
1538
+#endif
1539
+
1428 1540
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1429 1541
     // BED
1430 1542
     soft_pwm_b = soft_pwm_bed;
@@ -1497,6 +1609,21 @@ ISR(TIMER0_COMPB_vect)
1497 1609
     }
1498 1610
   }
1499 1611
 #endif
1612
+
1613
+#if EXTRUDERS > 3
1614
+  // EXTRUDER 3
1615
+  if (soft_pwm_3 < slow_pwm_count) {
1616
+    // turn OFF heather only if the minimum time is up 
1617
+    if (state_timer_heater_3 == 0) { 
1618
+      // if change state set timer 
1619
+      if (state_heater_3 == 1) {
1620
+	state_timer_heater_3 = MIN_STATE_TIME;
1621
+      }
1622
+      state_heater_3 = 0;
1623
+      WRITE(HEATER_3_PIN, 0);
1624
+    }
1625
+  }
1626
+#endif
1500 1627
   
1501 1628
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1502 1629
   // BED
@@ -1545,6 +1672,12 @@ ISR(TIMER0_COMPB_vect)
1545 1672
     if (state_timer_heater_2 > 0) 
1546 1673
       state_timer_heater_2--;
1547 1674
 #endif
1675
+
1676
+#if EXTRUDERS > 3
1677
+    // Extruder 3
1678
+    if (state_timer_heater_3 > 0) 
1679
+      state_timer_heater_3--;
1680
+#endif
1548 1681
     
1549 1682
 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
1550 1683
     // Bed   
@@ -1630,10 +1763,28 @@ ISR(TIMER0_COMPB_vect)
1630 1763
       #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
1631 1764
         raw_temp_2_value += ADC;
1632 1765
       #endif
1633
-      temp_state = 8;//change so that Filament Width is also measured
1634
-      
1766
+      temp_state = 8;
1635 1767
       break;
1636
-    case 8: //Prepare FILWIDTH 
1768
+    case 8: // Prepare TEMP_3
1769
+      #if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
1770
+        #if TEMP_3_PIN > 7
1771
+          ADCSRB = 1<<MUX5;
1772
+        #else
1773
+          ADCSRB = 0;
1774
+        #endif
1775
+        ADMUX = ((1 << REFS0) | (TEMP_3_PIN & 0x07));
1776
+        ADCSRA |= 1<<ADSC; // Start conversion
1777
+      #endif
1778
+      lcd_buttons_update();
1779
+      temp_state = 9;
1780
+      break;
1781
+    case 9: // Measure TEMP_3
1782
+      #if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
1783
+        raw_temp_3_value += ADC;
1784
+      #endif
1785
+      temp_state = 10; //change so that Filament Width is also measured
1786
+      break;
1787
+    case 10: //Prepare FILWIDTH 
1637 1788
      #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1) 
1638 1789
       #if FILWIDTH_PIN>7 
1639 1790
          ADCSRB = 1<<MUX5;
@@ -1644,9 +1795,9 @@ ISR(TIMER0_COMPB_vect)
1644 1795
       ADCSRA |= 1<<ADSC; // Start conversion 
1645 1796
      #endif 
1646 1797
      lcd_buttons_update();       
1647
-     temp_state = 9; 
1798
+     temp_state = 11; 
1648 1799
      break; 
1649
-    case 9:   //Measure FILWIDTH 
1800
+    case 11:   //Measure FILWIDTH 
1650 1801
      #if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1) 
1651 1802
      //raw_filwidth_value += ADC;  //remove to use an IIR filter approach 
1652 1803
       if(ADC>102)  //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
@@ -1662,7 +1813,7 @@ ISR(TIMER0_COMPB_vect)
1662 1813
      break;      
1663 1814
       
1664 1815
       
1665
-    case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
1816
+    case 12: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
1666 1817
       temp_state = 0;
1667 1818
       break;
1668 1819
 //    default:
@@ -1687,6 +1838,9 @@ ISR(TIMER0_COMPB_vect)
1687 1838
 #if EXTRUDERS > 2
1688 1839
       current_temperature_raw[2] = raw_temp_2_value;
1689 1840
 #endif
1841
+#if EXTRUDERS > 3
1842
+      current_temperature_raw[3] = raw_temp_3_value;
1843
+#endif
1690 1844
       current_temperature_bed_raw = raw_temp_bed_value;
1691 1845
     }
1692 1846
 
@@ -1701,6 +1855,7 @@ ISR(TIMER0_COMPB_vect)
1701 1855
     raw_temp_0_value = 0;
1702 1856
     raw_temp_1_value = 0;
1703 1857
     raw_temp_2_value = 0;
1858
+    raw_temp_3_value = 0;
1704 1859
     raw_temp_bed_value = 0;
1705 1860
 
1706 1861
 #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
@@ -1721,6 +1876,8 @@ ISR(TIMER0_COMPB_vect)
1721 1876
         min_temp_error(0);
1722 1877
 #endif
1723 1878
     }
1879
+
1880
+
1724 1881
 #if EXTRUDERS > 1
1725 1882
 #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
1726 1883
     if(current_temperature_raw[1] <= maxttemp_raw[1]) {
@@ -1753,7 +1910,24 @@ ISR(TIMER0_COMPB_vect)
1753 1910
         min_temp_error(2);
1754 1911
     }
1755 1912
 #endif
1756
-  
1913
+#if EXTRUDERS > 3
1914
+#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
1915
+    if(current_temperature_raw[3] <= maxttemp_raw[3]) {
1916
+#else
1917
+    if(current_temperature_raw[3] >= maxttemp_raw[3]) {
1918
+#endif
1919
+        max_temp_error(3);
1920
+    }
1921
+#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
1922
+    if(current_temperature_raw[3] >= minttemp_raw[3]) {
1923
+#else
1924
+    if(current_temperature_raw[3] <= minttemp_raw[3]) {
1925
+#endif
1926
+        min_temp_error(3);
1927
+    }
1928
+#endif
1929
+
1930
+
1757 1931
   /* No bed MINTEMP error? */
1758 1932
 #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
1759 1933
 # if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
@@ -1812,5 +1986,3 @@ float unscalePID_d(float d)
1812 1986
 }
1813 1987
 
1814 1988
 #endif //PIDTEMP
1815
-
1816
-

+ 23
- 15
Marlin/temperature.h View File

@@ -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 View File

@@ -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 View File

@@ -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

+ 3
- 3
Marlin/ultralcd.h View File

@@ -46,9 +46,9 @@
46 46
   
47 47
   extern bool cancel_heatup;
48 48
   
49
-  #ifdef FILAMENT_LCD_DISPLAY
50
-        extern unsigned long message_millis;
51
-  #endif
49
+#ifdef FILAMENT_LCD_DISPLAY
50
+  extern unsigned long message_millis;
51
+#endif
52 52
 
53 53
   void lcd_buzz(long duration,uint16_t freq);
54 54
   bool lcd_clicked();

Loading…
Cancel
Save