возможность загружать и проводить изменения над управляющими командами для устройства объемной печати.
Для решения поставленных задач была
спроектирована система:
Рисунок 3.1 - Блок-схема диспетчерской программы
Модуль «Чтения данных» отвечает за интерпретацию входящих данных во внутреннее представление в программе для их последующей их обработки. А так же валидацию входящих данных для обеспечения корректной ее обработки в дальнейшем. Программное обеспечение должно иметь возможность обрабатывать:
трехмерные модели в формате «.stl» двух типов, ASCII и бинарные, представляющие собой описание треугольников из которых состоит модель объекта;
управляющие команды устройством объемной печати (G-code);
файлы конфигурации программы, содержащие в себе
предустановленные настройки для устройства объемной печати моделей и данного
программного обеспечения.
Рисунок 3.2 - Декомпозиция модуля «Чтение
данных».
Модуль «Обработка данных» производит
автоматизированную генерацию управляющих программ для устройства объемной
печати в соответствии с выбранными настройками конфигурации программы и
загруженной пользователем моделью. На вход его подаются интерпретированная в
модуле «Чтение данных» 3D модель объекта и конфигурации печати. Данный модуль
проводит анализ модели, строит периметры модели, проводит обнаружение твердых
поверхностей и поверхностей заполнения, производит нарезку модели по слоям и
генерирует путь экструдера для печати данной модели. Путь движения экструдера
после этого преобразуется в набор управляющих команд для устройства объемной
печати.
Рисунок 3.3 - Декомпозиция модуля «Обработка
данных»
Модуль «Запись данных» отвечает за сохранение на
жестком диске данных об используемой конфигурации системы, управляющих командах
для устройства объемной печати, а так же 3D модели.
Рисунок 3.4 - Декомпозиция модуля «Запись
данных»
Модуль «Визуализация данных» отвечает за отображение 3D моделей, загруженных пользователем в программу, и позволяет производить над ним манипуляции перемещения, сдвига, поворота для позиционирования их перед печатью.
.1.2 Разработка алгоритма управляющей программы контроллера
Исходя из поставленных задач, необходимо разработать управляющую программу контроллера для обеспечения следующих функций:
Приём G-кода (через USB-порт либо с SD-карты)
Отработка G-кода (процесс формообразования)
Контроль температуры и давления в экструдере
Контроль безопасности (опрос датчиков безопасности)
Взаимодействие с оператором (через ЭВМ, либо
через клавиатуру и ЖК-дисплей)
Рисунок 3.5 - Блок-схема управляющей программы
контроллера
Модуль «Инициализация работы» отвечает за инициализацию системы установки. За начальную проверку безопасности. За перемещение экструдера в стартовую позицию, с последующей установкой начала координат. И за организацию приёма данных(G-кода). Позиционирование экструдера заключается в доводе кареток до касания с концевыми выключателями, после чего экструдер перемещается в начальную запрограммированную заранее позицию и эта позиция считается отправной точкой (началом координат (0,0,0)).
Рисунок 3.6 - Декомпозиция модуля «Инициализация
работы»
Модуль «Чтение G-кода» выполняет чтение файла с G-кодом и его покадровую интерпретацию. После чего передаёт кадры на отработку.
Модуль «Отработка G-кода» выполняет основную функцию формообразования, то есть передаёт управляющие сигналы на рабочие органы установки. При этом оба этих модуля держат постоянную связь с модулем «Взаимодействие с оператором».
Модуль «Взаимодействие с оператором» служит для обеспечения возможности оператору следить за процессом печати и при необходимости вносить коррективы в работу установки. При этом оператор постоянно получает информацию о ходе печати, о том как выполнены его команды и получает мгновенное сообщение в случае возникновения неисправностей. Управление и получение сообщений возможно как с помощью ЭВМ, подключённого через USB-порт, так и без ЭВМ, а с помощью клавиш на установке и ЖК-дисплея.
Рисунок 3.7 - Декомпозиция модуля
«Взаимодействие с оператором»
Модуль «Опрос датчиков безопасности» выполняет
периодический опрос датчиков безопасности (прерывания по таймеру) и при
появлении аварийного сигнала, на каком-либо из них останавливает работу
установки и выдаёт оператору сообщение об возникновении аварийной ситуации.
3.2 Разработка программного обеспечения
автоматизированной установки
3.2.1 Разработка управляющей программы контроллера
Выбранная ранее в качестве управляющего устройства плата контроллера DFRduino MEGA едва ли потребует замены даже в случае расширения функционала установки с будущем, но если вдруг таковое случится, её можно заменить на любую Arduino-совместимую плату контроллера, обладающую большими возможностями.
Плата контроллера DFRduino MEGA программируется и прошивается при помощи фирменной утилиты Arduino IDE. Эта программная среда использует язык программирования C++ с дополнительными библиотеками для обеспечения работы с контроллером. Она обладает нужной нам библиотекой для управления шаговыми двигателями через драйвера шаговых двигателей. Эта библиотека называется stepper.h.
Как было сказаны выше, управления шаговыми двигателями программируется при помощи библиотеки stepper.h. Далее поговорим подробнее о функциях из этой библиотеки, которые используются в нашей программе.
Начинается всё с объявления шагового двигателя.
Для этого используется функция Stepper. Функция принимает 3 параметра: первый -
количество шагов на оборот (в нашем случае это 200), второе и третье - номера
контактов, к которым подключен драйвер, то есть его контакты step и dir.
Выглядит это примерно так (задали 200 шагов на оборот и подключение к 13 и 14
выводам)
Stepper AStepper = Stepper(200, 14, 13);
Далее требуется усановить скорость вращения двигателя. Для это служит функция Stepper.setSpeed. Эта функция принимает один параметр - количество оборотов в минуту. Задание скорости вращения в 120 оборотов в минуту выглядит так:.setSpeed(120);
Для вращения шагового двигателя используется
функция Stepper.step. Она принимает один параметр - число шагов, на которое
необходимо повернуться, если число положительное, то попорот идёт по часовой
стрелке и наоборот, если отрицательное. Поворот двигателя на один шаг выглядит
следующим образом:
AStepper.step(1);
Так же перед управлением двигателями необходимо
запрограммировать необходимые порты на вывод, иначе ничего не выйдет.
Программирование портов на ввод или вывод информации осуществляется с помощью
функции pinMode. Эта функция принимает два параметра: первый - номер порта,
второй - режим работы (ввод или вывод). Программирование 13 и 14 портов на
вывод осуществляется следующим образом:
pinMode(13, OUTPUT);(14, OUTPUT);
С управлением моторами разобрались. Далее
следует разобраться с опросом концевых выключателей. Опрос дискретных датчиков
происходит при помощи опрос дискретных портов, к которым они подключены.
Сначала необходимо задать требуемые порты на ввод информации.
pinMode(1, INPUT);(2, INPUT);(3, INPUT);
pinMode(4, INPUT);
После необходимо периодически опрашивать порты.
Опрос портов выполняется функцией digitalRead, единственным параметром, которой
является номер опрашиваемого дискретного порта. Функция возвращает значение 1, если
на входе порта напряжение выше 3 вольт и 0 в противном случае. Опрос датчиков
производится через переменную и выполняется следующим образом:
AES = digitalRead(1);= digitalRead(2);=
digitalRead(3);
Опрос концевых выключателей на осях производится лишь в функции начального позиционирования. Так как для позиционирования необходима высокая точность необходимо производить опрос датчиков на каждый повёрнутый шаг двигателя, то есть раз в пол секунды.
Далее перейдём к экструдеру. В экструдере
необходимо поддерживать нужную температуру и давления пластика в нагревательной
камере. Для нагрева у нас используется резистор номиналом 5,6-8,2 Ом,
подключённый через модуль реле к блоку питания. Для включения нагрева
необходимо подать логическую единицы на дискретный порт, к которому подключен
модуль реле (дискретный порт должен быть настроен на вывод). Подача логической
единицы на порт происходит с помощью функции digitalWrite, которая принимает
два параметра: первый - номер дискретного порта, а второй - его значение (0 или
1, LOW или HIGH). Функция выглядит следующим образом:
digitalWrite(5, HIGH);
Контроль температуры осуществляется с помощью термистора, подключенного к аналоговому входу. Для этого необходимо запрограммировать прерывание по системному таймеру для периодического опроса аналогового порта, к которому подключен датчик температуры.
Контроллера Arduino MEGA имеет шесть таймеров, которые нумеруются начиная с 0 и до 5. Первые два таймера имеют 8-битный счётчик, остальные четыре - 16-битный (то есть первые ведут счёт максимум до 255, а остальные четыре до 65535). Так же таймера работают с определёнными определителями от частоты контроллера (8, 16, 32, 64, 128 и т.д.). Эти параметры определяют частоту срабатывания прерываний. Так же существует несколько типов, по которым генерируются прерывания:
Прерывание по переполнению (по достижению максимального значения счётчика происходит прерывание и сброс)
Прерывание по совпадению (при совпадении назначенного числа происходит прерывание и сброс)
Прерывание по обратному счёту (так же как и первое, только счёт ведётся с 255 до 0, при нуле - прерывание и сброс)
В нашем случае можно использовать первый тип.
Следует подобрать предделитель таким образом, чтобы прерывание не возникало
слишком часто, дабы не нагружать машинной время контроллера лишними операциями,
и не достаточно большим, чтобы температура колебалась сверх допустимого
предела. Для вычисления точного значения необходимо воспользоваться формулой
3.1.
|
|
(3.1) |
где fцп - частота работы микропроцессора;пд - предделитель таймера;сч - значение, до которого ведётся счёт, после чего происходит сброс.
С предделителем 8 и режимом счёта до 65535
частота будет:
То есть частота вызова прерывания по таймеру 2 - 30,5 раз в секунду.
Для того, чтобы настроить данный таймер на работу в нужном режиме необходимо установить нужные значения в регистрах, отвечающих за этот таймер, а именно TIMSK2 (бит TOIE2) отвечает за разрешение/запрещение прерываний по переполнению, TCCR2A (биты WGM21 и WGM20) отвечает за режим работы таймера/счётчика, TCCR2B (бит WGM22) так же отвечает за режим работы, и наконец tcnt2 отвечающий за частоту срабатывания.
Итак для наших нужд программирование таймера будет выглядеть следующим образом:
&= ~(1<<TOIE2); //запрещение прерывания по переполнению
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));B &= ~(1<<AS2);
ASSR &= ~(1<<AS2); //синхронизация от
системного генератора= 65535; //установка счётчика|= (1<<TOIE2);
//разрешение прерывания по переполнению
Таким образом запрограммировали таймер 2 на частоту срабатывания примерно 30,5 Гц.
Далее нужна функция обработчик этого прерывания. Для этого необходимо описать нужную нам функция и использовать её в обработчике прерывания.
Допустим наша функция называется ThermMonitor и она опрашивает аналоговый порт к которому подключен термистор и сравнивает его значение с заданным диапазоном температур. Если значение выдаётся за нижний предел диапазона, то включает нагрев, если за верхний - выключает.
Чтение порта выполняется командой analogRead с параметром - номер порта. А включение и выключение нагрева происходит по описанному выше сценарию. Итого получается простая функция с чтением порта и одним условием.
Внести эту функция в обработчик перекрывания
можно следующим образом:
ISR(TIMER2_OVF_vect)
{= tcnt2;
ThermMonitor();
}
Так же в этом прерывании можно использовать и функцию проверки датчика пламени. Так как он то же аналоговый не получится использовать прерывание по порту. Для этого внесём в обработчик прерывания ещё одну функцию FireMonitor, которая опрашивает датчик пламени и при наличии сигнала с него использует функцию EmergencyShutdown - функцию аварийной остановки.
Выглядеть это будет следующим образом:
(TIMER2_OVF_vect)
{= tcnt2;();();
}
И раз уж зашло дело об опросе датчиков безопасности зададим прерывание и для датчика дверцы.
Делается это с помощью функции attachInterrupt, который принимает три параметра: пернвый - номер прерывания, второй - функция обработчик прерывания и третий - тип возникновения прерывания.
В нашем случае будет выглядеть так: (0,
EmergencyShutdown, FALLING);
При исчезновении сигнала с датчика дверцы происходит вызов функции EmergencyShutdown, которая останавливает процесс печати, выключает нагрев и выводит сигнал о нарушении безопасности.
Но вернёмся к экструдеру, в нём нужно по-прежнему контролировать постоянное давление во время печати. Для этого в процесс печати, когда необходима подача пластика нужно внести функцию опрашивающую датчик давления и меняющую в зависимости от этого скорость шагового двигателя, подающего пластик.
Далее стоит перейти к ЖК-дисплею. Модуль ЖК-дисплея использует два аналоговых выхода. Для программирования ЖК-дисплея существует специальная библиотека - LiquidCristal.h.
При помощи функций из этой библиотеки необходимо задать подключение дисплея и инициализировать его. Задание дисплея происходит следующим образом:
LCD(3, 4);
Теперь LCD подключен к 3 и 4 аналоговым портам (разумеется они должны быть настроены на выод информации).
Далее инициализируем дисплей с помощью функции LiquidCristal.begin два параметра которой - это количество символов в строке и длина строки, в нашем случае это 16 на 2. Инициализация выглядит следующим образом:
.begin(16, 2);
Для вывода информации используются функции LiquidCristal.print и LiquidCristal.println. Единственный их параметр это текст для вывода. Отличаются они тем, что первая функция после вывода оставляет курсор на той же строке, а вторая - на следующей.
Вывод текста выглядит следующим образом:
.println(“инициализация”);.print(“завершена”);
Этот код выведет на дисплей фразу «инициализация завершена» в две строки.
Чтобы очистить дисплей есть функция LiquidCristal.clear, для перемещения курсора используется функция LiquidCristal.setCursor.
Остался опрос датчика клавиатуры. Так как датчик клавиатуры аналоговый, то его опрос так же необходимо выполнять от прерывания таймера. Для этого можно использовать уже готовый ранее таймер 2, либо запрограммировать другой. Для начала используем таймер 2, и если не будет возникать проблем, то надобности в другом таймере не будет. Для работы с клавиатурой создадим функцию KeyMonitor. Эта функция считывает состояние аналогового порта к которому подключена клавиатура и в зависимости от сигнала применяет нужную функцию.