[Из песочницы] Делаем трехосевой фрезерный станок с число-программным управлением

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

[Из песочницы] Делаем трехосевой фрезерный станок с число-программным управлением

Коротко об авторе

Студент 4-го курса Белорусского государственного университета информатики и радиоэлектроники, факультета «Компьютерных систем и сетей», кафедры «Электронных вычислительных машин», специальности «Вычислительные машины системы и сети».

Спойлер

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

Техническое задание или что стоит ожидать на выходе

Полученный фрезерный станок должен удовлетворять следующим условиям:

  • Иметь приемлемую рабочую область
  • Иметь приемлемую скорость движения по осям
  • Обрабатывать детали из дерева средней и высокой твердости. В идеале обрабатывать алюминий

Главное правило станков — жесткость. Чем выше жесткость станка, тем меньше вибраций, люфтов, проседаний, изгибов и прочих дефектов которые повлияют на качество обрабатываемой болванки. Так как станок будет изготавливаются полностью в домашних условиях, то единственным материалом который можно реально обработать в таком количестве дома и из которого получится сделать станину станка — дерево. Есть конечно разные виды. И за неимением большого капитала ибо студент для создания будет использовано все, что найдется. А это по сути доски на пробу сверлом довольно мягкого дерева. Хотя так же есть и небольшие листы фанеры. Чем богаты, то и будет использовано.

Так же стоит отметить на чем будет запущено управление станком. Есть один очень древний компьютер, берег его как раз примерно для таких целей. AMD Duron 1.2 ГГц, RAM 768 МБ, 64 МБ Video Mem, HDD 20ГБ. Как раз для этих целей сгодится. Управление будет под Linux CNC. Ибо Mach3 под Win не захотел толково работать. Ресурсов ему немного больше нужно.

Разработка

Разработка станка будет разбита на несколько частей.

  • Разработка контроллера шагового двигателя
  • Разработка драйвера шагового двигателя
  • Разработка оптической развязки
  • Разработка планки питания

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

Разработка контроллера шагового двигателя

Контроллера шагового двигателя будет разработан на PIC микроконтроллере. Почему? Во-первых, нужно было окончательно усвоить как работают шаговые двигатели, во-вторых, так интереснее, в-третьих, та же готовая микросхема L297 стоила почему-то дороговато, и в итоге получалось собрать на микроконтроллере немного дешевле.

В качестве управляющего микроконтроллера был взят PIC16F630. Имеет минимум периферии и достаточное количество ног для управления. Порт C служит для прямого вывода управляющих импульсов. На пины A1, A2 заведены входные сигналы DIR, STEP. Пин A2 включен в режиме внешних прерываний, а DIR работает как обычный пин ввода. Контроллер запущен через кварц на 20 MHz.

Код был написан на С с использованием маленькой asm вставки и собран на CCS C компиляторе.

#include <16f630.h> #case   #FUSES NOWDT                     #FUSES NOMCLR                    #FUSES HS                      #FUSES PUT                     #FUSES BROWNOUT   #use delay(clock = 20 MHz)                                                                                                                          #use fast_io(C)                                                      #opt 9                                    #define DIR		PIN_A1                                                              #define CLK		PIN_A2    #define LED		PIN_A0                                                                                                            #zero_ram                                      //half step array      const int steps[256] =     {                  	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101,                                                                                          	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101,                                                                                           	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101,                                                                                           	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101,                                                                                           	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101,                                                                                           	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101,                                                                                           	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101,                                                                                           	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101, 	0b00000100,0b00000110,0b00000010,0b00001010,0b00001000,0b00001001,0b00000001,0b00000101                                                                                              };                                                                        unsigned int8 nowStep = 0;                                                                                                                           #INT_TIMER1                                                      void LoadDrop_isr()       {                                                                            	output_c(0);               }                                                                                                                                                                                                                   #INT_EXT                     void clk_isr() {                                        //input_state(DIR) ? nowStep++ : nowStep--;                                                    	#asm asis                 	BTFSC  05.1    	INCF   nowStep,F            	BTFSS  05.1                                                         	DECF   nowStep,F       	#endasm                                   	output_c(steps[nowStep]); 	set_timer1(0);		 }                                                                                                                                                                                             void main()                                                                                                                                   {                             	output_a(0);                          	input_a();   	         	set_tris_c(0);                     	output_c(0);   	                            	setup_comparator(NC_NC_NC_NC);                         	setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);                        	set_timer1(0);                                                           	                           	ext_int_edge(L_TO_H);     	                                                           	enable_interrupts(INT_TIMER1);              	enable_interrupts(INT_EXT);                    	enable_interrupts(GLOBAL);   	                                                                     	unsigned int16 blinkCounter = 0;  	              	MAIN_LOOP:                     	                                   		 if(!blinkCounter++)               		 	output_toggle(LED);         		 	                 	goto MAIN_LOOP;                                                                                                                                                       }                                                

Для описания кода, проще будет начать с логики работы контроллера. При запуске контроллера происходит начальная настройка железа и включение прерываний. Номер шага хранится в беззнаковой 8-и битной переменной nowStep и в начале номер равен нулю. Далее запускается вечный цикл программы в MAIN_LOOP в котором происходит просто моргание светодиодом подключенного к пину A0. Для чего? Во-первых, видно что камень не подвис, во-вторых, спецэффекты! Пин А2 настроен на внешнее прерывание по восходящему фронту. Когда на ноге будет зарегистрировано событие, будет обработано прерывание INT_EXT в котором происходит переключение следующего шага. Для вывода следующего шага происходит инкремент или декремент указателя шага nowStep в зависимости от входного DIR. Затем из массива шагов steps из позиции nowStep целиком в порт выводится новая комбинация коммутации обмоток двигателя. Так же, в начале инициализации микроконтроллера происходит настройка и запуск таймера 1. Этот таймер сбрасывает выходные сигналы, чтобы предотвратить перегрев двигателей. Таймер сбрасывает выходные сигналы через примерно 100 мс после выставления сигнала. То есть это сугубо мера предосторожности.

В симуляции удалось достичь периода сигнала CLK в 15 мкс, что соответствует частоте в 66.(6) КГц. Для первого раза не плохо, я думаю, хотя, дальнейшая оптимизация возможна.

Разработка драйвера шагового двигателя

Тут далеко идти не придется. Схема типовая. Драйвер построен на базе готового драйвера L298N.

Зачем резисторы R1 — R4? Честно сказать, я не знаю. Изначально в документации идет схема в связке с L297, вся связь без резисторов. Однако в интернете находил схемы с резисторами на линиях. Посмотрел на блок-схему в даташите на L298N. Все INPUT линии заходят на инверсный вход И элемента. Ничего случится не должно и без резисторов. Но я решил не рисковать и на всякий случай вставить, на этот раз. Много хуже не будет, упадет крутизна фронта на входе.

В остальном схема повторяет ту, что дана в даташите.

Разработка оптической развязки

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

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

Изначально были взяты оптопары 4N25. Ибо подумал, что 60 кГц вытянет любая сегодняшняя оптопара. Но на деле, нет, не вытянули, не успевали. По этому в результате пришлось заменить на 6N135, у которых быстродействие значительно выше (до 2MHz по даташиту). По пинам они не совместимы напрямую, однако, удалось их вставить без переделки платы целиком. Новой схемы я не делал, думаю, кому захочется, тот сможет переразвести плату самостоятельно.

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

Разработка планки питания

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

Планка питания содержит по шесть коннекторов для линий 5 В и 12 В, а так же два отдельных коннектора для подключения кулеров.

Сборка и результат

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

Изготовление драйвера шагового двигателя

Перенес рисунок ЛУТом:

Вытравил и залудил:

Просверлил:

Запаял:

Далее нужно было повторить успех еще для 2-х осей:

Изготовление платы оптической развязки

Перенес ЛУТом и поправил маркером:

Вытравил:

Залудил:

В сборе вся электроника:

Сборка станка

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

Сначала была такая конструкция:

Первый вариант оси Z:

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

В ходе которой оси X и Y были вынесены на отдельную площадку и превратились в подвижный стол:

Уже было лучше, но все равно очень далеко от чего-то не шатающегося. В итоге пришел к такому варианту:

Однако ось Z все еще слишком сильно дергалась и прогибалась. На этот раз я сел и хорошо подумал и уже занялся некоторым проектированием. В итоге получилась такая конструкция:

В качестве направляющих использованы равнополочные алюминиевые уголки с полкой 25 мм и толщиной 2мм. Стальных не смог найти. Они были бы много раз лучше. Направляющие промышленного изготовления, конечно, все равно не идут ни в какое сравнение.

Подвижная каретка:

В сборе новая ось Z:

Результат. Можно заметить, что собранная ось, и конструкция в целом, все же отличается даже от спроектированной. Все же совместить и центрировать ось когда из точных инструментов у тебя только штангенциркуль и ручная дрель довольно не простая задача. По этому пришлось передумывать и экспериментировать на ходу:

Пробы что-то выфрезеровать:

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

Управляющий компьютер

Управляющее ПО станков с ЧПУ должно работать на системах реального времени, чтобы генерировать точно синхронизированные сигналы. По-этому, Windows не очень хорошо для этого подходит. Конечно, для правильной работы написаны драйвера которые решают эту проблему, но ресурсов обычно это требует больше, а стабильность такой системы ниже чем систем реального времени.
Обработка велась под управлением LinuxCNC. Установка и настройка не должна вызвать больших трудностей. На сайте программы уже есть готовые билды так и исходники для гурманов. Существует несколько способов установки: на уже установленную систему или с нуля вместе с настроенной ОС. Я выбрал второй вариант, так как не на столько опытен в работе с Linux, и времени было маловато, чтобы разбираться с процессом пропатчивания. Второй вариант представляет из себя обычный Debian дистрибутив с RTC ядром и уже установленным LinuxCNC.

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

Заключение

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

  1. Повысить напряжение питания двигателей с 12 В до их рабочих 24 В
  2. Укрепить конструкцию, а в идеале подготовить новый проект станка с предварительным полным проектированием
  3. Добавить концевые переключатели и кнопку аварийной остановки
  4. Провести оптимизацию работы контроллеров ШД
  5. Пересобрать электронику станка на одной плате за исключением платы опторазвязки
  6. Заменить шпиндель станка на соответствующий целям. То есть высоко оборотистый и более мощный двигатель, чем текущий китайский гравер.
  7. Заменить двигатель на оси Z, так как текущий двигатель меньше по мощности и самый нагруженный

Полученный станок обладает рабочей областью больше 270 мм по осям X и Y, и около 150 мм по Z. Скорости перемещения по осям X и Y больше 500 мм/с, а по Z 300 мм/с. Это при 12 В рабочего напряжения. То есть половина от их рабочих характеристик. Есть куда расти.

Что можно сказать с уверенностью — это того стоило. Как минимум с одной задачей станок справится хорошо уже сейчас: вырезание плат. Можно забыть о травлении и ЛУТ. У вырезания плат есть, конечно, свои недостатки, но лучше иметь альтернативы, чем единственный вариант. На видео работы было видно как станок фрезой 3 мм фрезеровал букву М, может и с малой скоростью подачи и слоями по 0.1 мм, но это тоже результат.

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

Источник

CNC, БГУИР, ВМСиС, фрезерный станок, ЧПУ

Читайте также