Добавление коэффициента компенсации геометрических особенностей и сохранения в EEPROM, в автоматической калибровки на Marlin

Erzay 3D
Идет загрузка
Загрузка
15.01.2019
1682
12
Техничка

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых постах.

Отписаться от уведомлений вы всегда сможете в профиле автора.

3

Добрый день, Уважаемые читатели!

Я хотел бы продолжить тему с разработками и процессами этапов разработок относящихся к 3D принтерам, все работы проходили/ проходят в рамках текущего стартап проекта 'Erzay3D'. Сниппет кода является продолжением статьи Добавление RGB Светодиодную ленту к Marlin .

Выравнивание неровностей на печатающей платформе является, пожалуй, наиболее важным из оперативных действий необходимых для любого FDM 3D принтера особенно если говорить о дельта конструкции. Невозможно собрать абсолютно идентичный принтер с другим, при условии что сборка является ручной. Поэтому настройка уровня стола является индивидуальной для каждого 3D принтера. Если печатная платформа не отрегулирована по уровню, то печатающая головка может находиться высоко от площадки построения в целом или одного из краёв, в связи с чем, подавайемый пластик будет находится слишком высоко от поверхности печати и вызывать плохое сцепление и точность, или печатающая головка может находится слишком близко, что может вызвать кляксы пластика на печатной поверхности и затор экструдера или же деформации сопла, прогревающей поверхности вплоть до выхода из строя функционала принтера. Существует несколько способов настройки уровня стола, самый популярный это ручная настройка, подкручивая вручную винты, тем самым изменяя положения стола, но для идеальной настройки потребуется множество итераций и подобную процедуру нужно делать не один раз. В этой статье будет рассмотрена автоматическая калибровка реализованная с помощью датчиков и математических расчётов микроконтроллера. Функционал данной системы имеется и в прошивки «Marlin». С помощью четырёх датчиков и печатающей платформы (3 датчиков служат стартом для начала движения тяговых и один находится на самой печатающей головке) и ранее заданных параметров, алгоритм распределяет точки по площади печатающей платформы и отправляет печатающую головку в данные координаты. С помощью датчика установленного на печатающей головки, в каждой точке за меряется глубина от старта движения тяговых, таким образом строится матрица значений, затем совершается их интерполяция и отклонения записывается в буферную память. Исходя из этих значений при печати учитываются эта вновь сформированная плоскость для печати с учётом её неровностей.

Нашей команде удалось выявить некоторые недочёты переделать эту систему :

- выполнять автоматическую калибровку перед каждой печати очень неудобно и на это тратиться лишнее время, такой способ был выбран по причине того что у датчиков определяющих старт движения тяговых имеются погрешности от 200 до 400 микрон (при механических датчиках), и разумеется если после выполнения калибровки отправить оси на парковку то погрешность в построенной матрицы будет в 200-400 микрон, а эти значения плачевны для печати. Мы же нашли выход из этой проблемы, установив оптические датчики на парковку тяговых с погрешность в 10-20 микрон, установив индукционный датчик на печатающую головку использующий для проб глубин точек с погрешностью в 1-5 микрон( на сегодняшний день ушли от индукционного датчика, в связи с проблемами описанными далее, на наш взгляд датчик давления отрабатывает функционал лучше). Посадили движение тяговых на линейные направляющие, что уменьшило вибрацию и увеличило точность что не немаловажно влияет на погрешности измерений. И установили запись параметров автоматический калибровки в энергонезависимую память что позволит выполнять калибровку раз в 10-20 печатей и ненужно её запускать перед каждой печатью, это позволило значительно упростить и улучшить данный процесс;

- также выяснилось одна из проблем в погрешности самой калибровки, это связано с тем что датчик калибровки находится далеко от центра сопла, возможно есть и другие причины, они пока нами не выявлены. Решение было на программном уровне в добавлении коэффициентов погрешности плоскостей x и y. Данное значение достаточно установить один раз и в будущем при калибровке коэффициент будет учитываться;

- столкнулись с проблемами выхода калибровки за приделы стола, для этого были адаптированы программные энд стопы выхода печати за область стола( на текущей момент в UBL калибровки такой проблемы нету).

Включение/отключение этой функции производится по специальному G-коду. Если эта функция включена, после каждой автокалибровки (отправка команды «G29») все параметры рабочей поверхности будут автоматически сохраняться в энергонезависимую память и в дальнейшем использоваться перед каждой печатью (исключает необходимость запуска автокалибровки перед каждой печатью). Полный сброс осуществляется при условии очистки энергонезависимой памяти (либо при отключении этой функции по специальному G-коду). :

1. «G29» Сохранение калибровки на ЕЕПРОМ происходит автоматически после выполнения команды ;

2. «М700» используется для управления сохранением калибровки на энергонезависимую память EEPROM ;

3. «М700 R» — обнулить/сбросить текущую калибровку в памяти и калибровку в EEPROM;

4. «М700 O» — вывести в консоль текущие параметры калибровки;

5. «М700 P» — вывести в консоль сохраненные на EEPROM параметры калибровки;

6. «М215» — информация о текущих коэффициентах (Установка значения «М215 Х 0.0 Y 0.0» либо по одной оси (либо только М215 Х0.0 либо М215 Y0.0));

7. «М215 S» — сохранить в ЕЕПРОМ текущие данные в оперативной памяти;

8. «М215 L» — загрузить коэффициенты из ЕЕПРОМ;

9. «М215 R» — сбросить коэффициенты в ЕЕПРОМ до 0.0;

10. «M215 D» — загрузить заводские настройки коэффициентов (индивидуально для каждой модели).

Также команды М500, М501 и т. д. работают для этого коэффициента точно так же, как и на все другие параметры.

Сниппет из файла configuration _ store . cpp . Предназначение кода – сохранение, вывод в консоль и сброс уникальных для принтера настроек, хранящихся на энергонезависимой памяти EEPROM (светодиоды, автоматическая калибровка стола).



#ifdef LED_ENABLE

CONFIG_ECHO_START;

SERIAL_ECHOLNPGM('LEDs in Printing mode:');

SERIAL_ECHOPAIR('Red ', LED_mode [PRINTING] [RED]);

SERIAL_ECHOPAIR(' Green ', LED_mode [PRINTING] [GREEN]);

SERIAL_ECHOPAIR(' Blue ', LED_mode [PRINTING] [BLUE]);

SERIAL_EOL;

CONFIG_ECHO_START;

SERIAL_ECHOLNPGM('LEDs in Waiting mode:');

SERIAL_ECHOPAIR('Red ', LED_mode [WAITING] [RED]);

SERIAL_ECHOPAIR(' Green ', LED_mode [WAITING] [GREEN]);

SERIAL_ECHOPAIR(' Blue ', LED_mode [WAITING] [BLUE]);

SERIAL_EOL;

CONFIG_ECHO_START;

SERIAL_ECHOLNPGM ('LEDs in Heating mode are set according to the nozzle temperature');

SERIAL_ECHOLNPGM ('M580 [M] RXXX GXXX BXXX //M is for mode (W - Watinig, P - Prining). All parameters should be from 0 to 100 and integers.');

SERIAL_EOL;

#endif

SERIAL_ECHOPAIR ('Z coefficient is ', coefficient_z);

}

void save_coefficient_to_EEPROM (float coeff) {

int address = 445;

EEPROM_UPDATE_VAR(address, coeff);

}

float loadcoefficient () {

int address = 445;

float coeff;

EEPROM_READ_VAR(address, coeff);

return coeff;

}

void resetcoefficient () {

int address = 445;

float zeroo = 0.0;

EEPROM_UPDATE_VAR(address, zeroo);

}

float loaddefaultcoefficient () {

coefficient_z = Z_COEFFICIENT;

return coefficient_z;

}

#ifdef LED_ENABLE

void save_LED_eeprom () { //сохраняем данные о светодиодах на еепром.

int address = 444; //IMPORTARNT!!! V27 of EEPROM!!!

for (int i = 0; i <= 2; i++)

{

for (int ii = 0; ii <= 2; ii++)

{

EEPROM_WRITE_VAR(address, LED_mode [i] [ii]); // 0 - heating, 1 - printing, 2 - waiting, 0 - red, 1 - green, 2 - blue

}

}

}

void load_LED_eeprom () {

int address = 444; //IMPORTARNT!!! V27 of EEPROM!!!

for (int i = 0; i <= 2; i++)

{

for (int ii = 0; ii <= 2; ii++)

{

EEPROM_READ_VAR(address, LED_mode [i] [ii]); // 0 - heating, 1 - printing, 2 - waiting, 0 - red, 1 - green, 2 - blue

if (LED_mode [i] [ii] < 0)

{

LED_mode [i] [ii] = 0;

}

}

}

}

void LED_eeprom_update () {

int address = 444; //IMPORTARNT!!! V27 of EEPROM!!!

for (int i = 0; i <= 2; i++)

{

for (int ii = 0; ii <= 2; ii++)

{

EEPROM_UPDATE_VAR(address, LED_mode [i] [ii]); // 0 - heating, 1 - printing, 2 - waiting, 0 - red, 1 - green, 2 - blue

}

}

}

#endif

#ifdef CALIB_TO_EEPROM

void save_calibration_EEPROM (float abl_array[][ABL_GRID_POINTS_X]) { //Следи за адресом, здесь адрес может варьироваться

int address = 460;

for (int i=0; i < ABL_GRID_POINTS_X; i++)

{

for (int ii=0; ii < ABL_GRID_POINTS_X; ii++)

{

EEPROM_WRITE_VAR (address, abl_array[i][ii]);

}

}

SERIAL_ECHOLNPGM('Calibration values have been saved on EEPROM');

SERIAL_EOL;

}

void load_calibration_EEPROM (float abl_array[][ABL_GRID_POINTS_X]) { //Следи за адресом, здесь адрес может варьироваться

int address = 460;

for (int i=0; i < ABL_GRID_POINTS_X; i++)

{

for (int ii=0; ii < ABL_GRID_POINTS_X; ii++)

{

EEPROM_READ_VAR (address, abl_array[i][ii]);

if (abl_array[i] [ii] < -5.0 || abl_array[i][ii] > 5.0)

{

abl_array[i] [ii] = 0.1;

}

}

}

SERIAL_ECHOLNPGM('Saved calibration values have been loaded from EEPROM');

SERIAL_EOL;

}

void reset_calibration_EEPROM (float abl_array[][ABL_GRID_POINTS_X]) {

int address = 460;

float number = 0.10;

for (int i=0; i < ABL_GRID_POINTS_X; i++)

{

for (int ii=0; ii < ABL_GRID_POINTS_X; ii++)

{

EEPROM_UPDATE_VAR (address, number);

}

}

planner.abl_enabled = false;

SERIAL_ECHOLNPGM('Calibration EEPROM has been reset');

SERIAL_EOL;

}

void print_EEPROM_calibration () {

int address = 460;

float abl_array[ABL_GRID_POINTS_X][ABL_GRID_POINTS_X] = {{-1}};

for (int i=0; i < ABL_GRID_POINTS_X; i++)

{

for (int ii=0; ii < ABL_GRID_POINTS_X; ii++)

{

EEPROM_READ_VAR (address, abl_array[i][ii]);

SERIAL_ECHO(abl_array[i][ii]);

SERIAL_ECHOPGM(' ');

}

SERIAL_EOL;

}

SERIAL_ECHOLNPGM('Saved calibration values have been loaded from EEPROM');

SERIAL_EOL;

}

#endif // !DISABLE_M503

#endif //!CALIB_TO_EEPROM

Сниппет из файла marlin _ main . cpp . Различные функции и структуры в этом файле выполняют разные функции, в том числе вывод в консоль данных об уникальных конфигурациях 3D машины, применение коэффициента компенсации геометрических особенностей принтера, обработка данных автоматической калибровки рабочей поверхности принтера (в т. ч. Восстановление, загрузка из энергонезависимой памяти и т. д.), отключение программных эндстопов для оптимизации алгоритма автокалибровки рабочей поверхности.

#ifdef CALIB_TO_EEPROM

inline void gcode_M700() {

//G-код для обработки автоматического сохранения

//автокалибровки в энергонезависимую память

if (code_seen('R')) { reset_calibration_EEPROM (bed_level_grid); reset_bed_level();}

if (code_seen('S')) save_calibration_EEPROM (bed_level_grid);

if (code_seen('L')) { my_gcode_G29 (); }

if (code_seen('P')) print_EEPROM_calibration ();

if (code_seen('O')) output_current_calibration ();

if (code_seen('B')) report_current_position ();

}

#ifdef LED_ENABLE

inline void gcode_M580 () { //вывод в консоль и прием настроек светодиодной ленты

char bad_command1 [] = 'Wrong commad. Type M580 [M] Rxxx Gxxx Bxxx for M=mode, R,G,B = Red, Green, Blue. For example, to change the Printing mode LED color type: M580 P R50 G9 B100.';

char bad_command2 [] = 'Or you may change just one or two colors by typing for example: M580 P G9. The numbers should be integers from 0 to 100.';

int temp_LED_status = 0;

char LED_mode_printing [] = 'Printing';

char LED_mode_waiting [] = 'Waiting';

char *pLED_temp_mode = NULL;

int buff_red, buff_green, buff_blue = 0;

SERIAL_ECHO_START;

if (code_seen('.')) {SERIAL_ECHO(bad_command1); SERIAL_EOL; SERIAL_ECHO(bad_command2); SERIAL_EOL; return ;}

if (code_seen('W') || code_seen('P')) {

if (code_seen('W')) temp_LED_status = WAITING;

if (code_seen('P')) temp_LED_status = PRINTING;

} else {SERIAL_ECHO(bad_command1); SERIAL_EOL; SERIAL_ECHO(bad_command2); SERIAL_EOL; return ;}

switch (temp_LED_status) {

case WAITING:

pLED_temp_mode = LED_mode_waiting;

break;

case PRINTING:

pLED_temp_mode = LED_mode_printing;

break;

}

if (code_seen ('R') || code_seen ('G') || code_seen ('B')) {

if (code_seen ('R')) {

buff_red = code_value_int ();

if (buff_red < 0 || buff_red > 100)

{

SERIAL_ECHO(bad_command1);

SERIAL_EOL;

SERIAL_ECHO(bad_command2);

SERIAL_EOL;

return ;

}

}

if (code_seen ('G')) {

buff_green = code_value_int ();

if (buff_green < 0 || buff_green > 100)

{

SERIAL_ECHO(bad_command1);

SERIAL_EOL;

SERIAL_ECHO(bad_command2);

SERIAL_EOL;

return ;

}

}

if (code_seen ('B')) {

buff_blue = code_value_int ();

if (buff_blue < 0 || buff_blue > 100)

{

SERIAL_ECHO(bad_command1);

SERIAL_EOL;

SERIAL_ECHO(bad_command2);

SERIAL_EOL;

return ;

}

}

} else {SERIAL_ECHO(bad_command1); SERIAL_EOL; SERIAL_ECHO(bad_command2); SERIAL_EOL; return ;}

if (code_seen ('R')) LED_mode [temp_LED_status] [RED] = buff_red;

if (code_seen ('G')) LED_mode [temp_LED_status] [GREEN] = buff_green;

if (code_seen ('B')) LED_mode [temp_LED_status] [BLUE] = buff_blue;

SERIAL_ECHO('Colors of LEDs in the mode ');

SERIAL_ECHO(*pLED_temp_mode);

SERIAL_ECHO(' were changed. Now they are: Red ');

SERIAL_ECHO(LED_mode [temp_LED_status] [RED]);

SERIAL_ECHO(' Green ');

SERIAL_ECHO(LED_mode [temp_LED_status] [GREEN]);

SERIAL_ECHO(' Blue ');

SERIAL_ECHO(LED_mode [temp_LED_status] [BLUE]);

SERIAL_EOL;

}

#endif //LED_ENABLE

inline void gcode_M215 () { //работа с коэффициентом компенсации геометрических //особенностей принтера

if (code_seen('Z')) {

coefficient_z = code_value_float();

SERIAL_ECHO_START;

SERIAL_ECHOLNPAIR ('Z coefficient has been changed to ', coefficient_z);

} else

#ifdef EEPROM_SETTINGS

if (code_seen('S')) {

save_coefficient_to_EEPROM (coefficient_z);

SERIAL_ECHO_START;

SERIAL_ECHOLNPAIR ('Z coefficient has been written to EEPROM ', coefficient_z);

}

else if (code_seen('L')) {

coefficient_z = loadcoefficient ();

SERIAL_ECHO_START;

SERIAL_ECHOLNPAIR ('Z coefficient has been read from EEPROM ', coefficient_z);

}

else if (code_seen('R')) {

resetcoefficient ();

coefficient_z = loadcoefficient ();

SERIAL_ECHO_START;

SERIAL_ECHOLNPAIR ('Z coefficient is ', coefficient_z);

}

else if (code_seen('D')) {

coefficient_z = loaddefaultcoefficient ();

SERIAL_ECHO_START;

SERIAL_ECHOLNPAIR ('Z coefficient is ', coefficient_z);

SERIAL_ECHOLN ('Use M215 S or M500 to save it to EEPROM');

} else

#endif

{

SERIAL_ECHO_START;

SERIAL_ECHOLNPAIR ('Current Z coefficient is ', coefficient_z);

}

}

#ifdef LED_ENABLE //инициализация светодиодов при пуске принтера

pinMode(REDPIN, OUTPUT);

pinMode(GREENPIN, OUTPUT);

pinMode(BLUEPIN, OUTPUT);

#ifdef EEPROM_SETTINGS

load_LED_eeprom ();

#endif

LED_status = WAITING;

change_LED_status ();

#endif

void handle_status_leds(void) { //выбор режима работы светодиодов, таймер включения

//float max_temp = 0.0;

if (millis() > next_status_led_update_ms) {

next_status_led_update_ms += LCD_UPDATE_INTERVAL+100; // Update every 0.5s

change_LED_status ();

bool isheating = isHeatingFlag ();

if (isheating)

{

LED_status = HEATING;

return ;

}

if ((planner.movesplanned()) && ((thermalManager.current_temperature [0] + 3) > thermalManager.target_temperature [0]) && ((thermalManager.current_temperature [0] - 3) < thermalManager.target_temperature [0]))

{

LED_status = PRINTING;

if (mytimer_should_turnoff == false) {mytimer_should_turnoff = true;}

return ;

}

else { LED_status = WAITING; if (mytimer_should_turnoff == false) {mytimer_should_turnoff = true;} }

}

}

#endif

Спустя время Marlin обновил систему калибровки с некоторыми совпадениями наших доработок, неизвестно совпадение ли это)

Всем спасибо за внимание, команда ООО 'Робокинетика'!

Патент программы для ЭВМ №2018611221

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых постах.

Отписаться от уведомлений вы всегда сможете в профиле автора.

3
Комментарии к статье

Комментарии

15.01.2019 в 18:12
1

у датчиков определяющих старт движения тяговых имеются погрешности от 200 до 400 микрон (при механических датчиках)
эээээ... а Вы точно в единицах измерения не ошиблись, а?

Вот как, скажите, как я умудряюсь на собранной из остатков, на пластиковых углах, дельте, с механическими концевиками (кстати - обычные отечественные текстолитовые МП-шки) калибровать поверхность штатными средствами Marlin'а 1.1.9, с клоном BLtouch, в погрешность 20 мкм с отличной укладкой первого слоя? Калибруется в 3-4 итерации. Магия какая то?

400 мкм - это диаметр сопла. Вы это... осетра то поурежьте (с)! Неприлично как-то...

15.01.2019 в 18:31
0

калибровать поверхность штатными средствами Marlin'а 1.1.9, с клоном BLtouch, в погрешность 20 мкм с отличной укладкой первого слоя? Калибруется в 3-4 итерации. Магия какая то?
У вас просто неправильные пчелы и делают неправильный мед.

15.01.2019 в 18:55
0

делают неправильный мед.
и дельта тоже неправильная. Сделанная не по моим же заповедям )))

15.01.2019 в 18:36
0

Marlin'а 1.1.9- UBL калибровку стали использовать, да в ней уже есть сохранение в EEPROM и она калибрует не только в декартовой системе как было в ранних версиях. Такие погрешности производители публикуют в тех документах по датчикам, может и правда одним нулём ошибся, пожалуй перепроверю. Сложно вериться что на механических датчиках удаётся печатать с EPROM с погрешностью в 20 микрон, не поверю пока не увижу своими глазами.

15.01.2019 в 20:08
0

https://youtu.be/il9bNWn66BY?t=696

15.01.2019 в 19:04
1

Такие погрешности производители публикуют в тех документах по датчикам, может и правда одним нулём ошибся, пожалуй перепроверю.
Перепроверьте. Дружище Vmzsoft калибрует поверхность микриком от мышки.

Сложно вериться что на механических датчиках удаётся печатать с EPROM с погрешностью в 20 микрон
По последней калибровке, которую делал, 4 итерации и 21 мкм (0.021 на дисплее показатель sd 'светился'), могу фотку дисплея следующей калибровки (если эта собьется) предоставить. Или первого слоя.

На самом деле - механические 'микрики' с отломанными лапками более чем точны для нужд FDM (если, конечно, соплом 0.15 с первым слоем 0.05 мм не печатать).

А описанные Вами проблемы с индукционным датчиком являются следствием 'качания', ну или перекоса эффектора из-за неидеальной геометрии рамы и длин тяг. Оффсет датчика и вызывает дополнительные 30-100 мкм погрешности из-за того самого перекоса. С BLtouch я вопрос решил подбором размещения тяг на 'пауке' и сравнением калибровки по карте высот датчика и бумажки под соплом.

P.S.: Ну и да - я предпочитаю большие эффекторы (оффсет >30, лучше 35 мм) и большие расстояния между центрами тяг (60-80 мм), чтобы уменьшить эффект 'качания'.

16.01.2019 в 11:08
0

[quote]Перепроверьте. Дружище Vmzsoft калибрует поверхность микриком от мышки.[/quote]

А нет ссылки на мануал? Или его нет?

15.01.2019 в 19:47
0

Такие погрешности производители публикуют в тех документах по датчикам, может и правда одним нулём ошибся, пожалуй перепроверю.
 Предположу, либо датчики такие, либо документы от них.

15.01.2019 в 21:45
0

А почему не просто пластинки с контактами без дополнительной механики, стянутые пружинкой и конденсатор? Подъехало, разомкнуло, а то качелька, пружинка, контакт или просто изогнутая пластинка как в микрике от мышки (все эти кнопочки, зависимы от температуры и частоты срабатывания. Пощелкали 20 раз подряд, момент срабатывания поменялся, подождали пару минут и всё вернулось.

Я за простой механический прерыватель, без дополнительной механики как в микрике или на картинке выше. 

Похоже, самый лучший концевик получится из частей обычного выключателя.

16.01.2019 в 14:45
0

Какая дельта геморройная.
У меня H-BOT. Калибрую стол очень редко и на глаз, упором сопла в стекло. Остальные корректировки задаю z-offset-ом и жирностью первого слоя.

msv
04.06.2019 в 13:28
0

На вкус и цвет...
Собрал два кубика. Продал. Вернулся на дельты.
Один раз настроил калибровку и забыл. Стол крутить не надо.
Сопло переставил - перекалибровал в автомате и все. Стол опять крутить не надо.
Красота. Ну и эффект 'кота и стиральной машинки' никто не отменял)))

04.06.2019 в 13:25
0

Было ранее большое исследование по микрикам. Обычным китайским, от мышек, советским. Даже видео было.

А вообще - по теме. Выбросил недавно пьезо калибровку - устал с помехами бороться. Поставил наскоро прикрученный китайский ендстоп на микрике.
Пробовал в лоб и с отломанной железкой (без колесика).
Итог - как указывали выше. 0,02 - 0,022 в три - четыре итерации, семь точек.
На пьезо итерации до 11 доходили. И точность 0,05 - 0,1 смело. Плюс Сопло дырку законопачивает клеем.
Главное - что бы датчик максимально соосно с соплом был и не шатался.
Если он смещен на пару сантиметров от оси сопла - амба, даже на безлюфтовой магнитной дельте стол после калибровки оказывается завален в сторону смещения датчика.
С одной стороны будет колбаску класть, а с другой вмазыватся. А для Dondolo становится совсем грустно.
А значит и BLToutch для дельты ограниченно применим. Под соплом его не поставишь - высокий, смещение будет приличное при размещении сбоку.
Посему максимальная соосность, а лучше калибровка по соплу - например резистивный мост, на датчиках от весов.
Да даже косселевская схема с микриком или опто и хотенд на качельке.
Если бы не лень, то и бумажкой замечательно было бы )))

Сейчас пилю Dondolo с соосным выставлением (без смещения) сопел.
И учитывая прочие равные - проще делать навесной датчик без всяких лишних серв, пристегивая его под соплом, соосно с оным. И микрик от мышки тут вне конкуренции. Маленький, надежный, точный, легкий.
А если выставить z probe offset, то и забыть поставить датчик не страшно - сопло просто не доедет до стала и оттормозится с ошибкой.

Вся калибровка штатная G33
Марлин 1.9.x и 2

На Клиппере примерно то же самое, но точность похуже чуть, нет итераций и не показывает точность.

Для написания комментариев, пожалуйста, авторизуйтесь.

Читайте в блогах

Вентиляция. То, чего нет в магазинах.

Печать на Anycubic Photon S модели подготовленной в слайсере от Mango3D (Lychee Slicer)

Небольшие заметки о клиппере

Распродажа 3D принтеров в интернет-магазине 3DSN

Согревающая акция на RK Gadget!

Зубы в народ