Уха из Марлина или разбираем прошивку по косточкам
Погуглив немного и не найдя ничего внятного кроме процесса создания конфигурационного файла и описания G-кодов, принял решение разобраться с исходниками досконально. Для чего?
1. Дабы упростить себе процесс настройки и траблешутинга.
2. Для использования в своем проекте «экзотических» устройств, типа измерителя толщины нити, умной подсветки, вытяжки и … (по секрету) экструдера выдавливания нити из гранул.
3. Возможности писать свои скрипты и вживлять их в прошивку, создавать собственные G-коды.
4. Прочее – подскажите в комментариях.
Возможно начинающим программистам, коим я и сам являюсь, будет полезна эта информация. Гуру в языке С думаю, не найдут здесь ничего нового.
Для начала хочу остановиться на файловой структуре исходника и поделиться с вами этим, если будет интерес у сообщества – продолжу описывать свой опыт исследования прошивки.
Итак, качаем zip-файл с исходным кодом. https://github.com/MarlinFirmware/Marlin Распаковываем, видим:Ныряем в папку Marlin, видим 3 папки и кучу файлов. Попытаюсь вкратце пояснить что в каком месте хранится и за что какой файл отвечает.
Сразу определимся что файлы с расширением хххххх.h –это заголовочные файлы, в них определяются переменные, функции, процедуры. Кода в них практически нет. Код содержится в файлах с расширением xxxxxx.cpp.
Поехали:
Marlin.ino - это скетч для среды Arduino IDE. Используется в том случае, если в качестве платформы для принтера используется AVR-платформа. В моем случае это Arduino Mega & RAMPS 1.4. В файле подтягиваются стандартные библиотеки и файл конфигурации.
Configuration.h – это и есть файл конфигурации, в нем вносятся изменения до начала компиляции кода. Подробно расписывать пока не буду, информации о содержимом достаточно в русскоязычном и импортном Инете.
boards.h – содержит список всех платформ и плат, на которые можно установить Marlin. Каждой плате присвоен свой идентификатор, который прописывается в конфигурационном файле перед компиляцией. В моем случае это:
# define BOARD_ RAMPS_14_ EFB 43 // RAMPS 1.4 ( Power outputs: Extruder, Fan, Bed)
pins_хххххх.h – файлы содержат назначение пинов для каждой платформы. Я использую RAMPS, поэтому мне интересен файл pins_RAMPS_14.h. Корректировать номера выводов будет полезно в том случае, если по каким-то причинам невозможно использовать стандартное назначение (первое что приходит на ум – спалили вывод, или решили подключать внешнее устройство на другой разъем).
Надо сказать, что компиляция исходного кода в прошивку производится с использованием условий #if ENABLED() - #endif. Это позволяет включать в нее только тот код, который нужен в конкретном случае. Например, если в конфигурационном файле мы определили переменную FILAMENT_RUNOUT_SENSOR, раскомментировав ее, то следующая конструкция включит в прошивку определение 4 пина как вывода для присоединения датчика нити, если мы не используем датчик – то нет.
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define FILRUNOUT_PIN 4
#endif
language_хххх.h – здесь содержатся фразы на различных языках для вывода на экран и в USB порт для отладки. Здесь можно пошалить от души, меняя фразы на свои. Кириллица есть в файле - language_ru.h.
watchdog.h, watchdog.cpp – файлы отвечают за фичу под названием «Сторожевой пес». Фича полезна тем, что позволяет контролировать выполнение основной программы, в случае ее зависания уводит контроллер в рестарт. Работает предельно просто – запускается отдельный аппаратный таймер, в нашем конкретном случае – на 4 сек. В основной программе периодически вызывается команда обнуления этого таймера. Если за 4 сек. его никто не обнулит – он понимает что «что-то пошло не так» и рестартует контроллер.
blinkm.cpp, blinkm.h – содержит библиотеку для управления трех-цветным светодиодом по I2C протоколу. (куда его цеплять и зачем он нужен пока остается загадкой).
buzzer.cpp, buzzer.h – управляет пищалкой. Есть два режима работы – на пищалку подается последовательность импульсов с определенной частотой (пьезоизлучатель) или просто включитьвыключить (паровозный гудок :D )
cardreader.cpp, cardreader.h – комментарии излишни, - код для работы с флеш-картой. Управление SD картой организовано на уровне G-кода секции «М». Сюда же относятся все файлы вида Sdxxxxxxx.h и Sdxxxxxxxx.cpp.
configuration_store.cpp, configuration_store.h – код для чтениязаписи данных в энергонезависимую память. Удобство прошивки заключается в том, что параметры, выставленные при настройке и калибровке сразу записываются в EEPROM, и их не надо каждый раз выставлять заново при включении принтера.
servo.cpp, servo.h – используются для управления сервомоторами при, например, автокалибровке стола. Я их использовать пока не планирую.
MarlinSerial.cpp, MarlinSerial.h – библиотека для работы с USB.
ultralcd.cpp, ultralcd.h – работа с экранами.
stepper.cpp, stepper.h – для управления движками (как работают ШД - буду разбираться более подробно и тщательно позже, и если кому интересно отпишусь)
temperature.cpp, temperature.h – рулят температурой хот-ендов и стола. Тоже ничего примечательного, за исключением того, что в прошивке предусмотрена проверка работоспособности термисторов. Для этого в конфигурационном файле задаются параметры минимальной температуры например - HEATER_0_MINTEMP, и если температура ниже, то система думает, что термистор неисправен и не включает нагрев. Поэтому никогда не ставьте ноль в этих переменных.
Не знаю почему, но процедура обработки датчика толщины прутка тоже попала в файл temperature.cpp.
thermistortables.h - Здесь собраны калибровочные таблицы для каждого термистора, известного прошивке. Сам тип мы выбираем в конфигурационном файле. Но если вы решили использовать «экзотический» термистор, которого нет в списке, а у вас для него есть таблица значений, то смело меняйте любую известную на свою и выбирайте в конфигурации соответствующий термистор.
Ну и самые интересные файлы:
Marlin_main.cpp, Marlin_main.h – это основной заголовок и основной код программы. В подпрограмме void setup() собраны подпрограммы инициализации основных устройств и назначение переменных. В void loop() – основная подпрограмма. Здесь же собраны подпрограмма чтения G-кодов и все подпрограммы обработки этих кодов.
Вот так при кодах G0 и G1 вызывается подпрограмма gcode_ G0_ G1();
// Handle a known G, M, or T
switch (command_code) {
case 'G': switch (codenum) {
// G0, G1
case 0:
case 1:
gcode_G0_G1();
break;
Как раз здесь можно создать свой G-код. К примеру, G777. Добавляем:
case 777:
gcode_G777();
break;
и выше, рядом с другими обработчиками, добавляем подпрограмму его обработки:
inline void gcode_ G777 () {
ваш код
}
У меня пока все. Может по косточкам пока не удалось разобрать, но на куски уже порезали… :D
Если у кого есть более глубокие наработки по добавлению фич в прошивку – буду рад увидеть в комментах.
Еще больше интересных статей
Изготовление деталей для 3D принтеров из металла
Подпишитесь на автора
Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.
Отписаться от уведомлений вы всегда сможете в профиле автора.
В конструкции 3D принтера очень удобно использовать детали из листовой...
3RF модификации Sprite Extruder
Подпишитесь на автора
Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.
Отписаться от уведомлений вы всегда сможете в профиле автора.
Ссылка для 3D-мо...
Настраиваем прошивку Marlin и заливаем её в 3D принтер
Подпишитесь на автора
Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.
Отписаться от уведомлений вы всегда сможете в профиле автора.
Комментарии и вопросы
Вы его сами разбирали хоть раз...
Где я указывал? Цитату покажит...
А нам для чего указывать что д...
Здравствуйте, столкнулся с про...
Здравствуйте, столкнул с пробл...
Здравствуйте, столкнул с пробл...
Сопло 0,8. Прошивка Марлин Rob...