Автоматическая калибровка на датчике веса на примере Rostock mini

Tags:

Во всех моих 3д-принтерах меня каждый раз неимоверно бесила необходимость выставлять высоту сопла над уровнем стола. Необходимость эта возникала регулярно, при каждой замене сопла или каких-то других действиях с хотэндом, требовавших его разборки.

Периодически я видел всякие конструкции на базе датчиков приближения (холла), оптических датчиков и прочих шайтан-машин. Но все они требовали точно так же выставлять уровень сопла после каких-либо манипуляций с хотом. Правда, теперь уровень задавался относительно датчика, а не стола. Но радости это все равно не приносило.

Проблему решать надо было кардинально. Для этого нужно, чтобы в качестве датчика уровня использовалось само сопло.

Первое и самое очевидное решение - кинуть один провод на хот, второй на стол, и все это дело завсести на пины концевика. Надежное и дешевое решение, если у вас стол из алюминия без покрытия. У меня на столе лежит зеркало, и такой способ мне не подходит.

Второй способ был - поставить микрик на каретку так, чтобы касание соплом стола вызывало срабатывание микрика. Способ рабочий, но у меня не получилось избавиться от люфтов в креплении хот-энда, и я от него отказался.

Затем на просторах ютуба я увидел, как работает автоматическая калибровка на датчике веса. Правда, там пленочные датчики крепились на стол, но быстрый поиск по запасникам алиэкспресса выдал металлические датчики в виде брусков, на которые уже можно повесить хот-энд.

Я заказал модуль АЦП HX711 и сам датчик на 1кг. Спустя месяц ожидания все это дело было получено и настало время прикрутить эту красоту к принтеру.

Есть два варианта подключения. Первый - это подключить АЦП напрямую к мозгам принтера и сказать прошивке, что это датчик веса. Но это решение, на мой взгляд, сильно так себе. Во-первых, поддержка таких датчиков находится пока только в экспериментальном состоянии. Во-вторых, мозгам и так есть чем заняться помимо того, чтобы постоянно читать вес от датчика и пытаться понять, что там происходит. Значит нам нужен второй вариант: подключить это через промежуточный контроллер, который будет прикидываться концевиком для мозгов принтера. Его и выберем.

План действий будет следующий:

  • Печатаем крепления датчика на эффектор
  • Подключаем датчик веса к Arduino
  • Подключаем Arduino с датчиком к мозгам принтера
  • Редактируем прошивку принтера.

Крепления можно скачать тут. Вариант сыроватый, но рабочий и дорабатываемый по мере выявления недостатков.

Теперь подключаем контроллер к АЦП. Я нарыл в закромах Arduino Nano, но это не принципиально. На время отладки и калибровки сойдет и так, а дальше я поменяю на Attiny13, которая будет монтироваться вместе с платой АЦП прямо на эффектор для уменьшения уровня наводок по всем этим трактам. Почему на эффектор, а не рядом с основными мозгами принтера? Потому что для наилучшей точности стоит максимально укоротить провода между АЦП и датчиком веса. А если мы монтируем туда АЦП, то есть смысл прицепить туда и контроллер, чтобы от эффектора просто вести три провода к мозгам.

Также с этим АЦП есть нюанс: по умолчанию частота выборок АЦП составляет 10Гц, что слишком мало для нашего применения. То есть, технически, будет работать и так, но точность срабатывания будет плохой. Для нормальной работы надо перевести АЦП в режим частоты опроса 80Гц. Для этого надо отцепить ногу RATE от земли и посадить ее на VCC. HX711 schema

Тут есть два варианта, зависят от ревизии платы HX711.

Вариант с новой ревизией - просто отпаиваем резистор под которым написано 10Hz и запаиваем перемычку в красном квадрате (слева от которой написано 80Hz). HX711 new

Если не повезло и пришла старая ревизия, то надо отпаять от платы вторую сверху ногу со стороны 4х-пинового разъема и подпаять ее к VCC или первой сверху ноге. HX711 old

Все, модуль переключен в режим опроса 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.

Схема подключения:

4n35

Устанавливаем датчик на принтер. После того, как все установлено, подводим датчик к столу. Задача - откалибровать порог срабатывания так, чтобы датчик срабатывал от касания стола, но не срабатывал от движений головы.

Для контроля срабатываний без заглядывания в сериал-монитор удобно подключить светодиод. Цепляем землю диода на пин 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. Голова поедет вниз и начнет тыкаться в стол согласно количеству точек, указанных в прошивке. После окончания калибровки будет выдана карта высот. Стоит убедиться, что все значения в ней находятся на одном уровне в переделах погрешности (второй цифры после запятой). Ну, это если стол ровный, без бугров, впадин и перекосов.

Все. На этом процесс настройки автокалибровки завершен, и можно заняться ее тюнигом.

Добавляем второй экструдер к RAMPS 1.4/Marlin

Tags:

В прошлой серии мы установили прошивку Marin на Arduino Mega+RAMPS 1.4 и откалибровали все это дело. Теперь пришло время добавить второй экструдер.

Для этого нам понадобится:

  • второй экструдер
  • второй хот-энд в сборе и все прилегающие детали, типа трубки боудена
  • каретка на два экструдера. Я использую такую.

В общем случае все просто идем в Arduino IDE и правим конфигурацию.

Меняем конфигурацию платы управления на RAMPS 1.4 c 2 экструдерами и подогреваемым столом

#ifndef MOTHERBOARD
  #define MOTHERBOARD BOARD_RAMPS_14_EEB
#endif

Указываем кол-во экструдеров:

#define EXTRUDERS 2

Указываем тип датчика температуры для второго экструдера:

#define TEMP_SENSOR_1 1

Максимальную температуру:

#define HEATER_1_MAXTEMP 250

Если надо, устанавливаем направление вращения мотора:

#define INVERT_E1_DIR true

В целом, если у вас одинаковые моторы на обоих экструдерах, то на этом настройка закончена.

Но если у моторы разные или на одном экструдере у меня мотор с шестерней подачи диаметром 10мм, а на втором - 7мм, то тут начинаются проблемы с калибровкой.

Как откалибровать второй экструдер? Идем в пронтерфейс и говорим:

T1

Эта команда указывает что сейчас активен экструдер номер 2 (отсчет начинается с 0). Включаем подачу филамента, для подачи будет использоваться число шагов из прошивки, т.е. для первого экструдера. Смотрим разницу и с помощью пропорции получаем кол-во шагов для активного экструдера. У меня из-за разницы в подающих шестернях получилось 80 шагов на мм.

Говорим:

M92 E80

Этим мы устанавливаем новое кол-во шагов для текущего экструдера. Проверяем, при необходимости подгоняем значение.

После калибровки вылезает проблема - Marlin не поддерживает установку разного числа шагов для разных экструдеров, соответственно в прошивке нам эти данные не сохранить. Придется этот вопрос решать програмно.

Напишем небольшой фильтр которым будем обрабатывать готовый g-code файл.

#!/usr/bin/env perl

use strict;

my $T0 = 'M92 E95';
my $T1 = 'M92 E80';

local $^I = '.bak';
while (<>) {
    s/^T0/T0\n$T0/;
    s/^T1/T1\n$T1/;
    print;
}

Этот скрипт ищет команду T и заменяет ее нужным нам значением. В данном случае добавляет команду M92 E. Скрипт получает на вход имя файла, перебирает его построчно и в каждой строке заменяет совпадения на то что мы указали. Оригинальный файл сохраняется с расширением .bak.

Дальше нам надо задать смещение экструдеров

Для Slic3r идем в Printer Settings -> Extruder 2 и выставляем смещение. Примерное смещение можно получить если измерив расстояние между соплами, однако программое расстояние может отличаться от физического расстояния, так что все равно придется заняться калибровкой.

Для этого печатаем деталь для калибровки 2х экструдеров и точно подгоняем все для идеальной работы.

Настраиваем прошивку Marlin для Arduino + RAMPS 1.4

Tags:

Так получилось что некоторое время назад я стал владельцем китайского клона Prusa i3 под гордым китайским названием Hesine M505. Это чудо китайской мысли конечно было далеко от совершенства, но с задачей печатать все подряд справлялось вполне успешно. Однако, чем дальше в лес - тем толще партизаны. И забравшись в лес подальше возжелал я печатать детали с использованием растворимых поддержек, да и двумя цветами печатать тоже было бы неплохо.

К сожалению, у родной для принтера платы Melzi V2 был фатальный недостаток - на ней отсутсвовал порт для подключения второго экструдера. Изучение матчасти показало, что можно взять еще одну такую же плату и воткнуть ее в режиме слейва. Однако ценник на это удовольствие получался высоковатым. И, что самое неприятно, при таком апгрейде терялась возможность подключения экрана и кнопок управления. Т.е. печатать можно будет только с компьютера, а это не самая лучшая идея по многим причинам.

Так я пришел к решению полностью заменить мозги принтера. Выбор был сделан в пользу нестареющей класски Arduino Mega 2560 + RAMPS 1.4 + A4988. Быстро сказка сказывается, да долго посылочка едет. Получив посылку с мозгами, моторами и прочим полезным в хозяйстве инвентарем я обнаружил что забыл заказать шестерню податчика экструдера. Благо на тот момент она уже ехала ко мне с али, где я заказал ее просто так, от жадности.

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

Ставить мы будем классику жанра - Marlin. Клонируем репозиторий в любое удобное место отсюда https://github.com/MarlinFirmware/Marlin. Скачиваем Arduino IDE.

В Arduino IDE открываем прошивку. Выбираем нашу плату Arduino Mega 2560 и процессор AtMega 2560.

Дальше нас интересует вкладка с файлом Configuration.h, теперь мы будем его безудержно править.

Выбираем нашу плату: RAMPS 1.4 с одним хотэндом

#ifndef MOTHERBOARD
  #define MOTHERBOARD BOARD_RAMPS_14_EFB
#endif

В файле boards.h приведен полный список поддерживаемых плат и их вариаций. Нас пока интересует только RAMPS 1.4 с одним экструдером.

Выставляем кол-во температурных сенсоров. Сенсоров должно быть по числу экструдеров. В нашем случае 1. Убеждаемся что напротив первого сенсора в списке стоит 1.

#define TEMP_SENSOR_0 1

Выставляем максимальную температуру хотэнда и стола.

#define HEATER_0_MAXTEMP 250
#define BED_MAXTEMP 130

У меня стоят термопредохранители на 252 градуса, так что максимальная температура хота должна быть ниже температуры срабатывания предохранителя. Если собираетесь печатать чем-то вроде поликарбоната - то температуру надо поднять. Со столом таже история, единственное что даже печать нейлоном не требует очень больших температур стола, 130 градусов должно хватить всем.

В Hesine M505 стоят нормально замкнутые концевики, а в прошивка по умолчанию рассчитывает на нормально разомкнутые. Включаем инвертирование концевиков:

// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.

Проверяем направление вращения моторов. Тут история примерно таже что и с концевиками, т.к. прошивка изначально рассчитана на Ultimaker.

// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
#define INVERT_X_DIR true
#define INVERT_Y_DIR true
#define INVERT_Z_DIR false

И для экструдера повторяем операцию.

#define INVERT_E0_DIR true

Выставляем размеры рабочей зоны

#define X_MIN_POS 0
#define Y_MIN_POS 0
#define Z_MIN_POS 0
#define X_MAX_POS 250
#define Y_MAX_POS 230
#define Z_MAX_POS 140

Для начала можно выставить заводомо большие чем рабочая зона габариты. Потом все откалибруется по месту. По умолчанию в прошивке стоят значени 200х200х200, тогда как у Hesine M505 рабочее поле по всем направлениям больше чем эти цифры. И прошивка просто не даст двигаться за их пределы.

Устанавливаем координаты начала стола. Это нужно чтобы ноль стола в слайсере совпадал с нулем в координатах принтера. Иначе модель может вылезать за пределы зоны печати.

#define MANUAL_X_HOME_POS -30
#define MANUAL_Y_HOME_POS -20

Выставляем шаги для моторов.

#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,1600,95}

Параметры тут следующие: мотор_Х, мотор_Y, мотор_Z, мотор_экструдера

Для рассчета шагов по X и Y используем следующую формулу:

(200*16)/(16*2)=80 шагов

Где 200 - это число шагов двигателя на 360 градусов. Типичная цифра для моторов с шагом 1.8 градуса. 16 в числителе - кол-во микрошагов на шаг. 16 в знаменателе - кол-во зубов на шпуле. 2 - стандартный шаг для ремня GT2

Для Z:

3200/2 = 1600

В Hesine M505 штатно используется трапециидальный винт с шагом резьбы 2мм. Соответственно мы белим число шагов на полный оборот на кол-во миллиметров которые будут пройдены за оборот и получаем число шагов на миллиметр.

Подачу экструдера пока посчитаем и выставим предварительно. Потом ее все равно придется подгонять. Шестерня экструдера штатно имеет диаметр около 10мм. Получаем длинну окружности на один оборот: 3.14*10=31.4 мм на оборот.

Делим число шагов на длинну окружности и получаем число шагов на миллиметр.

3200/31.4=101.9

округляем до 102.

Заливаем все это дело в Arduino.

После того как все залилось и все железо подключено запускаем Pronterface и начинаем калибровку.

  • Двигаем моторы и проверяем что они крутятся в нужную сторону. Если это не так - меняем параметр INVERT_*_DIR на противоположное значение.
  • Проверяем состояние концевиков. По команде M119 будет показано состояние концевиков. Если концевик нажат - напротив него должно быть написано TRIGGERED. Напротив ненажатого - open. Если это не так - меняем настройку *MINENDSTOP_INVERTING.
  • Даем команду G28. Все оси должны приехать в свое минимальное положение. Дальше через Pronterface двигаем все оси в их безопасное максимальное положение и даем комаду M114. Она покажет текущее положение по осям. Вносим эти данные в настройку *MAXPOS.
  • Опять говорим G28. Передвигаем экструдер в нулевую координату стола по X-Y. Смотрим что показывает M114 и эти цифры переносим в MANUAL_*HOMEPOS с обратным знаком. Т.е. если M114 говорит что координата по Х сейчас 30 - то в настройку пишем -30. Это значит что после ухода в HOME экструдер отъедет от него на 30мм и будет считать это положение нолем.
  • откручиваем сопло или трубку боудена у экструдера. На прутке отмечаем расстояние, например 10 см, и прогоняем эту же длинну из Pronterface. После этого смотрим сколько в реальности прошло прутка и корректируем кол-во шагов для экструдера чтобы он прогонял четко нужное кол-во пластика. Важно понимать что на горячую с установленным соплом эта цифра все равно будет отличаться от установленного. Если вы всегда печатаете соплом одного диаметра - можно повторить эту операцию с соплом и полученные данные внести в прошивку. Я использую несколько сопел, так что объем пластика корректирую через настройку потока в слайсере.

После того как все это сделано - печатаем тестовую модель. Я использую пустой куб 20х20х20 мм. После того как он отпечатан - проверяем что размеры сторон у нас точно соответсвуют тому что должно быть. Если это не так по отдельным измерениям - корректируем кол-во шагов для нужной оси.

На этом основные настройки закончены. Дальше можно тюнить приведенные выше параметры для более качественной печати.

Яндекс.Метрика