Merge pull request #4256 from thinkyhead/rc_fix_singlenozzle_temp
Additional tweaks for HOTENDS == 1
This commit is contained in:
		
						commit
						5b0e46c986
					
				| @ -57,9 +57,6 @@ void prt_hex_byte(unsigned int); | |||||||
| void prt_hex_word(unsigned int); | void prt_hex_word(unsigned int); | ||||||
| int how_many_E5s_are_here(unsigned char*); | int how_many_E5s_are_here(unsigned char*); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void gcode_M100() { | void gcode_M100() { | ||||||
|   static int m100_not_initialized = 1; |   static int m100_not_initialized = 1; | ||||||
|   unsigned char* sp, *ptr; |   unsigned char* sp, *ptr; | ||||||
| @ -73,49 +70,49 @@ void gcode_M100() { | |||||||
|   // probably caused by bad pointers.  Any unexpected values will be flagged in
 |   // probably caused by bad pointers.  Any unexpected values will be flagged in
 | ||||||
|   // the right hand column to help spotting them.
 |   // the right hand column to help spotting them.
 | ||||||
|   //
 |   //
 | ||||||
| #if ENABLED(M100_FREE_MEMORY_DUMPER) // Disable to remove Dump sub-command
 |   #if ENABLED(M100_FREE_MEMORY_DUMPER) // Disable to remove Dump sub-command
 | ||||||
|   if (code_seen('D')) { |     if (code_seen('D')) { | ||||||
|     ptr = (unsigned char*) __brkval; |       ptr = (unsigned char*) __brkval; | ||||||
|     //
 |       //
 | ||||||
|     // We want to start and end the dump on a nice 16 byte boundry even though
 |       // We want to start and end the dump on a nice 16 byte boundry even though
 | ||||||
|     // the values we are using are not 16 byte aligned.
 |       // the values we are using are not 16 byte aligned.
 | ||||||
|     //
 |       //
 | ||||||
|     SERIAL_ECHOPGM("\n__brkval : "); |       SERIAL_ECHOPGM("\n__brkval : "); | ||||||
|     prt_hex_word((unsigned int) ptr); |       prt_hex_word((unsigned int) ptr); | ||||||
|     ptr = (unsigned char*)((unsigned long) ptr & 0xfff0); |       ptr = (unsigned char*)((unsigned long) ptr & 0xfff0); | ||||||
|     sp = top_of_stack(); |       sp = top_of_stack(); | ||||||
|     SERIAL_ECHOPGM("\nStack Pointer : "); |       SERIAL_ECHOPGM("\nStack Pointer : "); | ||||||
|     prt_hex_word((unsigned int) sp); |       prt_hex_word((unsigned int) sp); | ||||||
|     SERIAL_EOL; |  | ||||||
|     sp = (unsigned char*)((unsigned long) sp | 0x000f); |  | ||||||
|     n = sp - ptr; |  | ||||||
|     //
 |  | ||||||
|     // This is the main loop of the Dump command.
 |  | ||||||
|     //
 |  | ||||||
|     while (ptr < sp) { |  | ||||||
|       prt_hex_word((unsigned int) ptr); // Print the address
 |  | ||||||
|       SERIAL_CHAR(':'); |  | ||||||
|       for (i = 0; i < 16; i++) {      // and 16 data bytes
 |  | ||||||
|         prt_hex_byte(*(ptr + i)); |  | ||||||
|         SERIAL_CHAR(' '); |  | ||||||
|         delay(2); |  | ||||||
|       } |  | ||||||
|       SERIAL_CHAR('|');         // now show where non 0xE5's are
 |  | ||||||
|       for (i = 0; i < 16; i++) { |  | ||||||
|         delay(2); |  | ||||||
|         if (*(ptr + i) == 0xe5) |  | ||||||
|           SERIAL_CHAR(' '); |  | ||||||
|         else |  | ||||||
|           SERIAL_CHAR('?'); |  | ||||||
|       } |  | ||||||
|       SERIAL_EOL; |       SERIAL_EOL; | ||||||
|       ptr += 16; |       sp = (unsigned char*)((unsigned long) sp | 0x000f); | ||||||
|       delay(2); |       n = sp - ptr; | ||||||
|  |       //
 | ||||||
|  |       // This is the main loop of the Dump command.
 | ||||||
|  |       //
 | ||||||
|  |       while (ptr < sp) { | ||||||
|  |         prt_hex_word((unsigned int) ptr); // Print the address
 | ||||||
|  |         SERIAL_CHAR(':'); | ||||||
|  |         for (i = 0; i < 16; i++) {      // and 16 data bytes
 | ||||||
|  |           prt_hex_byte(*(ptr + i)); | ||||||
|  |           SERIAL_CHAR(' '); | ||||||
|  |           delay(2); | ||||||
|  |         } | ||||||
|  |         SERIAL_CHAR('|');         // now show where non 0xE5's are
 | ||||||
|  |         for (i = 0; i < 16; i++) { | ||||||
|  |           delay(2); | ||||||
|  |           if (*(ptr + i) == 0xe5) | ||||||
|  |             SERIAL_CHAR(' '); | ||||||
|  |           else | ||||||
|  |             SERIAL_CHAR('?'); | ||||||
|  |         } | ||||||
|  |         SERIAL_EOL; | ||||||
|  |         ptr += 16; | ||||||
|  |         delay(2); | ||||||
|  |       } | ||||||
|  |       SERIAL_ECHOLNPGM("Done."); | ||||||
|  |       return; | ||||||
|     } |     } | ||||||
|     SERIAL_ECHOLNPGM("Done."); |   #endif | ||||||
|     return; |  | ||||||
|   } |  | ||||||
| #endif |  | ||||||
|   //
 |   //
 | ||||||
|   // M100 F   requests the code to return the number of free bytes in the memory pool along with
 |   // M100 F   requests the code to return the number of free bytes in the memory pool along with
 | ||||||
|   // other vital statistics that define the memory pool.
 |   // other vital statistics that define the memory pool.
 | ||||||
| @ -158,28 +155,28 @@ void gcode_M100() { | |||||||
|   // M100 C x  Corrupts x locations in the free memory pool and reports the locations of the corruption.
 |   // M100 C x  Corrupts x locations in the free memory pool and reports the locations of the corruption.
 | ||||||
|   // This is useful to check the correctness of the M100 D and the M100 F commands.
 |   // This is useful to check the correctness of the M100 D and the M100 F commands.
 | ||||||
|   //
 |   //
 | ||||||
| #if ENABLED(M100_FREE_MEMORY_CORRUPTOR) |   #if ENABLED(M100_FREE_MEMORY_CORRUPTOR) | ||||||
|   if (code_seen('C')) { |     if (code_seen('C')) { | ||||||
|     int x = code_value_int(); // x gets the # of locations to corrupt within the memory pool
 |       int x = code_value_int(); // x gets the # of locations to corrupt within the memory pool
 | ||||||
|     SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); |       SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); | ||||||
|     ptr = (unsigned char*) __brkval; |       ptr = (unsigned char*) __brkval; | ||||||
|     SERIAL_ECHOPAIR("\n__brkval : ", ptr); |       SERIAL_ECHOPAIR("\n__brkval : ", ptr); | ||||||
|     ptr += 8; |       ptr += 8; | ||||||
|     sp = top_of_stack(); |       sp = top_of_stack(); | ||||||
|     SERIAL_ECHOPAIR("\nStack Pointer : ", sp); |       SERIAL_ECHOPAIR("\nStack Pointer : ", sp); | ||||||
|     SERIAL_ECHOLNPGM("\n"); |       SERIAL_ECHOLNPGM("\n"); | ||||||
|     n = sp - ptr - 64;    // -64 just to keep us from finding interrupt activity that
 |       n = sp - ptr - 64;    // -64 just to keep us from finding interrupt activity that
 | ||||||
|     // has altered the stack.
 |       // has altered the stack.
 | ||||||
|     j = n / (x + 1); |       j = n / (x + 1); | ||||||
|     for (i = 1; i <= x; i++) { |       for (i = 1; i <= x; i++) { | ||||||
|       *(ptr + (i * j)) = i; |         *(ptr + (i * j)) = i; | ||||||
|       SERIAL_ECHOPGM("\nCorrupting address: 0x"); |         SERIAL_ECHOPGM("\nCorrupting address: 0x"); | ||||||
|       prt_hex_word((unsigned int)(ptr + (i * j))); |         prt_hex_word((unsigned int)(ptr + (i * j))); | ||||||
|  |       } | ||||||
|  |       SERIAL_ECHOLNPGM("\n"); | ||||||
|  |       return; | ||||||
|     } |     } | ||||||
|     SERIAL_ECHOLNPGM("\n"); |   #endif | ||||||
|     return; |  | ||||||
|   } |  | ||||||
| #endif |  | ||||||
|   //
 |   //
 | ||||||
|   // M100 I    Initializes the free memory pool so it can be watched and prints vital
 |   // M100 I    Initializes the free memory pool so it can be watched and prints vital
 | ||||||
|   // statistics that define the free memory pool.
 |   // statistics that define the free memory pool.
 | ||||||
|  | |||||||
| @ -4365,7 +4365,7 @@ inline void gcode_M104() { | |||||||
|       SERIAL_PROTOCOL_F(thermalManager.degTargetBed(), 1); |       SERIAL_PROTOCOL_F(thermalManager.degTargetBed(), 1); | ||||||
|     #endif |     #endif | ||||||
|     #if HOTENDS > 1 |     #if HOTENDS > 1 | ||||||
|       for (int8_t e = 0; e < HOTENDS; ++e) { |       HOTEND_LOOP() { | ||||||
|         SERIAL_PROTOCOLPGM(" T"); |         SERIAL_PROTOCOLPGM(" T"); | ||||||
|         SERIAL_PROTOCOL(e); |         SERIAL_PROTOCOL(e); | ||||||
|         SERIAL_PROTOCOLCHAR(':'); |         SERIAL_PROTOCOLCHAR(':'); | ||||||
| @ -4391,7 +4391,7 @@ inline void gcode_M104() { | |||||||
|       SERIAL_PROTOCOL(thermalManager.getHeaterPower(target_extruder)); |       SERIAL_PROTOCOL(thermalManager.getHeaterPower(target_extruder)); | ||||||
|     #endif |     #endif | ||||||
|     #if HOTENDS > 1 |     #if HOTENDS > 1 | ||||||
|       for (int8_t e = 0; e < HOTENDS; ++e) { |       HOTEND_LOOP() { | ||||||
|         SERIAL_PROTOCOLPGM(" @"); |         SERIAL_PROTOCOLPGM(" @"); | ||||||
|         SERIAL_PROTOCOL(e); |         SERIAL_PROTOCOL(e); | ||||||
|         SERIAL_PROTOCOLCHAR(':'); |         SERIAL_PROTOCOLCHAR(':'); | ||||||
| @ -4410,13 +4410,13 @@ inline void gcode_M104() { | |||||||
|         SERIAL_PROTOCOLPGM("C->"); |         SERIAL_PROTOCOLPGM("C->"); | ||||||
|         SERIAL_PROTOCOL_F(thermalManager.rawBedTemp() / OVERSAMPLENR, 0); |         SERIAL_PROTOCOL_F(thermalManager.rawBedTemp() / OVERSAMPLENR, 0); | ||||||
|       #endif |       #endif | ||||||
|       for (int8_t cur_hotend = 0; cur_hotend < HOTENDS; ++cur_hotend) { |       HOTEND_LOOP() { | ||||||
|         SERIAL_PROTOCOLPGM("  T"); |         SERIAL_PROTOCOLPGM("  T"); | ||||||
|         SERIAL_PROTOCOL(cur_hotend); |         SERIAL_PROTOCOL(e); | ||||||
|         SERIAL_PROTOCOLCHAR(':'); |         SERIAL_PROTOCOLCHAR(':'); | ||||||
|         SERIAL_PROTOCOL_F(thermalManager.degHotend(cur_hotend), 1); |         SERIAL_PROTOCOL_F(thermalManager.degHotend(e), 1); | ||||||
|         SERIAL_PROTOCOLPGM("C->"); |         SERIAL_PROTOCOLPGM("C->"); | ||||||
|         SERIAL_PROTOCOL_F(thermalManager.rawHotendTemp(cur_hotend) / OVERSAMPLENR, 0); |         SERIAL_PROTOCOL_F(thermalManager.rawHotendTemp(e) / OVERSAMPLENR, 0); | ||||||
|       } |       } | ||||||
|     #endif |     #endif | ||||||
|   } |   } | ||||||
| @ -5436,7 +5436,7 @@ inline void gcode_M206() { | |||||||
| 
 | 
 | ||||||
|     SERIAL_ECHO_START; |     SERIAL_ECHO_START; | ||||||
|     SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); |     SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); | ||||||
|     for (int e = 0; e < HOTENDS; e++) { |     HOTEND_LOOP() { | ||||||
|       SERIAL_CHAR(' '); |       SERIAL_CHAR(' '); | ||||||
|       SERIAL_ECHO(hotend_offset[X_AXIS][e]); |       SERIAL_ECHO(hotend_offset[X_AXIS][e]); | ||||||
|       SERIAL_CHAR(','); |       SERIAL_CHAR(','); | ||||||
| @ -7968,8 +7968,9 @@ void prepare_move_to_destination() { | |||||||
|     float max_temp = 0.0; |     float max_temp = 0.0; | ||||||
|     if (ELAPSED(millis(), next_status_led_update_ms)) { |     if (ELAPSED(millis(), next_status_led_update_ms)) { | ||||||
|       next_status_led_update_ms += 500; // Update every 0.5s
 |       next_status_led_update_ms += 500; // Update every 0.5s
 | ||||||
|       for (int8_t cur_hotend = 0; cur_hotend < HOTENDS; ++cur_hotend) |       HOTEND_LOOP() { | ||||||
|         max_temp = max(max(max_temp, thermalManager.degHotend(cur_hotend)), thermalManager.degTargetHotend(cur_hotend)); |         max_temp = max(max(max_temp, thermalManager.degHotend(e)), thermalManager.degTargetHotend(e)); | ||||||
|  |       } | ||||||
|       #if HAS_TEMP_BED |       #if HAS_TEMP_BED | ||||||
|         max_temp = max(max(max_temp, thermalManager.degTargetBed()), thermalManager.degBed()); |         max_temp = max(max(max_temp, thermalManager.degTargetBed()), thermalManager.degBed()); | ||||||
|       #endif |       #endif | ||||||
|  | |||||||
| @ -618,7 +618,7 @@ void Config_ResetDefault() { | |||||||
| 
 | 
 | ||||||
|   #if ENABLED(PIDTEMP) |   #if ENABLED(PIDTEMP) | ||||||
|     #if ENABLED(PID_PARAMS_PER_HOTEND) |     #if ENABLED(PID_PARAMS_PER_HOTEND) | ||||||
|       for (uint8_t e = 0; e < HOTENDS; e++) |       HOTEND_LOOP | ||||||
|     #else |     #else | ||||||
|       int e = 0; UNUSED(e); // only need to write once
 |       int e = 0; UNUSED(e); // only need to write once
 | ||||||
|     #endif |     #endif | ||||||
| @ -834,15 +834,15 @@ void Config_PrintSettings(bool forReplay) { | |||||||
|     #if ENABLED(PIDTEMP) |     #if ENABLED(PIDTEMP) | ||||||
|       #if HOTENDS > 1 |       #if HOTENDS > 1 | ||||||
|         if (forReplay) { |         if (forReplay) { | ||||||
|           for (uint8_t i = 0; i < HOTENDS; i++) { |           HOTEND_LOOP() { | ||||||
|             CONFIG_ECHO_START; |             CONFIG_ECHO_START; | ||||||
|             SERIAL_ECHOPAIR("  M301 E", i); |             SERIAL_ECHOPAIR("  M301 E", e); | ||||||
|             SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, i)); |             SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, e)); | ||||||
|             SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, i))); |             SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, e))); | ||||||
|             SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, i))); |             SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, e))); | ||||||
|             #if ENABLED(PID_ADD_EXTRUSION_RATE) |             #if ENABLED(PID_ADD_EXTRUSION_RATE) | ||||||
|               SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, i)); |               SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, e)); | ||||||
|               if (i == 0) SERIAL_ECHOPAIR(" L", lpq_len); |               if (e == 0) SERIAL_ECHOPAIR(" L", lpq_len); | ||||||
|             #endif |             #endif | ||||||
|             SERIAL_EOL; |             SERIAL_EOL; | ||||||
|           } |           } | ||||||
|  | |||||||
| @ -392,7 +392,7 @@ static void lcd_implementation_status_screen() { | |||||||
|   #endif |   #endif | ||||||
| 
 | 
 | ||||||
|   // Extruders
 |   // Extruders
 | ||||||
|   for (int i = 0; i < HOTENDS; i++) _draw_heater_status(5 + i * 25, i); |   HOTEND_LOOP() _draw_heater_status(5 + e * 25, e); | ||||||
| 
 | 
 | ||||||
|   // Heated bed
 |   // Heated bed
 | ||||||
|   #if HOTENDS < 4 && HAS_TEMP_BED |   #if HOTENDS < 4 && HAS_TEMP_BED | ||||||
|  | |||||||
| @ -436,7 +436,7 @@ Temperature::Temperature() { } | |||||||
| 
 | 
 | ||||||
| void Temperature::updatePID() { | void Temperature::updatePID() { | ||||||
|   #if ENABLED(PIDTEMP) |   #if ENABLED(PIDTEMP) | ||||||
|     for (int e = 0; e < HOTENDS; e++) { |     HOTEND_LOOP() { | ||||||
|       temp_iState_max[e] = (PID_INTEGRAL_DRIVE_MAX) / PID_PARAM(Ki, e); |       temp_iState_max[e] = (PID_INTEGRAL_DRIVE_MAX) / PID_PARAM(Ki, e); | ||||||
|       #if ENABLED(PID_ADD_EXTRUSION_RATE) |       #if ENABLED(PID_ADD_EXTRUSION_RATE) | ||||||
|         last_position[e] = 0; |         last_position[e] = 0; | ||||||
| @ -465,12 +465,12 @@ int Temperature::getHeaterPower(int heater) { | |||||||
|       EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN ? 2 : 3 |       EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN ? 2 : 3 | ||||||
|     }; |     }; | ||||||
|     uint8_t fanState = 0; |     uint8_t fanState = 0; | ||||||
|     for (int f = 0; f < HOTENDS; f++) { |     HOTEND_LOOP() { | ||||||
|       if (current_temperature[f] > EXTRUDER_AUTO_FAN_TEMPERATURE) |       if (current_temperature[e] > EXTRUDER_AUTO_FAN_TEMPERATURE) | ||||||
|         SBI(fanState, fanBit[f]); |         SBI(fanState, fanBit[e]); | ||||||
|     } |     } | ||||||
|     uint8_t fanDone = 0; |     uint8_t fanDone = 0; | ||||||
|     for (int f = 0; f <= 3; f++) { |     for (int8_t f = 0; f <= 3; f++) { | ||||||
|       int8_t pin = fanPin[f]; |       int8_t pin = fanPin[f]; | ||||||
|       if (pin >= 0 && !TEST(fanDone, fanBit[f])) { |       if (pin >= 0 && !TEST(fanDone, fanBit[f])) { | ||||||
|         unsigned char newFanSpeed = TEST(fanState, fanBit[f]) ? EXTRUDER_AUTO_FAN_SPEED : 0; |         unsigned char newFanSpeed = TEST(fanState, fanBit[f]) ? EXTRUDER_AUTO_FAN_SPEED : 0; | ||||||
| @ -507,95 +507,99 @@ void Temperature::_temp_error(int e, const char* serial_msg, const char* lcd_msg | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Temperature::max_temp_error(uint8_t e) { | void Temperature::max_temp_error(uint8_t e) { | ||||||
|   _temp_error(e, PSTR(MSG_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP)); |   #if HOTENDS == 1 | ||||||
|  |     UNUSED(e); | ||||||
|  |   #endif | ||||||
|  |   _temp_error(HOTEND_INDEX, PSTR(MSG_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP)); | ||||||
| } | } | ||||||
| void Temperature::min_temp_error(uint8_t e) { | void Temperature::min_temp_error(uint8_t e) { | ||||||
|   _temp_error(e, PSTR(MSG_T_MINTEMP), PSTR(MSG_ERR_MINTEMP)); |   #if HOTENDS == 1 | ||||||
|  |     UNUSED(e); | ||||||
|  |   #endif | ||||||
|  |   _temp_error(HOTEND_INDEX, PSTR(MSG_T_MINTEMP), PSTR(MSG_ERR_MINTEMP)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float Temperature::get_pid_output(int e) { | float Temperature::get_pid_output(int e) { | ||||||
|  |   #if HOTENDS == 1 | ||||||
|  |     UNUSED(e); | ||||||
|  |     #define _HOTEND_TEST     true | ||||||
|  |     #define _HOTEND_EXTRUDER active_extruder | ||||||
|  |   #else | ||||||
|  |     #define _HOTEND_TEST     e == active_extruder | ||||||
|  |     #define _HOTEND_EXTRUDER e | ||||||
|  |   #endif | ||||||
|   float pid_output; |   float pid_output; | ||||||
|   #if ENABLED(PIDTEMP) |   #if ENABLED(PIDTEMP) | ||||||
|     #if DISABLED(PID_OPENLOOP) |     #if DISABLED(PID_OPENLOOP) | ||||||
|       pid_error[e] = target_temperature[e] - current_temperature[e]; |       pid_error[HOTEND_INDEX] = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX]; | ||||||
|       dTerm[e] = K2 * PID_PARAM(Kd, e) * (current_temperature[e] - temp_dState[e]) + K1 * dTerm[e]; |       dTerm[HOTEND_INDEX] = K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + K1 * dTerm[HOTEND_INDEX]; | ||||||
|       temp_dState[e] = current_temperature[e]; |       temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX]; | ||||||
|       if (pid_error[e] > PID_FUNCTIONAL_RANGE) { |       if (pid_error[HOTEND_INDEX] > PID_FUNCTIONAL_RANGE) { | ||||||
|         pid_output = BANG_MAX; |         pid_output = BANG_MAX; | ||||||
|         pid_reset[e] = true; |         pid_reset[HOTEND_INDEX] = true; | ||||||
|       } |       } | ||||||
|       else if (pid_error[e] < -(PID_FUNCTIONAL_RANGE) || target_temperature[e] == 0) { |       else if (pid_error[HOTEND_INDEX] < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0) { | ||||||
|         pid_output = 0; |         pid_output = 0; | ||||||
|         pid_reset[e] = true; |         pid_reset[HOTEND_INDEX] = true; | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         if (pid_reset[e]) { |         if (pid_reset[HOTEND_INDEX]) { | ||||||
|           temp_iState[e] = 0.0; |           temp_iState[HOTEND_INDEX] = 0.0; | ||||||
|           pid_reset[e] = false; |           pid_reset[HOTEND_INDEX] = false; | ||||||
|         } |         } | ||||||
|         pTerm[e] = PID_PARAM(Kp, e) * pid_error[e]; |         pTerm[HOTEND_INDEX] = PID_PARAM(Kp, HOTEND_INDEX) * pid_error[HOTEND_INDEX]; | ||||||
|         temp_iState[e] += pid_error[e]; |         temp_iState[HOTEND_INDEX] += pid_error[HOTEND_INDEX]; | ||||||
|         temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); |         temp_iState[HOTEND_INDEX] = constrain(temp_iState[HOTEND_INDEX], temp_iState_min[HOTEND_INDEX], temp_iState_max[HOTEND_INDEX]); | ||||||
|         iTerm[e] = PID_PARAM(Ki, e) * temp_iState[e]; |         iTerm[HOTEND_INDEX] = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX]; | ||||||
| 
 | 
 | ||||||
|         pid_output = pTerm[e] + iTerm[e] - dTerm[e]; |         pid_output = pTerm[HOTEND_INDEX] + iTerm[HOTEND_INDEX] - dTerm[HOTEND_INDEX]; | ||||||
| 
 |  | ||||||
|         #if ENABLED(SINGLENOZZLE) |  | ||||||
|           #define _NOZZLE_TEST     true |  | ||||||
|           #define _NOZZLE_EXTRUDER active_extruder |  | ||||||
|           #define _CTERM_INDEX     0 |  | ||||||
|         #else |  | ||||||
|           #define _NOZZLE_TEST     e == active_extruder |  | ||||||
|           #define _NOZZLE_EXTRUDER e |  | ||||||
|           #define _CTERM_INDEX     e |  | ||||||
|         #endif |  | ||||||
| 
 | 
 | ||||||
|         #if ENABLED(PID_ADD_EXTRUSION_RATE) |         #if ENABLED(PID_ADD_EXTRUSION_RATE) | ||||||
|           cTerm[_CTERM_INDEX] = 0; |           cTerm[HOTEND_INDEX] = 0; | ||||||
|           if (_NOZZLE_TEST) { |           if (_HOTEND_TEST) { | ||||||
|             long e_position = stepper.position(E_AXIS); |             long e_position = stepper.position(E_AXIS); | ||||||
|             if (e_position > last_position[_NOZZLE_EXTRUDER]) { |             if (e_position > last_position[_HOTEND_EXTRUDER]) { | ||||||
|               lpq[lpq_ptr++] = e_position - last_position[_NOZZLE_EXTRUDER]; |               lpq[lpq_ptr++] = e_position - last_position[_HOTEND_EXTRUDER]; | ||||||
|               last_position[_NOZZLE_EXTRUDER] = e_position; |               last_position[_HOTEND_EXTRUDER] = e_position; | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|               lpq[lpq_ptr++] = 0; |               lpq[lpq_ptr++] = 0; | ||||||
|             } |             } | ||||||
|             if (lpq_ptr >= lpq_len) lpq_ptr = 0; |             if (lpq_ptr >= lpq_len) lpq_ptr = 0; | ||||||
|             cTerm[_CTERM_INDEX] = (lpq[lpq_ptr] / planner.axis_steps_per_mm[E_AXIS]) * PID_PARAM(Kc, e); |             cTerm[HOTEND_INDEX] = (lpq[lpq_ptr] / planner.axis_steps_per_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX); | ||||||
|             pid_output += cTerm[e]; |             pid_output += cTerm[HOTEND_INDEX]; | ||||||
|           } |           } | ||||||
|         #endif //PID_ADD_EXTRUSION_RATE
 |         #endif //PID_ADD_EXTRUSION_RATE
 | ||||||
| 
 | 
 | ||||||
|         if (pid_output > PID_MAX) { |         if (pid_output > PID_MAX) { | ||||||
|           if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
 |           if (pid_error[HOTEND_INDEX] > 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration
 | ||||||
|           pid_output = PID_MAX; |           pid_output = PID_MAX; | ||||||
|         } |         } | ||||||
|         else if (pid_output < 0) { |         else if (pid_output < 0) { | ||||||
|           if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
 |           if (pid_error[HOTEND_INDEX] < 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration
 | ||||||
|           pid_output = 0; |           pid_output = 0; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     #else |     #else | ||||||
|       pid_output = constrain(target_temperature[e], 0, PID_MAX); |       pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX); | ||||||
|     #endif //PID_OPENLOOP
 |     #endif //PID_OPENLOOP
 | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(PID_DEBUG) |     #if ENABLED(PID_DEBUG) | ||||||
|       SERIAL_ECHO_START; |       SERIAL_ECHO_START; | ||||||
|       SERIAL_ECHOPAIR(MSG_PID_DEBUG, e); |       SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX); | ||||||
|       SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[e]); |       SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]); | ||||||
|       SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); |       SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); | ||||||
|       SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[e]); |       SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[HOTEND_INDEX]); | ||||||
|       SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[e]); |       SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[HOTEND_INDEX]); | ||||||
|       SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[e]); |       SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[HOTEND_INDEX]); | ||||||
|       #if ENABLED(PID_ADD_EXTRUSION_RATE) |       #if ENABLED(PID_ADD_EXTRUSION_RATE) | ||||||
|         SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[e]); |         SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[HOTEND_INDEX]); | ||||||
|       #endif |       #endif | ||||||
|       SERIAL_EOL; |       SERIAL_EOL; | ||||||
|     #endif //PID_DEBUG
 |     #endif //PID_DEBUG
 | ||||||
| 
 | 
 | ||||||
|   #else /* PID off */ |   #else /* PID off */ | ||||||
|     pid_output = (current_temperature[e] < target_temperature[e]) ? PID_MAX : 0; |     pid_output = (current_temperature[HOTEND_INDEX] < target_temperature[HOTEND_INDEX]) ? PID_MAX : 0; | ||||||
|   #endif |   #endif | ||||||
| 
 | 
 | ||||||
|   return pid_output; |   return pid_output; | ||||||
| @ -672,7 +676,7 @@ void Temperature::manage_heater() { | |||||||
|   #endif |   #endif | ||||||
| 
 | 
 | ||||||
|   // Loop through all hotends
 |   // Loop through all hotends
 | ||||||
|   for (int e = 0; e < HOTENDS; e++) { |   HOTEND_LOOP() { | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(THERMAL_PROTECTION_HOTENDS) |     #if ENABLED(THERMAL_PROTECTION_HOTENDS) | ||||||
|       thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); |       thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); | ||||||
| @ -879,7 +883,7 @@ void Temperature::updateTemperaturesFromRawValues() { | |||||||
|   #if ENABLED(HEATER_0_USES_MAX6675) |   #if ENABLED(HEATER_0_USES_MAX6675) | ||||||
|     current_temperature_raw[0] = read_max6675(); |     current_temperature_raw[0] = read_max6675(); | ||||||
|   #endif |   #endif | ||||||
|   for (uint8_t e = 0; e < HOTENDS; e++) { |   HOTEND_LOOP() { | ||||||
|     current_temperature[e] = Temperature::analog2temp(current_temperature_raw[e], e); |     current_temperature[e] = Temperature::analog2temp(current_temperature_raw[e], e); | ||||||
|   } |   } | ||||||
|   current_temperature_bed = Temperature::analog2tempBed(current_temperature_bed_raw); |   current_temperature_bed = Temperature::analog2tempBed(current_temperature_bed_raw); | ||||||
| @ -933,7 +937,7 @@ void Temperature::init() { | |||||||
|   #endif |   #endif | ||||||
| 
 | 
 | ||||||
|   // Finish init of mult hotend arrays
 |   // Finish init of mult hotend arrays
 | ||||||
|   for (int e = 0; e < HOTENDS; e++) { |   HOTEND_LOOP() { | ||||||
|     // populate with the first value
 |     // populate with the first value
 | ||||||
|     maxttemp[e] = maxttemp[0]; |     maxttemp[e] = maxttemp[0]; | ||||||
|     #if ENABLED(PIDTEMP) |     #if ENABLED(PIDTEMP) | ||||||
| @ -1140,13 +1144,16 @@ void Temperature::init() { | |||||||
|    * their target temperature by a configurable margin. |    * their target temperature by a configurable margin. | ||||||
|    * This is called when the temperature is set. (M104, M109) |    * This is called when the temperature is set. (M104, M109) | ||||||
|    */ |    */ | ||||||
|   void Temperature::start_watching_heater(int e) { |   void Temperature::start_watching_heater(uint8_t e) { | ||||||
|     if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) { |     #if HOTENDS == 1 | ||||||
|       watch_target_temp[e] = degHotend(e) + WATCH_TEMP_INCREASE; |       UNUSED(e); | ||||||
|       watch_heater_next_ms[e] = millis() + (WATCH_TEMP_PERIOD) * 1000UL; |     #endif | ||||||
|  |     if (degHotend(HOTEND_INDEX) < degTargetHotend(HOTEND_INDEX) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) { | ||||||
|  |       watch_target_temp[HOTEND_INDEX] = degHotend(HOTEND_INDEX) + WATCH_TEMP_INCREASE; | ||||||
|  |       watch_heater_next_ms[HOTEND_INDEX] = millis() + (WATCH_TEMP_PERIOD) * 1000UL; | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|       watch_heater_next_ms[e] = 0; |       watch_heater_next_ms[HOTEND_INDEX] = 0; | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -1224,7 +1231,7 @@ void Temperature::init() { | |||||||
| #endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED
 | #endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED
 | ||||||
| 
 | 
 | ||||||
| void Temperature::disable_all_heaters() { | void Temperature::disable_all_heaters() { | ||||||
|   for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i); |   HOTEND_LOOP() setTargetHotend(0, e); | ||||||
|   setTargetBed(0); |   setTargetBed(0); | ||||||
| 
 | 
 | ||||||
|   // If all heaters go down then for sure our print job has stopped
 |   // If all heaters go down then for sure our print job has stopped
 | ||||||
|  | |||||||
| @ -38,6 +38,16 @@ | |||||||
|   #define SOFT_PWM_SCALE 0 |   #define SOFT_PWM_SCALE 0 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if HOTENDS == 1 | ||||||
|  |   #define HOTEND_LOOP() const uint8_t e = 0; | ||||||
|  |   #define HOTEND_INDEX  0 | ||||||
|  |   #define EXTRUDER_IDX  0 | ||||||
|  | #else | ||||||
|  |   #define HOTEND_LOOP() for (int8_t e = 0; e < HOTENDS; e++) | ||||||
|  |   #define HOTEND_INDEX  e | ||||||
|  |   #define EXTRUDER_IDX  active_extruder | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| class Temperature { | class Temperature { | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
| @ -112,7 +122,12 @@ class Temperature { | |||||||
| 
 | 
 | ||||||
|     #if ENABLED(PREVENT_DANGEROUS_EXTRUDE) |     #if ENABLED(PREVENT_DANGEROUS_EXTRUDE) | ||||||
|       static float extrude_min_temp; |       static float extrude_min_temp; | ||||||
|       static bool tooColdToExtrude(uint8_t e) { return degHotend(e) < extrude_min_temp; } |       static bool tooColdToExtrude(uint8_t e) { | ||||||
|  |         #if HOTENDS == 1 | ||||||
|  |           UNUSED(e); | ||||||
|  |         #endif | ||||||
|  |         return degHotend(HOTEND_INDEX) < extrude_min_temp; | ||||||
|  |       } | ||||||
|     #else |     #else | ||||||
|       static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; } |       static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; } | ||||||
|     #endif |     #endif | ||||||
| @ -230,53 +245,47 @@ class Temperature { | |||||||
|     //inline so that there is no performance decrease.
 |     //inline so that there is no performance decrease.
 | ||||||
|     //deg=degreeCelsius
 |     //deg=degreeCelsius
 | ||||||
| 
 | 
 | ||||||
|     #if HOTENDS == 1 |     static float degHotend(uint8_t e) { | ||||||
|       #define HOTEND_ARG 0 |  | ||||||
|     #else |  | ||||||
|       #define HOTEND_ARG hotend |  | ||||||
|     #endif |  | ||||||
| 
 |  | ||||||
|     static float degHotend(uint8_t hotend) { |  | ||||||
|       #if HOTENDS == 1 |       #if HOTENDS == 1 | ||||||
|         UNUSED(hotend); |         UNUSED(e); | ||||||
|       #endif |       #endif | ||||||
|       return current_temperature[HOTEND_ARG]; |       return current_temperature[HOTEND_INDEX]; | ||||||
|     } |     } | ||||||
|     static float degBed() { return current_temperature_bed; } |     static float degBed() { return current_temperature_bed; } | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(SHOW_TEMP_ADC_VALUES) |     #if ENABLED(SHOW_TEMP_ADC_VALUES) | ||||||
|     static float rawHotendTemp(uint8_t hotend) { |     static float rawHotendTemp(uint8_t e) { | ||||||
|       #if HOTENDS == 1 |       #if HOTENDS == 1 | ||||||
|         UNUSED(hotend); |         UNUSED(e); | ||||||
|       #endif |       #endif | ||||||
|       return current_temperature_raw[HOTEND_ARG]; |       return current_temperature_raw[HOTEND_INDEX]; | ||||||
|     } |     } | ||||||
|     static float rawBedTemp() { return current_temperature_bed_raw; } |     static float rawBedTemp() { return current_temperature_bed_raw; } | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|     static float degTargetHotend(uint8_t hotend) { |     static float degTargetHotend(uint8_t e) { | ||||||
|       #if HOTENDS == 1 |       #if HOTENDS == 1 | ||||||
|         UNUSED(hotend); |         UNUSED(e); | ||||||
|       #endif |       #endif | ||||||
|       return target_temperature[HOTEND_ARG]; |       return target_temperature[HOTEND_INDEX]; | ||||||
|     } |     } | ||||||
|     static float degTargetBed() { return target_temperature_bed; } |     static float degTargetBed() { return target_temperature_bed; } | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 |     #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 | ||||||
|       static void start_watching_heater(int e = 0); |       static void start_watching_heater(uint8_t e = 0); | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 |     #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 | ||||||
|       static void start_watching_bed(); |       static void start_watching_bed(); | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|     static void setTargetHotend(const float& celsius, uint8_t hotend) { |     static void setTargetHotend(const float& celsius, uint8_t e) { | ||||||
|       #if HOTENDS == 1 |       #if HOTENDS == 1 | ||||||
|         UNUSED(hotend); |         UNUSED(e); | ||||||
|       #endif |       #endif | ||||||
|       target_temperature[HOTEND_ARG] = celsius; |       target_temperature[HOTEND_INDEX] = celsius; | ||||||
|       #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 |       #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 | ||||||
|         start_watching_heater(HOTEND_ARG); |         start_watching_heater(HOTEND_INDEX); | ||||||
|       #endif |       #endif | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -287,19 +296,19 @@ class Temperature { | |||||||
|       #endif |       #endif | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static bool isHeatingHotend(uint8_t hotend) { |     static bool isHeatingHotend(uint8_t e) { | ||||||
|       #if HOTENDS == 1 |       #if HOTENDS == 1 | ||||||
|         UNUSED(hotend); |         UNUSED(e); | ||||||
|       #endif |       #endif | ||||||
|       return target_temperature[HOTEND_ARG] > current_temperature[HOTEND_ARG]; |       return target_temperature[HOTEND_INDEX] > current_temperature[HOTEND_INDEX]; | ||||||
|     } |     } | ||||||
|     static bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } |     static bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } | ||||||
| 
 | 
 | ||||||
|     static bool isCoolingHotend(uint8_t hotend) { |     static bool isCoolingHotend(uint8_t e) { | ||||||
|       #if HOTENDS == 1 |       #if HOTENDS == 1 | ||||||
|         UNUSED(hotend); |         UNUSED(e); | ||||||
|       #endif |       #endif | ||||||
|       return target_temperature[HOTEND_ARG] < current_temperature[HOTEND_ARG]; |       return target_temperature[HOTEND_INDEX] < current_temperature[HOTEND_INDEX]; | ||||||
|     } |     } | ||||||
|     static bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } |     static bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } | ||||||
| 
 | 
 | ||||||
| @ -329,8 +338,8 @@ class Temperature { | |||||||
|       #if ENABLED(AUTOTEMP) |       #if ENABLED(AUTOTEMP) | ||||||
|         if (planner.autotemp_enabled) { |         if (planner.autotemp_enabled) { | ||||||
|           planner.autotemp_enabled = false; |           planner.autotemp_enabled = false; | ||||||
|           if (degTargetHotend(active_extruder) > planner.autotemp_min) |           if (degTargetHotend(EXTRUDER_IDX) > planner.autotemp_min) | ||||||
|             setTargetHotend(0, active_extruder); |             setTargetHotend(0, EXTRUDER_IDX); | ||||||
|         } |         } | ||||||
|       #endif |       #endif | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user