--- Marlin/Configuration.h 2013-12-07 04:31:28.000000000 -0500 +++ Marlin/Configuration.h 2014-01-18 14:07:25.617772061 -0500 @@ -19,7 +19,7 @@ #define STRING_CONFIG_H_AUTHOR "Adrian/Lawsy/Rincewind/Tealvince" // Who made the changes. // change to 3 for SD3 //{SD Patch} -#define SOLIDOODLE_VERSION 3 //{SD Patch} +#define SOLIDOODLE_VERSION 2 //{SD Patch} // Enable support for either of the Z-Wobble Solutions //#define ZWOBBLE_PATCH //{SD Patch} (+5528 Bytes) @@ -78,9 +78,27 @@ // Original Solidoodle w/ Sanguinololu shipped pre June 2013 - Choose 62 // Solidoodle w/ Printrboard shipped post June 2013 - Choose 81 #ifndef MOTHERBOARD -#define MOTHERBOARD 62 +#define MOTHERBOARD 81 #endif +#define ENABLE_AUTO_BED_LEVELING + +// This is a hacky definition that is designed to get my force sensitive resistor +// as bed level detctor working. It will cause TEMP_PIN_2 to monitor the analog +// value of the force sensitive resistor rather than a thermistor. Define it to +// be the analog pin number where the FSR is connected (or -1 for no FSR). +#define TEMP_2_PIN_IS_BEDLEVEL_FSR 3 + +// If a bedleve FSR is installed, this is the number of samples to accumulate +// to provide a smoothed out running average +#define BEDLEVEL_FSR_SAMPLE_COUNT 5 + +#define BEDLEVEL_FSR_MAX_MOVE_INC 0.1 +#define BEDLEVEL_FSR_MIN_MOVE_INC 0.01 + +#define ENDSTOPS_ONLY_FOR_HOMING +#define Z_SAFE_HOMING + // Define this to set a custom name for your generic Mendel, // #define CUSTOM_MENDEL_NAME "This Mendel" @@ -349,14 +367,14 @@ // these are the positions on the bed to do the probing #define LEFT_PROBE_BED_POSITION 15 - #define RIGHT_PROBE_BED_POSITION 170 - #define BACK_PROBE_BED_POSITION 180 - #define FRONT_PROBE_BED_POSITION 20 + #define RIGHT_PROBE_BED_POSITION 135 + #define BACK_PROBE_BED_POSITION 135 + #define FRONT_PROBE_BED_POSITION 15 // these are the offsets to the prob 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 + #define X_PROBE_OFFSET_FROM_EXTRUDER 0 + #define Y_PROBE_OFFSET_FROM_EXTRUDER 0 + #define Z_PROBE_OFFSET_FROM_EXTRUDER 0 #define Z_RAISE_BEFORE_HOMING 4 // (in mm) Raise Z before homing (G28) for Probe Clearance. // Be sure you have this distance over your Z_MAX_POS in case @@ -371,7 +389,7 @@ //The value is the delay to turn the servo off after powered on - depends on the servo speed; 300ms is good value, but you can try lower it. // You MUST HAVE the SERVO_ENDSTOPS defined to use here a value higher than zero otherwise your code will not compile. - #define PROBE_SERVO_DEACTIVATION_DELAY 300 + #define PROBE_SERVO_DEACTIVATION_DELAY 0 //If you have enabled the Bed Auto Levelling and are using the same Z Probe for Z Homing, --- Marlin/Marlin_main.cpp 2013-12-07 04:31:28.000000000 -0500 +++ Marlin/Marlin_main.cpp 2014-01-20 19:54:37.955383342 -0500 @@ -160,6 +160,7 @@ // M400 - Finish all moves // M401 - Lower z-probe if present // M402 - Raise z-probe if present +// M402 - report bedlevel FSR smoothed average value // 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. @@ -874,6 +875,9 @@ #endif // ACCURATE_BED_LEVELING static void run_z_probe() { +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + enable_endstops(true); +#endif plan_bed_level_matrix.set_to_identity(); feedrate = homing_feedrate[Z_AXIS]; @@ -900,6 +904,92 @@ current_position[Z_AXIS] = st_get_position_mm(Z_AXIS); // make sure the planner knows where we are as it may be a bit different than we last said to move to plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + + // The code above got use moved to the Z endstop, but the actual bed + // level needs to be detected by a change in the FSR value from the + // nozzle touching the bed, so disable the endstop check and try to + // move a little bit more to zero in on exactly where the bed is + // under the nozzle. Need to be careful here - don't want to crash into + // the bed or keep moving a long time after hitting it. + + enable_endstops(false); + endstops_hit_on_purpose(); + + float max_move_inc = BEDLEVEL_FSR_MAX_MOVE_INC; + float min_move_inc = BEDLEVEL_FSR_MIN_MOVE_INC; + + float move_inc = max_move_inc; + for ( ; ; ) { + + // While we are motionless and sitting above the bed, read the + // FSR value to get a base value to compare with. + + StartBedlevelFsrSample(); + float base_fsr = WaitForBedlevelFsrSample(); + float base_var = GetBedlevelVariation(); + + SERIAL_PROTOCOLPGM("base FSR:"); + SERIAL_PROTOCOL(base_fsr); + SERIAL_PROTOCOLPGM(" base VAR:"); + SERIAL_PROTOCOL(base_var); + SERIAL_PROTOCOLPGM(" move inc:"); + SERIAL_PROTOCOL(move_inc); + SERIAL_PROTOCOLPGM(" current Z:"); + SERIAL_PROTOCOL(current_position[Z_AXIS]); + SERIAL_PROTOCOLLN(""); + + base_var *= 3.0; + + // Now move down "move_inc" at a time till we get a new FSR value + // outside of the base +/- variation. + + for ( ; ; ) { + plan_buffer_line(current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS] - move_inc, + current_position[E_AXIS], + feedrate/60, + active_extruder); + st_synchronize(); + current_position[Z_AXIS] = st_get_position_mm(Z_AXIS); + + StartBedlevelFsrSample(); + float cur_fsr = WaitForBedlevelFsrSample(); + SERIAL_PROTOCOLPGM("cur FSR:"); + SERIAL_PROTOCOL(cur_fsr); + SERIAL_PROTOCOLPGM(" current Z:"); + SERIAL_PROTOCOL(current_position[Z_AXIS]); + SERIAL_PROTOCOLLN(""); + if ((cur_fsr < (base_fsr - base_var)) || + (cur_fsr > (base_fsr + base_var))) { + // The FSR values changed to be outside the base sample range, + // assume we touched the bed. + break; + } + } + if (move_inc <= min_move_inc) { + // We just moved into contact with the bed by the smallest move + // we want to make. Our work here is done. + break; + } + // Nove move back up above the bed and cut the size of the move + // in half and try again to get a more accurate position if possible. + plan_buffer_line(current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS] + move_inc, + current_position[E_AXIS], + feedrate/60, + active_extruder); + st_synchronize(); + current_position[Z_AXIS] = st_get_position_mm(Z_AXIS); + move_inc /= 2.0; + } + + // make sure the planner knows where we are as it may be a bit different than we last said to move to + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); +#endif } static void do_blocking_move_to(float x, float y, float z) { @@ -973,6 +1063,18 @@ #endif // #ifdef ENABLE_AUTO_BED_LEVELING +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + +static void report_bedlevel_fsr() { + StartBedlevelFsrSample(); + float avg = WaitForBedlevelFsrSample(); + SERIAL_PROTOCOLPGM("FSR:"); + SERIAL_PROTOCOL(avg); + SERIAL_PROTOCOLLN(""); +} + +#endif + static void homeaxis(int axis) { #define HOMEAXIS_DO(LETTER) \ ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1)) @@ -2579,6 +2681,19 @@ } break; #endif +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + case 403: + { + report_bedlevel_fsr(); // Report the bedlevel FSR running average + } + break; + case 404: + { + enable_endstops(false) ; + endstops_hit_on_purpose(); + } + break; +#endif case 500: // M500 Store settings in EEPROM { Config_StoreSettings(); --- Marlin/pins.h 2013-12-07 04:31:28.000000000 -0500 +++ Marlin/pins.h 2014-01-13 17:29:44.743057968 -0500 @@ -1464,7 +1464,11 @@ #endif #define TEMP_1_PIN -1 +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) +#define TEMP_2_PIN TEMP_2_PIN_IS_BEDLEVEL_FSR +#else #define TEMP_2_PIN -1 +#endif #define SDPOWER -1 #define SDSS 14 --- Marlin/temperature.h 2013-12-07 04:31:28.000000000 -0500 +++ Marlin/temperature.h 2014-01-18 12:36:42.589824254 -0500 @@ -44,6 +44,11 @@ #ifdef TEMP_SENSOR_1_AS_REDUNDANT extern float redundant_temperature; #endif +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + extern void StartBedlevelFsrSample(); + extern float WaitForBedlevelFsrSample(); + extern float GetBedlevelVariation(); +#endif #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1 extern unsigned char soft_pwm_bed; --- Marlin/temperature.cpp 2013-12-07 04:31:28.000000000 -0500 +++ Marlin/temperature.cpp 2014-01-18 12:45:58.043066624 -0500 @@ -47,6 +47,10 @@ int redundant_temperature_raw = 0; float redundant_temperature = 0.0; #endif +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + int bedlevel_fsr_samples[BEDLEVEL_FSR_SAMPLE_COUNT] = { 0 }; + volatile unsigned char bedlevel_fsr_next_sample = 0; +#endif #ifdef PIDTEMP float Kp=DEFAULT_Kp; float Ki=(DEFAULT_Ki*PID_dT); @@ -671,6 +675,46 @@ return 0; #endif } +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + +/* Called to enable accumulation of another BEDLEVEL_FSR_SAMPLE_COUNT samples + from the bedlevel FSR */ +void StartBedlevelFsrSample() { + bedlevel_fsr_next_sample = 0; +} + +/* Called to wait for BEDLEVEL_FSR_SAMPLE_COUNT samples and return the average. */ +float WaitForBedlevelFsrSample() { + while (bedlevel_fsr_next_sample != BEDLEVEL_FSR_SAMPLE_COUNT) { + manage_heater(); + manage_inactivity(); + lcd_update(); + } + float avg = 0.0; + for (int i = 0; i < BEDLEVEL_FSR_SAMPLE_COUNT; ++i) { + avg += (float)bedlevel_fsr_samples[i]; + } + avg /= (float)BEDLEVEL_FSR_SAMPLE_COUNT; + return avg; +} + +// Called after WaitForBedlevelFsrSample(), this returns the plus or minus +// variation of the samples around the average. +float GetBedlevelVariation() { + int max_fsr = bedlevel_fsr_samples[0]; + int min_fsr = bedlevel_fsr_samples[0]; + for (int i = 1; i < BEDLEVEL_FSR_SAMPLE_COUNT; ++i) { + if (max_fsr < bedlevel_fsr_samples[i]) { + max_fsr = bedlevel_fsr_samples[i]; + } + if (min_fsr > bedlevel_fsr_samples[i]) { + min_fsr = bedlevel_fsr_samples[i]; + } + } + return ((float)(max_fsr - min_fsr))/2.0; +} + +#endif /* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context, and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */ @@ -916,13 +960,15 @@ #endif #endif - #if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 - target_temperature[2]=0; - soft_pwm[2]=0; - #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 - WRITE(HEATER_2_PIN,LOW); - #endif - #endif + #if (! defined(TEMP_2_PIN_IS_BEDLEVEL_FSR)) || (TEMP_2_PIN_IS_BEDLEVEL_FSR == -1) + #if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 + target_temperature[2]=0; + soft_pwm[2]=0; + #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 + WRITE(HEATER_2_PIN,LOW); + #endif + #endif + #endif #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 target_temperature_bed=0; @@ -1198,6 +1244,11 @@ #ifdef TEMP_SENSOR_1_AS_REDUNDANT redundant_temperature_raw = raw_temp_1_value; #endif +#if defined(TEMP_2_PIN_IS_BEDLEVEL_FSR) && (TEMP_2_PIN_IS_BEDLEVEL_FSR != -1) + if (bedlevel_fsr_next_sample != BEDLEVEL_FSR_SAMPLE_COUNT) { + bedlevel_fsr_samples[bedlevel_fsr_next_sample++] = raw_temp_2_value; + } +#endif #if EXTRUDERS > 2 current_temperature_raw[2] = raw_temp_2_value; #endif