Прошивка Marlin для 3D принтеров. Настройка 3D принтера, установка, загрузка, тестирование. – 3DRadar

Подробная инструкция по тому, как перепрошить и настроить FDM-принтер с использованием дефолтного и отредактированного ПО.

Что такое «прошивка 3D-принтера»?

image5.jpg

Источник: all3dp.com

Прошивка — это «интеллект» 3D-принтера, его основная программа, что позволяет обработать команды G-code, полученные из слайсера, реализовав его в конкретные действия и характеристики действий, выполняемых аппаратной частью 3D-принтера. Например, программное обеспечение отправляет команду G-code «G1 X50 Y50». Прошивка 3D-принтера определяет полярность, напряжение и продолжительность импульса на моторы, необходимые чтобы переместить экструдер на X = 50 мм и Y = 50 мм, после чего прошивка отправляет электрические сигналы к этим моторам. Таким же образом прошивка преобразует команды G-code в действия кулера, нагревателей и других элементов 3D-принтера.

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

Предыстория

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

Предыстория получилась длинной, поэтому убрал ее под спойлер

Лет 5 назад я заинтересовался 3D-печатью. Не в профессиональном плане, а просто стало любопытно что же это такое, что она может и как работает. Сначала был приобретен FDM-принтер, один из самых бюджетных на тот момент — Anet A8. И в общем-то мне понравилось, учитывая, что чудес от него я не ждал. На нем я до сих пор иногда печатаю что-то утилитарное — какие-нибудь крепления, подставки, корпуса. А затем мне стало интересно пощупать фотополимерную печать с ее потрясающей детализацией, но тогда фотополимерные принтеры назвать бюджетными было никак нельзя. И вот пару лет назад я все-таки созрел на покупку одного из них — Anycubic Photon S. Уже и цены были не такими высокими, и я смог себе позволить потратить энную сумму просто для удовлетворения любопытства.

Сначала, конечно же, был эффект «вау» — он печатает такие мельчайшие детали, да так аккуратно. Никаких слоев, прыщей и т.п., присущих FDM-принтерам. Область печати, конечно, не ахти — всего примерно 115х65 мм, но фигурки и модельки получаются очень хорошо 🙂 Когда эффект «вау» прошел, я понял, что детализация у него не такая хорошая, какая могла бы быть. После чего я по примеру знакомого его слегка модернизировал. Пришла новая волна «вау» — детализация повысилась в разы. Правда, стали четко видны границы пикселей, но только если рассматривать модель на расстоянии 20-30 см. Кстати, последующая покраска напечатанных моделей оказалась довольно неплохим способом отдохнуть от работы — мозг отдыхает, руки возятся. Результат дарится знакомым как интересный сувенир.

Но по мере освоения принтера я начал замечать недостатки в работе принтера. Нельзя настроить это, сложно изменить то, не работает так как хотелось бы и т.д. В частности, например, мой принтер не умел работать с каталогами на флэшке, не поддерживал кириллические имена файлов, скорость движения платформы в определенных случаях была не той, что бы меня устроила. Я даже дизассемблировал прошивку и начал разбираться с ее внутренностями. Реализовал работу с кириллицей в именах файлов, изменил процесс вывода на интерфейсный экран (ускорил), переделал работу с языками. Но все это было несерьезно, нужно было иметь исходники, чтобы можно было нормально переделать все что хотелось. А исходники никто из производителей почему-то не дает. И вот несколько месяцев назад я узнал, что есть такой набор для фотополимерного принтера от довольно известного в сфере 3D-печати производителя — MKS DLP. В набор входят: сама материнская плата, дисплей засветки с защитным стеклом (5.5″, 2560х1440) и интерфейсный дисплей с сенсорной панелью (3.5″, 480х320). И для этого набора идут открытые исходники и схема — бери и переделывай как угодно! И я приобрел этот набор, рассчитывая изменить в исходниках то, что мне не нравится.

Когда я получил комплект и скачал с гитхаба исходники, приготовившись их слегка модифицировать, у меня случился легкий шок. Ну, во-первых их родная прошивка оказалась в принципе работоспособна, но это и все, что можно сказать о ней хорошего. Недостатков в ней полно и печатать с ней было бы очень не комфортно. Уже на этапе проб родной прошивки у меня начала закрадываться мысль, что модифицировать придется не так уж слегка. А когда я открыл их проект с исходниками… Во-первых, это жуткая мешанина Ардуины и библиотек CMSIS и HAL от ST (плата построена на микроконтроллере STM32F407). Во-вторых, в проект впихнута полная версия Marlin 3D. Кто не знает — Marlin 3D — это проект для управления FDM 3D-принтерами. Он поддерживает работу до 6 шаговыми двигателями, несколькими нагревателями с контролем температуры, кучи концевиков, парсинг G-кода с построением траекторий движения осей и много-много чего еще. Больше 3 МБ исходников. И сюда он был целиком впихнут только ради управления одним шаговым двигателем. Причем это управление было сделано совершенно без заморочек — в текстовой строке формировался G-код движения оси и эта строка передавалась на вход парсера Мерлина. Ну это как если бы взяли целиком автомобиль для того, чтобы использовать одну из его фар для освещения. Вообще создалось впечатление, что производитель взял исходники от своих плат для FDM-принтеров и просто сверху прикостылял код для работы с фотополимерной частью.

Кроме того, там была еще GUI-библиотека в бинарнике, без исходников. И я понял, что проще будет написать свою прошивку с нуля, чем пытаться что-то сделать с родными исходниками.

Итак, что мы имеем:

  • комплект MKS DLP, в который входят: материнская плата, интерфейсный дисплей 3.5″ 480х320 и дисплей засветки 5.5″ 2560х1440
  • родные исходники от производителя
  • схема материнской платы (без названий активных и номиналов пассивных компонентов)

Материнская плата построена на основе микроконтроллера STM32F407. Для управления дисплеем засветки на плате стоит

FPGA

китайского производителя GW1N-LV4LQ144ES, SDRAM и две микросхемы MIPI-интерфейса SSD2828. Микроконтроллер загоняет в FPGA изображение слоя, FPGA сохраняет его в SDRAM и оттуда рефрешит дисплей через SSD2828. Конфигурацию (прошивку) FPGA производитель, кстати, не предоставляет в исходниках 🙁 Кроме этого, на материнской плате есть:

  • вход питания 12-24 вольта
  • USB A разъем для подключения флэшки/картридера
  • коммутируемые выходы питания для засветки и двух вентиляторов
  • драйвер шагового двигателя A4988 и разъем для подключения двигателя
  • два разъема для подключения концевиков оси Z — верхнего и нижнего
  • разъем для подключения модуля WiFi
  • микросхема FLASH-памяти W25Q64
  • микросхема EEPROM-памяти AT24C16

Интерфейсный дисплей с резистивной тач-панелью подключается плоским 40-пиновым шлейфом. Контроллер дисплея — ILI9488, контроллер тач-панели — HR2046 (аналог TSC2046).

Для инициализации периферии я использовал программу STM32CUBE MX. Но не использовал напрямую полученный из него результат, а вставлял нужные куски в свои исходники. При работе с периферией использовал библиотеки HAL от ST, а там, где нужно было получить максимальную скорость — работал с регистрами напрямую.

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

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

1. Пользовательский интерфейс

Сначала была инициализация дисплея. Тут ничего интересного, стандартная последовательность для контроллера ILI9488. Ее я выдрал из родных исходников, вырезав оттуда код инициализации других видов дисплеев (которые, вероятно, остались там еще от FDM-жизни этих исходников). Дальше я занялся шрифтами.

1.1 Шрифты

В сети множество библиотек работы со шрифтами для микроконтроллеров, но абсолютное большинство из них работают с моноширинными шрифтами, а мне это не очень нравится. Это когда у всех символов одинаковая ширина, что у буквы «ж», что у буквы «i». Когда-то для одного из своих пет-проектов я написал библиотеку пропорциональных шрифтов. В ней для каждого шрифта используются два массива — массив с битовыми данными самих символов и массив с указанием ширины каждого символа. И небольшая структура с параметрами шрифта — указатели на массивы, высота шрифта, количество символов в шрифте:

typedef struct{ uint16_t *width; uint8_t *data; uint8_t height; uint16_t symcount;} LCDUI_FONT;

Казалось бы, такая организация шрифта должна занимать в памяти больше места, чем просто битовый массив моноширинного шрифта, однако это не совсем так. Во-первых, сама моноширинность дает избыток хранящихся данных. Например, если в шрифте высотой 8 и шириной 5 пикселей для буквы «i» было бы достаточно 1 байта (1 бит ширины и 8 бит высоты), то она все равно будет занимать 5 байт данных (5 бит ширины и 8 бит высоты), т.к. ширина фиксирована. Во-вторых, как правило в таких шрифтах делается выравнивание по границам байта каждой строки или каждой колонки, смотря как организованы данные.

Например, взять тот же шрифт 5х8. Если битовые данные хранятся по строкам, то для каждой строки получается избыток 3 бита. Или 3 байта на символ:

image

Или шрифт 7х12 с хранением данных по колонкам, тогда получается избыток данных 4 бита на колонку или 3.5 байта на символ:

image

В моей библиотеке битовые данные непрерывны для символа и выравнивание по границе байта идет только в конце символа.

Плюс есть еще одна небольшая хитрость, позволяющая слегка уменьшить хранимый размер шрифта: символ может не иметь битовых данных, а ссылаться на другой символ с таким же начертанием. К примеру, кириллические буквы «А», «В», «Е», «К» и т.д. могут иметь отсылку на латинские буквы с тем же начертанием. Это делается с помощью указания отрицательного значения ширины соответствующего символа в массиве ширин символов. Если там стоит отрицательное значение, значит изображение этого символа берется из символа в позиции (ширина * -1).

Вот процедура нахождения в массиве данных символа:

uint8_t* _lcdui_GetCharData(char c){ if (c < 32) return 0; if (c > 126) c -= 65; c -= 32; if (c >= lcdui_current_font->symcount) return 0; uint16_t c1 = lcdui_current_font->width[c]; if (c1 & 0x8000) c = (c1 & 0x7FFF); uint16_t ch = lcdui_current_font->height; int32_t i = 0, ptr = 0, bits = 0, line_bits = ch; for (i = 0; i < c; i++) { if (lcdui_current_font->width[i] & 0x8000) continue; bits = lcdui_current_font->width[i] * line_bits; ptr += bits >> 3; if (bits & 0x07) ptr++; } return &(lcdui_current_font->data[ptr]);}

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

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

Например, на фото ниже голубой текст и верхняя белая строка отрисованы моей библиотекой, а белая нижняя — стандартной ардуино-подобной библиотекой из родных исходников:

image

Голубой текст отрисовался в несколько раз быстрее, чем нижняя белая строка.

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

Процедура вывода текста умеет переносить текст на новую строку в конце экрана или по встреченному символу перевода строки, умеет выравнивать влево, вправо и по центру, ограничивать область, за пределы которой текст не выйдет (будет обрезан). И умеет выводить символы с закрашиванием фона фоновым цветом или с сохранением фона. Второй вариант работает медленнее, так как уже не получается заливать данные символа в дисплей одним потоком, но все равно достаточно быстро, чтобы вывод 3-4 строк не был заметен глазу.

1.2 Вывод изображений интерфейса

Для пользовательского интерфейса понадобится выводить на дисплей изображения — фон, иконки, кнопки. Сначала я решил сильно не заморачиваться и хранить все изображения в формате .bmp в 8-мегабайтной флэш-памяти, имеющейся на плате. И даже уже написал для этого процедуру. Файл сохраняется в 16-битном формате (R5 G6 B5) с прямым или обратным порядком строк, и может уже быть напрямую скормленным процедуре отрисовки. Но размер фоновой картинки размером 480х320 выходит более 300 Кбайт. С учетом того, что часть этой флэш-памяти будет отводиться под обновление прошивки, 30 фоновых изображений займут всю память. Вроде и немало, но все же меньше, чем хотелось бы иметь на всякий случай. А ведь должны быть еще кнопки, иконки и т.п. Поэтому было решено преобразовывать изображения в какой-то сжатый формат.

Со сжатием вариантов немного — все более-менее хорошо сжимающие изображения алгоритмы требуют или прилично оперативки (по меркам микроконтроллера) или прилично времени на разжатие. Картинки же должны выводиться, разжимаясь на лету, и желательно чтобы картинка при выводе не уподоблялась ползущему прогресс-бару. Поэтому я остановился на RLE-сжатии — 1 байт кодирует количество повторов, а два следующих за ним — цвет. Для этого так же была написана утилита, преобразующая файлы .bmp в сжатые таким образом изображения. Заголовок состоит всего из 4 байт — по 2 байта на ширину и высоту изображения. В среднем фоновые изображения сжимаются таким способом в 5-7 раз, сильно зависит от размера одноцветных участков (чего и следовало ожидать). Например вот такая картинка сжалась с исходных 307 КБ до 74 КБ:

image

А вот такая — до 23 КБ с тех же 307:

v5bxg-bjr2qtcee80k0qg-njdda.png
Да, кстати, дизайнер из меня еще более фиговый, чем программист…

Меня такой результат устроил. Декодирование и вывод изображений происходит очень быстро — примерно 40 миллисекунд на полное фоновое изображение. Так что на таком варианте я и остановился.

И, кстати, переход на режим DMA для вывода данных в дисплей не дал почти никакого ускорения вывода. Дисплей подключен по внешней 16-битной шине данных как внешняя память, но вот его тайминги довольно печальны, что и сводит почти на нет преимущества DMA-вывода перед попиксельным выводом «вручную».

1.3 Основа GUI

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

С тач-панелью все просто — микроконтроллер по прерываниям постоянно опрашивает контроллер тач-панели и усредняет последние 4 полученных результата, переводя их в координаты дисплея. Таким образом в любой момент известно состояние сенсора — нажат он или нет и если нажат, то в каком именно месте. Еще одна прослойка между тач-панелью и основной частью программы — процедура обработки нажатий кнопок, которая уже довольно давно кочует у меня из проекта в проект с небольшими адаптациями под конкретные условия.

Вот вкратце ее принцип работы

Изначально всем кнопкам присваивается статус «СВОБОДНА». По прерыванию таймера вызывается процесс опроса кнопок (100-150 раз в секунду). Если кнопка оказывается нажата, то ей присваивается статус «ПРЕДНАЖАТА». При следующем опросе если она все еще остается нажатой, ее счетчик увеличивается на единицу. Если оказывается, что счетчик достиг определенного значения, то кнопке присваивается статус «НАЖАТА», а счетчик обнуляется. Если при очередном опросе кнопка оказалась не нажатой, имея статус «ПРЕДНАЖАТА», то ее статус меняется на «СВОБОДНА». Когда оказывается отпущенной кнопка со статусом «НАЖАТА», ей дается статус «ОТПУЩЕНА». Основная программа просто опрашивает когда может статус кнопок и если у какой-то кнопки статус оказывается «НАЖАТА» или «ОТПУЩЕНА», то вызывается процедура обработки нажатия или отпускания этой кнопки. Тут реализуется и программный фильтр дребезга контактов (статус «ПРЕДНАЖАТА»), и срабатывание нажатия кнопки даже если основная программа во время нажатия была чем-то занята. Кроме того, там еще есть статусы и для длительного нажатия, и для повторяющегося ввода при длительном нажатии.

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

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

В конечном итоге я пришел к такой схеме: интерфейс состоит из двух основных типов элементов — экранов и кнопок.

Экран — это своего рода полноэкранный контейнер для кнопок. У экрана есть следующие свойства:

  • фоновое изображение
  • цвет фона
  • способ отрисовки фона — заливка фоновым цветом или вывод изображения
  • текст заголовка
  • цвет текста заголовка
  • шрифт текста заголовка
  • указатель на родительский экран (в который нужно вернуться при закрытии этого)
  • массив указателей на кнопки
  • указатель на процедуру обработки событий (вызывается периодически в основном цикле программы)
  • указатель на процедуру отрисовки экрана

Структура экрана
typedef struct{ void *addparameter; char *bgimagename; void *prevscreen; LNG_STRING_ID name; TG_RECT nameposition; TG_TEXTOPTIONS nameoptions; uint8_t btns_count; TG_BUTTON *buttons; LCDUI_FONT_TYPE font; LCDUI_FONT_TYPE namefont; uint16_t textcolor; uint16_t nametextcolor; uint16_t backcolor; struct { paintfunc _callpaint; // repaint screen processfunc _process; // screen process handling (check for changes, touch pressed, etc) } funcs;} TG_SCREEN;

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

Свойства кнопок:

  • координаты на экране
  • цвет фона
  • фоновое изображение для свободного состояния
  • фоновое изображение для нажатого состояния
  • фоновое изображение для выключенного состояния (disabled)
  • фоновое изображение для активного состояния (для активного элемента группы переключателей, например)
  • способ отрисовки — изображением или фоновым цветом
  • перерисовывать ли кнопку при ее нажатии и отпускании
  • текст кнопки
  • шрифт текста кнопки
  • координаты области вывода текста кнопки
  • цвета текста и фона для всех состояний
  • флаги отключенного и активного состояний
  • флаг необходимости перерисовать (изменилось состояние)
  • опции вывода текста (выравнивание, прозрачность)
  • идентификатор кнопки
  • идентификатор группы (для группы переключателей)
  • указатели на процедуры отрисовки, обработки событий и нажатия
  • указатели на дочерний экран, вызываемый при нажатии на эту кнопку

Структура кнопки
typedef struct{ void *addparameter; uint8_t button_id; int8_t group_id; // for swithed options buttons, >0 – single selection from group (select), <0 – multiple selection (switch) TG_RECT position; void *parentscreen; void *childscreen; char *bgimagename_en; char *bgimagename_press; char *bgimagename_dis; char *bgimagename_act; // for swithed options buttons LNG_STRING_ID text; TG_RECT textposition; LCDUI_FONT_TYPE font; uint16_t textcolor_en; uint16_t textcolor_press; uint16_t textcolor_dis; uint16_t textcolor_act; // for swithed options buttons uint16_t backcolor_en; uint16_t backcolor_press; uint16_t backcolor_dis; uint16_t backcolor_act; // for swithed options buttons struct { uint8_t active:1; // for swithed options buttons uint8_t needrepaint:1; uint8_t pressed:1; uint8_t disabled:1; uint8_t repaintonpress:1; // repaint or not when pressed – for indicate pressed state BGPAINT_TYPE bgpaint:2; } options; TG_TEXTOPTIONS textoptions; struct { paintfunc _call_paint; // repaint button pressfunc _call_press; // touch events handling pressfunc _call_longpress; // touch events handling processfunc _call_process; // periodical processing (for example text value refresh) } funcs;} TG_BUTTON;

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

А вот на что не хватило возможностей этой схемы — так это на модальные окна с сообщениями или вопросами (типа MessageBox в Windows API), поэтому для них я сделал отдельный тип экранов. Без фоновых изображений и с размером, определяющимся заголовком или самим сообщением — что окажется больше. Эти сообщения могут быть созданы в четырех вариантах — с кнопками «Да/Нет», с кнопками «Ок/Отмена», с одной кнопкой «Ок» или вообще без кнопок (типа «Подождите, идет загрузка данных…»).

lqbyy3pjupzofen0uyan5acrzeu.jpeg

Структура окна сообщений
typedef struct{ MSGBOXTYPE type; void *prevscreen; char caption[128]; char text[512]; TG_RECT boxpos; uint8_t btns_count; TG_BUTTON buttons[TG_BTN_CNT_MSGBOX]; uint16_t caption_height; LCDUI_FONT_TYPE font_caption; LCDUI_FONT_TYPE font_text; uint16_t text_color; uint16_t box_backcolor; uint16_t capt_textcolor; uint16_t capt_backcolor;} TG_MSGBOX;

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

1.4 Мультиязычность

wu02vxws3slyciywbsyemvqic0e.jpeg

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

char *mshortname = LANG_GetString(LSTR_SHORT_JANUARY);

При изменении языка происходит просто изменение указателя с массива текстов на старом языке на массив с текстами на новом языке:

void LANG_SetLanguage(uint8_t lang){ lngCurrent = lngLanguages[lang].strings; return;}

Все тексты в исходниках — в кодировке UTF-8. С этими кодировками тоже пришлось повозиться. Тексты — в UTF-8, кириллица файлов — в Unicode-16, некоторые строки — в обычном ANSI. Тянуть в прошивку целый набор библиотек для поддержки многобайтовых кодировок не хотелось, поэтому было написано несколько функций для преобразований из кодировки в кодировку и для операций с текстами в разных кодировках, например, добавить к концу строки Unicode16 строку в UTF-8.

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

1.5 Хранение изображений и прочих ресурсов

Для хранения больших ресурсов на плате имеется SPI-флэш на 8 мегабайт W25Q64. Изначально я хотел поступить как всегда — задать смещение для каждого ресурса внутри флэши и сохранять их туда как просто бинарные данные. Но потом понял, что проблемы с таким способом мне гарантированно обеспечены как только количество сохраняемых ресурсов перевалит за пару десятков и мне захочется изменить, например, какую-то картинку, которая сохранена шестой по порядку. Если ее размер увеличится, то придется сдвигать адреса всех следующих ресурсов и перезаписывать их заново. Или оставлять после каждого ресурса запасное пространство неизвестного размера — кто его знает как может измениться какой-то из ресурсов. Да в гробу я видал эту возню 🙂 Поэтому я плюнул и организовал на этой флэши файловую систему. К тому времени у меня уже работала файловая система для USB на основе библиотеки FatFS, так что мне было достаточно просто написать отдельные низкоуровневые функции чтения/записи секторов. Одно только меня слегка расстроило — размер стираемого сектора в этой микросхеме аж целых 4 КБ. Это во-первых приводит к тому, что файлы будут занимать место порциями по 4 КБ (записал файл 200 байт — он занял 4 КБ флэши), а во-вторых буфер в структуре каждого файлового указателя будет отъедать те же 4 КБ оперативки, которой в микроконтроллере не так уж много — 192 КБ. Можно было бы, конечно, извратиться и написать низкоуровневые функции так, чтобы они могли писать и читать и меньшими порциями, рапортуя о размере сектора, например, 512 байт. Но это замедлило бы работу с флэш, так что оставил размер сектора 4 КБ. Так что обращение к любому ресурсу осуществляется просто по имени его файла, что оказалось очень удобным. На данный момент, например, количество хранимых ресурсов перевалило уже за 90. И их обновление я сделал максимально простым — обновляемые (или новые) ресурсы записываются на USB-флэшку в определенный каталог, флэшка вставляется в плату, плата перезагружается в сервисный режим (во время включения или перезагрузки нажать и держать правый верхний угол дисплея) и автоматически копирует все найденные в этом каталоге файлы с USB-флэшки в SPI-флэш.

yd_wlp_z3-xhgviokhibp_gvt2u.jpeg

Где взять?

Последняя версия прошивки Marlin выложена на официальном сайте разработчика  https://github.com/MarlinFirmware/Marlin. Скачать более ранее версии прошивки можно по ссылке. Также на сайте присутствуют много различных версий, но мы рекомендуем скачивать  самую последнюю версию, помеченную как Latest release. На момент написания статьи, данной версией была 1.0.2-2

Latest-release.jpg

Под Downdloads нажмите на Source code (zip) и скачайте архив прошивки себе на компьютер. Далее извлеките содержимое архива в папку.

Программное обеспечение

Софт для 3D-принтера RepRap – имеется инструкция для Marlin

Принципы обновления firmware для устройств

Согласно новой парадигме программный софт и аппаратная часть выполняется в рамках проектов с открытым исходным кодом. Именно в рамках такого проекта разрабатываются полупрофессиональные 3D принтеры. Для них существует универсальная прошивка Marlin, рассчитанная на работу с микроконтроллерными платами ArduinoMega и RAMPS Shield v.1.4. Соответственно, прошивка для 3d принтера Marlin совместима со всеми моделями, в которых они использованы. Перед выполнением работ потребуется установить плату RAMPS shield в ArduinoMega и сделать действия, описанные ниже.

RAMPS Shield

Для перепрошивки устройства понадобится плата RAMPS Shield

Проблема данного ПО в отношении пользователей состоит в том, что софт не обновляется автоматически, как это характерно для компьютеров.

Новые версии нужно устанавливать самостоятельно, используя файлы, доступные на сайте Marlin.

После установки выполняется настройка прошивки 3d принтера.

Marlin Arduino

На сайте Marlin необходимо скачать последнюю версию Arduino

Общий процесс соответствует следующей последовательности:

  • файлы скачиваются с сайта Marlin;
  • затем компилируются в среде Arduino IDE;
  • после этого записываются на управляющую плату RAMPS shield.

Чтобы обновить прошивку, нужно самостоятельно скачать файлы и проделать описанные действия. Для всех моделей действия аналогичны, включая модель PRUSA I3.

Вкладка Configuration.h

Все действия нужно производить на вкладке Configuration.h

Прошивка

Marlin – под Arduino Mega 2560. На форуме на русском языке

Настройка configuration.h (температура и скорость) – Робофорум

Firmware Installation – англоязычное подробное описание установки и настройки прошивки со скриншотами

Basic Configuration Set-up Guide

Определение платы и версии прошивки принтера

image2.jpg

Источник: all3dp.com

Перед началом перепрошивки 3D-принтера необходимо установить производителя платы контроллера. Эта информация выгравирована или нанесена непосредственно на самой материнской плате. Чаще всего в бюджетных FDM 3D-принтерах установлены платы Arduino. Также встречаются аппараты, которые построены на базе плат Smoothie, BeagleBone и Duet, а также собственных электронных компонентах разработки производителя принтера. Производители плат публикуют самые свежие версии прошивок на своих официальных сайтах. Например: Arduino, Wanhao 3D printer, Phrozen.

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

image1.jpg

Источник: all3dp.com

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

Прошивку заводских плат рекомендуется только обновлять, по мере появления новых версий на официальном сайте. Однако, даже при появлении свежей версии, перепрошивка может быть излишней. Как показывает практика, если 3D-принтер исправно выполняет свои задачи, то не стоит ему мешать. Народная мудрость гласит: «Не чини то, что не сломано».

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

Слайсер

KISSlicer, обсуждение на Робофоруме

Slic3r

Изменение параметров принтера

image3.jpg

Источник: all3dp.com

Когда новая версия прошивки скачана на компьютер, пользователь не может вручную внести правки в файл конфигурации. В исходных кодах Marlin и Repetier редактируемые файлы имеют особое расширение, например .h. Рекомендуется сохранять копию не измененной версии прошивки на компьютере — это позволит сэкономить время, если придётся отказаться от отредактированного файла. После внесения изменений в файл конфигурации, новые значения следует сохранить, после чего можно приступать к перепрошивке.

Распространенные переменные параметры:

  • Тип платы контроллера (#define MOTHERBOARD BOARD_RAMPS_14_EFB) — бренд платы, на которую будет установлена новая прошивка;

  • Тип термистора (#define TEMP_SENSOR_0 5) — определение термистора, который измеряет температуру сопла;

  • Шаги / на мм (#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 500 }) — определение количества шагов, которые должен совершить мотор для перемещения экструдера на 1 мм;

  • Максимальные значения температур (#define HEATER_0_MAXTEMP 285) — если при апгрейде 3D-принтера установлен экструдер, который позволяет работать с тугоплавкими пластиками, в прошивке следует указать верное значение максимальной температуры.

Хост

Pronterface (он же PrintRun) – предпочтительнее, чем следующий

Repetier-Host – иногда нестабилен

Установка прошивки: компиляция и загрузка

Установка прошивки на принтер осуществляется с компьютера, к которому 3D-принтер подключен. Важно понимать, что установка — это процесс создания (компиляция) исходного кода прошивки и её загрузка в микроконтроллеры управляющей платы. В программе (в приведённом на скриншоте примере — Marlin) необходимо указать модель платы (Arduino Mega 2560) и порт (подключенный 3D-принтер). Чтобы не ошибиться с портом, на момент перепрошивки лучше оставить подключенным только один 3D-принтер.

image8.jpg

Источник: matterhackers.com

Затем необходимо скомпилировать файлы прошивки, то есть — перевести понятный человеку код в бинарный. Это автоматический процесс. Если всё было сделано верно, будет создан файл для загрузки на принтер. В противном случае программа выдаст сообщение об ошибке, что потребует изменения параметров конфигурации или повторного компилирования не отредактированной версии прошивки. 

image7.jpg

Источник: matterhackers.com

Скомпилированную прошивку загружают на 3D-принтер. Процесс загрузки занимает несколько минут, после чего 3D-принтер автоматически перезагрузится.

image6.jpg

Источник: matterhackers.com

Популярные прошивки для 3D-принтера

Marlin — популярная прошивка для 3D-принтеров, совместимая с 8- и 32-битными платами. Прошивка предоставляет пользователю широкий диапазон настроек. Например, для контроллера интерфейса дисплея предусмотрен выбор из 30 языков. С сайта проекта можно скачать последнюю и несколько прошлых версий прошивки.

Repetier-Firmware — прошивка от команды, создавшей популярный слайсер Repetier-Host. Совместима с 8-битными платами и с 32-битными платами с контроллерами AVR (Arduino Due и RADDS). Есть поддержка онлайн-редактирования файла конфигурации.

RepRap Firmware — прошивка, разработанная для 32-битных микросхем на базе контроллеров AVR.

Smoothieware — подобно прошивке RepRap, Smoothieware работает только на ограниченном количестве плат, основными из которых являются Smoothieboard и Azteeg X5 Mini.

Рейтинг
( 1 оценка, среднее 5 из 5 )
Загрузка ...