Небольшой мини-плоттер из деталей DVD-привода - Своими руками
Своими руками

Небольшой мини-плоттер из деталей DVD-привода

>

Есть много проектов по переработке старых DVD-плееров в мини-плоттер с ЧПУ (CNC Plotter) на базе Arduino. Это хороший проект, идеально подходящий для знакомства с Arduino. Дополнительные механические детали и, в частности, держатель для карандашей мастер предлагает напечатать на 3D-принтере. Поэтому в этой статье я предлагаю создать мини-плоттер, изготовив механические элементы методом 3D-печати.
Мастер попытался использовать материалы, которые легкодоступны и дешевы. Для управления шаговыми двигателями осей X и Y, есть два варианта. Либо использование двух L293D (по одному для каждой оси), либо установка Motor Shield для Arduino.
Инструменты и материалы:-Arduino Uno;-Макетная плата 400 точек;
-Драйвер L293D;
-Серводвигатель SG90;-Два DVD-привода б/у или новых;-Провод 4 куска по 15 см каждого цвета (желтый, зеленый, красный, белый);
-Термоусадочная трубка;
-Фанера 20 x 16 см (толщина 10 мм);
-Две планки фанеры 15 x 5 см (для стоек);
-Оргстекло 76 х 76 мм толщиной 5 мм;
-Пружина диаметром 8 мм, от 6 до 8 витков;
-Ось диаметром 3 мм x 80 мм или стержень с резьбой;-Клеевой пистолет;-2 винта M2 для крепления серводвигателя;-8 винтов M4 x 35мм;
-8 гаек M4;
-Винт M5 x 20 мм;
-Гайка M5;
-Одна барашковая гайка M5;
-Шайбы диаметром 14 мм;
-Перемычки;-3D-принтер;-Паяльник;
Шаг первый: DVD-приводы
Первым делом нужно разобрать приводы. Для дальнейшей работы понадобиться только рамка с кареткой.
Небольшой мини-плоттер из деталей DVD-приводаШаг второй: подготовка шаговых двигателей
На этом этапе нужно подготовить провода для шаговых двигателей. Можно припаяться прямо у двигателя, но есть риск оборвать провод при дальнейшем монтаже. Мастер рекомендует подключаться на конце шлейфа. Сначала с помощью ножа нужно отделить каждую дорожку примерно на 2 см. Затем залудить конец дорожки и ранее зачищенный провод. Надеть на провод термоусадочную трубку. Спаять концы. Заизолировать термоусадкой.

Маркировки на двигателе нет, но подключение довольно простое. Первый провод на двигателе (обычно) соответствует 1-му выходу L293D (или Motor Shield) и так далее.
Небольшой мини-плоттер из деталей DVD-приводаНебольшой мини-плоттер из деталей DVD-приводаШаг второй: 3D-печать
Дальше нужно напечатать некоторые детали. Файлы для печати можно скачать здесь.

Нужны следующие детали:
Кронштейны для вертикального крепления оси Х 4 шт.
Распорки 4 шт
Монтажные кронштейны для макетных плат 4 шт
Опорная плита оси Z 1 шт
Держатель для карандашей диаметром 8 мм 1 шт
Кольцо наклона диаметром 8 мм 1 шт
Все конструктивные элементы были спроектированы с использованием открытого программного обеспечения Open Scad. Для печати деталей понадобится 9,55 м PLA (29 граммов). Печать в быстром режиме занимает около 3 часов.
Небольшой мини-плоттер из деталей DVD-приводаШаг третий: схема подключения
Схема подключения довольно простая и не должна вызвать сложностей, даже у новичка.
Небольшой мини-плоттер из деталей DVD-приводаНебольшой мини-плоттер из деталей DVD-приводаНебольшой мини-плоттер из деталей DVD-приводаШаг четвертый: сборка
Сборку мастер начинает с фиксации оси X с помощью 4 распорок и 4 винтов M4 x 30 мм. Затем устанавливает 2 вертикальные стойки оси Y (из фанеры). Для фиксации стоек к основанию использует 4 скобы.

Наконец устанавливает ось Y на вертикальных стойках. Высота не важна, она будет отрегулирована позже.
Небольшой мини-плоттер из деталей DVD-приводаС помощь темрмоклея устанавливает рабочий стол. Мастер сделал его из оргстекла, но подойдет любая ровная поверхность.
Чтобы правильно установить рабочий стол, нужно отодвинуть каретку как можно дальше, в крайнее положение. С помощью шайб (подлаживая шайбы) нужно отрегулировать установку рабочего стола в горизонтальном положении относительно стоек.
Небольшой мини-плоттер из деталей DVD-приводаПосле установки серводвигателя, нужно установить держатель для карандаша.
Держатель прикручивается к рычагу сервопривода. Между подвижной и неподвижной частями держателя устанавливается пружина. Карандаш фиксируется с помощью винта и барашковой гайки.
Небольшой мини-плоттер из деталей DVD-приводаНебольшой мини-плоттер из деталей DVD-приводаНебольшой мини-плоттер из деталей DVD-приводаШаг пятый: тестирование
После того, как подключение и сборка будут завершены, нужно проверить правильность движений осей X и Y и вычислить калибровочные значения.

Тест оси X
Ось X подключена к контактам 8, 9, 10 и 11. Нужно запустить код ниже, чтобы проверить, движется ли ось X должным образом. По умолчанию ему нужно было сделать 100 шагов. Разделив 100 на пройденное расстояние в миллиметрах, мы получаем калибровку оси X, необходимую для настройки.
Небольшой мини-плоттер из деталей DVD-привода Показать / Скрыть текст/*
Mini Traceur Arduino (CNC Plotter)
Test de l'axe X
Projets DIY 02/2016
*/
#include <Stepper.h> //Librairie pour piloter les moteurs pas à pas

const int pasParRotation = 20; //Nombre de pas pour réaliser un tour

//Pins sur lesquels est relié le moteur de l'axe X
Stepper myStepperX(pasParRotation, 8,9,10,11);

void setup() {
myStepperX.setSpeed(100); //Vitesse de déplacement
//Indiquer le nombre de pas que le moteur pas à pas doit faire
//Généralement un moteur de lecteur CD/DVD peut faire 250 pas au maxium
//Indiquer un chiffre négatif pour inverser le sens de déplacement
myStepperX.step(100);
delay(100);
}

void loop() {}
Тест оси Y
Таким же образом проверяем ось Y и вычисляем значение калибровки.
Небольшой мини-плоттер из деталей DVD-привода Показать / Скрыть текст/*
Mini Traceur Arduino (CNC Plotter)
Test de l'axe Y
Projets DIY 02/2016
*/
#include <Stepper.h> //Librairie pour piloter les moteurs pas à pas

const int pasParRotation = 20; //Nombre de pas pour réaliser un tour

//Pins sur lesquels est relié le moteur de l'axe X
Stepper myStepperX(pasParRotation, 2,3,4,5);

void setup() {
myStepperX.setSpeed(100); //Vitesse de déplacement
//Indiquer le nombre de pas que le moteur pas à pas doit faire
//Généralement un moteur de lecteur CD/DVD peut faire 250 pas au maxium
//Indiquer un chiffre négatif pour inverser le sens de déplacement
myStepperX.step(100);
delay(100);
}

void loop() {}
Ниже перечислены основные проблемы при настройки плоттера.
Двигатель не работает: сначала проверьте проводку L293D. Контакты IN и OUT можно попробовать поменять местами.
Направление движения меняется на противоположное. Поменяйте местами подключения на L293D.

Двигатель останавливается, не доходит до конца. Вероятно, на его пути есть препятствие. Проверьте, не слишком ли длинный крепежный винт.
Шаг шестой: программное обеспечение
Калибровка осей X и Y мини-плоттер почти выполнена, осталось только загрузить программу ЧПУ в Arduino. Перед загрузкой программы необходимо настроить следующие параметры в соответствии с мини-плоттером (раздел конфигурации можно найти в начале кода):
Ход серводвигателя для подъема карандаша
Ход серводвигателя для опускания карандаша
Предупреждение: нельзя использовать серводвигатель, для нажатия карандаш на лист бумаги. Сила, оказываемая серводвигателем, может быть слишком сильной и препятствовать перемещению оси X. Карандаш прижимается к листу только благодаря пружине.
Код можно скачать ниже.
Небольшой мини-плоттер из деталей DVD-привода Показать / Скрыть текст/*
Mini Traceur CNC Arduino
Traduction de la configuration du traceur en français et ajout d'une variable "vitesseDeplacement" permettant d'ajuster la vitesse de déplacement des axes X et Y
Projets DIY – 02/2016

D'après
Mini CNC Plotter firmware, based in TinyCNC https://github.com/MakerBlock/TinyCNC-Sketches
Send GCODE to this Sketch using gctrl.pde https://github.com/damellis/gctrl
Convert SVG to GCODE with MakerBot Unicorn plugin for Inkscape available here https://github.com/martymcguire/inkscape-unicorn

More information about the Mini CNC Plotter here (german, sorry): http://www.makerblog.at/2015/02/projekt-mini-cnc-plotter-aus-alten-cddvd-laufwerken/
*/

#include <Servo.h>
#include <Stepper.h>

#define LINE_BUFFER_LENGTH 512

/*
PARAMETRES DE CONFIGURATION
*/

const int penZUp = 130; // Angle servomoteur, crayon relevé
const int penZDown = 40; // Angle servomoteur, crayon baissé
const int penServoPin = 6; // Pin sur lequel est relié le servomoteur
const int stepsPerRevolution = 20; // Valeur par défaut
const int vitesseDeplacement = 250; // Vitesse de déplacement des axes X et Y

Servo penServo; // Objet pour actionner le servomoteur

// Initialisation des moteurs pas à pas pilotés à l'aide d'un pont H L293D
Stepper myStepperY(stepsPerRevolution, 2,3,4,5); // Axe Y
Stepper myStepperX(stepsPerRevolution, 8,9,10,11); // Axe X

// Calibration, nombre de pas par millimètre
float StepsPerMillimeterX = 6.0;
float StepsPerMillimeterY = 6.0;

/*
FIN DE LA CONFIGURATION
*/

/* Structures, global variables */
struct point {
float x;
float y;
float z;
};

// Current position of plothead
struct point actuatorPos;

// Drawing settings, should be OK
float StepInc = 1;
int StepDelay = 0;
int LineDelay = 50;
int penDelay = 50;

// Drawing robot limits, in mm
// OK to start with. Could go up to 50 mm if calibrated well.
float Xmin = 0;
float Xmax = 40;
float Ymin = 0;
float Ymax = 40;
float Zmin = 0;
float Zmax = 1;

float Xpos = Xmin;
float Ypos = Ymin;
float Zpos = Zmax;

// Set to true to get debug output.
boolean verbose = false;

// Needs to interpret
// G1 for moving
// G4 P300 (wait 150ms)
// M300 S30 (pen down)
// M300 S50 (pen up)
// Discard anything with a (
// Discard any other command!

/**********************
* void setup() – Initialisations
***********************/
void setup() {
// Setup
Serial.begin( 9600 );

penServo.attach(penServoPin);
penServo.write(penZUp);
delay(200);

// Decrease if necessary
myStepperX.setSpeed(vitesseDeplacement);
myStepperY.setSpeed(vitesseDeplacement);

// Set & move to initial default position
// TBD

// Notifications!!!
Serial.println("Mini CNC Plotter alive and kicking!");
Serial.print("X range is from ");
Serial.print(Xmin);
Serial.print(" to ");
Serial.print(Xmax);
Serial.println(" mm.");
Serial.print("Y range is from ");
Serial.print(Ymin);
Serial.print(" to ");
Serial.print(Ymax);
Serial.println(" mm.");
}

/**********************
* void loop() – Main loop
***********************/
void loop()
{
delay(200);
char line[ LINE_BUFFER_LENGTH ];
char c;
int lineIndex;
bool lineIsComment, lineSemiColon;

lineIndex = 0;
lineSemiColon = false;
lineIsComment = false;

while (1) {

// Serial reception – Mostly from Grbl, added semicolon support
while ( Serial.available()>0 ) {
c = Serial.read();
if (( c == 'n') || (c == 'r') ) { // End of line reached
if ( lineIndex > 0 ) { // Line is complete. Then execute!
line[ lineIndex ] = ''; // Terminate string
if (verbose) {
Serial.print( "Received : ");
Serial.println( line );
}
processIncomingLine( line, lineIndex );
lineIndex = 0;
}
else {
// Empty or comment line. Skip block.
}
lineIsComment = false;
lineSemiColon = false;
Serial.println("ok");
}
else {
if ( (lineIsComment) || (lineSemiColon) ) { // Throw away all comment characters
if ( c == ')' ) lineIsComment = false; // End of comment. Resume line.
}
else {
if ( c <= ' ' ) { // Throw away whitepace and control characters
}
else if ( c == '/' ) { // Block delete not supported. Ignore character.
}
else if ( c == '(' ) { // Enable comments flag and ignore all characters until ')' or EOL.
lineIsComment = true;
}
else if ( c == ';' ) {
lineSemiColon = true;
}
else if ( lineIndex >= LINE_BUFFER_LENGTH-1 ) {
Serial.println( "ERROR – lineBuffer overflow" );
lineIsComment = false;
lineSemiColon = false;
}
else if ( c >= 'a' && c <= 'z' ) { // Upcase lowercase
line[ lineIndex++ ] = c-'a'+'A';
}
else {
line[ lineIndex++ ] = c;
}
}
}
}
}
}

void processIncomingLine( char* line, int charNB ) {
int currentIndex = 0;
char buffer[ 64 ]; // Hope that 64 is enough for 1 parameter
struct point newPos;

newPos.x = 0.0;
newPos.y = 0.0;

// Needs to interpret
// G1 for moving
// G4 P300 (wait 150ms)
// G1 X60 Y30
// G1 X30 Y50
// M300 S30 (pen down)
// M300 S50 (pen up)
// Discard anything with a (
// Discard any other command!

while( currentIndex < charNB ) {
switch ( line[ currentIndex++ ] ) { // Select command, if any
case 'U':
penUp();
break;
case 'D':
penDown();
break;
case 'G':
buffer[0] = line[ currentIndex++ ]; // /! Dirty – Only works with 2 digit commands
// buffer[1] = line[ currentIndex++ ];
// buffer[2] = '';
buffer[1] = '';

switch ( atoi( buffer ) ){ // Select G command
case 0: // G00 & G01 – Movement or fast movement. Same here
case 1:
// /! Dirty – Suppose that X is before Y
char* indexX = strchr( line+currentIndex, 'X' ); // Get X/Y position in the string (if any)
char* indexY = strchr( line+currentIndex, 'Y' );
if ( indexY <= 0 ) {
newPos.x = atof( indexX + 1);
newPos.y = actuatorPos.y;
}
else if ( indexX <= 0 ) {
newPos.y = atof( indexY + 1);
newPos.x = actuatorPos.x;
}
else {
newPos.y = atof( indexY + 1);
indexY = '';
newPos.x = atof( indexX + 1);
}
drawLine(newPos.x, newPos.y );
// Serial.println("ok");
actuatorPos.x = newPos.x;
actuatorPos.y = newPos.y;
break;
}
break;
case 'M':
buffer[0] = line[ currentIndex++ ]; // /! Dirty – Only works with 3 digit commands
buffer[1] = line[ currentIndex++ ];
buffer[2] = line[ currentIndex++ ];
buffer[3] = '';
switch ( atoi( buffer ) ){
case 300:
{
char* indexS = strchr( line+currentIndex, 'S' );
float Spos = atof( indexS + 1);
// Serial.println("ok");
if (Spos == 30) {
penDown();
}
if (Spos == 50) {
penUp();
}
break;
}
case 114: // M114 – Repport position
Serial.print( "Absolute position : X = " );
Serial.print( actuatorPos.x );
Serial.print( " – Y = " );
Serial.println( actuatorPos.y );
break;
default:
Serial.print( "Command not recognized : M");
Serial.println( buffer );
}
}
}

}

/*********************************
* Draw a line from (x0;y0) to (x1;y1).
* Bresenham algo from https://www.marginallyclever.com/blog/2013/08/how-to-build-an-2-axis-arduino-cnc-gcode-interpreter/
* int (x1;y1) : Starting coordinates
* int (x2;y2) : Ending coordinates
**********************************/
void drawLine(float x1, float y1) {

if (verbose)
{
Serial.print("fx1, fy1: ");
Serial.print(x1);
Serial.print(",");
Serial.print(y1);
Serial.println("");
}

// Bring instructions within limits
if (x1 >= Xmax) {
x1 = Xmax;
}
if (x1 <= Xmin) {
x1 = Xmin;
}
if (y1 >= Ymax) {
y1 = Ymax;
}
if (y1 <= Ymin) {
y1 = Ymin;
}

if (verbose)
{
Serial.print("Xpos, Ypos: ");
Serial.print(Xpos);
Serial.print(",");
Serial.print(Ypos);
Serial.println("");
}

if (verbose)
{
Serial.print("x1, y1: ");
Serial.print(x1);
Serial.print(",");
Serial.print(y1);
Serial.println("");
}

// Convert coordinates to steps
x1 = (int)(x1*StepsPerMillimeterX);
y1 = (int)(y1*StepsPerMillimeterY);
float x0 = Xpos;
float y0 = Ypos;

// Let's find out the change for the coordinates
long dx = abs(x1-x0);
long dy = abs(y1-y0);
int sx = x0<x1 ? StepInc : -StepInc;
int sy = y0<y1 ? StepInc : -StepInc;

long i;
long over = 0;

if (dx > dy) {
for (i=0; i<dx; ++i) {
myStepperX.step(sx);
over+=dy;
if (over>=dx) {
over-=dx;
myStepperY.step(sy);
}
delay(StepDelay);
}
}
else {
for (i=0; i<dy; ++i) {
myStepperY.step(sy);
over+=dx;
if (over>=dy) {
over-=dy;
myStepperX.step(sx);
}
delay(StepDelay);
}
}

if (verbose)
{
Serial.print("dx, dy:");
Serial.print(dx);
Serial.print(",");
Serial.print(dy);
Serial.println("");
}

if (verbose)
{
Serial.print("Going to (");
Serial.print(x0);
Serial.print(",");
Serial.print(y0);
Serial.println(")");
}

// Delay before any next lines are submitted
delay(LineDelay);
// Update the positions
Xpos = x1;
Ypos = y1;
}

// Raises pen
void penUp() {
penServo.write(penZUp);
delay(LineDelay);
Zpos=Zmax;
if (verbose) {
Serial.println("Pen up!");
}
}
// Lowers pen
void penDown() {
penServo.write(penZDown);
delay(LineDelay);
Zpos=Zmin;
if (verbose) {
Serial.println("Pen down.");
}
}Шаг седьмой: подготовка и работа станка
Почти все готово. Все оси работают, калибровка сделана, программа ЧПУ загружена в Arduino. Теперь нужно подготовить компьютер к отправке файлов gcode на мини-плоттер.

Для пользователей Windows: скачайте gctrl.exe и запустите.

Для пользователей Mac OS и Linux: сначала установите Processing, затем откройте gctrl.pde.
gctrl – эффективная, но базовая программа в том смысле, что она не выполняет никаких проверок выбранного файла, график запускается, как только файл выбран (можно прервать сценарий, нажав «x»).

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

Дальше нажмите “p” в меню программы. В появившемся диалоговом окне выберите последовательный порт, к которому подключен ваш Arduino.
Затем нажмите «g», чтобы выбрать файл gcode для построения графика.
Небольшой мини-плоттер из деталей DVD-приводаПолезные команды:
x’: остановить текущий график, карандаш остается в текущем положении
‘h’: возвращает каретку в исходное положение
Как подготовить файлы gcode можно узнать изучив это руководство.
Весь процесс изготовления такого плоттера можно посмотреть на видео.

SitesReady

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

Follow us

Don't be shy, get in touch. We love meeting interesting people and making new friends.