//-------------------------------------------------- // Tempcontrol with PID for Hotend //-------------------------------------------------- void heater_PID_control(heater_struct *hotend) { signed short error; signed short delta_temp; signed short heater_duty; hotend->akt_temp = analog2temp(adc_read(hotend->ad_cannel)); //MIN save to display the jitter of Heaterbarrel #ifdef MINTEMP if(hotend->akt_temp < 4) { hotend->target_temp = 0; heater_switch(hotend->io_adr, 0); } #endif //MAX save to display the jitter of Heaterbarrel #ifdef MAXTEMP if(hotend->akt_temp > 300) { hotend->target_temp = 0; heater_switch(hotend->io_adr, 0); } #endif error = hotend->target_temp - hotend->akt_temp; //printf("ERR: %d ", error); delta_temp = hotend->akt_temp - hotend->prev_temp; hotend->prev_temp = hotend->akt_temp; hotend->pTerm = (signed short)(((long)hotend->PID_Kp * error) / 256); const signed short H0 = min(HEATER_DUTY_FOR_SETPOINT(hotend->target_temp),HEATER_CURRENT); heater_duty = H0 + hotend->pTerm; if(abs(error) < 30) { hotend->temp_iState += error; //printf("I1: %d ", hotend->temp_iState); hotend->temp_iState = constrain(hotend->temp_iState, hotend->temp_iState_min, hotend->temp_iState_max); //printf("I2: %d ", hotend->temp_iState); hotend->iTerm = (signed short)(((long)hotend->PID_I * hotend->temp_iState) / 256); heater_duty += hotend->iTerm; } //printf("I: %d ", hotend->iTerm); signed short prev_error = abs(hotend->target_temp - hotend->prev_temp); signed short log3 = 1; // discrete logarithm base 3, plus 1 if(prev_error > 81){ prev_error /= 81; log3 += 4; } if(prev_error > 9){ prev_error /= 9; log3 += 2; } if(prev_error > 3){ prev_error /= 3; log3 ++; } hotend->dTerm = (signed short)(((long)hotend->PID_Kd * delta_temp) / (256*log3)); //printf("D: %d ", hotend->dTerm); heater_duty += hotend->dTerm; //printf("PWM: %d \n", heater_duty); heater_duty = constrain(heater_duty, 0, HEATER_CURRENT); if(hotend->target_temp == 0) hotend->pwm = 0; else hotend->pwm = (unsigned char)heater_duty; }
void manage_heater() { //Temperatur Monitor for repetier if((millis() - previous_millis_monitor) > 250 ) { previous_millis_monitor = millis(); if(manage_monitor <= 1) { showString(PSTR("MTEMP:")); Serial.print(millis()); if(manage_monitor<1) { showString(PSTR(" ")); Serial.print(analog2temp(current_raw)); showString(PSTR(" ")); Serial.print(target_temp); showString(PSTR(" ")); #ifdef PIDTEMP Serial.println(heater_duty); #else #if (HEATER_0_PIN > -1) if(READ(HEATER_0_PIN)) Serial.println(255); else Serial.println(0); #else Serial.println(0); #endif #endif } #if THERMISTORBED!=0 else { showString(PSTR(" ")); Serial.print(analog2tempBed(current_bed_raw)); showString(PSTR(" ")); Serial.print(analog2tempBed(target_bed_raw)); showString(PSTR(" ")); #if (HEATER_1_PIN > -1) if(READ(HEATER_1_PIN)) Serial.println(255); else Serial.println(0); #else Serial.println(0); #endif } #endif } } // ENDE Temperatur Monitor for repetier if((millis() - previous_millis_heater) < HEATER_CHECK_INTERVAL ) return; previous_millis_heater = millis(); #ifdef HEATER_USES_THERMISTOR current_raw = analogRead(TEMP_0_PIN); #ifdef DEBUG_HEAT_MGMT log_int("_HEAT_MGMT - analogRead(TEMP_0_PIN)", current_raw); log_int("_HEAT_MGMT - NUMTEMPS", NUMTEMPS); #endif // When using thermistor, when the heater is colder than targer temp, we get a higher analog reading than target, // this switches it up so that the reading appears lower than target for the control logic. current_raw = 1023 - current_raw; #elif defined HEATER_USES_AD595 current_raw = analogRead(TEMP_0_PIN); #elif defined HEATER_USES_MAX6675 current_raw = read_max6675(); #endif //MIN / MAX save to display the jitter of Heaterbarrel if(current_raw > current_raw_maxval) current_raw_maxval = current_raw; if(current_raw < current_raw_minval) current_raw_minval = current_raw; #ifdef SMOOTHING if (!nma) nma = SMOOTHFACTOR * current_raw; nma = (nma + current_raw) - (nma / SMOOTHFACTOR); current_raw = nma / SMOOTHFACTOR; #endif #ifdef WATCHPERIOD if(watchmillis && millis() - watchmillis > WATCHPERIOD) { if(watch_raw + 1 >= current_raw) { target_temp = target_raw = 0; WRITE(HEATER_0_PIN,LOW); #ifdef PID_SOFT_PWM g_heater_pwm_val = 0; #else analogWrite(HEATER_0_PIN, 0); #if LED_PIN>-1 WRITE(LED_PIN,LOW); #endif #endif } else { watchmillis = 0; } } #endif //If tmp is lower then MINTEMP stop the Heater //or it os better to deaktivate the uutput PIN or PWM ? #ifdef MINTEMP if(current_raw <= minttemp) target_temp = target_raw = 0; #endif #ifdef MAXTEMP if(current_raw >= maxttemp) { target_temp = target_raw = 0; #if (ALARM_PIN > -1) WRITE(ALARM_PIN,HIGH); #endif } #endif #if (TEMP_0_PIN > -1) || defined (HEATER_USES_MAX6675) || defined (HEATER_USES_AD595) #ifdef PIDTEMP int current_temp = analog2temp(current_raw); error = target_temp - current_temp; int delta_temp = current_temp - prev_temp; prev_temp = current_temp; pTerm = ((long)PID_PGAIN * error) / 256; const int H0 = min(HEATER_DUTY_FOR_SETPOINT(target_temp),HEATER_CURRENT); heater_duty = H0 + pTerm; if(error < 30) { temp_iState += error; temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max); iTerm = ((long)PID_IGAIN * temp_iState) / 256; heater_duty += iTerm; } int prev_error = abs(target_temp - prev_temp); int log3 = 1; // discrete logarithm base 3, plus 1 if(prev_error > 81){ prev_error /= 81; log3 += 4; } if(prev_error > 9){ prev_error /= 9; log3 += 2; } if(prev_error > 3){ prev_error /= 3; log3 ++; } dTerm = ((long)PID_DGAIN * delta_temp) / (256*log3); heater_duty += dTerm; heater_duty = constrain(heater_duty, 0, HEATER_CURRENT); #ifdef PID_SOFT_PWM g_heater_pwm_val = (unsigned char)heater_duty; #else analogWrite(HEATER_0_PIN, heater_duty); #if LED_PIN>-1 analogWrite(LED_PIN, constrain(LED_PWM_FOR_BRIGHTNESS(heater_duty),0,255)); #endif #endif #else if(current_raw >= target_raw) { WRITE(HEATER_0_PIN,LOW); #if LED_PIN>-1 WRITE(LED_PIN,LOW); #endif } else { WRITE(HEATER_0_PIN,HIGH); #if LED_PIN > -1 WRITE(LED_PIN,HIGH); #endif } #endif #endif if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL) return; previous_millis_bed_heater = millis(); #ifndef TEMP_1_PIN return; #endif #if TEMP_1_PIN == -1 return; #else #ifdef BED_USES_THERMISTOR current_bed_raw = analogRead(TEMP_1_PIN); #ifdef DEBUG_HEAT_MGMT log_int("_HEAT_MGMT - analogRead(TEMP_1_PIN)", current_bed_raw); log_int("_HEAT_MGMT - BNUMTEMPS", BNUMTEMPS); #endif // If using thermistor, when the heater is colder than targer temp, we get a higher analog reading than target, // this switches it up so that the reading appears lower than target for the control logic. current_bed_raw = 1023 - current_bed_raw; #elif defined BED_USES_AD595 current_bed_raw = analogRead(TEMP_1_PIN); #endif #ifdef MINTEMP if(current_bed_raw >= target_bed_raw || current_bed_raw < minttemp) #else if(current_bed_raw >= target_bed_raw) #endif { WRITE(HEATER_1_PIN,LOW); } else { WRITE(HEATER_1_PIN,HIGH); } #endif #ifdef CONTROLLERFAN_PIN controllerFan(); //Check if fan should be turned on to cool stepper drivers down #endif }