From 1d0fe035f3aeb4af0e686fcb13c9a720248db462 Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Mon, 4 Aug 2014 21:44:04 -0500 Subject: [PATCH 01/22] Change pinMode to SET_INPUT or SET_OUTPUT Original code is using WRITE from fastio, but original used pinMode to set pin direction and did not use the fastio SET_INPUT or SET_OUTPUT. This caused an issue with the rotary encoder interface to boards based on teensyduino, since for teensyduino pin numbers for fastio and the usual Arduino IO are different. --- Marlin/ultralcd.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 9797b0bff1..e6774108ac 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -1133,30 +1133,30 @@ void lcd_init() lcd_implementation_init(); #ifdef NEWPANEL - pinMode(BTN_EN1,INPUT); - pinMode(BTN_EN2,INPUT); + SET_INPUT(BTN_EN1); + SET_INPUT(BTN_EN2); WRITE(BTN_EN1,HIGH); WRITE(BTN_EN2,HIGH); #if BTN_ENC > 0 - pinMode(BTN_ENC,INPUT); + SET_INPUT(BTN_ENC); WRITE(BTN_ENC,HIGH); #endif #ifdef REPRAPWORLD_KEYPAD - pinMode(SHIFT_CLK,OUTPUT); - pinMode(SHIFT_LD,OUTPUT); - pinMode(SHIFT_OUT,INPUT); + SET_OUTPUT(SHIFT_CLK); + SET_OUTPUT(SHIFT_LD); + SET_INPUT(SHIFT_OUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); #endif #else // Not NEWPANEL #ifdef SR_LCD_2W_NL // Non latching 2 wire shift register - pinMode (SR_DATA_PIN, OUTPUT); - pinMode (SR_CLK_PIN, OUTPUT); + SET_OUTPUT(SR_DATA_PIN); + SET_OUTPUT(SR_CLK_PIN); #elif defined(SHIFT_CLK) - pinMode(SHIFT_CLK,OUTPUT); - pinMode(SHIFT_LD,OUTPUT); - pinMode(SHIFT_EN,OUTPUT); - pinMode(SHIFT_OUT,INPUT); + SET_OUTPUT(SHIFT_CLK); + SET_OUTPUT(SHIFT_LD); + SET_OUTPUT(SHIFT_EN); + SET_INPUT(SHIFT_OUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); WRITE(SHIFT_EN,LOW); @@ -1168,7 +1168,7 @@ void lcd_init() #endif//!NEWPANEL #if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0) - pinMode(SDCARDDETECT,INPUT); + SET_INPUT(SDCARDDETECT); WRITE(SDCARDDETECT, HIGH); lcd_oldcardstatus = IS_SD_INSERTED; #endif//(SDCARDDETECT > 0) From 85649a4549bc0a3613f675149997210ad5ab26da Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Wed, 6 Aug 2014 19:30:57 -0500 Subject: [PATCH 02/22] Real-time filament diameter measurement and control This feature allows the printer to read the filament diameter automatically and adjust the printer in real time. Added code to read an analog voltage that represents a filament diameter measurement. This measurement is delayed in a ring buffer to compensate for sensors that are a distance away from the extruder. The measurement is used to adjust the volumetric_multiplier for the extruder. Some additional g codes (M404, M405, M406, M407) are used to set parameters and turn on/off the control. g code M221 is updated. Pins for RAMPS1.4, RAMBO, and Printrboard are identified for analog input. The configuration file is updated with relevant user parameters. --- Marlin/Configuration.h | 30 +++++++++++ Marlin/Marlin.h | 10 ++++ Marlin/Marlin_main.cpp | 84 ++++++++++++++++++++++++++++- Marlin/pins.h | 16 ++++++ Marlin/planner.cpp | 31 +++++++++++ Marlin/temperature.cpp | 117 ++++++++++++++++++++++++++++++++++++++--- Marlin/temperature.h | 8 +++ 7 files changed, 289 insertions(+), 7 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 46d6b96dd1..45c6ea4864 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -755,6 +755,36 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of //#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1 //#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 70,0} // X,Y,Z Axis Extend and Retract angles +/**********************************************************************\ + * Support for a filament diameter sensor + * Also allows adjustment of diameter at print time (vs at slicing) + * Single extruder only at this point (extruder 0) + * + * Motherboards + * 34 - RAMPS1.4 - uses Analog input 5 on the AUX2 connector + * 81 - Printrboard - Uses Analog input 2 on the Aux 2 connector + * 301 - Rambo - uses Analog input 3 + * Note may require analog pins to be defined for different motherboards + **********************************************************************/ +#define FILAMENT_SENSOR +#define FILAMENT_SENSOR_EXTRUDER_NUM 0 //The number of the extruder that has the filament sensor (0,1,2) +#define MEASUREMENT_DELAY_CM 14 //measurement delay in cm. This is the distance from filament sensor to middle of barrel + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm). Used for sensor reading validation +#define MEASURED_UPPER_LIMIT 3.30 //upper limit factor used for sensor reading validation in mm +#define MEASURED_LOWER_LIMIT 1.90 //lower limit factor for sensor reading validation in mm +#define MAX_MEASUREMENT_DELAY 20 //delay buffer size in bytes (1 byte = 1cm)- limits maximum measurement delay allowable (must be larger than MEASUREMENT_DELAY_CM and lower number saves RAM) + +//defines used in the code +#define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA //set measured to nominal initially +#define STANDARD_DIA 1.12837915 //The diameter of filament that has a cross sectional area of 1 square mm. This dia should be used in the slicer software settings + + + + + + + #include "Configuration_adv.h" #include "thermistortables.h" diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 062b6d43c4..3fb6ec5531 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -229,6 +229,16 @@ extern int EtoPPressure; extern unsigned char fanSpeedSoftPwm; #endif +#ifdef FILAMENT_SENSOR + extern volatile float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75 + extern volatile bool filament_sensor; //indicates that filament sensor readings should control extrusion + extern float filament_width_meas; //holds the filament diameter as accurately measured + extern signed char measurement_delay[]; //ring buffer to delay measurement + extern int delay_index1, delay_index2; //index into ring buffer + extern float delay_dist; //delay distance counter + extern int meas_delay_cm; //delay distance +#endif + #ifdef FWRETRACT extern bool autoretract_enabled; extern bool retracted[EXTRUDERS]; diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index b373e22137..48d867c833 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -157,6 +157,10 @@ // M400 - Finish all moves // M401 - Lower z-probe if present // M402 - Raise z-probe if present +// M404 - N Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters +// M405 - Turn on Filament Sensor extrusion control. Optional D to set delay in centimeters between sensor and extruder +// M406 - Turn off Filament Sensor extrusion control +// M407 - Displays measured filament diameter // M500 - stores parameters in EEPROM // M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). // M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. @@ -296,6 +300,18 @@ int EtoPPressure=0; bool cancel_heatup = false ; +#ifdef FILAMENT_SENSOR + //Variables for Filament Sensor input + volatile float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404 + volatile bool filament_sensor=false; //M405 turns on filament_sensor control, M406 turns it off + float filament_width_meas=DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter + signed char measurement_delay[MAX_MEASUREMENT_DELAY+1]; //ring buffer to delay measurement store extruder factor after subtracting 100 + int delay_index1=0; + int delay_index2=0; //index into ring buffer + float delay_dist=0; //delay distance counter + int meas_delay_cm = MEASUREMENT_DELAY_CM; //distance delay setting +#endif + //=========================================================================== //=============================Private Variables============================= //=========================================================================== @@ -2317,7 +2333,13 @@ void process_commands() } } else { //reserved for setting filament diameter via UFID or filament measuring device - break; + if(active_extruder == FILAMENT_SENSOR_EXTRUDER_NUM){ + radius = analog2widthFil() * 0.5; + area = M_PI * pow(radius, 2); + }else{ + area = 1.0; + } + } tmp_extruder = active_extruder; if(code_seen('T')) { @@ -2771,6 +2793,66 @@ void process_commands() } break; #endif + +#ifdef FILAMENT_SENSOR +case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width + { + #if (FILWIDTH_PIN > -1) + if(code_seen('N')) filament_width_nominal=code_value(); + else{ + SERIAL_PROTOCOLPGM("Filament dia (nominal mm):"); + SERIAL_PROTOCOLLN(filament_width_nominal); + } + #endif + } + break; + + case 405: //M405 Turn on filament sensor for control + { + + + if(code_seen('D')) meas_delay_cm=code_value(); + + if(meas_delay_cm> MAX_MEASUREMENT_DELAY) + meas_delay_cm = MAX_MEASUREMENT_DELAY; + + filament_sensor = true ; + int temp_ratio = widthFil_to_size_ratio(); + + for (delay_index1=0; delay_index1<(MAX_MEASUREMENT_DELAY+1); ++delay_index1 ){ + measurement_delay[delay_index1]=temp_ratio-100; //subtract 100 to scale within a signed byte + } + delay_index1=0; + delay_index2=0; + + //SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); + //SERIAL_PROTOCOL(filament_width_meas); + //SERIAL_PROTOCOLPGM("Extrusion ratio(%):"); + //SERIAL_PROTOCOL(extrudemultiply); + } + break; + + case 406: //M406 Turn off filament sensor for control + { + filament_sensor = false ; + } + break; + + case 407: //M407 Display measured filament diameter + { + + filament_width_meas = code_value(); + + SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); + SERIAL_PROTOCOLLN(filament_width_meas); + } + break; + #endif + + + + + case 500: // M500 Store settings in EEPROM { Config_StoreSettings(); diff --git a/Marlin/pins.h b/Marlin/pins.h index c3644a086a..1ec236a074 100644 --- a/Marlin/pins.h +++ b/Marlin/pins.h @@ -558,6 +558,15 @@ #define E1_DIR_PIN 34 #define E1_ENABLE_PIN 30 +#if MOTHERBOARD == 34 //FMM added for Filament Extruder +#ifdef FILAMENT_SENSOR + //define analog pin for the filament width sensor input + //Use the RAMPS 1.4 Analog input 5 on the AUX2 connector + #define FILWIDTH_PIN 5 +#endif +#endif + + #if MOTHERBOARD == 68 #define E2_STEP_PIN 23 #define E2_DIR_PIN 25 @@ -1692,6 +1701,9 @@ #define Z_STOP_PIN 36 #define TEMP_0_PIN 1 // Extruder / Analog pin numbering #define TEMP_BED_PIN 0 // Bed / Analog pin numbering + #ifdef FILAMENT_SENSOR + #define FILWIDTH_PIN 2 + #endif //FILAMENT_SENSOR #endif #define TEMP_1_PIN -1 @@ -2326,6 +2338,10 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a #endif #endif //ULTRA_LCD +#ifdef FILAMENT_SENSOR + //Filip added pin for Filament sensor analog input + #define FILWIDTH_PIN 3 +#endif //FILAMENT_SENSOR #endif diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 5b20f86f99..fefae6e181 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -117,6 +117,10 @@ static long x_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; // Segment times (in static long y_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; #endif +#ifdef FILAMENT_SENSOR + static char meas_sample; //temporary variable to hold filament measurement sample +#endif + // Returns the index of the next block in the ring buffer // NOTE: Removed modulo (%) operator, which uses an expensive divide and multiplication. static int8_t next_block_index(int8_t block_index) { @@ -737,6 +741,33 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0 block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0 +#ifdef FILAMENT_SENSOR + //FMM update ring buffer used for delay with filament measurements + + if(filament_sensor && (extruder==0)) //only for extruder 0 + { + delay_dist = delay_dist + delta_mm[E_AXIS]; //increment counter with next move in e axis + if (delay_dist> (10*(MAX_MEASUREMENT_DELAY+1))) //check if counter is over max buffer size in mm + delay_dist = delay_dist - 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer + if(delay_dist<0) + delay_dist = delay_dist + 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer + delay_index1=delay_dist/10; //calculate index + if(delay_index1 != delay_index2) //moved index + { + meas_sample=widthFil_to_size_ratio()-100; //subtract off 100 to reduce magnitude - to store in a signed char + } + while( delay_index1 != delay_index2) + { + delay_index2 = delay_index2 + 1; + if(delay_index2>MAX_MEASUREMENT_DELAY) + delay_index2=delay_index2-(MAX_MEASUREMENT_DELAY+1); //loop around buffer when incrementing + measurement_delay[delay_index2]=meas_sample; + } + + } +#endif + + // Calculate and limit speed in mm/sec for each axis float current_speed[4]; float speed_factor = 1.0; //factor <=1 do decrease speed diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index a10c255af9..467b6dbdb3 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -71,7 +71,10 @@ unsigned char soft_pwm_bed; #ifdef BABYSTEPPING volatile int babystepsTodo[3]={0,0,0}; #endif - + +#ifdef FILAMENT_SENSOR + int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only +#endif //=========================================================================== //=============================private variables============================ //=========================================================================== @@ -158,6 +161,9 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0); #define SOFT_PWM_SCALE 0 #endif +#ifdef FILAMENT_SENSOR + static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor +#endif //=========================================================================== //============================= functions ============================ //=========================================================================== @@ -601,6 +607,21 @@ void manage_heater() } #endif #endif + +//code for controlling the extruder rate based on the width sensor +#ifdef FILAMENT_SENSOR + if(filament_sensor) + { + meas_shift_index=delay_index1-meas_delay_cm; + if(meas_shift_index<0) + meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed + + //get the delayed info and add 100 to reconstitute to a percent of the nominal filament diameter + //then adjust as a factor to the Standard Diameter (has an area of 1mm squared) + //then square it to get an area + volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/filament_width_nominal*STANDARD_DIA/100.0,2); + } +#endif } #define PGM_RD_W(x) (short)pgm_read_word(&x) @@ -702,6 +723,40 @@ static void updateTemperaturesFromRawValues() CRITICAL_SECTION_END; } + +// For converting raw Filament Width to milimeters +#ifdef FILAMENT_SENSOR +float analog2widthFil() { +return current_raw_filwidth/16383.0*5.0; +//return current_raw_filwidth; +} + +// For converting raw Filament Width to an volumetric ratio +int widthFil_to_size_ratio() { + +float temp; + +#if (FILWIDTH_PIN > -1) //check if a sensor is supported +filament_width_meas=current_raw_filwidth/16383.0*5.0; +#endif + +temp=filament_width_meas; +if(filament_width_measMEASURED_UPPER_LIMIT) + temp= MEASURED_UPPER_LIMIT; + + +return(filament_width_nominal/temp*100); + + +} +#endif + + + + + void tp_init() { #if (MOTHERBOARD == 80) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) @@ -797,6 +852,17 @@ void tp_init() #endif #endif + //Added for Filament Sensor + #ifdef FILAMENT_SENSOR + #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1) + #if FILWIDTH_PIN < 8 + DIDR0 |= 1< 1) || defined(HEATERS_PARALLEL) @@ -1122,6 +1188,10 @@ ISR(TIMER0_COMPB_vect) static unsigned char soft_pwm_b; #endif + #if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1) + static unsigned long raw_filwidth_value = 0; //added for filament width sensor + #endif + if(pwm_count == 0){ soft_pwm_0 = soft_pwm[0]; if(soft_pwm_0 > 0) { @@ -1248,10 +1318,39 @@ ISR(TIMER0_COMPB_vect) #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1) raw_temp_2_value += ADC; #endif - temp_state = 0; - temp_count++; + temp_state = 8;//change so that Filament Width is also measured + break; - case 8: //Startup, delay initial temp reading a tiny bit so the hardware can settle. + case 8: //Prepare FILWIDTH + #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1) + #if FILWIDTH_PIN>7 + ADCSRB = 1< -1) + //raw_filwidth_value += ADC; //remove to use an IIR filter approach + if(ADC>102) //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data. + { + raw_filwidth_value= raw_filwidth_value-(raw_filwidth_value>>7); //multipliy raw_filwidth_value by 127/128 + + raw_filwidth_value= raw_filwidth_value + ((unsigned long)ADC<<7); //add new ADC reading + } + #endif + temp_state = 0; + + temp_count++; + break; + + + case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle. temp_state = 0; break; // default: @@ -1260,7 +1359,7 @@ ISR(TIMER0_COMPB_vect) // break; } - if(temp_count >= OVERSAMPLENR) // 8 * 16 * 1/(16000000/64/256) = 131ms. + if(temp_count >= OVERSAMPLENR) // 10 * 16 * 1/(16000000/64/256) = 164ms. { if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading. { @@ -1276,6 +1375,12 @@ ISR(TIMER0_COMPB_vect) #endif current_temperature_bed_raw = raw_temp_bed_value; } + +//Add similar code for Filament Sensor - can be read any time since IIR filtering is used +#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1) + current_raw_filwidth = raw_filwidth_value>>10; //need to divide to get to 0-16384 range since we used 1/128 IIR filter approach +#endif + temp_meas_ready = true; temp_count = 0; diff --git a/Marlin/temperature.h b/Marlin/temperature.h index df2b5deacf..ca4efabec1 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -31,6 +31,14 @@ void tp_init(); //initialize the heating void manage_heater(); //it is critical that this is called periodically. +#ifdef FILAMENT_SENSOR +// For converting raw Filament Width to milimeters + float analog2widthFil(); + +// For converting raw Filament Width to an extrusion ratio + int widthFil_to_size_ratio(); +#endif + // low level conversion routines // do not use these routines and variables outside of temperature.cpp extern int target_temperature[EXTRUDERS]; From 62db9848d3f9ffcfe73e74cc7069fb4fe2b63b64 Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Sat, 16 Aug 2014 06:50:13 -0500 Subject: [PATCH 03/22] Improvements and bug fixes in sensor delay buffer for filament sensor code Improvement to avoid reinitializing delay buffer with every print. Fixed issues in buffer indexing and memory out of bounds due to floating point imprecision. Simplified the code by avoiding conversion to standard diameter and 1cu mm extrusion, which caused complications in determining mm extruded. --- Marlin/Marlin.h | 4 ++-- Marlin/Marlin_main.cpp | 40 +++++++++++++++++++++------------------- Marlin/planner.cpp | 28 ++++++++++++++++++++++------ Marlin/temperature.cpp | 22 ++++++++++++++-------- 4 files changed, 59 insertions(+), 35 deletions(-) diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 3fb6ec5531..7ced062964 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -230,8 +230,8 @@ extern unsigned char fanSpeedSoftPwm; #endif #ifdef FILAMENT_SENSOR - extern volatile float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75 - extern volatile bool filament_sensor; //indicates that filament sensor readings should control extrusion + extern float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75 + extern bool filament_sensor; //indicates that filament sensor readings should control extrusion extern float filament_width_meas; //holds the filament diameter as accurately measured extern signed char measurement_delay[]; //ring buffer to delay measurement extern int delay_index1, delay_index2; //index into ring buffer diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 48d867c833..6ce02d364a 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -302,12 +302,12 @@ bool cancel_heatup = false ; #ifdef FILAMENT_SENSOR //Variables for Filament Sensor input - volatile float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404 - volatile bool filament_sensor=false; //M405 turns on filament_sensor control, M406 turns it off + float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404 + bool filament_sensor=false; //M405 turns on filament_sensor control, M406 turns it off float filament_width_meas=DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter signed char measurement_delay[MAX_MEASUREMENT_DELAY+1]; //ring buffer to delay measurement store extruder factor after subtracting 100 - int delay_index1=0; - int delay_index2=0; //index into ring buffer + int delay_index1=0; //index into ring buffer + int delay_index2=-1; //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized float delay_dist=0; //delay distance counter int meas_delay_cm = MEASUREMENT_DELAY_CM; //distance delay setting #endif @@ -504,6 +504,7 @@ void servo_init() #endif } + void setup() { setup_killpin(); @@ -553,6 +554,7 @@ void setup() st_init(); // Initialize stepper, this enables interrupts! setup_photpin(); servo_init(); + lcd_init(); _delay_ms(1000); // wait 1sec to display the splash screen @@ -2333,12 +2335,8 @@ void process_commands() } } else { //reserved for setting filament diameter via UFID or filament measuring device - if(active_extruder == FILAMENT_SENSOR_EXTRUDER_NUM){ - radius = analog2widthFil() * 0.5; - area = M_PI * pow(radius, 2); - }else{ - area = 1.0; - } + break; + } tmp_extruder = active_extruder; @@ -2816,15 +2814,19 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp if(meas_delay_cm> MAX_MEASUREMENT_DELAY) meas_delay_cm = MAX_MEASUREMENT_DELAY; - filament_sensor = true ; - int temp_ratio = widthFil_to_size_ratio(); + if(delay_index2 == -1) //initialize the ring buffer if it has not been done since startup + { + int temp_ratio = widthFil_to_size_ratio(); + + for (delay_index1=0; delay_index1<(MAX_MEASUREMENT_DELAY+1); ++delay_index1 ){ + measurement_delay[delay_index1]=temp_ratio-100; //subtract 100 to scale within a signed byte + } + delay_index1=0; + delay_index2=0; + } + + filament_sensor = true ; - for (delay_index1=0; delay_index1<(MAX_MEASUREMENT_DELAY+1); ++delay_index1 ){ - measurement_delay[delay_index1]=temp_ratio-100; //subtract 100 to scale within a signed byte - } - delay_index1=0; - delay_index2=0; - //SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); //SERIAL_PROTOCOL(filament_width_meas); //SERIAL_PROTOCOLPGM("Extrusion ratio(%):"); @@ -2841,7 +2843,7 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp case 407: //M407 Display measured filament diameter { - filament_width_meas = code_value(); + SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); SERIAL_PROTOCOLLN(filament_width_meas); diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index fefae6e181..aac41faa7b 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -743,15 +743,25 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi #ifdef FILAMENT_SENSOR //FMM update ring buffer used for delay with filament measurements - - if(filament_sensor && (extruder==0)) //only for extruder 0 + + + if((extruder==FILAMENT_SENSOR_EXTRUDER_NUM) && (delay_index2 > -1)) //only for extruder with filament sensor and if ring buffer is initialized { delay_dist = delay_dist + delta_mm[E_AXIS]; //increment counter with next move in e axis - if (delay_dist> (10*(MAX_MEASUREMENT_DELAY+1))) //check if counter is over max buffer size in mm + + while (delay_dist >= (10*(MAX_MEASUREMENT_DELAY+1))) //check if counter is over max buffer size in mm delay_dist = delay_dist - 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer - if(delay_dist<0) + while (delay_dist<0) delay_dist = delay_dist + 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer - delay_index1=delay_dist/10; //calculate index + + delay_index1=delay_dist/10.0; //calculate index + + //ensure the number is within range of the array after converting from floating point + if(delay_index1<0) + delay_index1=0; + else if (delay_index1>MAX_MEASUREMENT_DELAY) + delay_index1=MAX_MEASUREMENT_DELAY; + if(delay_index1 != delay_index2) //moved index { meas_sample=widthFil_to_size_ratio()-100; //subtract off 100 to reduce magnitude - to store in a signed char @@ -761,10 +771,16 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi delay_index2 = delay_index2 + 1; if(delay_index2>MAX_MEASUREMENT_DELAY) delay_index2=delay_index2-(MAX_MEASUREMENT_DELAY+1); //loop around buffer when incrementing + if(delay_index2<0) + delay_index2=0; + else if (delay_index2>MAX_MEASUREMENT_DELAY) + delay_index2=MAX_MEASUREMENT_DELAY; + measurement_delay[delay_index2]=meas_sample; } + - } + } #endif diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 467b6dbdb3..46cdc7cfbb 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -617,9 +617,16 @@ void manage_heater() meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed //get the delayed info and add 100 to reconstitute to a percent of the nominal filament diameter - //then adjust as a factor to the Standard Diameter (has an area of 1mm squared) //then square it to get an area - volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/filament_width_nominal*STANDARD_DIA/100.0,2); + + if(meas_shift_index<0) + meas_shift_index=0; + else if (meas_shift_index>MAX_MEASUREMENT_DELAY) + meas_shift_index=MAX_MEASUREMENT_DELAY; + + volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/100.0,2); + if (volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] <0.01) + volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01; } #endif } @@ -715,6 +722,9 @@ static void updateTemperaturesFromRawValues() #ifdef TEMP_SENSOR_1_AS_REDUNDANT redundant_temperature = analog2temp(redundant_temperature_raw, 1); #endif + #ifdef FILAMENT_SENSOR && (FILWIDTH_PIN > -1) //check if a sensor is supported + filament_width_meas = analog2widthFil(); + #endif //Reset the watchdog after we know we have a temperature measurement. watchdog_reset(); @@ -731,15 +741,11 @@ return current_raw_filwidth/16383.0*5.0; //return current_raw_filwidth; } -// For converting raw Filament Width to an volumetric ratio +// For converting raw Filament Width to a ratio int widthFil_to_size_ratio() { float temp; - -#if (FILWIDTH_PIN > -1) //check if a sensor is supported -filament_width_meas=current_raw_filwidth/16383.0*5.0; -#endif - + temp=filament_width_meas; if(filament_width_meas Date: Sat, 16 Aug 2014 07:08:09 -0500 Subject: [PATCH 04/22] Filament sensor changes to config file Update the config file for improvements and clarifying what diameter to use in the slicer software. --- Marlin/Configuration.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 45c6ea4864..c877eec90a 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -770,14 +770,13 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of #define FILAMENT_SENSOR_EXTRUDER_NUM 0 //The number of the extruder that has the filament sensor (0,1,2) #define MEASUREMENT_DELAY_CM 14 //measurement delay in cm. This is the distance from filament sensor to middle of barrel -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm). Used for sensor reading validation +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm) - this is then used in the slicer software. Used for sensor reading validation #define MEASURED_UPPER_LIMIT 3.30 //upper limit factor used for sensor reading validation in mm #define MEASURED_LOWER_LIMIT 1.90 //lower limit factor for sensor reading validation in mm #define MAX_MEASUREMENT_DELAY 20 //delay buffer size in bytes (1 byte = 1cm)- limits maximum measurement delay allowable (must be larger than MEASUREMENT_DELAY_CM and lower number saves RAM) //defines used in the code #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA //set measured to nominal initially -#define STANDARD_DIA 1.12837915 //The diameter of filament that has a cross sectional area of 1 square mm. This dia should be used in the slicer software settings From 75b3a68b65c53b1439756ea287158ca1bd63586a Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Sat, 16 Aug 2014 13:26:48 -0500 Subject: [PATCH 05/22] Revert "Change pinMode to SET_INPUT or SET_OUTPUT" This reverts commit 1d0fe035f3aeb4af0e686fcb13c9a720248db462. --- Marlin/ultralcd.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index e6774108ac..9797b0bff1 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -1133,30 +1133,30 @@ void lcd_init() lcd_implementation_init(); #ifdef NEWPANEL - SET_INPUT(BTN_EN1); - SET_INPUT(BTN_EN2); + pinMode(BTN_EN1,INPUT); + pinMode(BTN_EN2,INPUT); WRITE(BTN_EN1,HIGH); WRITE(BTN_EN2,HIGH); #if BTN_ENC > 0 - SET_INPUT(BTN_ENC); + pinMode(BTN_ENC,INPUT); WRITE(BTN_ENC,HIGH); #endif #ifdef REPRAPWORLD_KEYPAD - SET_OUTPUT(SHIFT_CLK); - SET_OUTPUT(SHIFT_LD); - SET_INPUT(SHIFT_OUT); + pinMode(SHIFT_CLK,OUTPUT); + pinMode(SHIFT_LD,OUTPUT); + pinMode(SHIFT_OUT,INPUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); #endif #else // Not NEWPANEL #ifdef SR_LCD_2W_NL // Non latching 2 wire shift register - SET_OUTPUT(SR_DATA_PIN); - SET_OUTPUT(SR_CLK_PIN); + pinMode (SR_DATA_PIN, OUTPUT); + pinMode (SR_CLK_PIN, OUTPUT); #elif defined(SHIFT_CLK) - SET_OUTPUT(SHIFT_CLK); - SET_OUTPUT(SHIFT_LD); - SET_OUTPUT(SHIFT_EN); - SET_INPUT(SHIFT_OUT); + pinMode(SHIFT_CLK,OUTPUT); + pinMode(SHIFT_LD,OUTPUT); + pinMode(SHIFT_EN,OUTPUT); + pinMode(SHIFT_OUT,INPUT); WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); WRITE(SHIFT_EN,LOW); @@ -1168,7 +1168,7 @@ void lcd_init() #endif//!NEWPANEL #if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0) - SET_INPUT(SDCARDDETECT); + pinMode(SDCARDDETECT,INPUT); WRITE(SDCARDDETECT, HIGH); lcd_oldcardstatus = IS_SD_INSERTED; #endif//(SDCARDDETECT > 0) From fe3a09bbcfe2866752df01394fbfcb117f1dc80c Mon Sep 17 00:00:00 2001 From: Filip Mulier Date: Mon, 1 Sep 2014 06:26:19 -0500 Subject: [PATCH 06/22] Correct analog sampling time for additional A to D sample Adjusted the #define PID_dT to reflect 10 A to D sample steps, vs original 8. --- Marlin/Configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index c877eec90a..c838d6ceeb 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -185,7 +185,7 @@ // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. #define PID_INTEGRAL_DRIVE_MAX 255 //limit for the integral term #define K1 0.95 //smoothing factor within the PID - #define PID_dT ((OVERSAMPLENR * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine + #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it // Ultimaker From 40ba644bb4c7e073f0e082f28f6d982654fe0d42 Mon Sep 17 00:00:00 2001 From: Javi Date: Sat, 6 Sep 2014 02:53:36 +0200 Subject: [PATCH 07/22] Added profile for RAMPS with 2 extruders and 1 fan. modified: Marlin/Configuration.h modified: Marlin/pins.h --- Marlin/Configuration.h | 1 + Marlin/pins.h | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index eb2141a89d..86a262f670 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -49,6 +49,7 @@ // 33 = RAMPS 1.3 / 1.4 (Power outputs: Extruder, Fan, Bed) // 34 = RAMPS 1.3 / 1.4 (Power outputs: Extruder0, Extruder1, Bed) // 35 = RAMPS 1.3 / 1.4 (Power outputs: Extruder, Fan, Fan) +// 36 = RAMPS 1.3 / 1.4 (Power outputs: Extruder0, Extruder1, Fan) // 4 = Duemilanove w/ ATMega328P pin assignment // 5 = Gen6 // 51 = Gen6 deluxe diff --git a/Marlin/pins.h b/Marlin/pins.h index 9351d06c51..69de774e6e 100644 --- a/Marlin/pins.h +++ b/Marlin/pins.h @@ -531,7 +531,7 @@ * Arduino Mega pin assignment * ****************************************************************************************/ -#if MOTHERBOARD == 3 || MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 77 || MOTHERBOARD == 67 || MOTHERBOARD == 68 +#if MOTHERBOARD == 3 || MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 36 || MOTHERBOARD == 77 || MOTHERBOARD == 67 || MOTHERBOARD == 68 #define KNOWN_BOARD 1 //////////////////FIX THIS////////////// @@ -547,7 +547,7 @@ // #define RAMPS_V_1_0 -#if MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 77 || MOTHERBOARD == 67 || MOTHERBOARD == 68 +#if MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 36 || MOTHERBOARD == 77 || MOTHERBOARD == 67 || MOTHERBOARD == 68 #define LARGE_FLASH true @@ -653,7 +653,7 @@ #define FAN_PIN 4 // IO pin. Buffer needed #endif - #if MOTHERBOARD == 77 + #if MOTHERBOARD == 77 || MOTHERBOARD == 36 #define FAN_PIN 8 #endif @@ -709,7 +709,7 @@ #define TEMP_2_PIN -1 // ANALOG NUMBERING #endif - #if MOTHERBOARD == 35 + #if MOTHERBOARD == 35 || MOTHERBOARD == 36 #define HEATER_BED_PIN -1 // NO BED #else #if MOTHERBOARD == 77 From 9bc7aec349ec47bab359357ed38e115fc7af7b44 Mon Sep 17 00:00:00 2001 From: filipmu Date: Sat, 6 Sep 2014 21:55:47 -0500 Subject: [PATCH 08/22] Update README.md Added the new m-codes to this document. --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 17e920ec00..f21883e36d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ========================== Marlin 3D Printer Firmware ========================== -[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224) - +[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224) + Marlin has a GPL license because I believe in open development. Please do not use this code in products (3D printers, CNC etc) that are closed source or are crippled by a patent. @@ -207,15 +207,15 @@ M Codes * M140 - Set bed target temp * M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating * Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling -* M200 D- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters). +* M200 D- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters). * M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) * M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!! * M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec * M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate * M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk * M206 - set additional homeing offset -* M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting -* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min] +* M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting +* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min] * M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction. * M218 - set hotend offset (in mm): T X Y * M220 S- set speed factor override percentage @@ -230,6 +230,10 @@ M Codes * M400 - Finish all moves * M401 - Lower z-probe if present * M402 - Raise z-probe if present +* M404 - N Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters +* M405 - Turn on Filament Sensor extrusion control. Optional D to set delay in centimeters between sensor and extruder +* M406 - Turn off Filament Sensor extrusion control +* M407 - Displays measured filament diameter * M500 - stores paramters in EEPROM * M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). * M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. From 88d12a762a354cc91e6c1016198ab2ca62b0581a Mon Sep 17 00:00:00 2001 From: Wing Tang Wong Date: Tue, 16 Sep 2014 14:29:44 -0700 Subject: [PATCH 09/22] Added #ifndef DELTA wrapper to float delta --- Marlin/Marlin_main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 493d64985a..0e9a373e7c 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -318,7 +318,10 @@ bool cancel_heatup = false ; //=========================================================================== const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; static float destination[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0}; + static float delta[3] = {0.0, 0.0, 0.0}; +#endif + static float offset[3] = {0.0, 0.0, 0.0}; static bool home_all_axis = true; static float feedrate = 1500.0, next_feedrate, saved_feedrate; From 58eabd21fb15c86d5f8403b3da97e03549c07be2 Mon Sep 17 00:00:00 2001 From: Wing Tang Wong Date: Tue, 16 Sep 2014 14:31:58 -0700 Subject: [PATCH 10/22] Added ifndef --- Marlin/Marlin_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 0e9a373e7c..97b7b3b763 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -319,6 +319,7 @@ bool cancel_heatup = false ; const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; static float destination[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0}; +#ifndef DELTA static float delta[3] = {0.0, 0.0, 0.0}; #endif From c35736a1405f675b18a554350cead1ec78f38b1f Mon Sep 17 00:00:00 2001 From: Fourmi Date: Fri, 26 Sep 2014 21:49:07 +0200 Subject: [PATCH 11/22] Update thermistortables.h Add another thermistor table,use with hotend "Simple ONE" & "All in ONE" --- Marlin/thermistortables.h | 69 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/Marlin/thermistortables.h b/Marlin/thermistortables.h index 07b385e119..b3e9df32b9 100644 --- a/Marlin/thermistortables.h +++ b/Marlin/thermistortables.h @@ -621,6 +621,75 @@ const short temptable_11[][2] PROGMEM = { }; #endif +#if (THERMISTORHEATER_0 == 12) || (THERMISTORHEATER_1 == 12) || (THERMISTORHEATER_2 == 12) || (THERMISTORBED == 12) +// Hisens thermistor B25/50 =3950 +/-1% + +const short temptable_12[][2] PROGMEM = { + { 22.5*OVERSAMPLENR, 300 }, +{ 24.125*OVERSAMPLENR, 295 }, +{ 25.875*OVERSAMPLENR, 290 }, +{ 27.8125*OVERSAMPLENR, 285 }, +{ 29.9375*OVERSAMPLENR, 280 }, +{ 32.25*OVERSAMPLENR, 275 }, +{ 34.8125*OVERSAMPLENR, 270 }, +{ 37.625*OVERSAMPLENR, 265 }, +{ 40.6875*OVERSAMPLENR, 260 }, +{ 44.0625*OVERSAMPLENR, 255 }, +{ 47.75*OVERSAMPLENR, 250 }, +{ 51.8125*OVERSAMPLENR, 245 }, +{ 56.3125*OVERSAMPLENR, 240 }, +{ 61.25*OVERSAMPLENR, 235 }, +{ 66.75*OVERSAMPLENR, 230 }, +{ 72.8125*OVERSAMPLENR, 225 }, +{ 79.5*OVERSAMPLENR, 220 }, +{ 87*OVERSAMPLENR, 215 }, +{ 95.3125*OVERSAMPLENR, 210 }, +{ 104.1875*OVERSAMPLENR, 205 }, +{ 112.75*OVERSAMPLENR, 200 }, +{ 123.125*OVERSAMPLENR, 195 }, +{ 135.75*OVERSAMPLENR, 190 }, +{ 148.3125*OVERSAMPLENR, 185 }, +{ 163.8125*OVERSAMPLENR, 180 }, +{ 179*OVERSAMPLENR, 175 }, +{ 211.125*OVERSAMPLENR, 170 }, +{ 216.125*OVERSAMPLENR, 165 }, +{ 236.5625*OVERSAMPLENR, 160 }, +{ 258.5*OVERSAMPLENR, 155 }, +{ 279.875*OVERSAMPLENR, 150 }, +{ 305.375*OVERSAMPLENR, 145 }, +{ 333.25*OVERSAMPLENR, 140 }, +{ 362.5625*OVERSAMPLENR, 135 }, +{ 393.6875*OVERSAMPLENR, 130 }, +{ 425*OVERSAMPLENR, 125 }, +{ 460.625*OVERSAMPLENR, 120 }, +{ 495.1875*OVERSAMPLENR, 115 }, +{ 530.875*OVERSAMPLENR, 110 }, +{ 567.25*OVERSAMPLENR, 105 }, +{ 601.625*OVERSAMPLENR, 100 }, +{ 637.875*OVERSAMPLENR, 95 }, +{ 674.5625*OVERSAMPLENR, 90 }, +{ 710*OVERSAMPLENR, 85 }, +{ 744.125*OVERSAMPLENR, 80 }, +{ 775.9375*OVERSAMPLENR, 75 }, +{ 806.875*OVERSAMPLENR, 70 }, +{ 835.1875*OVERSAMPLENR, 65 }, +{ 861.125*OVERSAMPLENR, 60 }, +{ 884.375*OVERSAMPLENR, 55 }, +{ 904.5625*OVERSAMPLENR, 50 }, +{ 923.8125*OVERSAMPLENR, 45 }, +{ 940.375*OVERSAMPLENR, 40 }, +{ 954.625*OVERSAMPLENR, 35 }, +{ 966.875*OVERSAMPLENR, 30 }, +{ 977.0625*OVERSAMPLENR, 25 }, +{ 986*OVERSAMPLENR, 20 }, +{ 993.375*OVERSAMPLENR, 15 }, +{ 999.5*OVERSAMPLENR, 10 }, +{ 1004.5*OVERSAMPLENR, 5 }, +{ 1008.5*OVERSAMPLENR, 0 } + + }; +#endif + #if (THERMISTORHEATER_0 == 20) || (THERMISTORHEATER_1 == 20) || (THERMISTORHEATER_2 == 20) || (THERMISTORBED == 20) // PT100 with INA826 amp on Ultimaker v2.0 electronics /* The PT100 in the Ultimaker v2.0 electronics has a high sample value for a high temperature. This does not match the normal thermistor behaviour so we need to set the following defines */ From 3cbb2f56c6417cdda8ff093b831878868dc01ef3 Mon Sep 17 00:00:00 2001 From: Fourmi Date: Fri, 26 Sep 2014 22:01:06 +0200 Subject: [PATCH 12/22] Update configuration.h Add another comment on configuration.h for the value of thermistor. I make a pull request on thermistortables.h with my thermistor (12),but y see there is a comment on configuration with number 12 but it's not present on thermistortables.h ? Thx --- Marlin/Configuration.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index eb2141a89d..89f2d6d75a 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -127,6 +127,7 @@ // 10 is 100k RS thermistor 198-961 (4.7k pullup) // 11 is 100k beta 3950 1% thermistor (4.7k pullup) // 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) +// 12 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" // 20 is the PT100 circuit found in the Ultimainboard V2.x // 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 // From b5dc228a7a510e964c4637358479b65bc474721f Mon Sep 17 00:00:00 2001 From: Fourmi Date: Sat, 27 Sep 2014 09:02:58 +0200 Subject: [PATCH 13/22] Update configuration.h Add another comment for thermistor 13 ,use with Hotend "Simple ONE & All In ONE" --- Marlin/Configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 89f2d6d75a..170a0c2f74 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -127,7 +127,7 @@ // 10 is 100k RS thermistor 198-961 (4.7k pullup) // 11 is 100k beta 3950 1% thermistor (4.7k pullup) // 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) -// 12 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" +// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" // 20 is the PT100 circuit found in the Ultimainboard V2.x // 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 // From a664763e6f63796c0f04fac7edc088885975dfb6 Mon Sep 17 00:00:00 2001 From: Fourmi Date: Sat, 27 Sep 2014 09:05:10 +0200 Subject: [PATCH 14/22] Update thermistortables.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add another thermistor table (13),it's a cartridge thermistor up to +300°C,use with Hotend "Simple ONE" & "All In ONE" Thx --- Marlin/thermistortables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/thermistortables.h b/Marlin/thermistortables.h index b3e9df32b9..bda697686b 100644 --- a/Marlin/thermistortables.h +++ b/Marlin/thermistortables.h @@ -621,7 +621,7 @@ const short temptable_11[][2] PROGMEM = { }; #endif -#if (THERMISTORHEATER_0 == 12) || (THERMISTORHEATER_1 == 12) || (THERMISTORHEATER_2 == 12) || (THERMISTORBED == 12) +#if (THERMISTORHEATER_0 == 13) || (THERMISTORHEATER_1 == 13) || (THERMISTORHEATER_2 == 13) || (THERMISTORBED == 13) // Hisens thermistor B25/50 =3950 +/-1% const short temptable_12[][2] PROGMEM = { From d1e4237e1ddd89b081c297154bcfd2551c924a4f Mon Sep 17 00:00:00 2001 From: Aldert Date: Sat, 4 Oct 2014 09:24:09 +0200 Subject: [PATCH 15/22] Update motion_control.cpp G03 Full circle did not work (G02 is working correct) --- Marlin/motion_control.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Marlin/motion_control.cpp b/Marlin/motion_control.cpp index 76609054ff..b26cbafc8d 100644 --- a/Marlin/motion_control.cpp +++ b/Marlin/motion_control.cpp @@ -44,6 +44,14 @@ void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8 if (angular_travel < 0) { angular_travel += 2*M_PI; } if (isclockwise) { angular_travel -= 2*M_PI; } + //20141002:full circle for G03 did not work, e.g. G03 X80 Y80 I20 J0 F2000 is giving an Angle of zero so head is not moving + //to compensate when start pos = target pos && angle is zero -> angle = 2Pi + if (position[axis_0] == target[axis_0] && position[axis_1] == target[axis_1] && angular_travel == 0) + { + angular_travel += 2*M_PI; + } + //end fix G03 + 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); From f989bd54355966f1740b386d39fc516ce70af74f Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 5 Oct 2014 13:20:53 -0700 Subject: [PATCH 16/22] Simple code cleanup. Rename "homeing" to homing. --- Marlin/Configuration.h | 1 - Marlin/ConfigurationStore.cpp | 12 ++-- Marlin/Marlin.h | 2 +- Marlin/MarlinSerial.cpp | 2 +- Marlin/Marlin_main.cpp | 56 +++++++++---------- .../delta/Configuration.h | 51 ++++++++++------- Marlin/language.h | 6 +- Marlin/pins.h | 4 +- Marlin/stepper.cpp | 2 +- 9 files changed, 72 insertions(+), 64 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index eb2141a89d..0af56f6c59 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -30,7 +30,6 @@ // Serial port 0 is still used by the Arduino bootloader regardless of this setting. #define SERIAL_PORT 0 -// This determines the communication speed of the printer // This determines the communication speed of the printer #define BAUDRATE 250000 diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp index 7bbfede752..dbbe33a23b 100644 --- a/Marlin/ConfigurationStore.cpp +++ b/Marlin/ConfigurationStore.cpp @@ -65,7 +65,7 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i,max_xy_jerk); EEPROM_WRITE_VAR(i,max_z_jerk); EEPROM_WRITE_VAR(i,max_e_jerk); - EEPROM_WRITE_VAR(i,add_homeing); + EEPROM_WRITE_VAR(i,add_homing); #ifdef DELTA EEPROM_WRITE_VAR(i,endstop_adj); EEPROM_WRITE_VAR(i,delta_radius); @@ -170,9 +170,9 @@ SERIAL_ECHOLNPGM("Scaling factors:"); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Home offset (mm):"); SERIAL_ECHO_START; - SERIAL_ECHOPAIR(" M206 X",add_homeing[0] ); - SERIAL_ECHOPAIR(" Y" ,add_homeing[1] ); - SERIAL_ECHOPAIR(" Z" ,add_homeing[2] ); + SERIAL_ECHOPAIR(" M206 X",add_homing[0] ); + SERIAL_ECHOPAIR(" Y" ,add_homing[1] ); + SERIAL_ECHOPAIR(" Z" ,add_homing[2] ); SERIAL_ECHOLN(""); #ifdef DELTA SERIAL_ECHO_START; @@ -229,7 +229,7 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i,max_xy_jerk); EEPROM_READ_VAR(i,max_z_jerk); EEPROM_READ_VAR(i,max_e_jerk); - EEPROM_READ_VAR(i,add_homeing); + EEPROM_READ_VAR(i,add_homing); #ifdef DELTA EEPROM_READ_VAR(i,endstop_adj); EEPROM_READ_VAR(i,delta_radius); @@ -303,7 +303,7 @@ void Config_ResetDefault() max_xy_jerk=DEFAULT_XYJERK; max_z_jerk=DEFAULT_ZJERK; max_e_jerk=DEFAULT_EJERK; - add_homeing[0] = add_homeing[1] = add_homeing[2] = 0; + add_homing[0] = add_homing[1] = add_homing[2] = 0; #ifdef DELTA endstop_adj[0] = endstop_adj[1] = endstop_adj[2] = 0; delta_radius= DELTA_RADIUS; diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 9e6ba2636a..adc58b4cd4 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -211,7 +211,7 @@ extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner extern float current_position[NUM_AXIS] ; -extern float add_homeing[3]; +extern float add_homing[3]; #ifdef DELTA extern float endstop_adj[3]; extern float delta_radius; diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp index a7251dd6a2..e4e737433a 100644 --- a/Marlin/MarlinSerial.cpp +++ b/Marlin/MarlinSerial.cpp @@ -73,7 +73,7 @@ void MarlinSerial::begin(long baud) bool useU2X = true; #if F_CPU == 16000000UL && SERIAL_PORT == 0 - // hard coded exception for compatibility with the bootloader shipped + // hard-coded exception for compatibility with the bootloader shipped // with the Duemilanove and previous boards and the firmware on the 8U2 // on the Uno and Mega 2560. if (baud == 57600) { diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 4f691b0360..f273639a9a 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -220,7 +220,7 @@ float volumetric_multiplier[EXTRUDERS] = {1.0 #endif }; float current_position[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0 }; -float add_homeing[3]={0,0,0}; +float add_homing[3]={0,0,0}; #ifdef DELTA float endstop_adj[3]={0,0,0}; #endif @@ -852,7 +852,7 @@ static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; static float x_home_pos(int extruder) { if (extruder == 0) - return base_home_pos(X_AXIS) + add_homeing[X_AXIS]; + return base_home_pos(X_AXIS) + add_homing[X_AXIS]; else // In dual carriage mode the extruder offset provides an override of the // second X-carriage offset when homed - otherwise X2_HOME_POS is used. @@ -884,9 +884,9 @@ static void axis_is_at_home(int axis) { return; } else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) { - current_position[X_AXIS] = base_home_pos(X_AXIS) + add_homeing[X_AXIS]; - min_pos[X_AXIS] = base_min_pos(X_AXIS) + add_homeing[X_AXIS]; - max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + add_homeing[X_AXIS], + current_position[X_AXIS] = base_home_pos(X_AXIS) + add_homing[X_AXIS]; + min_pos[X_AXIS] = base_min_pos(X_AXIS) + add_homing[X_AXIS]; + max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + add_homing[X_AXIS], max(extruder_offset[X_AXIS][1], X2_MAX_POS) - duplicate_extruder_x_offset); return; } @@ -914,11 +914,11 @@ static void axis_is_at_home(int axis) { for (i=0; i<2; i++) { - delta[i] -= add_homeing[i]; + delta[i] -= add_homing[i]; } - // SERIAL_ECHOPGM("addhome X="); SERIAL_ECHO(add_homeing[X_AXIS]); - // SERIAL_ECHOPGM(" addhome Y="); SERIAL_ECHO(add_homeing[Y_AXIS]); + // SERIAL_ECHOPGM("addhome X="); SERIAL_ECHO(add_homing[X_AXIS]); + // SERIAL_ECHOPGM(" addhome Y="); SERIAL_ECHO(add_homing[Y_AXIS]); // SERIAL_ECHOPGM(" addhome Theta="); SERIAL_ECHO(delta[X_AXIS]); // SERIAL_ECHOPGM(" addhome Psi+Theta="); SERIAL_ECHOLN(delta[Y_AXIS]); @@ -936,14 +936,14 @@ static void axis_is_at_home(int axis) { } else { - current_position[axis] = base_home_pos(axis) + add_homeing[axis]; - min_pos[axis] = base_min_pos(axis) + add_homeing[axis]; - max_pos[axis] = base_max_pos(axis) + add_homeing[axis]; + current_position[axis] = base_home_pos(axis) + add_homing[axis]; + min_pos[axis] = base_min_pos(axis) + add_homing[axis]; + max_pos[axis] = base_max_pos(axis) + add_homing[axis]; } #else - current_position[axis] = base_home_pos(axis) + add_homeing[axis]; - min_pos[axis] = base_min_pos(axis) + add_homeing[axis]; - max_pos[axis] = base_max_pos(axis) + add_homeing[axis]; + current_position[axis] = base_home_pos(axis) + add_homing[axis]; + min_pos[axis] = base_min_pos(axis) + add_homing[axis]; + max_pos[axis] = base_max_pos(axis) + add_homing[axis]; #endif } @@ -1432,12 +1432,12 @@ void process_commands() HOMEAXIS(Z); calculate_delta(current_position); - plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]); - + plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]); + #else // NOT DELTA home_all_axis = !((code_seen(axis_codes[X_AXIS])) || (code_seen(axis_codes[Y_AXIS])) || (code_seen(axis_codes[Z_AXIS]))); - + #if Z_HOME_DIR > 0 // If homing away from BED do Z first if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { HOMEAXIS(Z); @@ -1516,7 +1516,7 @@ void process_commands() #ifdef SCARA current_position[X_AXIS]=code_value(); #else - current_position[X_AXIS]=code_value()+add_homeing[0]; + current_position[X_AXIS]=code_value()+add_homing[0]; #endif } } @@ -1526,7 +1526,7 @@ void process_commands() #ifdef SCARA current_position[Y_AXIS]=code_value(); #else - current_position[Y_AXIS]=code_value()+add_homeing[1]; + current_position[Y_AXIS]=code_value()+add_homing[1]; #endif } } @@ -1591,7 +1591,7 @@ void process_commands() if(code_seen(axis_codes[Z_AXIS])) { if(code_value_long() != 0) { - current_position[Z_AXIS]=code_value()+add_homeing[2]; + current_position[Z_AXIS]=code_value()+add_homing[2]; } } #ifdef ENABLE_AUTO_BED_LEVELING @@ -1820,10 +1820,10 @@ void process_commands() current_position[i] = code_value(); } else { - current_position[i] = code_value()+add_homeing[i]; + current_position[i] = code_value()+add_homing[i]; } #else - current_position[i] = code_value()+add_homeing[i]; + current_position[i] = code_value()+add_homing[i]; #endif plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); } @@ -2700,9 +2700,9 @@ Sigma_Exit: SERIAL_PROTOCOLLN(""); SERIAL_PROTOCOLPGM("SCARA Cal - Theta:"); - SERIAL_PROTOCOL(delta[X_AXIS]+add_homeing[0]); + SERIAL_PROTOCOL(delta[X_AXIS]+add_homing[0]); SERIAL_PROTOCOLPGM(" Psi+Theta (90):"); - SERIAL_PROTOCOL(delta[Y_AXIS]-delta[X_AXIS]-90+add_homeing[1]); + SERIAL_PROTOCOL(delta[Y_AXIS]-delta[X_AXIS]-90+add_homing[1]); SERIAL_PROTOCOLLN(""); SERIAL_PROTOCOLPGM("SCARA step Cal - Theta:"); @@ -2828,19 +2828,19 @@ Sigma_Exit: if(code_seen('E')) max_e_jerk = code_value() ; } break; - case 206: // M206 additional homeing offset + case 206: // M206 additional homing offset for(int8_t i=0; i < 3; i++) { - if(code_seen(axis_codes[i])) add_homeing[i] = code_value(); + if(code_seen(axis_codes[i])) add_homing[i] = code_value(); } #ifdef SCARA if(code_seen('T')) // Theta { - add_homeing[0] = code_value() ; + add_homing[0] = code_value() ; } if(code_seen('P')) // Psi { - add_homeing[1] = code_value() ; + add_homing[1] = code_value() ; } #endif break; diff --git a/Marlin/example_configurations/delta/Configuration.h b/Marlin/example_configurations/delta/Configuration.h index c724484bd9..975e52efd2 100644 --- a/Marlin/example_configurations/delta/Configuration.h +++ b/Marlin/example_configurations/delta/Configuration.h @@ -8,7 +8,7 @@ //=========================================================================== //============================= DELTA Printer =============================== //=========================================================================== -// For a Delta printer rplace the configuration files wilth the files in the +// For a Delta printer replace the configuration files with the files in the // example_configurations/delta directory. // @@ -66,7 +66,7 @@ // 702= Minitronics v1.0 // 90 = Alpha OMCA board // 91 = Final OMCA board -// 301 = Rambo +// 301= Rambo // 21 = Elefu Ra Board (v3) #ifndef MOTHERBOARD @@ -89,7 +89,7 @@ #define POWER_SUPPLY 1 -// Define this to have the electronics keep the powersupply off on startup. If you don't know what this is leave it. +// Define this to have the electronics keep the power supply off on startup. If you don't know what this is leave it. // #define PS_DEFAULT_OFF //=========================================================================== @@ -103,7 +103,7 @@ // and processor overload (too many expensive sqrt calls). #define DELTA_SEGMENTS_PER_SECOND 200 -// NOTE NB all values for DELTA_* values MOUST be floating point, so always have a decimal point in them +// NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them // Center-to-center distance of the holes in the diagonal push rods. #define DELTA_DIAGONAL_ROD 250.0 // mm @@ -132,7 +132,7 @@ // 0 is not used // 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup) // 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) -// 3 is mendel-parts thermistor (4.7k pullup) +// 3 is Mendel-parts thermistor (4.7k pullup) // 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! // 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) // 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) @@ -141,13 +141,18 @@ // 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) // 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) // 10 is 100k RS thermistor 198-961 (4.7k pullup) -// 60 is 100k Maker's Tool Works Kapton Bed Thermister +// 60 is 100k Maker's Tool Works Kapton Bed Thermistor // // 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k // (but gives greater accuracy and more stable PID) // 51 is 100k thermistor - EPCOS (1k pullup) // 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup) // 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) +// +// 1047 is Pt1000 with 4k7 pullup +// 1010 is Pt1000 with 1k pullup (non standard) +// 147 is Pt100 with 4k7 pullup +// 110 is Pt100 with 1k pullup (non standard) #define TEMP_SENSOR_0 -1 #define TEMP_SENSOR_1 -1 @@ -184,6 +189,10 @@ // HEATER_BED_DUTY_CYCLE_DIVIDER intervals. //#define HEATER_BED_DUTY_CYCLE_DIVIDER 4 +// If you want the M105 heater power reported in watts, define the BED_WATTS, and (shared for all extruders) EXTRUDER_WATTS +//#define EXTRUDER_WATTS (12.0*12.0/6.7) // P=I^2/R +//#define BED_WATTS (12.0*12.0/1.1) // P=I^2/R + // PID settings: // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP @@ -198,13 +207,13 @@ #define K1 0.95 //smoothing factor within the PID #define PID_dT ((16.0 * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine -// If you are using a preconfigured hotend then you can use one of the value sets by uncommenting it +// If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it // Ultimaker #define DEFAULT_Kp 22.2 #define DEFAULT_Ki 1.08 #define DEFAULT_Kd 114 -// Makergear +// MakerGear // #define DEFAULT_Kp 7.0 // #define DEFAULT_Ki 0.1 // #define DEFAULT_Kd 12 @@ -273,7 +282,7 @@ #define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors #ifndef ENDSTOPPULLUPS - // fine Enstop settings: Individual Pullups. will be ignored if ENDSTOPPULLUPS is defined + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined // #define ENDSTOPPULLUP_XMAX // #define ENDSTOPPULLUP_YMAX // #define ENDSTOPPULLUP_ZMAX @@ -359,7 +368,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of #define BACK_PROBE_BED_POSITION 180 #define FRONT_PROBE_BED_POSITION 20 - // these are the offsets to the prob relative to the extruder tip (Hotend - Probe) + // these are the offsets to the probe relative to the extruder tip (Hotend - Probe) #define X_PROBE_OFFSET_FROM_EXTRUDER -25 #define Y_PROBE_OFFSET_FROM_EXTRUDER -29 #define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 @@ -380,7 +389,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of // #define PROBE_SERVO_DEACTIVATION_DELAY 300 -//If you have enabled the Bed Auto Levelling and are using the same Z Probe for Z Homing, +//If you have enabled the Bed Auto Leveling and are using the same Z Probe for Z Homing, //it is highly recommended you let this Z_SAFE_HOMING enabled!!! #define Z_SAFE_HOMING // This feature is meant to avoid Z homing with probe outside the bed area. @@ -407,7 +416,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of //Manual homing switch locations: #define MANUAL_HOME_POSITIONS // MANUAL_*_HOME_POS below will be used -// For deltabots this means top and center of the cartesian print volume. +// For deltabots this means top and center of the Cartesian print volume. #define MANUAL_X_HOME_POS 0 #define MANUAL_Y_HOME_POS 0 #define MANUAL_Z_HOME_POS 250 // For delta: Distance between nozzle and print surface after homing. @@ -443,11 +452,11 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of //=========================================================================== // EEPROM -// the microcontroller can store settings in the EEPROM, e.g. max velocity... -// M500 - stores paramters in EEPROM +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM // M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). // M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. -//define this to enable eeprom support +//define this to enable EEPROM support //#define EEPROM_SETTINGS //to disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out: // please keep turned on if you can. @@ -463,14 +472,14 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of #define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255 //LCD and SD support -//#define ULTRA_LCD //general lcd support, also 16x2 +//#define ULTRA_LCD //general LCD support, also 16x2 //#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family) //#define SDSUPPORT // Enable SD Card Support in Hardware Console //#define SDSLOW // Use slower SD transfer mode (not normally needed - uncomment if you're getting volume init error) //#define ENCODER_PULSES_PER_STEP 1 // Increase if you have a high resolution encoder //#define ENCODER_STEPS_PER_MENU_ITEM 5 // Set according to ENCODER_PULSES_PER_STEP or your liking -//#define ULTIMAKERCONTROLLER //as available from the ultimaker online store. -//#define ULTIPANEL //the ultipanel as on thingiverse +//#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store. +//#define ULTIPANEL //the UltiPanel as on Thingiverse // The MaKr3d Makr-Panel with graphic controller and SD support // http://reprap.org/wiki/MaKr3d_MaKrPanel @@ -594,7 +603,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of #define LCD_WIDTH 20 #define LCD_HEIGHT 4 #endif -#else //no panel but just lcd +#else //no panel but just LCD #ifdef ULTRA_LCD #ifdef DOGLCD // Change number of lines to match the 128x64 graphics display #define LCD_WIDTH 20 @@ -616,8 +625,8 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of // Increase the FAN pwm frequency. Removes the PWM noise but increases heating in the FET/Arduino //#define FAST_PWM_FAN -// Temperature status leds that display the hotend and bet temperature. -// If alle hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on. +// Temperature status LEDs that display the hotend and bet temperature. +// If all hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on. // Otherwise the RED led is on. There is 1C hysteresis. //#define TEMP_STAT_LEDS diff --git a/Marlin/language.h b/Marlin/language.h index 54ca5bc622..f9363cb267 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -409,7 +409,7 @@ #define MSG_SET_ORIGIN "Regler origine" #define MSG_PREHEAT_PLA " Prechauffage PLA" #define MSG_PREHEAT_PLA0 "Prechauff. PLA 1" - #define MSG_PREHEAT_PLA1 "Prechauff. PLA 2" + #define MSG_PREHEAT_PLA1 "Prechauff. PLA 2" #define MSG_PREHEAT_PLA2 "Prechauff. PLA 3" #define MSG_PREHEAT_PLA012 "Prech. PLA Tout" #define MSG_PREHEAT_PLA_BEDONLY "Prech. PLA Plateau" @@ -885,11 +885,11 @@ #define MSG_KILLED "УБИТО." #define MSG_STOPPED "ОСТАНОВЛЕНО." #define MSG_CONTROL_RETRACT "Откат mm:" - #define MSG_CONTROL_RETRACT_SWAP "своп Откат mm:" + #define MSG_CONTROL_RETRACT_SWAP "своп Откат mm:" #define MSG_CONTROL_RETRACTF "Откат V:" #define MSG_CONTROL_RETRACT_ZLIFT "Прыжок mm:" #define MSG_CONTROL_RETRACT_RECOVER "Возврат +mm:" - #define MSG_CONTROL_RETRACT_RECOVER_SWAP "своп Возврат +mm:" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "своп Возврат +mm:" #define MSG_CONTROL_RETRACT_RECOVERF "Возврат V:" #define MSG_AUTORETRACT "АвтоОткат:" #define MSG_FILAMENTCHANGE "Change filament" diff --git a/Marlin/pins.h b/Marlin/pins.h index 9351d06c51..caf010186f 100644 --- a/Marlin/pins.h +++ b/Marlin/pins.h @@ -2078,8 +2078,8 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a #define Z_DIR_PIN 28 #define Z_STOP_PIN 30 -#define E0_STEP_PIN 17 -#define E0_DIR_PIN 21 +#define E0_STEP_PIN 17 +#define E0_DIR_PIN 21 #define LED_PIN -1 diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index 9bc8eb8395..9e22eb198b 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -1241,7 +1241,7 @@ void microstep_init() pinMode(Y_MS1_PIN,OUTPUT); pinMode(Y_MS2_PIN,OUTPUT); pinMode(Z_MS1_PIN,OUTPUT); - pinMode(Z_MS2_PIN,OUTPUT); + pinMode(Z_MS2_PIN,OUTPUT); pinMode(E0_MS1_PIN,OUTPUT); pinMode(E0_MS2_PIN,OUTPUT); for(int i=0;i<=4;i++) microstep_mode(i,microstep_modes[i]); From 2f6c57eadc17ac9b15b493843229f1eae43cfaa2 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 5 Oct 2014 13:35:45 -0700 Subject: [PATCH 17/22] Proposed feature: Set Home Offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an item to the LCD menu that applies the current axis position to the “add_homeing” offset. --- Marlin/language.h | 11 +++++++++++ Marlin/ultralcd.cpp | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/Marlin/language.h b/Marlin/language.h index 54ca5bc622..0028722095 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -155,6 +155,7 @@ #define MSG_AUTOSTART "Autostart" #define MSG_DISABLE_STEPPERS "Disable steppers" #define MSG_AUTO_HOME "Auto home" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Set origin" #define MSG_PREHEAT_PLA "Preheat PLA" #define MSG_PREHEAT_PLA0 "Preheat PLA 1" @@ -279,6 +280,7 @@ #define MSG_AUTOSTART "Autostart" #define MSG_DISABLE_STEPPERS "Wylacz silniki" #define MSG_AUTO_HOME "Auto. poz. zerowa" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Ustaw punkt zero" #define MSG_PREHEAT_PLA "Rozgrzej PLA" #define MSG_PREHEAT_PLA0 "Rozgrzej PLA 1" @@ -406,6 +408,7 @@ #define MSG_AUTOSTART "Demarrage auto" #define MSG_DISABLE_STEPPERS "Arreter moteurs" #define MSG_AUTO_HOME "Home auto." + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Regler origine" #define MSG_PREHEAT_PLA " Prechauffage PLA" #define MSG_PREHEAT_PLA0 "Prechauff. PLA 1" @@ -534,6 +537,7 @@ #define MSG_AUTOSTART "Autostart" #define MSG_DISABLE_STEPPERS "Stepper abschalt." #define MSG_AUTO_HOME "Auto Nullpunkt" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Setze Nullpunkt" #define MSG_PREHEAT_PLA "Vorwärmen PLA" #define MSG_PREHEAT_PLA0 "Vorwärmen PLA 1" @@ -661,6 +665,7 @@ #define MSG_AUTOSTART " Autostart" #define MSG_DISABLE_STEPPERS "Apagar motores" #define MSG_AUTO_HOME "Llevar al origen" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Establecer cero" #define MSG_PREHEAT_PLA "Precalentar PLA" #define MSG_PREHEAT_PLA0 "Precalentar PLA 1" @@ -794,6 +799,7 @@ #define MSG_AUTOSTART "Автостарт" #define MSG_DISABLE_STEPPERS "Выкл. двигатели" #define MSG_AUTO_HOME "Парковка" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Запомнить ноль" #define MSG_PREHEAT_PLA "Преднагрев PLA" #define MSG_PREHEAT_PLA0 "Преднагрев PLA0" @@ -919,6 +925,7 @@ #define MSG_AUTOSTART "Autostart" #define MSG_DISABLE_STEPPERS "Disabilita Motori" #define MSG_AUTO_HOME "Auto Home" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Imposta Origine" #define MSG_PREHEAT_PLA "Preriscalda PLA" #define MSG_PREHEAT_PLA0 "Preriscalda PLA 1" @@ -1044,6 +1051,7 @@ #define MSG_AUTOSTART "Autostart" #define MSG_DISABLE_STEPPERS " Apagar motores" #define MSG_AUTO_HOME "Ir para origen" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Estabelecer orig." #define MSG_PREHEAT_PLA "Pre-aquecer PLA" #define MSG_PREHEAT_PLA0 " pre-aquecer PLA 1" @@ -1176,6 +1184,7 @@ #define MSG_AUTOSTART "Automaatti" #define MSG_DISABLE_STEPPERS "Vapauta moottorit" #define MSG_AUTO_HOME "Aja referenssiin" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Aseta origo" #define MSG_PREHEAT_PLA "Esilammita PLA" #define MSG_PREHEAT_PLA0 "Esilammita PLA 1" @@ -1299,6 +1308,7 @@ #define MSG_AUTOSTART " Autostart" #define MSG_DISABLE_STEPPERS "Amortar motors" #define MSG_AUTO_HOME "Levar a l'orichen" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Establir zero" #define MSG_PREHEAT_PLA "Precalentar PLA" #define MSG_PREHEAT_PLA0 "Precalentar PLA0" @@ -1431,6 +1441,7 @@ #define MSG_AUTOSTART "Autostart" #define MSG_DISABLE_STEPPERS "Motoren uit" #define MSG_AUTO_HOME "Auto home" + #define MSG_SET_HOME_OFFSETS "Set home offsets" #define MSG_SET_ORIGIN "Nulpunt instellen" #define MSG_PREHEAT_PLA "PLA voorverwarmen" #define MSG_PREHEAT_PLA0 "PLA voorverw. 0" diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index fb2ddbfffa..dfe0658c1f 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -307,6 +307,23 @@ static void lcd_autostart_sd() } #endif +void lcd_set_home_offsets() +{ + for(int8_t i=0; i < NUM_AXIS; i++) { + if (i != E_AXIS) { + add_homeing[i] -= current_position[i]; + current_position[i] = 0.0; + } + } + plan_set_position(0.0, 0.0, 0.0, current_position[E_AXIS]); + + // Audio feedback + enquecommand_P(PSTR("M300 S659 P200")); + enquecommand_P(PSTR("M300 S698 P200")); + lcd_return_to_status(); +} + + #ifdef BABYSTEPPING static void lcd_babystep_x() { @@ -566,6 +583,7 @@ static void lcd_prepare_menu() #endif MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84")); MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + MENU_ITEM(function, MSG_SET_HOME_OFFSETS, lcd_set_home_offsets); //MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0")); #if TEMP_SENSOR_0 != 0 #if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_BED != 0 From 6e343ef2f09bf6c935a67653732b511c32bc46b2 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 5 Oct 2014 18:34:54 -0700 Subject: [PATCH 18/22] Adjust the Z display to hide float rounding errors --- Marlin/ultralcd_implementation_hitachi_HD44780.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/ultralcd_implementation_hitachi_HD44780.h b/Marlin/ultralcd_implementation_hitachi_HD44780.h index 11e0a95196..befb25bfdb 100644 --- a/Marlin/ultralcd_implementation_hitachi_HD44780.h +++ b/Marlin/ultralcd_implementation_hitachi_HD44780.h @@ -467,7 +467,7 @@ static void lcd_implementation_status_screen() # endif//LCD_WIDTH > 19 lcd.setCursor(LCD_WIDTH - 8, 1); lcd.print('Z'); - lcd.print(ftostr32(current_position[Z_AXIS])); + lcd.print(ftostr32(current_position[Z_AXIS] + 0.00001)); #endif//LCD_HEIGHT > 2 #if LCD_HEIGHT > 3 From fb34265d75cd1f5a3f4768779947f87c5b1ef270 Mon Sep 17 00:00:00 2001 From: Matthew Schick Date: Mon, 6 Oct 2014 00:16:08 -0400 Subject: [PATCH 19/22] Make hotend optional when compiling with lcd support Signed-off-by: Matthew Schick --- Marlin/ultralcd.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index fb2ddbfffa..d6cc1b99c4 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -374,7 +374,9 @@ static void lcd_tune_menu() START_MENU(); MENU_ITEM(back, MSG_MAIN, lcd_main_menu); MENU_ITEM_EDIT(int3, MSG_SPEED, &feedmultiply, 10, 999); +#if TEMP_SENSOR_0 != 0 MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15); +#endif #if TEMP_SENSOR_1 != 0 MENU_ITEM_EDIT(int3, MSG_NOZZLE1, &target_temperature[1], 0, HEATER_1_MAXTEMP - 15); #endif @@ -780,7 +782,9 @@ static void lcd_control_temperature_menu() START_MENU(); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); +#if TEMP_SENSOR_1 != 0 MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15); +#endif #if TEMP_SENSOR_1 != 0 MENU_ITEM_EDIT(int3, MSG_NOZZLE1, &target_temperature[1], 0, HEATER_1_MAXTEMP - 15); #endif @@ -791,7 +795,7 @@ static void lcd_control_temperature_menu() MENU_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15); #endif MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255); -#ifdef AUTOTEMP +#if defined AUTOTEMP && (TEMP_SENSOR_0 != 0) MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &autotemp_enabled); MENU_ITEM_EDIT(float3, MSG_MIN, &autotemp_min, 0, HEATER_0_MAXTEMP - 15); MENU_ITEM_EDIT(float3, MSG_MAX, &autotemp_max, 0, HEATER_0_MAXTEMP - 15); @@ -816,7 +820,9 @@ static void lcd_control_temperature_preheat_pla_settings_menu() START_MENU(); MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu); MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &plaPreheatFanSpeed, 0, 255); +#if TEMP_SENSOR_0 != 0 MENU_ITEM_EDIT(int3, MSG_NOZZLE, &plaPreheatHotendTemp, 0, HEATER_0_MAXTEMP - 15); +#endif #if TEMP_SENSOR_BED != 0 MENU_ITEM_EDIT(int3, MSG_BED, &plaPreheatHPBTemp, 0, BED_MAXTEMP - 15); #endif @@ -831,7 +837,9 @@ static void lcd_control_temperature_preheat_abs_settings_menu() START_MENU(); MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu); MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &absPreheatFanSpeed, 0, 255); +#if TEMP_SENSOR_0 != 0 MENU_ITEM_EDIT(int3, MSG_NOZZLE, &absPreheatHotendTemp, 0, HEATER_0_MAXTEMP - 15); +#endif #if TEMP_SENSOR_BED != 0 MENU_ITEM_EDIT(int3, MSG_BED, &absPreheatHPBTemp, 0, BED_MAXTEMP - 15); #endif From af3e4d7510e6917dcc396e9f257dd012a600a00e Mon Sep 17 00:00:00 2001 From: Fourmi Date: Mon, 6 Oct 2014 14:21:44 +0200 Subject: [PATCH 20/22] Update line 627 ,wrong number on thermistortables Wrong number on line 627 > i change number "12" by the correct number "13" Soory --- Marlin/thermistortables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/thermistortables.h b/Marlin/thermistortables.h index bda697686b..ac1dea736a 100644 --- a/Marlin/thermistortables.h +++ b/Marlin/thermistortables.h @@ -624,7 +624,7 @@ const short temptable_11[][2] PROGMEM = { #if (THERMISTORHEATER_0 == 13) || (THERMISTORHEATER_1 == 13) || (THERMISTORHEATER_2 == 13) || (THERMISTORBED == 13) // Hisens thermistor B25/50 =3950 +/-1% -const short temptable_12[][2] PROGMEM = { +const short temptable_13[][2] PROGMEM = { { 22.5*OVERSAMPLENR, 300 }, { 24.125*OVERSAMPLENR, 295 }, { 25.875*OVERSAMPLENR, 290 }, From ca30aee9039e2f257d8665f7e0c2d426df8b2d06 Mon Sep 17 00:00:00 2001 From: Matt Stultz Date: Tue, 7 Oct 2014 00:16:27 -0400 Subject: [PATCH 21/22] Fix "add_homeing" to "add_homing" to match changes --- Marlin/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 54d1b8be46..6b4a19a10d 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -311,7 +311,7 @@ void lcd_set_home_offsets() { for(int8_t i=0; i < NUM_AXIS; i++) { if (i != E_AXIS) { - add_homeing[i] -= current_position[i]; + add_homing[i] -= current_position[i]; current_position[i] = 0.0; } } From 110c5dcf230f8fdd5e426f07e5f4e687e76af31f Mon Sep 17 00:00:00 2001 From: Christian Inci Date: Sat, 11 Oct 2014 00:25:36 +0200 Subject: [PATCH 22/22] Fixed typo. Signed-off-by: Christian Inci --- Marlin/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 6b4a19a10d..734c859d02 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -800,7 +800,7 @@ static void lcd_control_temperature_menu() START_MENU(); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); -#if TEMP_SENSOR_1 != 0 +#if TEMP_SENSOR_0 != 0 MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15); #endif #if TEMP_SENSOR_1 != 0