Автоматическая калибровка на датчике веса на примере Rostock mini
Во всех моих 3д-принтерах меня каждый раз неимоверно бесила необходимость выставлять высоту сопла над уровнем стола. Необходимость эта возникала регулярно, при каждой замене сопла или каких-то других действиях с хотэндом, требовавших его разборки.
Периодически я видел всякие конструкции на базе датчиков приближения (холла), оптических датчиков и прочих шайтан-машин. Но все они требовали точно так же выставлять уровень сопла после каких-либо манипуляций с хотом. Правда, теперь уровень задавался относительно датчика, а не стола. Но радости это все равно не приносило.
Проблему решать надо было кардинально. Для этого нужно, чтобы в качестве датчика уровня использовалось само сопло.
Первое и самое очевидное решение - кинуть один провод на хот, второй на стол, и все это дело завсести на пины концевика. Надежное и дешевое решение, если у вас стол из алюминия без покрытия. У меня на столе лежит зеркало, и такой способ мне не подходит.
Второй способ был - поставить микрик на каретку так, чтобы касание соплом стола вызывало срабатывание микрика. Способ рабочий, но у меня не получилось избавиться от люфтов в креплении хот-энда, и я от него отказался.
Затем на просторах ютуба я увидел, как работает автоматическая калибровка на датчике веса. Правда, там пленочные датчики крепились на стол, но быстрый поиск по запасникам алиэкспресса выдал металлические датчики в виде брусков, на которые уже можно повесить хот-энд.
Я заказал модуль АЦП HX711 и сам датчик на 1кг. Спустя месяц ожидания все это дело было получено и настало время прикрутить эту красоту к принтеру.
Есть два варианта подключения. Первый - это подключить АЦП напрямую к мозгам принтера и сказать прошивке, что это датчик веса. Но это решение, на мой взгляд, сильно так себе. Во-первых, поддержка таких датчиков находится пока только в экспериментальном состоянии. Во-вторых, мозгам и так есть чем заняться помимо того, чтобы постоянно читать вес от датчика и пытаться понять, что там происходит. Значит нам нужен второй вариант: подключить это через промежуточный контроллер, который будет прикидываться концевиком для мозгов принтера. Его и выберем.
План действий будет следующий:
- Печатаем крепления датчика на эффектор
- Подключаем датчик веса к Arduino
- Подключаем Arduino с датчиком к мозгам принтера
- Редактируем прошивку принтера.
Крепления можно скачать тут. Вариант сыроватый, но рабочий и дорабатываемый по мере выявления недостатков.
Теперь подключаем контроллер к АЦП. Я нарыл в закромах Arduino Nano, но это не принципиально. На время отладки и калибровки сойдет и так, а дальше я поменяю на Attiny13, которая будет монтироваться вместе с платой АЦП прямо на эффектор для уменьшения уровня наводок по всем этим трактам. Почему на эффектор, а не рядом с основными мозгами принтера? Потому что для наилучшей точности стоит максимально укоротить провода между АЦП и датчиком веса. А если мы монтируем туда АЦП, то есть смысл прицепить туда и контроллер, чтобы от эффектора просто вести три провода к мозгам.
Также с этим АЦП есть нюанс: по умолчанию частота выборок АЦП составляет 10Гц, что слишком мало для нашего применения. То есть, технически, будет работать и так, но точность срабатывания будет плохой.
Для нормальной работы надо перевести АЦП в режим частоты опроса 80Гц. Для этого надо отцепить ногу RATE
от земли и посадить ее на VCC.
Тут есть два варианта, зависят от ревизии платы HX711.
Вариант с новой ревизией - просто отпаиваем резистор под которым написано 10Hz и запаиваем перемычку в красном квадрате (слева от которой написано 80Hz).
Если не повезло и пришла старая ревизия, то надо отпаять от платы вторую сверху ногу со стороны 4х-пинового разъема и подпаять ее к VCC или первой сверху ноге.
Все, модуль переключен в режим опроса 80Гц и наша жизнь стала немного прекраснее.
Зачем это проделывать? Так как показания датчика нестабильны из-за наличия вентилятора на голове и постоянных движений эффектора в процессе калибровки, то в скетче используется фильтр НЧ, который сглаживает скачки показаний датчика для большей надежности работы. Фильтр берет 10 значений веса и из них получает отфильтрованные показания. На частоте 80Гц выборка 10 значений занимает примерно 120мс, на частоте 10Гц - займет секунду. Соответственно, надо жертвовать фильтром, что будет приводить к ложным срабатываниям во время движения головы.
Подключаем датчик к АЦП. Соединяем провода:
- Красный -> E+
- Черный -> E-
- Белый -> A-
- Зеленый -> A+
Подключаем АЦП к Arduino:
- VCC -> 5V Arduino
- DT -> A2
- CLK -> A3
- GND -> GND Arduino
Клонируем репозиторий
git clone https://github.com/alpha6/HX711_endstop
и открываем в Arduino IDE скетч - Tenso_sensor.ino
В скетче меняем const bool DEBUG = false;
на const bool DEBUG = true;
Заливаем скетч в Arduino и через Serial monitor смотрим за показаниями.
2 раза в секунду там должна появляться строка
current weight! [848342] [848267]
цифры будут зависеть от нагрузки на датчик и погоды на Юпитере и могут плавать между измерениями, даже если датчик просто лежит на столе.
Убеждаемся, что значения датчика меняются при воздействии на него. Если меняются, значит, все собрано верно. Если нет - надо поменять местами провода DT и CLK. Я так один раз перепутал контакты DT и CLK: с виду все работало, но при попытке калибровки принтер попытался проломить соплом стол.
В установленном на принтер виде цифра от датчика должна увеличиваться при касании стола!
Теперь сделаем из Arduino концевик для мозгов принтера.
Для управления принтером у меня используется плата Melzi. Для RAMPS все будет сильно проще с точки зрения получения пинов и настройки прошивки.
Для этого нам понадобится любой оптрон и резистор на 1кОм. Оптрон я использовал 4n35, потому что он был под рукой. Любой другой подключается аналогично с разницей на нумерацию ног.
На плате Melzi всего 3 пина под концевики, на Дельте они все используются для калибровки осей. Так что нам нужен какой-то другой концевик. На своем принтере я не использую экран с кнопками, и у меня есть целый свободный разъем на 10 пин рядом с ISP, так что я буду использовать пин A1 оттуда. Для RAMPS никаких подобных телодвижений не надо, благо, концевиков у него хватает.
- Соединяем землю Arduino и пин 2 оптрона
- Сажаем пин 1 через резистор на пин D7
- Пин 4 оптрона соединяем с землей 10 пинового разъема на Melzi. Для RAMPS соединяем с землей концевика Z-Min
- Пин 5 отпрона соединяем с пином A1 10 пинового разъема на Melzi. Для RAMPS соединяем с сигнальным пином концевика Z-Min.
Схема подключения:
Устанавливаем датчик на принтер. После того, как все установлено, подводим датчик к столу. Задача - откалибровать порог срабатывания так, чтобы датчик срабатывал от касания стола, но не срабатывал от движений головы.
Для контроля срабатываний без заглядывания в сериал-монитор удобно подключить светодиод. Цепляем землю диода на пин 5 оптрона, а + через резистор на +5В. Теперь диод будет загораться при срабатывании датчика.
Теперь отредактируем прошивку.
Я не буду описывать конфигурацию прошивки с нуля, опишу только специфичные для калибровки вещи. По всему остальному в интернете полно гайдов, а эта статья и так здоровенная выходит. Предполагается, что все остальное уже настроено для Дельты, принтер работает и нужно только автокалибровку прикрутить.
Будем использовать самые последние решения в стане прошивкостроения.
Клонируем репозиторий Marlin
git clone https://github.com/MarlinFirmware/Marlin.git
Переключаемся на бранч RcBugFix потому что в master и RC автокалибровка на дельтах не работает.
cd Marlin
git checkout -b RcBugFix
Открываем прошивку в Arduino IDE. Настраиваем все, что необходимо, и приступаем к настройке автокалибровки. Первым делом нам надо добавить концевик Z-Min для Melzi. На RAMPS он есть, и этот пункт нужно пропустить.
N.B. Если у вас вообще не Дельта с хомингом в Z-MIN, то просто воткните Arduino в Z_MIN и смело пропускайте все настройки высот и прочее, что относится к дельтам или принтерам с хомингом стола в Z_MAX.
Открываем вкладку pins_SANGUINOLOLU_11.h
и после
#define E0_DIR_PIN 0
добавляем строки
#define Z_MIN_PROBE_PIN 30
#define Z_MIN_PIN 30
Технически, должно хватить только указания Z_MIN_PIN, но в той ревизии, что сейчас лежит в гите, есть баг, и сборка падает, если не задан Z_MIN_PROBE_PIN.
Сохраняем файл и переходим в Configuration.h
Раскомментируем строку
#define USE_ZMIN_PLUG
В строке
#define Z_MIN_PROBE_ENDSTOP_INVERTING false
false
меняем на true
Раскомментируем строку
#define FIX_MOUNTED_PROBE
Выставим смещения Z-Probe на 0
#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // Y offset: -front +behind [the nozzle]
#define Z_PROBE_OFFSET_FROM_EXTRUDER 0
Раскомментируем строку
#define Z_MIN_PROBE_ENDSTOP
Ну, и главная наша цель:
#define AUTO_BED_LEVELING_FEATURE
Тоже раскомментируем. Также раскомментируем строку
#define AUTO_BED_LEVELING_BILINEAR
Это единственный доступный тип автоуровня для Дельты. Сопло проходит по всему столу и строит квадратную карту высот, по которой потом печатает. В строке:
#define ABL_GRID_MAX_POINTS_X 3
регулируется кол-во точек на грани квадрата. Т.е., при настройке в 3 сопло проверит высоту в 9 точках. Если указать 9 - то точек будет 81, время калибровки возрастет соответственно.
Также стоит выставить высоту области печати в значение, близкое к реальному.
#define MANUAL_Z_HOME_POS 156.8
Сопло после выполнения G28
и получения G29
идет в минимум со скоростью, указанной для хоминга. Скорость эта по умолчанию составляет 2000 мм/мин, на некотором расстоянии от поверхности стола скорость сбрасывается в 2 раза и на этой скорости происходит касание. Если заданная в прошивке высота области печати будет сильно больше реальной, то сопло просто врежется на полном ходу в стол и датчик может не успеть сработать. Точнее, датчику на срабатывание надо 120мс, за это время сопло пройдет 4мм вниз. А дальше все зависит от прочности конструкции и силы моторов. Один раз таким образом у меня получилось разбить стекло на столе.
А если область печати будет меньше реальной, то от заданной области печати сопло будет идти со скоростью в 2 раза меньше скорости калибровки, и ждать окончания процесса придется очень долго.
Скорости хоминга по Z регулирются этими строками:
#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)
Еще можно включить опцию двойного касания, дает большую точность (в теории), но и занимает больше времени:
#define PROBE_DOUBLE_TOUCH
Заливаем прошивку в принтер. Проверяем, что работает G28
, командой M119 проверяем, что концевик Z-MIN
в состоянии open
.
Теперь откалибруем датчик веса на нужный уровень срабатывания.
Для этого подводим голову к поверхности стола и прижимаем сопло к столу. В этот момент должен сработать датчик. Если этого не произошло, уменьшаем порог срабатывания:
long trigger = 13000;
Имеет смысл уменьшать сразу на 1000, но это зависит от используемого датчика. У меня датчик срабатывает от легкого касания сопла пальцем. Чемь меньше будет порог срабатывания, тем лучше, но без фанатизма. Он не должен срабатывать от торможения каретки при калибровке, например.
Датчик работает. В качестве финального штриха к портрету, проверяем, что в разных положения эффектора в области печати не срабатывает датчик из-за натяжения трубки боудена или проводов вентилятора. Пишу этот пункт по собственному опыту, ибо я долго боролся со срабатыванием датчика при торможении каретки, а оказалось, что это трубка боудена дергала хот вверх со всеми вытекающими. После изменения положения мотора экструдера проблема ушла.
Теперь, когда все проверено, говорим G29. Голова поедет вниз и начнет тыкаться в стол согласно количеству точек, указанных в прошивке. После окончания калибровки будет выдана карта высот. Стоит убедиться, что все значения в ней находятся на одном уровне в переделах погрешности (второй цифры после запятой). Ну, это если стол ровный, без бугров, впадин и перекосов.
Все. На этом процесс настройки автокалибровки завершен, и можно заняться ее тюнигом.