@ -26,7 +26,6 @@
It has preliminary support for Matthew Roberts advance algorithm
It has preliminary support for Matthew Roberts advance algorithm
http : //reprap.org/pipermail/reprap-dev/2011-May/003323.html
http : //reprap.org/pipermail/reprap-dev/2011-May/003323.html
This firmware is optimized for gen6 electronics .
*/
*/
# include <avr/pgmspace.h>
# include <avr/pgmspace.h>
@ -41,17 +40,14 @@
//===========================================================================
//===========================================================================
//=============================public variables============================
//=============================public variables============================
//===========================================================================
//===========================================================================
int target_raw [ 3 ] = { 0 , 0 , 0 } ;
int target_raw [ EXTRUDERS ] = { 0 } ;
int current_raw[ 3 ] = { 0 , 0 , 0 } ;
int target_raw_bed = 0 ;
int heatingtarget_raw[ 3 ] = { 0 , 0 , 0 } ;
int current_raw[ EXTRUDERS ] = { 0 } ;
int current_raw_bed = 0 ;
# ifdef PIDTEMP
# ifdef PIDTEMP
// used external
// probably used external
float pid_setpoint [ EXTRUDERS ] = { 0.0 } ;
float HeaterPower ;
float pid_setpoint = 0.0 ;
float Kp = DEFAULT_Kp ;
float Kp = DEFAULT_Kp ;
float Ki = DEFAULT_Ki ;
float Ki = DEFAULT_Ki ;
@ -72,45 +68,83 @@ static unsigned long previous_millis_bed_heater;
# ifdef PIDTEMP
# ifdef PIDTEMP
//static cannot be external:
//static cannot be external:
static float temp_iState = 0 ;
static float temp_iState [ EXTRUDERS ] = { 0 } ;
static float temp_dState = 0 ;
static float temp_dState [ EXTRUDERS ] = { 0 } ;
static float pTerm ;
static float pTerm [EXTRUDERS ] ;
static float iTerm ;
static float iTerm [EXTRUDERS ] ;
static float dTerm ;
static float dTerm [EXTRUDERS ] ;
//int output;
//int output;
static float pid_error ;
static float pid_error [ EXTRUDERS ] ;
static float temp_iState_min ;
static float temp_iState_min [ EXTRUDERS ] ;
static float temp_iState_max ;
static float temp_iState_max [ EXTRUDERS ] ;
// static float pid_input;
// static float pid_input[EXTRUDERS];
// static float pid_output;
// static float pid_output[EXTRUDERS];
static bool pid_reset ;
static bool pid_reset [ EXTRUDERS ] ;
# endif //PIDTEMP
# endif //PIDTEMP
static unsigned char soft_pwm [ EXTRUDERS ] ;
# ifdef WATCHPERIOD
# ifdef WATCHPERIOD
static int watch_raw [ EXTRUDERS ] = { - 1000 } ; // the first value used for all
static int watch_oldtemp [ 3 ] = { 0 , 0 , 0 } ;
static int watch_oldtemp [ 3 ] = { 0 , 0 , 0 } ;
static unsigned long watchmillis = 0 ;
static unsigned long watchmillis = 0 ;
# endif //WATCHPERIOD
# endif //WATCHPERIOD
// Init min and max temp with extreme values to prevent false errors during startup
// Init min and max temp with extreme values to prevent false errors during startup
static int minttemp_0 = 0 ;
static int minttemp [ EXTRUDERS ] = { 0 } ;
static int maxttemp_0 = 16383 ;
static int maxttemp [ EXTRUDERS ] = { 16383 } ; // the first value used for all
//static int minttemp_1 = 0;
//static int maxttemp_1 = 16383;
static int bed_minttemp = 0 ;
static int bed_minttemp = 0 ;
static int bed_maxttemp = 16383 ;
static int bed_maxttemp = 16383 ;
static int heater_pin_map [ EXTRUDERS ] = { HEATER_0_PIN
# if EXTRUDERS > 1
, HEATER_1_PIN
# endif
# if EXTRUDERS > 2
, HEATER_2_PIN
# endif
# if EXTRUDERS > 3
# error Unsupported number of extruders
# endif
} ;
static void * heater_ttbl_map [ EXTRUDERS ] = { ( void * ) heater_0_temptable
# if EXTRUDERS > 1
, ( void * ) heater_1_temptable
# endif
# if EXTRUDERS > 2
, ( void * ) heater_2_temptable
# endif
# if EXTRUDERS > 3
# error Unsupported number of extruders
# endif
} ;
static int heater_ttbllen_map [ EXTRUDERS ] = { heater_0_temptable_len
# if EXTRUDERS > 1
, heater_1_temptable_len
# endif
# if EXTRUDERS > 2
, heater_2_temptable_len
# endif
# if EXTRUDERS > 3
# error Unsupported number of extruders
# endif
} ;
//===========================================================================
//===========================================================================
//=============================functions ============================
//============================= functions ============================
//===========================================================================
//===========================================================================
void updatePID ( )
void updatePID ( )
{
{
# ifdef PIDTEMP
# ifdef PIDTEMP
temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki ;
for ( int e = 0 ; e < EXTRUDERS ; e + + ) {
temp_iState_max [ e ] = PID_INTEGRAL_DRIVE_MAX / Ki ;
}
# endif
# endif
}
}
int getHeaterPower ( int heater ) {
return soft_pwm [ heater ] ;
}
void manage_heater ( )
void manage_heater ( )
{
{
# ifdef USE_WATCHDOG
# ifdef USE_WATCHDOG
@ -119,73 +153,67 @@ void manage_heater()
float pid_input ;
float pid_input ;
float pid_output ;
float pid_output ;
if ( temp_meas_ready ! = true ) //better readability
if ( temp_meas_ready ! = true ) //better readability
return ;
return ;
CRITICAL_SECTION_START ;
CRITICAL_SECTION_START ;
temp_meas_ready = false ;
temp_meas_ready = false ;
CRITICAL_SECTION_END ;
CRITICAL_SECTION_END ;
for ( int e = 0 ; e < EXTRUDERS ; e + + )
{
# ifdef PIDTEMP
# ifdef PIDTEMP
pid_input = analog2temp ( current_raw [ TEMPSENSOR_HOTEND_0 ] ) ;
pid_input = analog2temp ( current_raw [ e] , e ) ;
# ifndef PID_OPENLOOP
# ifndef PID_OPENLOOP
pid_error = pid_setpoint - pid_input ;
pid_error [ e ] = pid_setpoint [ e ] - pid_input ;
if ( pid_error > 10 ) {
if ( pid_error [ e ] > 10 ) {
pid_output = PID_MAX ;
pid_output = PID_MAX ;
pid_reset = true ;
pid_reset [ e ] = true ;
}
}
else if ( pid_error < - 10 ) {
else if ( pid_error [ e ] < - 10 ) {
pid_output = 0 ;
pid_output = 0 ;
pid_reset = true ;
pid_reset [ e ] = true ;
}
}
else {
else {
if ( pid_reset = = true ) {
if ( pid_reset [ e ] = = true ) {
temp_iState = 0.0 ;
temp_iState [ e ] = 0.0 ;
pid_reset = false ;
pid_reset [ e ] = false ;
}
}
pTerm = Kp * pid_error ;
pTerm [ e ] = Kp * pid_error [ e ] ;
temp_iState + = pid_error ;
temp_iState [ e ] + = pid_error [ e ] ;
temp_iState = constrain ( temp_iState , temp_iState_min , temp_iState_max ) ;
temp_iState [ e ] = constrain ( temp_iState [ e ] , temp_iState_min [e ] , temp_iState_max [ e ] ) ;
iTerm = Ki * temp_iState ;
iTerm [ e ] = Ki * temp_iState [ e ] ;
//K1 defined in Configuration.h in the PID settings
//K1 defined in Configuration.h in the PID settings
# define K2 (1.0-K1)
# define K2 (1.0-K1)
dTerm = ( Kd * ( pid_input - temp_dState ) ) * K2 + ( K1 * dTerm ) ;
dTerm [ e ] = ( Kd * ( pid_input - temp_dState [ e ] ) ) * K2 + ( K1 * dTerm [ e ] ) ;
temp_dState = pid_input ;
temp_dState [ e ] = pid_input ;
// #ifdef PID_ADD_EXTRUSION_RATE
pid_output = constrain ( pTerm [ e ] + iTerm [ e ] - dTerm [ e ] , 0 , PID_MAX ) ;
// pTerm+=Kc*current_block->speed_e; //additional heating if extrusion speed is high
// #endif
pid_output = constrain ( pTerm + iTerm - dTerm , 0 , PID_MAX ) ;
}
}
# endif //PID_OPENLOOP
# endif //PID_OPENLOOP
# ifdef PID_DEBUG
# ifdef PID_DEBUG
//SERIAL_ECHOLN(" PIDDEBUG Input "<<pid_input<<" Output "<<pid_output" pTerm "<<pTerm<<" iTerm "<<iTerm<<" dTerm "<<dTerm);
SERIAL_ECHOLN ( " PIDDEBUG " < < e < < " : Input " < < pid_input < < " Output " < < pid_output " pTerm " < < pTerm [ e ] < < " iTerm " < < iTerm [ e ] < < " dTerm " < < dTerm [ e ] ) ;
# endif //PID_DEBUG
# endif //PID_DEBUG
HeaterPower = pid_output ;
# else /* PID off */
// Check if temperature is within the correct range
pid_output = 0 ;
if ( ( current_raw [ TEMPSENSOR_HOTEND_0 ] > minttemp_0 ) & & ( current_raw [ TEMPSENSOR_HOTEND_0 ] < maxttemp_0 ) ) {
if ( current_raw [ e ] < target_raw [ e ] ) {
analogWrite( HEATER_0_PIN , pid_output ) ;
pid_output = PID_MAX ;
}
}
else {
# endif
analogWrite ( HEATER_0_PIN , 0 ) ;
}
# endif //PIDTEMP
# ifndef PIDTEMP
// Check if temperature is within the correct range
// Check if temperature is within the correct range
if ( ( current_raw [ TEMPSENSOR_HOTEND_0 ] > minttemp_0 ) & & ( current_raw [ TEMPSENSOR_HOTEND_0 ] < maxttemp_0 ) ) {
if ( ( current_raw [ e ] > minttemp [ e ] ) & & ( current_raw [ e ] < maxttemp [ e ] ) )
if ( current_raw [ TEMPSENSOR_HOTEND_0 ] > = target_raw [ TEMPSENSOR_HOTEND_0 ] ) {
{
WRITE ( HEATER_0_PIN , LOW ) ;
//analogWrite(heater_pin_map[e], pid_output);
}
soft_pwm [ e ] = ( int ) pid_output > > 1 ;
else {
WRITE ( HEATER_0_PIN , HIGH ) ;
}
}
}
else {
else {
WRITE ( HEATER_0_PIN , LOW ) ;
//analogWrite(heater_pin_map[e], 0);
soft_pwm [ e ] = 0 ;
}
}
# endif
} // End extruder for loop
# ifdef WATCHPERIOD
# ifdef WATCHPERIOD
if ( watchmillis & & millis ( ) - watchmillis > WATCHPERIOD ) {
if ( watchmillis & & millis ( ) - watchmillis > WATCHPERIOD ) {
@ -204,20 +232,20 @@ void manage_heater()
return ;
return ;
previous_millis_bed_heater = millis ( ) ;
previous_millis_bed_heater = millis ( ) ;
# if TEMP_ 1 _PIN > -1
# if TEMP_ BED _PIN > -1
// Check if temperature is within the correct range
// Check if temperature is within the correct range
if ( ( current_raw [ TEMPSENSOR_BED ] > bed_minttemp ) & & ( current_raw [ TEMPSENSOR_BED ] < bed_maxttemp ) ) {
if ( ( current_raw _bed > bed_minttemp ) & & ( current_raw_bed < bed_maxttemp ) ) {
if ( current_raw [ TEMPSENSOR_BED ] > = target_raw [ TEMPSENSOR_BED ] )
if ( current_raw _bed > = target_raw_bed )
{
{
WRITE ( HEATER_ 1 _PIN, LOW ) ;
WRITE ( HEATER_ BED _PIN, LOW ) ;
}
}
else
else
{
{
WRITE ( HEATER_ 1 _PIN, HIGH ) ;
WRITE ( HEATER_ BED _PIN, HIGH ) ;
}
}
}
}
else {
else {
WRITE ( HEATER_ 1 _PIN, LOW ) ;
WRITE ( HEATER_ BED _PIN, LOW ) ;
}
}
# endif
# endif
}
}
@ -227,30 +255,38 @@ void manage_heater()
// For a thermistor, it uses the RepRap thermistor temp table.
// For a thermistor, it uses the RepRap thermistor temp table.
// This is needed because PID in hydra firmware hovers around a given analog value, not a temp value.
// This is needed because PID in hydra firmware hovers around a given analog value, not a temp value.
// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
int temp2analog ( int celsius ) {
int temp2analog ( int celsius , uint8_t e ) {
# ifdef HEATER_0_USES_THERMISTOR
if ( e > = EXTRUDERS )
{
SERIAL_ERROR_START ;
SERIAL_ERROR ( ( int ) e ) ;
SERIAL_ERRORLNPGM ( " - Invalid extruder number! " ) ;
kill ( ) ;
}
if ( heater_ttbl_map [ e ] ! = 0 )
{
int raw = 0 ;
int raw = 0 ;
byte i ;
byte i ;
short ( * tt ) [ ] [ 2 ] = ( short ( * ) [ ] [ 2 ] ) ( heater_ttbl_map [ e ] ) ;
for ( i = 1 ; i < NUMTEMPS_HEATER_0 ; i + + )
for ( i = 1 ; i < heater_ttbllen_map[ e ] ; i + + )
{
{
if ( PGM_RD_W ( heater_0_temptable [ i ] [ 1 ] ) < celsius )
if ( PGM_RD_W ( ( * tt ) [ i ] [ 1 ] ) < celsius )
{
{
raw = PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 0 ] ) +
raw = PGM_RD_W ( ( * tt ) [ i - 1 ] [ 0 ] ) +
( celsius - PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 1 ] ) ) *
( celsius - PGM_RD_W ( ( * tt ) [ i - 1 ] [ 1 ] ) ) *
( PGM_RD_W ( heater_0_temptable [ i ] [ 0 ] ) - PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 0 ] ) ) /
( PGM_RD_W ( ( * tt ) [ i ] [ 0 ] ) - PGM_RD_W ( ( * tt ) [ i - 1 ] [ 0 ] ) ) /
( PGM_RD_W ( heater_0_temptable [ i ] [ 1 ] ) - PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 1 ] ) ) ;
( PGM_RD_W ( ( * tt ) [ i ] [ 1 ] ) - PGM_RD_W ( ( * tt ) [ i - 1 ] [ 1 ] ) ) ;
break ;
break ;
}
}
}
}
// Overflow: Set to last value in the table
// Overflow: Set to last value in the table
if ( i = = NUMTEMPS_HEATER_0) raw = PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 0 ] ) ;
if ( i = = heater_ttbllen_map[ e ] ) raw = PGM_RD_W ( ( * tt ) [ i - 1 ] [ 0 ] ) ;
return ( 1023 * OVERSAMPLENR ) - raw ;
return ( 1023 * OVERSAMPLENR ) - raw ;
# elif defined HEATER_0_USES_AD595
}
return celsius * ( 1024.0 / ( 5.0 * 100.0 ) ) * OVERSAMPLENR ;
return celsius * ( 1024.0 / ( 5.0 * 100.0 ) ) * OVERSAMPLENR ;
# endif
}
}
// Takes bed temperature value as input and returns corresponding raw value.
// Takes bed temperature value as input and returns corresponding raw value.
@ -258,12 +294,11 @@ int temp2analog(int celsius) {
// This is needed because PID in hydra firmware hovers around a given analog value, not a temp value.
// This is needed because PID in hydra firmware hovers around a given analog value, not a temp value.
// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
int temp2analogBed ( int celsius ) {
int temp2analogBed ( int celsius ) {
# ifdef BED_USES_THERMISTOR
# ifdef BED_USES_THERMISTOR
int raw = 0 ;
int raw = 0 ;
byte i ;
byte i ;
for ( i = 1 ; i < BNUMTEMPS ; i + + )
for ( i = 1 ; i < bedtemptable_len ; i + + )
{
{
if ( PGM_RD_W ( bedtemptable [ i ] [ 1 ] ) < celsius )
if ( PGM_RD_W ( bedtemptable [ i ] [ 1 ] ) < celsius )
{
{
@ -277,45 +312,52 @@ int temp2analogBed(int celsius) {
}
}
// Overflow: Set to last value in the table
// Overflow: Set to last value in the table
if ( i = = BNUMTEMPS ) raw = PGM_RD_W ( bedtemptable [ i - 1 ] [ 0 ] ) ;
if ( i = = bedtemptable_len ) raw = PGM_RD_W ( bedtemptable [ i - 1 ] [ 0 ] ) ;
return ( 1023 * OVERSAMPLENR ) - raw ;
return ( 1023 * OVERSAMPLENR ) - raw ;
# elif defined BED_USES_AD595
# elif defined BED_USES_AD595
return lround ( celsius * ( 1024.0 * OVERSAMPLENR / ( 5.0 * 100.0 ) ) ) ;
return lround ( celsius * ( 1024.0 * OVERSAMPLENR / ( 5.0 * 100.0 ) ) ) ;
# else
# else
# warning No heater-type defined for the bed.
# warning No heater-type defined for the bed.
# endif
return 0 ;
return 0 ;
# endif
}
}
// Derived from RepRap FiveD extruder::getTemperature()
// Derived from RepRap FiveD extruder::getTemperature()
// For hot end temperature measurement.
// For hot end temperature measurement.
float analog2temp ( int raw ) {
float analog2temp ( int raw , uint8_t e ) {
# ifdef HEATER_0_USES_THERMISTOR
if ( e > = EXTRUDERS )
{
SERIAL_ERROR_START ;
SERIAL_ERROR ( ( int ) e ) ;
SERIAL_ERRORLNPGM ( " - Invalid extruder number ! " ) ;
kill ( ) ;
}
if ( heater_ttbl_map [ e ] ! = 0 )
{
float celsius = 0 ;
float celsius = 0 ;
byte i ;
byte i ;
short ( * tt ) [ ] [ 2 ] = ( short ( * ) [ ] [ 2 ] ) ( heater_ttbl_map [ e ] ) ;
raw = ( 1023 * OVERSAMPLENR ) - raw ;
raw = ( 1023 * OVERSAMPLENR ) - raw ;
for ( i = 1 ; i < NUMTEMPS_HEATER_0 ; i + + )
for ( i = 1 ; i < heater_ttbllen_map[ e ] ; i + + )
{
{
if ( PGM_RD_W ( heater_0_temptable [ i ] [ 0 ] ) > raw )
if ( PGM_RD_W ( ( * tt ) [ i ] [ 0 ] ) > raw )
{
{
celsius = PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 1 ] ) +
celsius = PGM_RD_W ( ( * tt ) [ i - 1 ] [ 1 ] ) +
( raw - PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 0 ] ) ) *
( raw - PGM_RD_W ( ( * tt ) [ i - 1 ] [ 0 ] ) ) *
( float ) ( PGM_RD_W ( heater_0_temptable [ i ] [ 1 ] ) - PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 1 ] ) ) /
( float ) ( PGM_RD_W ( ( * tt ) [ i ] [ 1 ] ) - PGM_RD_W ( ( * tt ) [ i - 1 ] [ 1 ] ) ) /
( float ) ( PGM_RD_W ( heater_0_temptable [ i ] [ 0 ] ) - PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 0 ] ) ) ;
( float ) ( PGM_RD_W ( ( * tt ) [ i ] [ 0 ] ) - PGM_RD_W ( ( * tt ) [ i - 1 ] [ 0 ] ) ) ;
break ;
break ;
}
}
}
}
// Overflow: Set to last value in the table
// Overflow: Set to last value in the table
if ( i = = NUMTEMPS_HEATER_0) celsius = PGM_RD_W ( heater_0_temptable [ i - 1 ] [ 1 ] ) ;
if ( i = = heater_ttbllen_map[ e ] ) celsius = PGM_RD_W ( ( * tt ) [ i - 1 ] [ 1 ] ) ;
return celsius ;
return celsius ;
# elif defined HEATER_0_USES_AD595
}
return raw * ( ( 5.0 * 100.0 ) / 1024.0 ) / OVERSAMPLENR ;
return raw * ( ( 5.0 * 100.0 ) / 1024.0 ) / OVERSAMPLENR ;
# else
# error PLEASE DEFINE HEATER TYPE
# endif
}
}
// Derived from RepRap FiveD extruder::getTemperature()
// Derived from RepRap FiveD extruder::getTemperature()
@ -327,7 +369,7 @@ float analog2tempBed(int raw) {
raw = ( 1023 * OVERSAMPLENR ) - raw ;
raw = ( 1023 * OVERSAMPLENR ) - raw ;
for ( i = 1 ; i < BNUMTEMPS ; i + + )
for ( i = 1 ; i < bedtemptable_len ; i + + )
{
{
if ( PGM_RD_W ( bedtemptable [ i ] [ 0 ] ) > raw )
if ( PGM_RD_W ( bedtemptable [ i ] [ 0 ] ) > raw )
{
{
@ -341,7 +383,7 @@ float analog2tempBed(int raw) {
}
}
// Overflow: Set to last value in the table
// Overflow: Set to last value in the table
if ( i = = BNUMTEMPS ) celsius = PGM_RD_W ( bedtemptable [ i - 1 ] [ 1 ] ) ;
if ( i = = bedtemptable_len ) celsius = PGM_RD_W ( bedtemptable [ i - 1 ] [ 1 ] ) ;
return celsius ;
return celsius ;
@ -355,6 +397,19 @@ float analog2tempBed(int raw) {
void tp_init ( )
void tp_init ( )
{
{
// Finish init of mult extruder arrays
for ( int e = 0 ; e < EXTRUDERS ; e + + ) {
// populate with the first value
# ifdef WATCHPERIOD
watch_raw [ e ] = watch_raw [ 0 ] ;
# endif
maxttemp [ e ] = maxttemp [ 0 ] ;
# ifdef PIDTEMP
temp_iState_min [ e ] = 0.0 ;
temp_iState_max [ e ] = PID_INTEGRAL_DRIVE_MAX / Ki ;
# endif //PIDTEMP
}
# if (HEATER_0_PIN > -1)
# if (HEATER_0_PIN > -1)
SET_OUTPUT ( HEATER_0_PIN ) ;
SET_OUTPUT ( HEATER_0_PIN ) ;
# endif
# endif
@ -364,11 +419,12 @@ void tp_init()
# if (HEATER_2_PIN > -1)
# if (HEATER_2_PIN > -1)
SET_OUTPUT ( HEATER_2_PIN ) ;
SET_OUTPUT ( HEATER_2_PIN ) ;
# endif
# endif
# if (HEATER_BED_PIN > -1)
# ifdef PIDTEMP
SET_OUTPUT ( HEATER_BED_PIN ) ;
temp_iState_min = 0.0 ;
# endif
temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki ;
# if (FAN_PIN > -1)
# endif //PIDTEMP
SET_OUTPUT ( FAN_PIN ) ;
# endif
// Set analog inputs
// Set analog inputs
ADCSRA = 1 < < ADEN | 1 < < ADSC | 1 < < ADIF | 0x07 ;
ADCSRA = 1 < < ADEN | 1 < < ADSC | 1 < < ADIF | 0x07 ;
@ -381,7 +437,6 @@ void tp_init()
DIDR0 | = 1 < < TEMP_0_PIN ;
DIDR0 | = 1 < < TEMP_0_PIN ;
# else
# else
DIDR2 | = 1 < < ( TEMP_0_PIN - 8 ) ;
DIDR2 | = 1 < < ( TEMP_0_PIN - 8 ) ;
ADCSRB = 1 < < MUX5 ;
# endif
# endif
# endif
# endif
# if (TEMP_1_PIN > -1)
# if (TEMP_1_PIN > -1)
@ -389,7 +444,6 @@ void tp_init()
DIDR0 | = 1 < < TEMP_1_PIN ;
DIDR0 | = 1 < < TEMP_1_PIN ;
# else
# else
DIDR2 | = 1 < < ( TEMP_1_PIN - 8 ) ;
DIDR2 | = 1 < < ( TEMP_1_PIN - 8 ) ;
ADCSRB = 1 < < MUX5 ;
# endif
# endif
# endif
# endif
# if (TEMP_2_PIN > -1)
# if (TEMP_2_PIN > -1)
@ -397,7 +451,13 @@ void tp_init()
DIDR0 | = 1 < < TEMP_2_PIN ;
DIDR0 | = 1 < < TEMP_2_PIN ;
# else
# else
DIDR2 = 1 < < ( TEMP_2_PIN - 8 ) ;
DIDR2 = 1 < < ( TEMP_2_PIN - 8 ) ;
ADCSRB = 1 < < MUX5 ;
# endif
# endif
# if (TEMP_BED_PIN > -1)
# if TEMP_BED_PIN < 8
DIDR0 | = 1 < < TEMP_BED_PIN ;
# else
DIDR2 | = 1 < < ( TEMP_BED_PIN - 8 ) ;
# endif
# endif
# endif
# endif
@ -407,27 +467,34 @@ void tp_init()
TIMSK0 | = ( 1 < < OCIE0B ) ;
TIMSK0 | = ( 1 < < OCIE0B ) ;
// Wait for temperature measurement to settle
// Wait for temperature measurement to settle
delay ( 2 0 0) ;
delay ( 2 5 0) ;
# ifdef HEATER_0_MINTEMP
# ifdef HEATER_0_MINTEMP
minttemp _0 = temp2analog ( HEATER_0_MINTEMP ) ;
minttemp [ 0 ] = temp2analog ( HEATER_0_MINTEMP , 0 ) ;
# endif //MINTEMP
# endif //MINTEMP
# ifdef HEATER_0_MAXTEMP
# ifdef HEATER_0_MAXTEMP
maxttemp _0 = temp2analog ( HEATER_0_MAXTEMP ) ;
maxttemp [ 0 ] = temp2analog ( HEATER_0_MAXTEMP , 0 ) ;
# endif //MAXTEMP
# endif //MAXTEMP
# ifdef HEATER_1_MINTEMP
# if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
minttemp_1 = temp2analog ( HEATER_1_MINTEMP ) ;
minttemp [ 1 ] = temp2analog ( HEATER_1_MINTEMP , 1 ) ;
# endif //MINTEMP
# endif // MINTEMP 1
# ifdef HEATER_1_MAXTEMP
# if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
maxttemp_1 = temp2analog ( HEATER_1_MAXTEMP ) ;
maxttemp [ 1 ] = temp2analog ( HEATER_1_MAXTEMP , 1 ) ;
# endif //MAXTEMP
# endif //MAXTEMP 1
# if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
minttemp [ 2 ] = temp2analog ( HEATER_2_MINTEMP , 2 ) ;
# endif //MINTEMP 2
# if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
maxttemp [ 2 ] = temp2analog ( HEATER_2_MAXTEMP , 2 ) ;
# endif //MAXTEMP 2
# ifdef BED_MINTEMP
# ifdef BED_MINTEMP
bed_minttemp = temp2analog ( BED_MINTEMP ) ;
bed_minttemp = temp2analog Bed ( BED_MINTEMP ) ;
# endif //BED_MINTEMP
# endif //BED_MINTEMP
# ifdef BED_MAXTEMP
# ifdef BED_MAXTEMP
bed_maxttemp = temp2analog ( BED_MAXTEMP ) ;
bed_maxttemp = temp2analog Bed ( BED_MAXTEMP ) ;
# endif //BED_MAXTEMP
# endif //BED_MAXTEMP
}
}
@ -436,15 +503,17 @@ void tp_init()
void setWatch ( )
void setWatch ( )
{
{
# ifdef WATCHPERIOD
# ifdef WATCHPERIOD
if ( isHeatingHotend0 ( ) )
int t = 0 ;
for ( int e = 0 ; e < EXTRUDERS ; e + + )
{
{
watchmillis = max ( 1 , millis ( ) ) ;
if ( isHeatingHotend ( e ) )
watch_oldtemp [ TEMPSENSOR_HOTEND_0 ] = degHotend ( 0 ) ;
watch_oldtemp [ TEMPSENSOR_HOTEND_0 ] = degHotend ( 0 ) ;
{
t = max ( t , millis ( ) ) ;
watch_raw [ e ] = current_raw [ e ] ;
}
}
}
else
watchmillis = t ;
{
watchmillis = 0 ;
}
# endif
# endif
}
}
@ -453,6 +522,7 @@ void disable_heater()
{
{
# if TEMP_0_PIN > -1
# if TEMP_0_PIN > -1
target_raw [ 0 ] = 0 ;
target_raw [ 0 ] = 0 ;
soft_pwm [ 0 ] = 0 ;
# if HEATER_0_PIN > -1
# if HEATER_0_PIN > -1
digitalWrite ( HEATER_0_PIN , LOW ) ;
digitalWrite ( HEATER_0_PIN , LOW ) ;
# endif
# endif
@ -460,6 +530,7 @@ void disable_heater()
# if TEMP_1_PIN > -1
# if TEMP_1_PIN > -1
target_raw [ 1 ] = 0 ;
target_raw [ 1 ] = 0 ;
soft_pwm [ 1 ] = 0 ;
# if HEATER_1_PIN > -1
# if HEATER_1_PIN > -1
digitalWrite ( HEATER_1_PIN , LOW ) ;
digitalWrite ( HEATER_1_PIN , LOW ) ;
# endif
# endif
@ -467,10 +538,38 @@ void disable_heater()
# if TEMP_2_PIN > -1
# if TEMP_2_PIN > -1
target_raw [ 2 ] = 0 ;
target_raw [ 2 ] = 0 ;
soft_pwm [ 2 ] = 0 ;
# if HEATER_2_PIN > -1
# if HEATER_2_PIN > -1
digitalWrite ( HEATER_2_PIN , LOW ) ;
digitalWrite ( HEATER_2_PIN , LOW ) ;
# endif
# endif
# endif
# endif
# if TEMP_BED_PIN > -1
target_raw_bed = 0 ;
# if HEATER_BED_PIN > -1
digitalWrite ( HEATER_BED_PIN , LOW ) ;
# endif
# endif
}
void max_temp_error ( uint8_t e ) {
digitalWrite ( heater_pin_map [ e ] , 0 ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLN ( e ) ;
SERIAL_ERRORLNPGM ( " : Extruder switched off. MAXTEMP triggered ! " ) ;
}
void min_temp_error ( uint8_t e ) {
digitalWrite ( heater_pin_map [ e ] , 0 ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLN ( e ) ;
SERIAL_ERRORLNPGM ( " : Extruder switched off. MINTEMP triggered ! " ) ;
}
void bed_max_temp_error ( void ) {
digitalWrite ( HEATER_BED_PIN , 0 ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( " Temperature heated bed switched off. MAXTEMP triggered !! " ) ;
}
}
// Timer 0 is shared with millies
// Timer 0 is shared with millies
@ -481,7 +580,35 @@ ISR(TIMER0_COMPB_vect)
static unsigned long raw_temp_0_value = 0 ;
static unsigned long raw_temp_0_value = 0 ;
static unsigned long raw_temp_1_value = 0 ;
static unsigned long raw_temp_1_value = 0 ;
static unsigned long raw_temp_2_value = 0 ;
static unsigned long raw_temp_2_value = 0 ;
static unsigned long raw_temp_bed_value = 0 ;
static unsigned char temp_state = 0 ;
static unsigned char temp_state = 0 ;
static unsigned char pwm_count = 1 ;
static unsigned char soft_pwm_0 ;
static unsigned char soft_pwm_1 ;
static unsigned char soft_pwm_2 ;
if ( pwm_count = = 0 ) {
soft_pwm_0 = soft_pwm [ 0 ] ;
if ( soft_pwm_0 > 0 ) WRITE ( HEATER_0_PIN , 1 ) ;
# if EXTRUDERS > 1
soft_pwm_1 = soft_pwm [ 1 ] ;
if ( soft_pwm_1 > 0 ) WRITE ( HEATER_1_PIN , 1 ) ;
# endif
# if EXTRUDERS > 2
soft_pwm_2 = soft_pwm [ 2 ] ;
if ( soft_pwm_2 > 0 ) WRITE ( HEATER_2_PIN , 1 ) ;
# endif
}
if ( soft_pwm_0 < = pwm_count ) WRITE ( HEATER_0_PIN , 0 ) ;
# if EXTRUDERS > 1
if ( soft_pwm_1 < = pwm_count ) WRITE ( HEATER_1_PIN , 0 ) ;
# endif
# if EXTRUDERS > 2
if ( soft_pwm_2 < = pwm_count ) WRITE ( HEATER_2_PIN , 0 ) ;
# endif
pwm_count + + ;
pwm_count & = 0x7f ;
switch ( temp_state ) {
switch ( temp_state ) {
case 0 : // Prepare TEMP_0
case 0 : // Prepare TEMP_0
@ -505,7 +632,26 @@ ISR(TIMER0_COMPB_vect)
# endif
# endif
temp_state = 2 ;
temp_state = 2 ;
break ;
break ;
case 2 : // Prepare TEMP_1
case 2 : // Prepare TEMP_BED
# if (TEMP_BED_PIN > -1)
# if TEMP_BED_PIN > 7
ADCSRB = 1 < < MUX5 ;
# endif
ADMUX = ( ( 1 < < REFS0 ) | ( TEMP_BED_PIN & 0x07 ) ) ;
ADCSRA | = 1 < < ADSC ; // Start conversion
# endif
# ifdef ULTIPANEL
buttons_check ( ) ;
# endif
temp_state = 3 ;
break ;
case 3 : // Measure TEMP_BED
# if (TEMP_BED_PIN > -1)
raw_temp_bed_value + = ADC ;
# endif
temp_state = 4 ;
break ;
case 4 : // Prepare TEMP_1
# if (TEMP_1_PIN > -1)
# if (TEMP_1_PIN > -1)
# if TEMP_1_PIN > 7
# if TEMP_1_PIN > 7
ADCSRB = 1 < < MUX5 ;
ADCSRB = 1 < < MUX5 ;
@ -518,15 +664,15 @@ ISR(TIMER0_COMPB_vect)
# ifdef ULTIPANEL
# ifdef ULTIPANEL
buttons_check ( ) ;
buttons_check ( ) ;
# endif
# endif
temp_state = 3 ;
temp_state = 5 ;
break ;
break ;
case 3 : // Measure TEMP_1
case 5 : // Measure TEMP_1
# if (TEMP_1_PIN > -1)
# if (TEMP_1_PIN > -1)
raw_temp_1_value + = ADC ;
raw_temp_1_value + = ADC ;
# endif
# endif
temp_state = 4 ;
temp_state = 6 ;
break ;
break ;
case 4 : // Prepare TEMP_2
case 6 : // Prepare TEMP_2
# if (TEMP_2_PIN > -1)
# if (TEMP_2_PIN > -1)
# if TEMP_2_PIN > 7
# if TEMP_2_PIN > 7
ADCSRB = 1 < < MUX5 ;
ADCSRB = 1 < < MUX5 ;
@ -539,22 +685,22 @@ ISR(TIMER0_COMPB_vect)
# ifdef ULTIPANEL
# ifdef ULTIPANEL
buttons_check ( ) ;
buttons_check ( ) ;
# endif
# endif
temp_state = 5 ;
temp_state = 7 ;
break ;
break ;
case 5 : // Measure TEMP_2
case 7 : // Measure TEMP_2
# if (TEMP_2_PIN > -1)
# if (TEMP_2_PIN > -1)
raw_temp_2_value + = ADC ;
raw_temp_2_value + = ADC ;
# endif
# endif
temp_state = 0 ;
temp_state = 0 ;
temp_count + + ;
temp_count + + ;
break ;
break ;
default :
// default:
SERIAL_ERROR_START ;
// SERIAL_ERROR_START;
SERIAL_ERRORLNPGM ( " Temp measurement error! " ) ;
// SERIAL_ERRORLNPGM("Temp measurement error!");
break ;
// break;
}
}
if ( temp_count > = 16 ) // 6 ms * 16 = 96 ms.
if ( temp_count > = 16 ) // 8 ms * 16 = 128 ms.
{
{
# ifdef HEATER_0_USES_AD595
# ifdef HEATER_0_USES_AD595
current_raw [ 0 ] = raw_temp_0_value ;
current_raw [ 0 ] = raw_temp_0_value ;
@ -562,16 +708,26 @@ ISR(TIMER0_COMPB_vect)
current_raw [ 0 ] = 16383 - raw_temp_0_value ;
current_raw [ 0 ] = 16383 - raw_temp_0_value ;
# endif
# endif
# if EXTRUDERS > 1
# ifdef HEATER_1_USES_AD595
# ifdef HEATER_1_USES_AD595
current_raw [ 1 ] = raw_temp_1_value ;
# else
current_raw [ 1 ] = 16383 - raw_temp_1_value ;
# endif
# endif
# if EXTRUDERS > 2
# ifdef HEATER_2_USES_AD595
current_raw [ 2 ] = raw_temp_2_value ;
current_raw [ 2 ] = raw_temp_2_value ;
# else
# else
current_raw [ 2 ] = 16383 - raw_temp_2_value ;
current_raw [ 2 ] = 16383 - raw_temp_2_value ;
# endif
# endif
# endif
# ifdef BED_USES_AD595
# ifdef BED_USES_AD595
current_raw [ 1 ] = raw_temp_1_value ;
current_raw _bed = raw_temp_bed _value;
# else
# else
current_raw [ 1 ] = 16383 - raw_temp_1 _value;
current_raw _bed = 16383 - raw_temp_bed _value;
# endif
# endif
temp_meas_ready = true ;
temp_meas_ready = true ;
@ -579,77 +735,28 @@ ISR(TIMER0_COMPB_vect)
raw_temp_0_value = 0 ;
raw_temp_0_value = 0 ;
raw_temp_1_value = 0 ;
raw_temp_1_value = 0 ;
raw_temp_2_value = 0 ;
raw_temp_2_value = 0 ;
# ifdef HEATER_0_MAXTEMP
raw_temp_bed_value = 0 ;
# if (HEATER_0_PIN > -1)
if ( current_raw [ TEMPSENSOR_HOTEND_0 ] > = maxttemp_0 ) {
for ( unsigned char e = 0 ; e < EXTRUDERS ; e + + ) {
target_raw [ TEMPSENSOR_HOTEND_0 ] = 0 ;
if ( current_raw [ e ] > = maxttemp [ e ] ) {
digitalWrite ( HEATER_0_PIN , 0 ) ;
target_raw [ e ] = 0 ;
SERIAL_ERROR_START ;
max_temp_error ( e ) ;
SERIAL_ERRORLNPGM ( " Temperature extruder 0 switched off. MAXTEMP triggered !! " ) ;
kill ( ) ; ;
}
if ( current_raw [ e ] < = minttemp [ e ] ) {
target_raw [ e ] = 0 ;
min_temp_error ( e ) ;
kill ( ) ;
kill ( ) ;
}
}
# endif
}
# endif
# ifdef HEATER_1_MAXTEMP
# if (HEATER_1_PIN > -1)
if ( current_raw [ TEMPSENSOR_HOTEND_1 ] > = maxttemp_1 ) {
target_raw [ TEMPSENSOR_HOTEND_1 ] = 0 ;
digitalWrite ( HEATER_2_PIN , 0 ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( " Temperature extruder 1 switched off. MAXTEMP triggered !! " ) ;
kill ( ) ;
}
# endif
# endif //MAXTEMP
# ifdef HEATER_0_MINTEMP
# if (HEATER_0_PIN > -1)
if ( current_raw [ TEMPSENSOR_HOTEND_0 ] < = minttemp_0 ) {
target_raw [ TEMPSENSOR_HOTEND_0 ] = 0 ;
digitalWrite ( HEATER_0_PIN , 0 ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( " Temperature extruder 0 switched off. MINTEMP triggered !! " ) ;
kill ( ) ;
}
# endif
# endif
# ifdef HEATER_1_MINTEMP
# if (HEATER_2_PIN > -1)
if ( current_raw [ TEMPSENSOR_HOTEND_1 ] < = minttemp_1 ) {
target_raw [ TEMPSENSOR_HOTEND_1 ] = 0 ;
digitalWrite ( HEATER_2_PIN , 0 ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( " Temperature extruder 1 switched off. MINTEMP triggered !! " ) ;
kill ( ) ;
}
# endif
# endif //MAXTEMP
# ifdef BED_MINTEMP
# if (HEATER_1_PIN > -1)
if ( current_raw [ 1 ] < = bed_minttemp ) {
target_raw [ 1 ] = 0 ;
digitalWrite ( HEATER_1_PIN , 0 ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( " Temperatur heated bed switched off. MINTEMP triggered !! " ) ;
kill ( ) ;
}
# endif
# endif
# ifdef BED_MAXTEMP
# if defined(BED_MAXTEMP) && (HEATER_BED_PIN > -1)
# if (HEATER_1_PIN > -1)
if ( current_raw_bed > = bed_maxttemp ) {
if ( current_raw [ 1 ] > = bed_maxttemp ) {
target_raw_bed = 0 ;
target_raw [ 1 ] = 0 ;
bed_max_temp_error ( ) ;
digitalWrite ( HEATER_1_PIN , 0 ) ;
kill ( ) ;
SERIAL_ERROR_START ;
}
SERIAL_ERRORLNPGM ( " Temperature heated bed switched off. MAXTEMP triggered !! " ) ;
# endif
kill ( ) ;
}
# endif
# endif
}
}
}
}