Существует аналогичный вариант с применением датчика от весов в качестве элемента измерения, его я тоже буду испытывать но позже.
В данной модели я использую тонкопленочные датчики касания (FSR sensors)
Идея: использовать в качестве датчика уровня кровати саму горячую голову экструдера.
Достоинства: высокая точность измерения, высокая повторяемость результата, не требуется калибровка по соотношению высот горячей головы и отдельного датчика. Точность позиционирования 0.005 мм , повторяемость зависит от механической прочности конструкции в целом, у меня она порядка 0.03 мм
Недостатки: в случае "подтекания" пластика в точках касания появляются бугорки, их требуется убирать для успешной следующей калибровки. Если смотреть с другой стороны - для следущей печати все равно требуется убирать результат печати, такие точки убираются обычным протиранием кровати любимым средством (я использую светлое пиво)
Особенности данной реализации: тестовая эксплуатация показала что из за теплового расширения материала экструдера имеет место разница измерений на холодной и горячей голове. Сам по себе этот факт не мешает нормальной работе, но величина расширения выше чем рабочий ход применяемого FSR датчика (0.05 мм), поэтому датчик может быть откалиброван либо для работы на горячей либо на холодной системе. Логично использовать калибровку на горячей системе, непосредственно перед печатью, и нужно помнить что на холодную система просто не откалибруется (сработает защита в прошивке).
Модель экструдера
Применяется консольное вывешивание горячей головы, свободный ход выбирается упорным болтиком, под который и подложен датчик.
близко подходящая к болту подачи горловина канала прутка позволяет печатать гибкими материалами типа FLEX
- Код: Выделить всё • Развернуть
commit 08be4315f042d279035bb94f0aa85aec4fca982f
Author: Sergey Taranenko <setar@roboforum.ru>
Date: Sat Jun 13 22:41:26 2015 +0300
Add FSR Sensor control for bed autolevel
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index ff6005f..c1aa19b 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -346,9 +346,11 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
#define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS)
//============================= Bed Auto Leveling ===========================
-//#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line)
+#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line)
#define Z_PROBE_REPEATABILITY_TEST // If not commented out, Z-Probe Repeatability test will be included if Auto Bed Leveling is Enabled.
+#define FSR_SENSOR // Touch FSR Sensor for bed autoleveling
+
#ifdef ENABLE_AUTO_BED_LEVELING
// There are 2 different ways to pick the X and Y locations to probe:
@@ -371,43 +373,43 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
#ifdef AUTO_BED_LEVELING_GRID
// set the rectangle in which to probe
- #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 LEFT_PROBE_BED_POSITION 30
+ #define RIGHT_PROBE_BED_POSITION (X_MAX_POS-30)
+ #define BACK_PROBE_BED_POSITION (Y_MAX_POS-15)
+ #define FRONT_PROBE_BED_POSITION 15
// set the number of grid points per dimension
// I wouldn't see a reason to go above 3 (=9 probing points on the bed)
- #define AUTO_BED_LEVELING_GRID_POINTS 2
+ #define AUTO_BED_LEVELING_GRID_POINTS 3
#else // not AUTO_BED_LEVELING_GRID
// with no grid, just probe 3 arbitrary points. A simple cross-product
// is used to esimate the plane of the print bed
- #define ABL_PROBE_PT_1_X 15
- #define ABL_PROBE_PT_1_Y 180
- #define ABL_PROBE_PT_2_X 15
- #define ABL_PROBE_PT_2_Y 20
- #define ABL_PROBE_PT_3_X 170
- #define ABL_PROBE_PT_3_Y 20
+ #define ABL_PROBE_PT_1_X 30
+ #define ABL_PROBE_PT_1_Y (Y_MAX_POS-15)
+ #define ABL_PROBE_PT_2_X (X_MAX_POS-30)
+ #define ABL_PROBE_PT_2_Y (Y_MAX_POS-15)
+ #define ABL_PROBE_PT_3_X (X_MAX_POS/2)
+ #define ABL_PROBE_PT_3_Y 15
#endif // AUTO_BED_LEVELING_GRID
// these are the offsets to the probe relative to the extruder tip (Hotend - Probe)
// X and Y offsets must be integers
- #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.35
- #define Z_RAISE_BEFORE_HOMING 4 // (in mm) Raise Z before homing (G28) for Probe Clearance.
+ #define Z_RAISE_BEFORE_HOMING 0 // (in mm) Raise Z before homing (G28) for Probe Clearance.
// Be sure you have this distance over your Z_MAX_POS in case
- #define XY_TRAVEL_SPEED 8000 // X and Y axis travel speed between probes, in mm/min
+ #define XY_TRAVEL_SPEED 6000 // X and Y axis travel speed between probes, in mm/min
- #define Z_RAISE_BEFORE_PROBING 15 //How much the extruder will be raised before traveling to the first probing point.
- #define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when traveling from between next probing points
+ #define Z_RAISE_BEFORE_PROBING 5 //How much the extruder will be raised before traveling to the first probing point.
+ #define Z_RAISE_BETWEEN_PROBINGS 1 //How much the extruder will be raised when traveling from between next probing points
//#define Z_PROBE_SLED // turn on if you have a z-probe mounted on a sled like those designed by Charles Bell
//#define SLED_DOCKING_OFFSET 5 // the extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like.
@@ -428,6 +430,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
// - If stepper drivers timeout, it will need X and Y homing again before Z homing
// - Position the probe in a defined XY point before Z Homing when homing all axis (G28)
// - Block Z homing only when the probe is outside bed area.
+ // - Block Z homing if defined FSR_SENSOR and measured value not correct
#ifdef Z_SAFE_HOMING
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index e3e5ef3..0d821ec 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1046,12 +1046,82 @@ static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float
#endif // AUTO_BED_LEVELING_GRID
+bool touching_print_surface(int threshold) {
+ return rawFSRSample() < threshold;
+}
+
static void run_z_probe() {
plan_bed_level_matrix.set_to_identity();
feedrate = homing_feedrate[Z_AXIS];
-
// move down until you find the bed
float zPosition = -10;
+#ifdef FSR_SENSOR
+ zPosition = current_position[Z_AXIS];
+ float step = 0.1;
+ int direction = -1;
+ int num_fsr_probe = 0;
+ float measured_fsr_position = 0;
+ // Consider the glass touched if the raw ADC value is reduced by 5% or more.
+ int analog_fsr_untouched = rawFSRSample();
+ int threshold = analog_fsr_untouched * 95L / 100;
+ if( analog_fsr_untouched < 500 ) {
+ SERIAL_ERROR_START;
+ SERIAL_ERRORLNPGM("Zprobe switched off. Force from FSR sensor is too high !");
+ LCD_ALERTMESSAGEPGM("Err: FSR FORCE HIGH");
+ #ifdef Z_SAFE_HOMING
+ for ( int i=5; i--; lcd_update())
+ {
+ delay(200);
+ }
+ cli(); // disable interrupts
+ suicide();
+ while(1) { /* Intentionally left empty */ } // Wait for reset
+ #endif
+ }
+ if( analog_fsr_untouched > 1000 ) {
+ SERIAL_ERROR_START;
+ SERIAL_ERRORLNPGM("Zprobe switched off. Force from FSR sensor is too low !");
+ LCD_ALERTMESSAGEPGM("Err: FSR FORCE LOW");
+ #ifdef Z_SAFE_HOMING
+ for ( int i=5; i--; lcd_update())
+ {
+ delay(200);
+ }
+ cli(); // disable interrupts
+ suicide();
+ while(1) { /* Intentionally left empty */ } // Wait for reset
+ #endif
+ }
+ while (!touching_print_surface(threshold)) {
+ zPosition += step * direction;
+ plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate, active_extruder);
+ st_synchronize();
+ }
+ while (num_fsr_probe < 2) {
+ num_fsr_probe++;
+ zPosition += 0.1;
+ feedrate = homing_feedrate[Z_AXIS];
+ step = 0.01;
+ direction = -1;
+ plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate, active_extruder);
+ st_synchronize();
+ while (step > 0.005) {
+ if (touching_print_surface(threshold)) {
+ direction = 1;
+ step *= 0.8;
+ feedrate *= 0.8;
+ } else {
+ direction = -1;
+ }
+ zPosition += step * direction;
+ plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate, active_extruder);
+ st_synchronize();
+ }
+ SERIAL_ECHOPGM("st_get_position_mm="); SERIAL_ECHOLN(st_get_position_mm(Z_AXIS));
+ measured_fsr_position += st_get_position_mm(Z_AXIS);
+ }
+ current_position[Z_AXIS] = measured_fsr_position / num_fsr_probe;
+#else // not FSR_SENSOR
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
st_synchronize();
@@ -1069,8 +1139,10 @@ static void run_z_probe() {
zPosition -= home_retract_mm(Z_AXIS) * 2;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
st_synchronize();
-
current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
+#endif // FSR_SENSOR
+
+
// 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]);
}
@@ -1171,6 +1243,10 @@ static float probe_pt(float x, float y, float z_before) {
SERIAL_PROTOCOL(y);
SERIAL_PROTOCOLPGM(" z: ");
SERIAL_PROTOCOL(measured_z);
+#ifdef FSR_SENSOR
+ SERIAL_PROTOCOLPGM(" FSR: ");
+ SERIAL_PROTOCOL(rawFSRSample());
+#endif
SERIAL_PROTOCOLPGM("\n");
return measured_z;
}
@@ -2813,6 +2889,12 @@ Sigma_Exit:
SERIAL_PROTOCOLPGM(MSG_Z_MAX);
SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
#endif
+ #ifdef FSR_SENSOR
+ #if defined(FSR_PIN) && FSR_PIN > -1
+ SERIAL_PROTOCOLPGM("FSR raw data: ");
+ SERIAL_PROTOCOLLN(rawFSRSample());
+ #endif
+ #endif
break;
//TODO: update for all axis, use for loop
#ifdef BLINKM
diff --git a/Marlin/pins.h b/Marlin/pins.h
index 0c4a649..5f46a7e 100644
--- a/Marlin/pins.h
+++ b/Marlin/pins.h
@@ -635,6 +635,11 @@
#endif
#endif
+#ifdef FSR_SENSOR
+ //define analog pin for the FSR touch sensor input
+ //Use the RAMPS 1.4 Analog input 10 on the AUX2 connector
+ #define FSR_PIN 10
+#endif
#if MB(AZTEEG_X3_PRO)
#define E2_STEP_PIN 23
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 8bdb764..003f7e0 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -77,7 +77,11 @@ unsigned char soft_pwm_bed;
#ifdef FILAMENT_SENSOR
int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
-#endif
+#endif
+
+#ifdef FSR_SENSOR
+ int raw_FSR_sample = 0;
+#endif
//===========================================================================
//=============================private variables============================
//===========================================================================
@@ -167,6 +171,12 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
#ifdef FILAMENT_SENSOR
static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor
#endif
+
+#ifdef FSR_SENSOR
+ static unsigned long raw_FSR_value = 0;
+#endif
+
+
//===========================================================================
//============================= functions ============================
//===========================================================================
@@ -1218,7 +1228,7 @@ ISR(TIMER0_COMPB_vect)
static unsigned long raw_temp_1_value = 0;
static unsigned long raw_temp_2_value = 0;
static unsigned long raw_temp_bed_value = 0;
- static unsigned char temp_state = 10;
+ static unsigned char temp_state = 12;
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
static unsigned char soft_pwm_0;
#ifdef SLOW_PWM_HEATERS
@@ -1630,13 +1640,32 @@ ISR(TIMER0_COMPB_vect)
raw_filwidth_value= raw_filwidth_value + ((unsigned long)ADC<<7); //add new ADC reading
}
#endif
- temp_state = 0;
-
+ temp_state = 10;
+ break;
+ case 10: //Prepare FSR_SENSOR
+ #if defined(FSR_PIN) && (FSR_PIN> -1)
+ #if FSR_PIN>7
+ ADCSRB = 1<<MUX5;
+ #else
+ ADCSRB = 0;
+ #endif
+ ADMUX = ((1 << REFS0) | (FSR_PIN & 0x07));
+ ADCSRA |= 1<<ADSC; // Start conversion
+ #endif
+ lcd_buttons_update();
+ temp_state = 11;
+ break;
+ case 11: // Measure FSR_SENSOR
+ #if defined(FSR_PIN) &&(FSR_PIN > -1)
+ raw_FSR_sample = ADC;
+ raw_FSR_value += raw_FSR_sample;
+ #endif
+ temp_state = 0;
temp_count++;
break;
- case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
+ case 12: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
temp_state = 0;
break;
// default:
diff --git a/Marlin/temperature.h b/Marlin/temperature.h
index 95c3514..307ef26 100644
--- a/Marlin/temperature.h
+++ b/Marlin/temperature.h
@@ -39,6 +39,10 @@ void manage_heater(); //it is critical that this is called periodically.
int widthFil_to_size_ratio();
#endif
+#ifdef FSR_SENSOR
+ extern int raw_FSR_sample;
+#endif
+
// low level conversion routines
// do not use these routines and variables outside of temperature.cpp
extern int target_temperature[EXTRUDERS];
@@ -92,6 +96,13 @@ FORCE_INLINE float degHotend(uint8_t extruder) {
};
#endif
+#ifdef FSR_SENSOR
+ FORCE_INLINE int rawFSRSample() {
+ return raw_FSR_sample;
+ };
+#endif
+
+
FORCE_INLINE float degBed() {
return current_temperature_bed;
};
--- добавлено 20.06.2015 ---
выложил версию 2 forum107/topic15550-30.html#p330602
--- добавлено 04.08.2015 ---
Код прошивки тут
https://github.com/setar/MarlinDev/comm ... 5436bb7336
здесь в приложении версия 1: