Рисовалка на основе 2-ух DVD-ROM

gumeldiman
Offline
Зарегистрирован: 05.02.2020

Привет всем!

Хочу поделится опытом в создании одной забавной штуки:

 

Это мини ЧПУ-шка для рисования чего либо. Отлично подойдет в качестве демонстрации возможностей Arduino, работы шаговых двигателей и сервопривода.

Вот ссылка на ВИДЕО работы данного устройства.

 

Для изготовления вам понадобятся:

- привод DVD-ROM * 2 шт

- ARDUINO UNO * 1 шт

- мотор-шилд l293d * 1 шт

- серво привод * 1 шт

- А также ваша фантазия + всякая всячина ;)

 

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

Самое сложное было реализовать механическую часть. За перемещение карандаша отвечают приводы от старых DVD-ROM'ов:

С приводами все более-менее понятно, один отвечает за перемещение по оси X, второй за перемещение по оси Y. Реализация в исполнении, не должна вызвать трудностей. Самое сложное для меня было придумать механизм для поднятия и опускания карандаша. Сгодился старый телефон - слайдер:

Ну а дальше все собрал на куске ЛДСП, каких-то уголках и прочего. С обратной стороны закрепил Ардуину, в нее воткнул шилд, соединил проводами 

Вид поделки с обратной стороны:

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

Изучая скетчи подобных рисовалок, зачастую люди писали трехэтажный код, в котором чёрт ногу сломает.. А я люблю когда код очень маленький и при этом все работает как надо. Правда я немного схитрил. Хитрость заключается в том, что на Ардуинку подается лишь нужная (готовая) информация, и она просто выполняет определенную работу. При этом с компьютером происходит некий "диалог". Компьютер говорит, - езжай туда-то. Рисовалка читает эту информацию, анализирует, выполняет и в ответ сообщает компьютеру, - готово, чё делать дальше? И компьютер выдает очередную координату. И так по кругу, до тех пор, пока не закончится рисунок. 

Собственно вот мой скетч:

/////////////////////////////////////////////////////////////.//////////////////////////////////////////////////
///                                                                                                          ///
///    Рисовалка собрана на базе двух DVD, микросервы и управлется мотор-шилдом l293d во главе Arduino UNO   ///
///                                                                                                          ///
///    Управление рисовалкой осуществляется через терминальное приложение, написанное на Delphi,             ///
///    данные поступают в виде текстовых строк в следующем формате:                                          ///
///    X100 - означает, что следущая координата X будет 100                                                  ///
///    Y200 - означает, что следущая координата Y будет 200                                                  ///
///    если в строке присутствет "-" (минус), координата будет отрицательной                                 ///
///    M - говорит о пуске двигателей, для перемещения карандаша                                             ///
///    U - поднять карандаш (холостой ход)                                                                   ///
///    D - опустить карандаш (рабочий ход)                                                                   ///
///    допускается использовать M, U, D d в одной строке с координатами, например                            ///
///    Y300DM - задаст координату Y, опустит карандаш и поедет в X,Y                                         ///
///    по завершении хода, в ком-порт отправляется "OK" - что говорит о готовности рисовалки                 ///
///    принять новые строки с информацией                                                                    ///
///                                                                                                          ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <AFMotor.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#include <Servo.h>

char STEP = SINGLE; // будем юзать этот способ "шагания"
//char STEP = DOUBLE;
//char STEP = INTERLEAVE;
//char STEP = MICROSTEP;

const int penZUp = 60;        // угол сервы для холостого хода
const int penZDown = 120;     // угол сервы для рабочего положения карандаша
const int penServoPin = 9;    // пин сервы
const int penDownDelay = 750; // время на опускание крандаша
const int penUpDelay = 250;   // время на поднятие крандаша
const int SpeedMotor = 150;   // скорость моторов

AF_Stepper motor1(20, 2); // мотор X, подключенный через мотор-шилд l293d
AF_Stepper motor2(20, 1); // мотор Y, подключенный через мотор-шилд l293d

void forwardstepX () { motor1.onestep(FORWARD,  STEP); } // такая заморока чтоб управлять моторами через AccelStepper
void backwardstepX() { motor1.onestep(BACKWARD, STEP); } // такая заморока чтоб управлять моторами через AccelStepper
void forwardstepY () { motor2.onestep(FORWARD,  STEP); } // такая заморока чтоб управлять моторами через AccelStepper
void backwardstepY() { motor2.onestep(BACKWARD, STEP); } // такая заморока чтоб управлять моторами через AccelStepper

// Motor shield has two motor ports, now we'll wrap them in an AccelStepper object
AccelStepper Xaxis(forwardstepX, backwardstepX); // мотор для X
AccelStepper Yaxis(forwardstepY, backwardstepY); // мотор для Y
MultiStepper steppers; // для согласованного управления движками
Servo PenServo;  // карандашная серва

void PenUp()   { PenServo.write(penZUp); delay(penUpDelay);     } // функция поднять карандаш
void PenDown() { PenServo.write(penZDown); delay(penDownDelay); } // функция опустить карандаш

void setup() 
{
  Serial.begin(9600); // для общения с иным миром
  Xaxis.setMaxSpeed(SpeedMotor); // скорость мотора по X
  Yaxis.setMaxSpeed(SpeedMotor); // скорость мотора по Y
  steppers.addStepper(Xaxis); // добавим мотор X
  steppers.addStepper(Yaxis); // добавим мотор Y
  PenServo.attach(penServoPin);  // подключим серву
  PenUp();
  Serial.println("Hellow world");
}

char a; // текущий символ
long b, X, Y, dir = 0; // текущее целое, и координаты X и Y, направление
long positions[2]; // для хранения координат моторов
boolean isMinus, isX, isY, isMove, isDown, isUp, isStep = false; // флаги для всякого

void loop() 
{  
  while (Serial.available()) // пока поступает информация, крутим цикл (хотя и if проканает..)
    {
      a = Serial.read(); // читаем символ и смотрим что там пришло
      if (a == '-') { isMinus = true; } // вдруг минус
      if (a == 'X') { isX = true; }     // данные для X
      if (a == 'Y') { isY = true; }     // данные для Y
      if (a == 'M') { isMove = true; }  // нужно ехать
      if (a == 'D') { isDown = true; }  // нужно опустить карандаш
      if (a == 'U') { isUp = true; }    // нужно поднять карандаш
      if (a == 'd') { isStep = true; }  // ручное управление
      if (a >= 48 && a <= 57){ b *= 10; b += a - 48; } // если цифра, сей хитрый алгоритм позволяет преобразовать строку в число посимвольно (!)
      if (a == 13) // если закончилась строка, то нужно что то сделать
        {          
          if (isDown) { PenDown(); } // подготовка к рабочему ходу
          if (isUp) { PenUp(); }     // подготовка к холостому ходу          
          if (isMinus) { b = -b; }   // если был минус 
          if (isX) { X = b; }        // если X
          if (isY) { Y = b; }        // если Y
          if (isMove)                // если нужно ехать, то
            {
              Serial.println("OK"); // напишем что все ништяк (предполагаем, что терминальная прога будет ждать эту информацию, чтобы отправить следущую)              
              positions[0] = X; // укажем X
              positions[1] = Y; // укажем Y
              steppers.moveTo(positions);    // указываем новую позицию 
              steppers.runSpeedToPosition(); // включаем оба движка и едем
            }   
          if (isStep) // если ручное управление
            {
              if (b > 0) {dir = FORWARD;} else {dir = BACKWARD;} // определим направление
              if (isX) { motor1.step(1, dir, STEP); } // шагаем по X
              if (isY) { motor2.step(1, dir, STEP); } // шагаем по Y
            }
          b = 0;           // обнулим текущее значение целого
          isX = false;     // обнулим признак X
          isY = false;     // обнулим признак Y
          isMove = false;  // обнулим необходимость движения
          isMinus = false; // обнулим минус
          isDown = false;  // обнулим необходимость вниз
          isUp = false;    // обнулим необходимость вверх
          isStep = false;  // обнулим необходимость ручного управления
        }
    }
}

Конечно, ввиду того что я начинающий писака, тут могут быть косячки. Но на самом деле вроде все нормально работает. )

А вот для управления этой рисовалкой пришлось сваять терминальное приложение. Исходный код я приводить не буду, он довольно большой. Программа писалась на Delphi 7. Посмотреть исходники и саму программу для управления рисовалкой можете по этой ссылке.

Программа позволяет управлять шаговыми двигателями с помощью стрелок на клавиатуре, поднимать либо опускать карандаш нажатием на PageUp/PageDown. При первом запуске, нужно подружить прогу с рисовалкой, для чего необходимо настроить номер порта, нажав на кнопку "настройки".

Чуть не забыл про самое главное. Откуда берется графическая информация. Для работы рисовалки нужно определенным образом подготовить файл формата *.plt. Я делаю его в графическом редакторе CorelDraw (версия может быть любой). В вышеуказанной ссылке вы найдете примеры plt-файлов. Самое главное, при создании такого файла сделать верными настройки, чтобы габарит векторного рисунка не выходил за пределы рабочей области этой рисовалки. Рабочая область ограничена физическими размерами DVD привода и составляет примерно 38х38 мм. Скорее всего это 1.5х1.5 дюйма. При этом, максимальные координаты которые передаются ардуинке должны находится в пределах 0..255, именно столько полных шагов делает DVD привод чтобы переместиться от начала до конца. Конечно это грубовато, но и размер рабочей области у нас не велик.

Короче говоря, я рекомендую делать plt-файлы, открывая файл "Пустой.cdr", в нем просто изменена рабочая область с формата А4 на 38х38 мм. Ваш рисунок должен быть в векторном виде и его вы просто экспортируете в формат *.plt

ВАЖНО в настройках экспорта поменять единицы измерения плоттера на 170 точек на дюйм. (при габарите в 1.5 дюйма это как раз 255):

Далее, полученный файл вы загружаете в окно терминального приложения:

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

Остальное все должно быть интуитивно понятно.

И еще крайне важно, чтобы карандаш в рисовалке, перед запуском рисования, находился в левой нижней точке (координаты 0,0).

 

*********************

Если что-то непонятно, спрашивайте, постараюсь ответить ))

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Круто!

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

gumeldiman пишет:

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

С софтом более - менее понятно, а вот с механикой не очень. Реально интересно. ДиВиДюхи есть, руки тоже. Понятка отсутсвует... А так - круто

RG22EM
Offline
Зарегистрирован: 27.08.2016

а CD-ROM пойдёт, у меня их полвагона

-NMi-
Offline
Зарегистрирован: 20.08.2018

ТС- слушай, а можно вот с таким "дэвайсом" промерять сверхтогные детали, заменим "карандаш" на микродатчик???

gumeldiman
Offline
Зарегистрирован: 05.02.2020

mykaida пишет:

gumeldiman пишет:

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

С софтом более - менее понятно, а вот с механикой не очень. Реально интересно. ДиВиДюхи есть, руки тоже. Понятка отсутсвует... А так - круто

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

Один привод, который приручен к ЛДСП двигает площадку вверх/вниз, это ось Y. Второй привод расположен вертикально и перпендикулярно первому (на стойках), этот привод двигает площадку с подъемным механизмом влево/вправо, это ось X. В свою очередь подъемный механизм управляется сервоприводом и опускает и поднимает карандаш.

А вообще, картинок то в сети полно

gumeldiman
Offline
Зарегистрирован: 05.02.2020

-NMi- пишет:

ТС- слушай, а можно вот с таким "дэвайсом" промерять сверхтогные детали, заменим "карандаш" на микродатчик???

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

gumeldiman
Offline
Зарегистрирован: 05.02.2020

RG22EM пишет:

а CD-ROM пойдёт, у меня их полвагона

Думаю, что подойдет. 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Как только вижу что-то подобное - сразу руки тянутся к кнопке и ставят жирный плюс!
Ведь есть же ещё специалисты кроме эффективных менеджеров!

Iskatel
Offline
Зарегистрирован: 18.04.2020

привет gumeldiman, а как рисунок в plt формат перевести, совсем не понятно из выше написаного. Можно поподробнее. 

gumeldiman
Offline
Зарегистрирован: 05.02.2020

Iskatel пишет:

привет gumeldiman, а как рисунок в plt формат перевести, совсем не понятно из выше написаного. Можно поподробнее. 

Хорошо. Формат *.plt (как можно догадаться разработан специально для плоттеров) имеет открытый текстовый формат, его можно открыть например блокнотом и посмотреть чего там внутри. С этим форматом я столкнулся на работе, а работал я в наружной рекламе. Наши дизайнеры работали в программе Corel Draw и эта же программа осуществляет экспорт графических данных в формат *.plt. С этим форматом работали наши режущие плоттеры на которых выполнялась резка виниловой пленки.

Режущий плоттер это и есть обыкновенный ЧПУ станок, выглядит он примерно так:

Есть станки поменьше, есть побольше. Инструмент в станке перемещается по оси X, а материал (пленка) перемещается по оси Y. Нож (флюгерного типа) в нужное время опускается и поднимается. Таким образом происходит резка виниловой пленки, затем лишнюю пленку удаляют с основы, а нужную переносят на изделие.

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

В первых строках *.plt файла хранится информация о скорости перемещения инструмента для разных цветов, я эту информацию не использую, а читаю только два вида строк (где есть PD или DU), например запись вида: 

PU100 50;
PD200 75;

будет говорить о том, что станку нужно поднять инструмент (PU - Pen Up) и переместить его в точку с координатами (100, 50). А затем опустить инструмент (PD - Pen Down) и переместить в точку (200, 75). Т.е. станок нарисует отрезок.

Как получить такой файл? Во-первых, нужна программа Corel Draw. Возможно, есть и другие программы, которые могут создавать plt-файлы. Но в данном случае, я буду говорить только про Corel Draw, т.к. его plt-файлы на 100% подходят для работы моей рисовалки. В программе нужно нарисовать векторную картинку. Как стоит догадаться, растровая графика нам не подойдет. Ну а далее, в программе делаем экспорт в *.plt файл, обязательно указывая единицы плоттера. См. скрины в первом сообщении, где указана рабочая область 1.5х1.5 дюйма и 170 точек на дюйм. Естественно габарит рисунка должен находится в этих пределах (1.5х1.5 дюйма или 38х38 мм). Как раз в этих пределах штуковина от CD-ROM и перемещается. При этом, стоит заметить, что 1.5*170 = 255. Т.е. для полного перемещения (от начала до конца) достаточно сделать 255 полных шагов.

Чтобы все получилось, советую задать область рисования 38х38 мм, нарисовать в этих пределах и сделать экспорт в plt, не забывая про разрешающую способность рисовалки - 170 точек на дюйм.

svm
Offline
Зарегистрирован: 06.11.2016

У меня тоже недавно возникла необходимость в создании макета ЧПУ фрезера. Дело в том, что ввиду наличия свободного времени решил собрать для управления ЧПУ фрезером мини пульт на 328 камне и дисплее от Нокии. В принципе набросок уже работает, но стали вылазить косяки. Опробывать работу нужно на реальном станочке, но он достаточно габаритный и тяжелый. А в мастерской стоят три пенька 800 МГц, которые работают чисто для управления станками, но не для программирования. Вот и решил сделать мини вариант для отладки программы на основе СД и ДВД приводов. Привода пришлось немного порезать с целью соответствия не только функционала, но и внешнего вида. Ось Z получилась несколько тяжеловатой из за чего скорость более 100 мм/мин поднять проблематично, но при поле 40х40 мм это не критично . Для полного соответствия поставил оптические концевики по всем осям. Сейчас управляется МАЧ3, но рядом лежит  ГРБЛ контроллер, для которого этот пульт и создается. Если еще пару недель будем дома, глядишь и что-то получится. Ну и фото этого эмулятора:

Deniskyn
Offline
Зарегистрирован: 13.04.2019

Покажите как все подключено плс...

svm
Offline
Зарегистрирован: 06.11.2016

Deniskyn пишет:

Покажите как все подключено плс...

Если вопрос ко мне, то подключение простейшее. Шаговики к выходам драйверов. Входные сигналы Step и Dir напрямую к LPT порту. Enable не используется. Концевики по желанию. Можно оптические, можно микрики. Тоже напрямую к LPT порту и земле. На шилд подается 12 В. Питание драйверов от отдельного стабилизатора 5 В. Не забыть подключить землю от LPT порта.

gumeldiman
Offline
Зарегистрирован: 05.02.2020

На шилде мотор оси "Х":

мотор оси "Х":

на шилде шлейф к мотору оси "Y":

мотор оси "Y":

Подключение сервопривода хорошо видно на первоначальных фотках

Morroc
Offline
Зарегистрирован: 24.10.2016

Зачем свой код то писали ? Есть же для чпу и 3д принтеров. Оно конечно интересно, но...