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…
Reference in a new issue