[Из песочницы] Печатаем картинки с помощью Arduino
Очень давно хотелось сделать какой-нибудь проект на Ardoino, да такой, чтобы всё в нём двигалось и работало. И, спустя пару месяцев проектирования, программирования и сборки получился вот такой мини-принтер, с помощью которого можно печатать разнообразные картинки и текст на самых обычных стикерах. Если после просмотра видео Вы загорелись необъятным желанием сделать нечто подобное — прошу под кат.
Что нам понадобится
- Arduino Uno. Для этого проекта я использовал оригинальную итальянскую плату Arduino Uno. Не произойдет совершенно ничего страшного, если в этом проекте использовать её китайский аналог, который будет стоить в несколько раз дешевле.
- Сервоприводы sg-90 — 3 штуки. Это самые дешёвые и маленькие сервоприводы из ныне существующих.
- Любой стержень. Я использовал для этого алюминиевый пруток 5 мм, который можно купить в любом строительном магазине
- Клей. В этом проекте я использовал 3 вида клея: столярный для фанеры, супер-клей для соединения шестерней с осями, также мне понадобился термический клей для крепления сервоприводов. Можно так сильно не запариваться и собрать все на какой-нибудь универсальный клей «Момент».
- Наждачная бумага. Даже при очень точном изготовлении деталей им потребуется подгонка, поэтому без шлифовки — никуда.
- Станок для лазерной резки (опционально). Если за Вас все детали сделает машина — это хорошо, но вполне реально сделать этот проект дома на коленке, используя обычный ручной лобзик. Первую версию принтера я делал именно так.
- Фломастер. Можно использовать несколько фломастеров для печати цветных картинок
- Пружинка и оси с маленьким диаметром. Для этого идеально подойдет «щелкающая» ручка, из которой можно достать пружинку и использовать её стержень в качестве оси
- Фанера 4 мм. Можно найти в строительном или хобби-магазине. Возможно, подойдут и другие варианты, например, оргстекло.
- Чертежи. Ссылки на них я оставлю здесь:
- Чертежи для лазерной резки;
- Чертежи для выпиливания вручную.
Собственно реализация
Изготовление деталей
Этот этап зависит от вашего желания и ваших возможностей. Можете вырезать на станке или выпиливать все детали вручную. Главное, что здесь надо отметить — это то, что качество и работоспособность этого проекта напрямую будет зависеть от вашей аккуратности. Также надо учитывать такой момент: некоторые детали, которые Вы увидите на фотографиях могут немного отличаться от тех, что будут на чертежах.
Самое сложное здесь — это пазо-шиповое соединение деталей и изготовление шестеренок.
Алгоритм здесь такой. распечатываете чертежи, наклеиваете их на фанеру. Затем сверлите все необходимые отверстия в местах внутренних контуров. Контуры пазов следует выпиливать, отступая немного места внутрь, чтобы потом шипы (после небольшой обработка надфилем) вошли в них внатяг. После этого выпиливаем внутренние контуры, отрываем/сошкуриваем бумагу, которую наклеили и шлифуем. Ничего сложного в этом нет, главное — работать аккуратно и не торопиться.
Чтобы этот текст не казался таким сухим, разбавлю его этапами изготовления шестеренки:
Собираем боковые стенки
Пока всё просто: берете детали и склеиваете их. Следите за перпендикулярностью и за тем, чтобы на деталях не оставалось лишнего клея.
Приклеиваем ножки к основанию
Эти ножки представляют только эстетическую ценность. Если вы хотите сэкономить немного времени, то этот этап можно пропустить
Собираем корпус воедино
Текст на передней и задней табличках можете изменить на свой вкус.
Делаем площадку для бумаги
Этот этап требует особой аккуратности и тщательности выполнения работы. Особую сложность представляют «Г»-образные рельсы, на которых и будет держаться вся эта площадка.
Вам нужно аккуратно приклеить тонкие полоски точно по рискам, указанным в чертеже. Для лучшего эффекта я использовал такие необычные «прищепки», но можно спокойно обойтись и без них. Главное — убрать лишний клей и следить за тем, чтобы полоски никуда не съехали. Дальше на них сверху приклеиваем полоски пошире — технология здесь такая же.
После того, как клей высохнет (минимум 20 минут), попробуйте вставить площадку в корпус. Если она зайдет туда, как по маслу и сможет совершать четкие движения вперед-назад, то вам сильно повезло — это именно то, что надо. В противном случае — берём в руки наждачную бумагу и шкурим те места рельсов площадки, на которых она у нас клинит.
С приклеиванием зубчатых реек проблем быть не должно. Следите за тем, чтобы они приклеились перпендикулярно.
Переходим к сборке механизма, удерживающего бумагу. Проблемы не должны возникнуть если собирать всё в такой последовательности. Сначала приклеиваем стойки, на них закрепляем рычажки. Потом к ним приклеиваем полоску фанеры, которая будет удерживать лис бумаги. А уже потом приклеиваем ту часть, в которую будут упираться пружинки.
Если всё было сделано правильно, то Ваш принтер должен выглядеть примерно вот так:
Протяжный механизм
Вот мы наконец и добрались до шестеренок… Их нужно просто насадить на заранее подготовленный стержень длиной около 110 мм так, как показано на фото ниже и приклеить на супер-клей (его надо наносить равномерно на стенки центрового отверстия шестеренки). Следите за тем, чтобы зубья шестеренок подходили к зубчатой рейке.
После того, как клей высохнет, попробуйте аккуратно прокрутить стержень — площадка должна двигаться.
Устанавливаем первый сервопривод
Первым делом нужно подготовить шестеренку для моторчика. В комплекте с каждым серво идет несколько пластиковых качелек. Их надо обрезать и обточить так, как показано на рисунке ниже. А затем вклеить её в шестерню.
А теперь переходим к установке привода. Для начала задвиньте площадку для бумаги до конца в принтер и прокрутите Ваш серво против часовой стрелки до упора. Затем надо подобрать оптимальное положение привода, то есть закрепить сервопривод так, чтобы у шестеренок не было больших люфтов, но при этом они не упирались друг в друга.
А теперь можно проверить, всё ли у нас работает. Для этого подключите серво к Вашему Arduino через pin9 и загрузите скетч из Образцов: Servo > Sweep. Его код я, на всякий случай, привожу ниже.
#include
#define MIN_ANGLE 0
#define MAX_ANGLE 180
Servo servo;
void setup() {
servo.attach(9);
}
void loop() {
for(int i=MIN_ANGLE; i<=MAX_ANGLE; ++i) {
servo.write(i);
delay(15);
}
for(int i=MAX_ANGLE; i>=MIN_ANGLE; --i) {
servo.write(i);
delay(15);
}
}
Если всё заработало — замечательно. Если нет — попробуйте поменять положение привода или значения MIN_ANGLE и MAX_ANGLE в коде.
Устанавливаем второй сервопривод
Здесь всё делается аналогично с первым мотором. Единственное отличие — понадобится небольшая ось длиной ~12 мм, чтобы закрепить две шестерни.
Ставим печатающую каретку
Если Вы сумели добраться до этого этапа, то особых трудностей у вас здесь быть не должно. Самое сложное здесь — аккуратно собрать каретку (чтобы она не болталась и не клинила), возможно, придется поработать наждачной бумагой. Следующая возможная проблема — неправильно приклеенная зубчатая рейка. Она должна идти строго параллельно основанию корпуса, клеить ее лучше, когда каретка находится в самом дальнем от сервопривода положении.
Проверяем эту сборку с помощью Arduino и вышеупомянутого скетча, если всё работает, как надо, то переходи к следующему этапу. Если нет, то проблема скорее всего связана с шестеренками или неправильно приклеенной зубчатой рейкой.
Последний сервопривод
На этом этапе собираем рычажок для фломастера. Нужно суметь просверлить сбоку отверстие для шурупа, которым мы будем поджимать винт. Постарайтесь, чтобы в состоянии, когда фломастер опущен, серво имел положение 90 градусов, тогда Вам не придется делать лишних исправлений в коде.
После установки мотора наш принтер будет уже почти готов. Рекомендую заклеить поверхность площадки для бумаги малярным скотчем, в процессе отладки принтера она может серьёзно испачкаться.
Первый запуск и отладка
Для начала мы подключаем серво к нашему Arduino Uno, не обязательно на данном этапе помещать его внутрь принтера, так будет неудобно работать. Первый мотор подключаем к pin2, второй — к pin4, третий — к pin6. Далее загружаем вот этот скетч (весь код я постарался подробно и понятно закомментировать, сильно в его подрробности вдаваться не буду):
#include
/*
* MiniPrinter
* Designed in May 2015
* By Alexandrow Yegor
*/
//Структура мотора, хранящая диапазон допустимых углов и экземпляр класса Servo
struct Motor {
int min_angle, max_angle;
Servo servo;
};
#define IMG_W 64 //Ширина изображения
#define IMG_H 64 //Высота изображения
int STEP = 2; //Градус поворота серво на 1 пиксель
#define IDLING_MS 4 // Время, тербующееся на поворот в 1 градус
#define WRITING_MS 8
struct Motor motor_x, motor_y, motor_p;
byte img[IMG_W/8]; //Изображение передается построчно
//Один пиксель = один бит
struct Motor newMotor(int pin, int a1, int a2) { //Инициализация мотора
struct Motor m;
m.servo.attach(pin);
m.min_angle = a1;
m.max_angle = a2;
return m;
}
void gotoStart() {
motor_p.servo.write(motor_p.max_angle); //Поднятие фломастера
delay(15);
//Перемещение в точку (0; 0)
motor_x.servo.write(motor_x.min_angle);
motor_y.servo.write(motor_y.min_angle);
delay(IDLING_MS * STEP * IMG_W + 150);
}
void finish() { //Закрыть принтер
motor_p.servo.write(motor_p.max_angle);
delay(15);
motor_x.servo.write(motor_x.min_angle);
motor_y.servo.write(motor_y.max_angle);
delay(IDLING_MS * STEP * IMG_W + 150);
}
void setup() { //Инициализация
Serial.begin(9600);
motor_y = newMotor(2, 50, 180);
motor_x = newMotor(4, 30, 160);
motor_p = newMotor(6, 90, 99);
gotoStart();
}
//Проверяет, есть ли в строке черные пиксели, которые еще не были напечатаны
boolean nextWayIsEmpty(int i) {
for(; i
Если Вы до этого момента уже протестировали и отладили все системы, то проблем быть не должно: площадка для бумаги должна слегка дернуться, а печатающая каретка должна занять крайнее левое положение. Если что-то из вышеперечисленного не доходит до краев, или, напротив, упирается в стенки, попробуйте подобрать параметры в функции setup ().
Если Вы столкнулись с проблемами посерьёзнее, рекомендую перечитать внимательно весь туториал еще раз, и проверить, все ли Вы сделали правильно. А еще будет неплохо в таком случае проверить каждый моторчик еще раз с помощью первого листинга (Servo sweep).
Далее мы подключаем наш принтер к компьютеру и запускаем вот эту программу (нужна установленная java).
Сначала мы выбираем тот последовательный порт, к которому подключен принтер и нажимаем кнопку «OK», после чего принтер должен слегка подёрнуть площадкой для бумаги. Затем нажимаем кнопку «Log». У нас открылось окно терминала. Далее вводим команду CL — принтер должен задвинуть площадку внутрь. Если ввести ST, то принтер вернется в исходное положение. Также можно отправлять несколько команд подряд, например: CLSTCL. Главное не использовать пробелов и других символов между командами.
Если с эти справились, идём дальше — устанавливаем рычажок с фломастером. Для начала закрепим фломастер на рычаге. расстояние от его кончика до нижней грани рычага должно составлять около 25 мм. После чего нужно вкрутить шуруп так, чтобы фломастер закрепился и никуда не делся. Теперь просто надеваем этот рычаг на ось сервопривода — расстояние от кончика фломастера до бумаги должно составлять около 7 мм. Более точно высоту можно отрегулировать с помощью команд PT+1 и PT-1. Они регулируют угол подъема фломастера, вместо 1 может быть любое число от 0 до 9.
А теперь настал самый ответственный момент — печать первого рисунка. Маленькие картинки разрешения 64×64 подходят лучше всего. Я рекомендую использовать вот этого Марио:
Скачать
Сначала нужно открыть изображение:
С помощью ползунков справа можно настроить контрастность изображения на свой вкус. Стоит помнить, что чем больше чёрных пикселей — тем дольше будет печататься картинка.
Это всё. Потом Вы просто нажимаете кнопку «Print» и любуетесь тем, как работает ваше творение. Единственная возможная проблема на этом этапе — нажатия фломастера. Он будет либо давить слишком сильно, либо не давить совсем. Помимо управления высотой фломастера через терминал, можно попробовать подстроить высоту вручную.
Также вы можете на свой страх и риск поменять значения глобальных переменных в скетче: поиграть со скоростью и размерами печати.
Как только вы будете довольны качеством получаемой картинки, можете смело помещать Arduino в корпус принтера, прикрутив её винтами — на этом Ваш проект можно считать завершенным, можете хвастаться им перед всеми друзьями!
Заключение
На этом всё, надеюсь, вам был интересен этот проект. В нём, конечно есть свои недостатки особенности реализации, так что ещё есть куда стремиться, что совершенствовать и что развивать. Буду рад любым советам, вопросам и пожеланиям в комментариях.