Порой во мне загорается огонек изобретателя, и я часами сижу и что-то паяю/выпиливаю. Так случилось в этот раз. Я загорелся идеей создать свой принтер. Тема создания 3d принтера уже избита, да и материально затратная. Немного подумав, я решил сделать бюджетный вариант принтера, который мог бы рисовать карандашом/ручкой/фломастером. А вспомнив свои попытки нарисовать что-то в стиле Dotwork, я остановил свой выбор на принтере, который автоматизирует именно этот процесс. Итого были сформированы следующие требования к принтеру:
- дешево
- для рисования используются подручные средства
- на выходе получаются рисунки в стиле Dotwork
А когда оказалось, что этот проект можно продвинуть как курсовую работу, было окончательно решено: принтеру быть. Чтобы конструкция получилась не слишком большой, размер области для печати был взят как А5.
Каркас
Процесс начался с поиска схемы для основы. Выбор пал на H-bot, так как он легок в реализации, недорог и, в отличие от CoreXY, в нем не надо резать ремень. Как видно из схемы, потребуется 2 шаговых двигателя, 4 оси и 1 ремень.
Для основы были использованы бруски с сечением 20*40. Конечно, лучше использовать фанеру и вырезать на ней нужные отверстия, тогда конструкция получилась бы более ровной и презентабельной, но из-за того, что кусок фанеры транспортировать и обрабатывать сложнее, были выбраны бруски.
Крепления для направляющих и подшипники к ним были куплены в Китае. Рассчитаны они на направляющие с диаметром 8мм. После непродолжительных поисков было решено сделать оси из спиц для вязания. Дешево, как раз нужной длины, легко распилить. К тому же, как оказалось, на спицах хорошо выдавливаются бороздки подшипниками. Это свойство позволило конструкции свободно двигать вдоль направляющих, несмотря на отсутствие у них параллельности.
Так как это все равно прототип, то линейные подшипники были закреплены проволокой. Крепко, надежно и если что, можно быстро снять.
Двигатель был куплен с шагом 0.9 градуса для наибольшей точности. Когда я поставил двигатели, обнаружилась новая проблема: шляпки на двигателях не подходили к ремню — происходило проскальзывание при полном обороте. Первоначальные попытки снять не увенчались успехом, нагревание/охлаждение никак не помогали, поэтому было принято зверское, но действенное решение:
Чтобы ремень не слетал, весь путь по платформе должен быть на одном уровне. В связи с этим, под подшипники пришлось подкладывать деревяшки, чтобы регулировать их высоту. Но и это не спасало от слета ремня. И снова на помощь пришла проволока:
Для управления двигателями была использована Arduino Uno, а точнее ее китайская копия. Как оказалось, вполне бы хватило и Arduino mini. Питания от arduino для двигателей не хватало, и поэтому был заказан MOTOR SHIELD L293D. Как блок питания был использован блок питания от старого модема, из всего найденного под рукой он выдавал наибольший вольтаж — 9V (двигатели рассчитаны на 5-12V). Для простоты подключения из модема был выломан вход, к нему припаяны 2 проводка и все это было подключено к shield. Shield насаживался на arduino.
Изначально для управления фломастером планировалось использовать систему из 2 колес, как в прокатных станках, но, для быстроты исполнения, крепление было сделано сразу на сервоприводе. Получается, что точки ставятся не кончиком фломастера, а боком. К первоначальной идее планируется вернуться в следующей версии принтера. Сервопривод также подключается к shield.
Наполнение кодом
Для arduino был написан код, который принимает от ПК по Serial Port команду в виде строки из 9 символов. Первый символ это код команды, далее идут по 4 символа на координаты X и Y. Ссылка на код на стороне ПК будет в конце статьи.
#include <AFMotor.h>
#include <Servo.h>
AF_Stepper motor(2048, 1);
AF_Stepper motor2(2048, 2);
Servo servo1;
int x0 = 0;
int y0 = 0;
int K = 1;
void setup() {
motor.setSpeed(15);
motor2.setSpeed(15);
servo1.attach(10);
servo1.write(65);
Serial.begin(9600);
}
void OneTouch(){
servo1.write(60);
delay(50);
servo1.write(65);
}
void MoveRight(int h){
motor.step(h, FORWARD, SINGLE);
motor2.step(h, FORWARD, SINGLE);
}
void MoveDown(int h){
motor.step(h, BACKWARD, SINGLE);
motor2.step(h, FORWARD, SINGLE);
}
void MoveUp(int h){
motor.step(h, FORWARD, SINGLE);
motor2.step(h, BACKWARD, SINGLE);
}
void MoveLeft(int h){
motor.step(h, BACKWARD, SINGLE);
motor2.step(h, BACKWARD, SINGLE);
}
void OnePointer(int x, int y){
int stepX = x - x0;
int stepY = y - y0;
if (stepX > 0)
MoveRight(stepX);
else
MoveLeft(-stepX);
if (stepY > 0)
MoveDown(stepY);
else
MoveUp(-stepY);
x0 = x;
y0 = y;
OneTouch();
}
void Move(int x, int y){
int stepX = x - x0;
int stepY = y - y0;
int kX, kY;
while ((stepX != 0) || (stepY != 0)){
kX=K;
kY=K;
if (kX> abs(stepX))
kX = abs(stepX);
if (kY> abs(stepY))
kY = abs(stepY);
if (stepX > 0){
MoveRight(kX);
stepX-=kX;
}
if (stepX < 0){
MoveLeft(kX);
stepX+=kX;
}
if (stepY > 0){
MoveDown(kY);
stepY-=kY;
}
if (stepY < 0){
MoveUp(kY);
stepY+=kY;
}
}
x0 = x;
y0 = y;
OneTouch();
}
void loop() {
while (Serial.available() == 0);
String buffer ="";
int i = 0;
delay(100);
while(i < 9) {
buffer += Serial.read();
i++;
}
String code = buffer.substring(0,1);
code.trim();
int cod = code.toInt();
String first = buffer.substring(0,5);
first.trim();
int x = first.toInt() - cod*10;
String second = buffer.substring(0,9);
second.trim();
int y = second.toInt() - x*10000 - cod * 100000;
switch (cod){
case 0:
Move(x,y);
OneTouch();
break;
case 1:
servo1.write(65);
delay(50);
Move(x,y);
break;
case 2:
servo1.write(60);
delay(50);
Move(x,y);
servo1.write(65);
break;
case 3:
servo1.write(65);
delay(50);
break;
case 4:
servo1.write(60);
delay(50);
break;
case 5:
Move(x,y);
break;
case 6:
Move(0,0);
motor.release();
motor2.release();
break;
case 7:
K=x;
break;
}
Serial.print(1);
}
Приложение на стороне ПК позволяет загрузить изображение, перевести в черно-белые тона и сгенерировать набор точек.
- сгенерировать рандомные значения X и Y
- взять цвет пикселя из изображения по этим координатам
- проверить в массиве значение по индексу равному цвету пикселя
- если значение больше 0, то:
- значение в массиве уменьшить на 1
- занести координаты в очередь
- нарисовать точку
Вот так выглядит окно приложения:
Как оказалось, если на двигателях не оставлять питание после каждого движения, то они прокручиваются назад, а если оставлять – то они греются. А еще больше греется shield, поэтому был откопан старый куллер и закреплен над микросхемами. Питание он берет от того же блока питания напрямую, чтобы не занимать разъёмы на shield. После двухчасового теста ничего не сгорело. Так же была добавлена коробка, для защиты конструкции.
Так как стола для него не было сделано, чтобы лист не шатался при печати, был взят лист формата А3. Платформа становится на лист и прижимает его. А чтобы и вся конструкция не скользила, на нее ставится гантель или банка варенья. Печатает она довольно медленно, в среднем на точку уходит 0,7 секунды. И вот что получается на выходе:
Заключение
Принтер получился медленным, непрезентабельным, требующим доработок, но печатающим в нужном стиле. Начало положено и сделаны многие выводы, как по конструкции, так и по коду, и если все же хватит терпения на вторую версию данного агрегата — все будет учтено и сделано более качественно.
Из потраченных на него средств (приблизительно):
- 3$ на спицы
- 17$ двигатели 2шт. (хотя можно было взять и менее точные)
- 3$ arduino Uno (но хватит и Nano)
- 5,5$ Линейные подшипники 8*15*24мм, 10 шт. (понадобилось 8шт.)
- 2,5$ MOTOR SHIELD L293D (можно купить отдельно 2 микросхемы L293D, а сервопривод питать от arduino)
- 2$ Обычные подшипники 8*22*7мм, 6шт.
- 8$ Крепления для направляющих 8мм, 8шт.
- 4$ Ремень 20-GT2-6 (2м) + 2 ролика
- 2$ Сервопривод Sg90 9G
- ~10$ на каркас, болты, гвозди, проволоку (тут можно сэкономить, если многое уже есть дома)
Бесплатно: вентилятор, блок питания.
Итого около 57$, хотя можно сделать и еще дешевле.
Автор: KuSu