Merge pull request #206 from kliment/experimental

Merge experimental into master
This commit is contained in:
kliment 2012-10-14 12:05:58 -07:00
commit de2feb0cac
13 changed files with 1137 additions and 355 deletions

View file

@ -7,6 +7,7 @@
// MEGA/RAMPS up to 1.2 = 3,
// RAMPS 1.3/1.4 = 33
// Gen6 = 5,
// Gen6 deluxe = 51
// Sanguinololu up to 1.1 = 6
// Sanguinololu 1.2 and above = 62
// Gen 7 @ 16MHZ only= 7
@ -152,6 +153,10 @@ const int NUM_AXIS = 4; // The axis order in all axis related arrays is X, Y, Z,
#define MAX_STEP_FREQUENCY 30000 // Max step frequency
//For the retract (negative Extruder) move this maxiumum Limit of Feedrate is used
//The next positive Extruder move use also this Limit,
//then for the next (second after retract) move the original Maximum (_MAX_FEEDRATE) Limit is used
#define MAX_RETRACT_FEEDRATE 100 //mm/sec
//-----------------------------------------------------------------------
//// Not used at the Moment
@ -166,7 +171,9 @@ const int NUM_AXIS = 4; // The axis order in all axis related arrays is X, Y, Z,
//#define STEP_DELAY_RATIO 0.25
///Oscillation reduction. Forces x,y,or z axis to be stationary for ## ms before allowing axis to switch direcitons. Alternative method to prevent skipping steps. Uncomment the line below to activate.
// At this Version with Planner this Function ist not used
//#define RAPID_OSCILLATION_REDUCTION
#ifdef RAPID_OSCILLATION_REDUCTION
const long min_time_before_dir_change = 30; //milliseconds
#endif
@ -179,6 +186,7 @@ const long min_time_before_dir_change = 30; //milliseconds
#define _RETRACT_ACCELERATION 2000 // Extruder Normal acceleration mm/s^2
#define _MAX_XY_JERK 20.0
#define _MAX_Z_JERK 0.4
#define _MAX_E_JERK 5.0 // (mm/sec)
//#define _MAX_START_SPEED_UNITS_PER_SECOND {25.0,25.0,0.2,10.0}
#define _MAX_ACCELERATION_UNITS_PER_SQ_SECOND {5000,5000,50,5000} // X, Y, Z and E max acceleration in mm/s^2 for printing moves or retracts
@ -186,11 +194,13 @@ const long min_time_before_dir_change = 30; //milliseconds
// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end
// of the buffer and all stops. This should not be much greater than zero and should only be changed
// if unwanted behavior is observed on a user's machine when running at very slow speeds.
#define MINIMUM_PLANNER_SPEED 2.0 // (mm/sec)
#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec)
#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate
#define DEFAULT_MINTRAVELFEEDRATE 0.0
#define _MIN_SEG_TIME 20000
// If defined the movements slow down when the look ahead buffer is only half full
#define SLOWDOWN
@ -230,6 +240,26 @@ const int dropsegments=5; //everything with less than this number of steps will
//After this count of steps a new SIN / COS caluclation is startet to correct the circle interpolation
#define N_ARC_CORRECTION 25
//-----------------------------------------------------------------------
//// FANCONTROL WITH SOFT PWM
//-----------------------------------------------------------------------
//With this option its possible to drive the fan with SOFT PWM (500hz) and use
//every Digital output for it, main usage for Sanguinololu
#define FAN_SOFT_PWM
//-----------------------------------------------------------------------
//// MINIMUM START SPEED FOR FAN
//-----------------------------------------------------------------------
//Minimum start speed for FAN when the last speed was zero
//Set to 0 to deaktivate
//If value is set the fan will drive with this minimum speed for MINIMUM_FAN_START_TIME
#define MINIMUM_FAN_START_SPEED 0
//This is the time how long the minimum FAN speed is set
#define MINIMUM_FAN_START_TIME 6000 //6sec
//-----------------------------------------------------------------------
//// HEATERCONTROL AND PID PARAMETERS
//-----------------------------------------------------------------------
@ -261,6 +291,10 @@ const int dropsegments=5; //everything with less than this number of steps will
//Command M601 / Command M602 Reset the MIN/MAX Value
//#define DEBUG_HEATER_TEMP
// M303 - PID relay autotune S<temperature> sets the target temperature.
// (default target temperature = 150C)
#define PID_AUTOTUNE
//PID Controler Settings
#define PID_INTEGRAL_DRIVE_MAX 80 // too big, and heater will lag after changing temperature, too small and it might not compensate enough for long-term errors
#define PID_PGAIN 2560 //256 is 1.0 // value of X means that error of 1 degree is changing PWM duty by X, probably no need to go over 25
@ -274,7 +308,7 @@ const int dropsegments=5; //everything with less than this number of steps will
#define LED_PWM_FOR_BRIGHTNESS(brightness) ((64*brightness-1384)/(300-brightness))
#endif
// Change this value (range 1-255) to limit the current to the nozzle
// Change this value (range 30-255) to limit the current to the nozzle
#define HEATER_CURRENT 255
// How often should the heater check for new temp readings, in milliseconds
@ -331,6 +365,11 @@ const int dropsegments=5; //everything with less than this number of steps will
//#define CONTROLLERFAN_PIN 23 //Pin used for the fan to cool controller, comment out to disable this function
#define CONTROLLERFAN_SEC 60 //How many seconds, after all motors were disabled, the fan should run
//This is for controlling a fan that will keep the extruder cool.
//#define EXTRUDERFAN_PIN 66 //Pin used to control the fan, comment out to disable this function
#define EXTRUDERFAN_DEC 50 //Hotend temperature from where the fan will be turned on
//#define CHAIN_OF_COMMAND 1 //Finish buffered moves before executing M42, fan speed, heater target, and so...
//-----------------------------------------------------------------------
// DEBUGING

View file

@ -17,7 +17,11 @@
* along with the Arduino Sd2Card Library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include "Sd2Card.h"
//------------------------------------------------------------------------------
#ifndef SOFTWARE_SPI

View file

@ -23,7 +23,11 @@
* \file
* Useful utility functions.
*/
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <avr/pgmspace.h>
/** Store and print a string in flash memory.*/
#define PgmPrint(x) SerialPrint_P(PSTR(x))

View file

@ -19,7 +19,11 @@
*/
#include "SdFat.h"
#include <avr/pgmspace.h>
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
//------------------------------------------------------------------------------
// callback function for date/time
void (*SdFile::dateTime_)(uint16_t* date, uint16_t* time) = NULL;

View file

@ -123,6 +123,10 @@ void check_buffer_while_arc();
void print_disk_info(void);
#endif //SDSUPPORT
#if (MINIMUM_FAN_START_SPEED > 0)
void manage_fan_start_speed(void);
#endif
#ifdef DEBUG
void log_message(char* message);
void log_bool(char* message, bool value);

File diff suppressed because it is too large Load diff

View file

@ -50,6 +50,8 @@ void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8
float millimeters_of_travel = hypot(angular_travel*radius, fabs(linear_travel));
if (millimeters_of_travel < 0.001) { return; }
uint16_t segments = floor(millimeters_of_travel/MM_PER_ARC_SEGMENT);
if(segments == 0) segments = 1;
/*
// Multiply inverse feed_rate to compensate for the fact that this movement is approximated
// by a number of discrete segments. The inverse feed_rate should be correct for the sum of

View file

@ -32,6 +32,10 @@
void controllerFan(void);
#endif
#ifdef EXTRUDERFAN_PIN
void extruderFan(void);
#endif
// Manage heater variables. For a thermistor or AD595 thermocouple, raw values refer to the
// reading from the analog pin. For a MAX6675 thermocouple, the raw value is the temperature in 0.25
// degree increments (i.e. 100=25 deg).
@ -50,8 +54,8 @@ unsigned long previous_millis_heater, previous_millis_bed_heater, previous_milli
#ifdef PIDTEMP
volatile unsigned char g_heater_pwm_val = 0;
unsigned char PWM_off_time = 0;
unsigned char PWM_out_on = 0;
//unsigned char PWM_off_time = 0;
//unsigned char PWM_out_on = 0;
int temp_iState = 0;
int temp_dState = 0;
@ -62,11 +66,15 @@ unsigned long previous_millis_heater, previous_millis_bed_heater, previous_milli
//int output;
int error;
int heater_duty = 0;
const int temp_iState_min = 256L * -PID_INTEGRAL_DRIVE_MAX / PID_IGAIN;
const int temp_iState_max = 256L * PID_INTEGRAL_DRIVE_MAX / PID_IGAIN;
int temp_iState_min = 256L * -PID_INTEGRAL_DRIVE_MAX / PID_IGAIN;
int temp_iState_max = 256L * PID_INTEGRAL_DRIVE_MAX / PID_IGAIN;
#endif
#if defined(FAN_SOFT_PWM) && (FAN_PIN > -1)
volatile unsigned char g_fan_pwm_val = 0;
#endif
#ifdef AUTOTEMP
float autotemp_max=AUTO_TEMP_MAX;
float autotemp_min=AUTO_TEMP_MIN;
@ -155,90 +163,348 @@ int read_max6675()
#endif
#ifdef PID_SOFT_PWM
//------------------------------------------------------------------------
// Soft PWM for Heater and FAN
//------------------------------------------------------------------------
#if defined(PID_SOFT_PWM) || (defined(FAN_SOFT_PWM) && (FAN_PIN > -1))
void init_Timer2_softpwm(void)
{
// This is a simple SOFT PWM with 500 Hz for Extruder Heating
TIFR2 = (1 << TOV2); // clear interrupt flag
TCCR2B = (1 << CS22) | (1 << CS20); // start timer (ck/128 prescalar)
TCCR2A = (1 << WGM21); // CTC mode
OCR2A = 128; // We want to have at least 30Hz or else it gets choppy
TIMSK2 = (1 << OCIE2A); // enable timer2 output compare match interrupt
TCCR2A = 0;//(1 << WGM21); // Normal mode
TIMSK2 |= (1 << TOIE2);
#ifdef PID_SOFT_PWM
OCR2A = 128; // We want to have at least 500Hz or else it gets choppy
TIMSK2 |= (1 << OCIE2A); // enable timer2 output compare match interrupt
#endif
#if defined(FAN_SOFT_PWM) && (FAN_PIN > -1)
OCR2B = 128; // We want to have at least 500Hz or else it gets choppy
TIMSK2 |= (1 << OCIE2B); // enable timer2 output compare match interrupt
#endif
}
#endif
ISR(TIMER2_COMPA_vect)
{
if(g_heater_pwm_val < 2)
{
#if LED_PIN > -1
WRITE(LED_PIN,LOW);
#endif
WRITE(HEATER_0_PIN,LOW);
PWM_out_on = 0;
OCR2A = 128;
}
else if(g_heater_pwm_val > 253)
#if defined(PID_SOFT_PWM) || (defined(FAN_SOFT_PWM) && (FAN_PIN > -1))
ISR(TIMER2_OVF_vect)
{
//--------------------------------------
// Soft PWM, Heater, start PWM cycle
//--------------------------------------
#ifdef PID_SOFT_PWM
if(g_heater_pwm_val >= 2)
{
#if LED_PIN > -1
WRITE(LED_PIN,HIGH);
#endif
WRITE(HEATER_0_PIN,HIGH);
PWM_out_on = 1;
OCR2A = 128;
if(g_heater_pwm_val <= 253)
OCR2A = g_heater_pwm_val;
else
OCR2A = 192;
}
else
{
if(PWM_out_on == 1)
{
#if LED_PIN > -1
WRITE(LED_PIN,LOW);
#endif
WRITE(HEATER_0_PIN,LOW);
PWM_out_on = 0;
OCR2A = PWM_off_time;
}
else
{
#if LED_PIN > -1
WRITE(LED_PIN,HIGH);
#endif
WRITE(HEATER_0_PIN,HIGH);
PWM_out_on = 1;
if(g_heater_pwm_val > 253)
{
OCR2A = 253;
PWM_off_time = 2;
}
else if(g_heater_pwm_val < 2)
{
OCR2A = 2;
PWM_off_time = 253;
}
else
{
OCR2A = g_heater_pwm_val;
PWM_off_time = 255 - g_heater_pwm_val;
}
}
#if LED_PIN > -1
WRITE(LED_PIN,LOW);
#endif
WRITE(HEATER_0_PIN,LOW);
OCR2A = 192;
}
#endif
//--------------------------------------
// Soft PWM, Fan, start PWM cycle
//--------------------------------------
#if defined(FAN_SOFT_PWM) && (FAN_PIN > -1)
if(g_fan_pwm_val >= 2)
{
#if (FAN_PIN > -1)
WRITE(FAN_PIN,HIGH);
#endif
if(g_fan_pwm_val <= 253)
OCR2B = g_fan_pwm_val;
else
OCR2B = 128;
}
else
{
#if (FAN_PIN > -1)
WRITE(FAN_PIN,LOW);
#endif
OCR2B = 128;
}
#endif
}
#endif
#ifdef PID_SOFT_PWM
ISR(TIMER2_COMPA_vect)
{
if(g_heater_pwm_val > 253)
{
#if LED_PIN > -1
WRITE(LED_PIN,HIGH);
#endif
WRITE(HEATER_0_PIN,HIGH);
}
else
{
#if LED_PIN > -1
WRITE(LED_PIN,LOW);
#endif
WRITE(HEATER_0_PIN,LOW);
}
}
#endif
#if defined(FAN_SOFT_PWM) && (FAN_PIN > -1)
ISR(TIMER2_COMPB_vect)
{
if(g_fan_pwm_val > 253)
{
#if (FAN_PIN > -1)
WRITE(FAN_PIN,HIGH);
#endif
}
else
{
#if (FAN_PIN > -1)
WRITE(FAN_PIN,LOW);
#endif
}
}
#endif
//--------------------END SOFT PWM---------------------------
//-------------------- START PID AUTOTUNE ---------------------------
// Based on PID relay test
// Thanks to Erik van der Zalm for this idea to use it for Marlin
// Some information see:
// http://brettbeauregard.com/blog/2012/01/arduino-pid-autotune-library/
//------------------------------------------------------------------
#ifdef PID_AUTOTUNE
void PID_autotune(int PIDAT_test_temp)
{
float PIDAT_input = 0;
int PIDAT_input_help = 0;
unsigned char PIDAT_count_input = 0;
float PIDAT_max, PIDAT_min;
unsigned char PIDAT_PWM_val = HEATER_CURRENT;
unsigned char PIDAT_cycles=0;
bool PIDAT_heating = true;
unsigned long PIDAT_temp_millis = millis();
unsigned long PIDAT_t1=PIDAT_temp_millis;
unsigned long PIDAT_t2=PIDAT_temp_millis;
unsigned long PIDAT_T_check_AI_val = PIDAT_temp_millis;
unsigned char PIDAT_cycle_cnt = 0;
long PIDAT_t_high;
long PIDAT_t_low;
long PIDAT_bias= HEATER_CURRENT/2;
long PIDAT_d = HEATER_CURRENT/2;
float PIDAT_Ku, PIDAT_Tu;
float PIDAT_Kp, PIDAT_Ki, PIDAT_Kd;
#define PIDAT_TIME_FACTOR ((HEATER_CHECK_INTERVAL*256.0) / 1000.0)
showString(PSTR("PID Autotune start\r\n"));
target_temp = PIDAT_test_temp;
#ifdef BED_USES_THERMISTOR
WRITE(HEATER_1_PIN,LOW);
#endif
for(;;)
{
if((millis() - PIDAT_T_check_AI_val) > 100 )
{
PIDAT_T_check_AI_val = millis();
PIDAT_cycle_cnt++;
#ifdef HEATER_USES_THERMISTOR
current_raw = analogRead(TEMP_0_PIN);
current_raw = 1023 - current_raw;
PIDAT_input_help += analog2temp(current_raw);
PIDAT_count_input++;
#elif defined HEATER_USES_AD595
current_raw = analogRead(TEMP_0_PIN);
PIDAT_input_help += analog2temp(current_raw);
PIDAT_count_input++;
#elif defined HEATER_USES_MAX6675
current_raw = read_max6675();
PIDAT_input_help += analog2temp(current_raw);
PIDAT_count_input++;
#endif
}
if(PIDAT_cycle_cnt >= 10 )
{
PIDAT_cycle_cnt = 0;
PIDAT_input = (float)PIDAT_input_help / (float)PIDAT_count_input;
PIDAT_input_help = 0;
PIDAT_count_input = 0;
PIDAT_max=max(PIDAT_max,PIDAT_input);
PIDAT_min=min(PIDAT_min,PIDAT_input);
if(PIDAT_heating == true && PIDAT_input > PIDAT_test_temp)
{
if(millis() - PIDAT_t2 > 5000)
{
PIDAT_heating = false;
PIDAT_PWM_val = (PIDAT_bias - PIDAT_d);
PIDAT_t1 = millis();
PIDAT_t_high = PIDAT_t1 - PIDAT_t2;
PIDAT_max = PIDAT_test_temp;
}
}
if(PIDAT_heating == false && PIDAT_input < PIDAT_test_temp)
{
if(millis() - PIDAT_t1 > 5000)
{
PIDAT_heating = true;
PIDAT_t2 = millis();
PIDAT_t_low = PIDAT_t2 - PIDAT_t1;
if(PIDAT_cycles > 0)
{
PIDAT_bias += (PIDAT_d*(PIDAT_t_high - PIDAT_t_low))/(PIDAT_t_low + PIDAT_t_high);
PIDAT_bias = constrain(PIDAT_bias, 20 ,HEATER_CURRENT - 20);
if(PIDAT_bias > (HEATER_CURRENT/2)) PIDAT_d = (HEATER_CURRENT - 1) - PIDAT_bias;
else PIDAT_d = PIDAT_bias;
showString(PSTR(" bias: ")); Serial.print(PIDAT_bias);
showString(PSTR(" d: ")); Serial.print(PIDAT_d);
showString(PSTR(" min: ")); Serial.print(PIDAT_min);
showString(PSTR(" max: ")); Serial.println(PIDAT_max);
if(PIDAT_cycles > 2)
{
PIDAT_Ku = (4.0*PIDAT_d)/(3.14159*(PIDAT_max-PIDAT_min));
PIDAT_Tu = ((float)(PIDAT_t_low + PIDAT_t_high)/1000.0);
showString(PSTR(" Ku: ")); Serial.print(PIDAT_Ku);
showString(PSTR(" Tu: ")); Serial.println(PIDAT_Tu);
PIDAT_Kp = 0.60*PIDAT_Ku;
PIDAT_Ki = 2*PIDAT_Kp/PIDAT_Tu;
PIDAT_Kd = PIDAT_Kp*PIDAT_Tu/8;
showString(PSTR(" Clasic PID \r\n"));
//showString(PSTR(" Kp: ")); Serial.println(PIDAT_Kp);
//showString(PSTR(" Ki: ")); Serial.println(PIDAT_Ki);
//showString(PSTR(" Kd: ")); Serial.println(PIDAT_Kd);
showString(PSTR(" CFG Kp: ")); Serial.println((unsigned int)(PIDAT_Kp*256));
showString(PSTR(" CFG Ki: ")); Serial.println((unsigned int)(PIDAT_Ki*PIDAT_TIME_FACTOR));
showString(PSTR(" CFG Kd: ")); Serial.println((unsigned int)(PIDAT_Kd*PIDAT_TIME_FACTOR));
PIDAT_Kp = 0.30*PIDAT_Ku;
PIDAT_Ki = PIDAT_Kp/PIDAT_Tu;
PIDAT_Kd = PIDAT_Kp*PIDAT_Tu/3;
showString(PSTR(" Some overshoot \r\n"));
showString(PSTR(" CFG Kp: ")); Serial.println((unsigned int)(PIDAT_Kp*256));
showString(PSTR(" CFG Ki: ")); Serial.println((unsigned int)(PIDAT_Ki*PIDAT_TIME_FACTOR));
showString(PSTR(" CFG Kd: ")); Serial.println((unsigned int)(PIDAT_Kd*PIDAT_TIME_FACTOR));
/*
PIDAT_Kp = 0.20*PIDAT_Ku;
PIDAT_Ki = 2*PIDAT_Kp/PIDAT_Tu;
PIDAT_Kd = PIDAT_Kp*PIDAT_Tu/3;
showString(PSTR(" No overshoot \r\n"));
showString(PSTR(" CFG Kp: ")); Serial.println((unsigned int)(PIDAT_Kp*256));
showString(PSTR(" CFG Ki: ")); Serial.println((unsigned int)(PIDAT_Ki*PIDAT_TIME_FACTOR));
showString(PSTR(" CFG Kd: ")); Serial.println((unsigned int)(PIDAT_Kd*PIDAT_TIME_FACTOR));
*/
}
}
PIDAT_PWM_val = (PIDAT_bias + PIDAT_d);
PIDAT_cycles++;
PIDAT_min = PIDAT_test_temp;
}
}
#ifdef PID_SOFT_PWM
g_heater_pwm_val = PIDAT_PWM_val;
#else
analogWrite_check(HEATER_0_PIN, PIDAT_PWM_val);
#if LED_PIN>-1
analogWrite_check(LED_PIN, PIDAT_PWM_val);
#endif
#endif
}
if((PIDAT_input > (PIDAT_test_temp + 55)) || (PIDAT_input > 255))
{
showString(PSTR("PID Autotune failed! Temperature to high\r\n"));
target_temp = 0;
return;
}
if(millis() - PIDAT_temp_millis > 2000)
{
PIDAT_temp_millis = millis();
showString(PSTR("ok T:"));
Serial.print(PIDAT_input);
showString(PSTR(" @:"));
Serial.println((unsigned char)PIDAT_PWM_val*1);
}
if(((millis() - PIDAT_t1) + (millis() - PIDAT_t2)) > (10L*60L*1000L*2L))
{
showString(PSTR("PID Autotune failed! timeout\r\n"));
return;
}
if(PIDAT_cycles > 5)
{
showString(PSTR("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h\r\n"));
return;
}
}
}
#endif
//---------------- END AUTOTUNE PID ------------------------------
void updatePID()
{
#ifdef PIDTEMP
temp_iState_min = (256L * -PID_INTEGRAL_DRIVE_MAX) / PID_Ki;
temp_iState_max = (256L * PID_INTEGRAL_DRIVE_MAX) / PID_Ki;
#endif
}
void manage_heater()
{
@ -247,6 +513,8 @@ int read_max6675()
if((millis() - previous_millis_monitor) > 250 )
{
previous_millis_monitor = millis();
if(manage_monitor <= 1)
{
showString(PSTR("MTEMP:"));
@ -378,7 +646,7 @@ int read_max6675()
int delta_temp = current_temp - prev_temp;
prev_temp = current_temp;
pTerm = ((long)PID_PGAIN * error) / 256;
pTerm = ((long)PID_Kp * error) / 256;
const int H0 = min(HEATER_DUTY_FOR_SETPOINT(target_temp),HEATER_CURRENT);
heater_duty = H0 + pTerm;
@ -386,7 +654,7 @@ int read_max6675()
{
temp_iState += error;
temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max);
iTerm = ((long)PID_IGAIN * temp_iState) / 256;
iTerm = ((long)PID_Ki * temp_iState) / 256;
heater_duty += iTerm;
}
@ -397,7 +665,7 @@ int read_max6675()
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);
dTerm = ((long)PID_Kd * delta_temp) / (256*log3);
heater_duty += dTerm;
heater_duty = constrain(heater_duty, 0, HEATER_CURRENT);
@ -491,6 +759,10 @@ int read_max6675()
controllerFan(); //Check if fan should be turned on to cool stepper drivers down
#endif
#ifdef EXTRUDERFAN_PIN
extruderFan(); //Check if fan should be turned on to cool extruder down
#endif
}
#if defined (HEATER_USES_THERMISTOR) || defined (BED_USES_THERMISTOR)
@ -601,3 +873,24 @@ void controllerFan()
}
#endif
#ifdef EXTRUDERFAN_PIN
unsigned long lastExtruderCheck = 0;
void extruderFan()
{
if ((millis() - lastExtruderCheck) >= 2500) //Not a time critical function, so we only check every 2500ms
{
lastExtruderCheck = millis();
if (analog2temp(current_raw) < EXTRUDERFAN_DEC)
{
WRITE(EXTRUDERFAN_PIN, LOW); //... turn the fan off
}
else
{
WRITE(EXTRUDERFAN_PIN, HIGH); //... turn the fan on
}
}
}
#endif

View file

@ -88,8 +88,13 @@ extern unsigned char manage_monitor;
extern int dTerm;
extern int error;
extern int heater_duty;
extern unsigned int PID_Kp, PID_Ki, PID_Kd;
#endif
#if defined(FAN_SOFT_PWM) && (FAN_PIN > -1)
extern volatile unsigned char g_fan_pwm_val;
#endif
#ifdef AUTOTEMP
extern float autotemp_max;
@ -112,8 +117,16 @@ extern unsigned char manage_monitor;
#ifdef PID_SOFT_PWM
#if defined(PID_SOFT_PWM) || (defined(FAN_SOFT_PWM) && (FAN_PIN > -1))
void init_Timer2_softpwm(void);
#endif
#ifdef PID_AUTOTUNE
void PID_autotune(int PIDAT_test_temp);
#endif
#ifdef PIDTEMP
void updatePID();
#endif
void manage_heater();

View file

@ -181,7 +181,7 @@
#if MOTHERBOARD == 2
#define KNOWN_BOARD 1
#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__)
#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) && !defined(__ATmega644P__) && !defined(__ATmega1284P__)
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
#endif
@ -598,6 +598,11 @@
* Gen6 pin assignment
*
****************************************************************************************/
#if MOTHERBOARD == 51
#define MOTHERBOARD 5
#define GEN6_DELUXE
#endif
#if MOTHERBOARD == 5
#define KNOWN_BOARD 1
@ -632,13 +637,18 @@
#define E_ENABLE_PIN 3 //Added @ EJE Electronics 20100715
#define TEMP_0_PIN 5 //changed @ rkoeppl 20110410
#define HEATER_0_PIN 14 //changed @ rkoeppl 20110410
#define HEATER_1_PIN -1 //changed @ rkoeppl 20110410
#ifdef GEN6_DELUXE
#define HEATER_1_PIN 1
#define TEMP_1_PIN 0
#else
#define HEATER_1_PIN -1
#define TEMP_1_PIN -1
#endif
#define SDPOWER -1
#define SDSS 17
#define LED_PIN -1 //changed @ rkoeppl 20110410
#define TEMP_1_PIN -1 //changed @ rkoeppl 20110410
#define FAN_PIN -1 //changed @ rkoeppl 20110410
#define PS_ON_PIN -1 //changed @ rkoeppl 20110410
//our pin for debugging.

View file

@ -23,27 +23,30 @@
#include "store_eeprom.h"
#include "Configuration.h"
#ifdef PIDTEMP
extern unsigned int PID_Kp, PID_Ki, PID_Kd;
#endif
#ifdef USE_EEPROM_SETTINGS
//======================================================================================
//========================= Read / Write EEPROM =======================================
template <class T> int EEPROM_writeAnything(int &ee, const T& value)
template <class T> int EEPROM_write_setting(int address, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
for (i = 0; i < (int)sizeof(value); i++)
eeprom_write_byte((unsigned char *)ee++, *p++);
eeprom_write_byte((unsigned char *)address++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int &ee, T& value)
template <class T> int EEPROM_read_setting(int address, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
for (i = 0; i < (int)sizeof(value); i++)
*p++ = eeprom_read_byte((unsigned char *)ee++);
*p++ = eeprom_read_byte((unsigned char *)address++);
return i;
}
//======================================================================================
@ -51,34 +54,34 @@ template <class T> int EEPROM_readAnything(int &ee, T& value)
void EEPROM_StoreSettings()
{
unsigned long ul_help = 20000;
unsigned int ui_help = 0;
char ver[4]= "000";
int i=EEPROM_OFFSET;
EEPROM_writeAnything(i,ver); // invalidate data first
EEPROM_writeAnything(i,axis_steps_per_unit);
EEPROM_writeAnything(i,max_feedrate);
EEPROM_writeAnything(i,max_acceleration_units_per_sq_second);
EEPROM_writeAnything(i,move_acceleration);
EEPROM_writeAnything(i,retract_acceleration);
EEPROM_writeAnything(i,minimumfeedrate);
EEPROM_writeAnything(i,mintravelfeedrate);
EEPROM_writeAnything(i,ul_help); //Min Segment Time, not used yet
EEPROM_writeAnything(i,max_xy_jerk);
EEPROM_writeAnything(i,max_z_jerk);
EEPROM_write_setting(EEPROM_OFFSET, ver); // invalidate data first
EEPROM_write_setting(axis_steps_per_unit_address, axis_steps_per_unit);
EEPROM_write_setting(max_feedrate_address, max_feedrate);
EEPROM_write_setting(max_acceleration_units_per_sq_second_address, max_acceleration_units_per_sq_second);
EEPROM_write_setting(move_acceleration_address, move_acceleration);
EEPROM_write_setting(retract_acceleration_address, retract_acceleration);
EEPROM_write_setting(minimumfeedrate_address, minimumfeedrate);
EEPROM_write_setting(mintravelfeedrate_address, mintravelfeedrate);
EEPROM_write_setting(min_seg_time_address, min_seg_time); //Min Segment Time, not used yet
EEPROM_write_setting(max_xy_jerk_address, max_xy_jerk);
EEPROM_write_setting(max_z_jerk_address, max_z_jerk);
EEPROM_write_setting(max_e_jerk_address, max_e_jerk);
//PID Settings, not used yet --> placeholder
ui_help = 2560;
EEPROM_writeAnything(i,ui_help); //Kp
ui_help = 64;
EEPROM_writeAnything(i,ui_help); //Ki
ui_help = 4096;
EEPROM_writeAnything(i,ui_help); //Kd
//PID Settings
#ifdef PIDTEMP
EEPROM_write_setting(Kp_address, PID_Kp); //Kp
EEPROM_write_setting(Ki_address, PID_Ki); //Ki
EEPROM_write_setting(Kd_address, PID_Kd); //Kd
#else
EEPROM_write_setting(Kp_address, 2048); //Kp
EEPROM_write_setting(Ki_address, 32); //Ki
EEPROM_write_setting(Kd_address, 2048); //Kd
#endif
char ver2[4]=EEPROM_VERSION;
i=EEPROM_OFFSET;
EEPROM_writeAnything(i,ver2); // validate data
EEPROM_write_setting(EEPROM_OFFSET, ver2); // validate data
showString(PSTR("Settings Stored\r\n"));
}
@ -86,7 +89,6 @@ void EEPROM_StoreSettings()
void EEPROM_printSettings()
{
// if def=true, the default values will be used
#ifdef PRINT_EEPROM_SETTING
showString(PSTR("Steps per unit:\r\n"));
showString(PSTR(" M92 X"));
@ -99,7 +101,7 @@ void EEPROM_printSettings()
Serial.println(axis_steps_per_unit[3]);
showString(PSTR("Maximum feedrates (mm/s):\r\n"));
showString(PSTR(" M203 X"));
showString(PSTR(" M202 X"));
Serial.print(max_feedrate[0]);
showString(PSTR(" Y"));
Serial.print(max_feedrate[1]);
@ -124,29 +126,32 @@ void EEPROM_printSettings()
showString(PSTR(" T"));
Serial.println(retract_acceleration);
showString(PSTR("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), X=maximum xY jerk (mm/s), Z=maximum Z jerk (mm/s)\r\n"));
showString(PSTR("Advanced variables (mm/s): S=Min feedrate, T=Min travel feedrate, X=max xY jerk, Z=max Z jerk, E=max E jerk\r\n"));
showString(PSTR(" M205 S"));
Serial.print(minimumfeedrate );
showString(PSTR(" T" ));
Serial.print(mintravelfeedrate );
// showString(PSTR(" B"));
// Serial.print(minsegmenttime );
// Serial.print(min_seg_time );
showString(PSTR(" X"));
Serial.print(max_xy_jerk );
showString(PSTR(" Z"));
Serial.println(max_z_jerk);
Serial.print(max_z_jerk);
showString(PSTR(" E"));
Serial.println(max_e_jerk);
#ifdef PIDTEMP
/*
showString(PSTR("PID settings:");
showString(PSTR(" M301 P"));
Serial.print(Kp);
showString(PSTR("PID settings:\r\n"));
showString(PSTR(" M301 P"));
Serial.print(PID_Kp);
showString(PSTR(" I"));
Serial.print(Ki);
SshowString(PSTR(" D"));
Serial.print(Kd);
*/
Serial.print(PID_Ki);
showString(PSTR(" D"));
Serial.println(PID_Kd);
#endif
#endif
@ -159,26 +164,27 @@ void EEPROM_RetrieveSettings(bool def, bool printout)
int i=EEPROM_OFFSET;
char stored_ver[4];
char ver[4]=EEPROM_VERSION;
unsigned long ul_help = 0;
EEPROM_readAnything(i,stored_ver); //read stored version
if ((!def)&&(strncmp(ver,stored_ver,3)==0))
EEPROM_read_setting(EEPROM_OFFSET,stored_ver); //read stored version
if ((!def)&&(strncmp(ver,stored_ver,3)==0))
{ // version number match
EEPROM_readAnything(i,axis_steps_per_unit);
EEPROM_readAnything(i,max_feedrate);
EEPROM_readAnything(i,max_acceleration_units_per_sq_second);
EEPROM_readAnything(i,move_acceleration);
EEPROM_readAnything(i,retract_acceleration);
EEPROM_readAnything(i,minimumfeedrate);
EEPROM_readAnything(i,mintravelfeedrate);
EEPROM_readAnything(i,ul_help); //min Segmenttime --> not used yet
EEPROM_readAnything(i,max_xy_jerk);
EEPROM_readAnything(i,max_z_jerk);
EEPROM_read_setting(axis_steps_per_unit_address, axis_steps_per_unit);
EEPROM_read_setting(max_feedrate_address, max_feedrate);
EEPROM_read_setting(max_acceleration_units_per_sq_second_address, max_acceleration_units_per_sq_second);
EEPROM_read_setting(move_acceleration_address, move_acceleration);
EEPROM_read_setting(retract_acceleration_address, retract_acceleration);
EEPROM_read_setting(minimumfeedrate_address, minimumfeedrate);
EEPROM_read_setting(mintravelfeedrate_address, mintravelfeedrate);
EEPROM_read_setting(min_seg_time_address, min_seg_time); //min Segmenttime --> not used yet
EEPROM_read_setting(max_xy_jerk_address, max_xy_jerk);
EEPROM_read_setting(max_z_jerk_address, max_z_jerk);
EEPROM_read_setting(max_e_jerk_address, max_e_jerk);
unsigned int Kp,Ki,Kd;
EEPROM_readAnything(i,Kp);
EEPROM_readAnything(i,Ki);
EEPROM_readAnything(i,Kd);
#ifdef PIDTEMP
EEPROM_read_setting(Kp_address, PID_Kp);
EEPROM_read_setting(Ki_address, PID_Ki);
EEPROM_read_setting(Kd_address, PID_Kd);
#endif
showString(PSTR("Stored settings retreived\r\n"));
}
@ -200,10 +206,18 @@ void EEPROM_RetrieveSettings(bool def, bool printout)
mintravelfeedrate=DEFAULT_MINTRAVELFEEDRATE;
max_xy_jerk=_MAX_XY_JERK;
max_z_jerk=_MAX_Z_JERK;
max_e_jerk=_MAX_E_JERK;
min_seg_time=_MIN_SEG_TIME;
#ifdef PIDTEMP
PID_Kp = PID_PGAIN;
PID_Ki = PID_IGAIN;
PID_Kd = PID_DGAIN;
#endif
showString(PSTR("Using Default settings\r\n"));
}
if(printout)
{
EEPROM_printSettings();

View file

@ -27,7 +27,7 @@
// the default values are used whenever there is a change to the data, to prevent
// wrong data being written to the variables.
// ALSO: always make sure the variables in the Store and retrieve sections are in the same order.
#define EEPROM_VERSION "S01"
#define EEPROM_VERSION "S03"
extern float axis_steps_per_unit[4];
@ -39,7 +39,23 @@ extern float mintravelfeedrate;
extern float minimumfeedrate;
extern float max_xy_jerk;
extern float max_z_jerk;
extern float max_e_jerk;
extern unsigned long min_seg_time;
#define axis_steps_per_unit_address (EEPROM_OFFSET + 4*sizeof(char))
#define max_feedrate_address (axis_steps_per_unit_address + 4*sizeof(float))
#define max_acceleration_units_per_sq_second_address (max_feedrate_address + 4*sizeof(float))
#define move_acceleration_address (max_acceleration_units_per_sq_second_address + 4*sizeof(long))
#define retract_acceleration_address (move_acceleration_address + sizeof(float))
#define mintravelfeedrate_address (retract_acceleration_address + sizeof(float))
#define minimumfeedrate_address (mintravelfeedrate_address + sizeof(float))
#define max_xy_jerk_address (minimumfeedrate_address + sizeof(float))
#define max_z_jerk_address (max_xy_jerk_address + sizeof(float))
#define max_e_jerk_address (max_z_jerk_address + sizeof(float))
#define min_seg_time_address (max_e_jerk_address + sizeof(float))
#define Kp_address (min_seg_time_address + sizeof(unsigned long))
#define Ki_address (Kp_address + sizeof(unsigned int))
#define Kd_address (Ki_address + sizeof(unsigned int))
extern void EEPROM_RetrieveSettings(bool def, bool printout );
extern void EEPROM_printSettings();

View file

@ -423,4 +423,4 @@ const short temptable_7[NUMTEMPS_7][2] = {
#error No bed thermistor table specified
#endif
#endif //THERMISTORTABLES_H_
#endif //THERMISTORTABLES_H_