Добавление RGB Светодиодную ленту к Marlin

Подписаться на 3Dtoday
VDREBEZGUN
Идет загрузка
Загрузка
11.01.19
3066
14
печатает на Ultimaker 2
Техничка
14
PREVIEW
Добрый день Уважаемые читатели!

Я хотел бы рассказать о некоторых своих разработках относящихся к 3D принтерам. Начну с добавления и управления RGB Светодиодной подсветки. Работа была проделана на прошивке Marlin, на плате Arduino Mega 2560,сниппет кода ниже.

Очень уж привлекала подсветка на Ultimeiker 2, подумал а почему бы не сделать её цветной и управляемой. По факту всё просто, нужно взять RGB светодиодную ленту, рассчитать необходимую длину ленты, исходя из вариантов 30 с.д. на метр или 60 с.д. на метр можно высчитать необходимый ток для управляемого драйвера. Одна LED-линия сегмента потребляет приблизительно 20мА при питании 12В. Т.о. если зажечь белый цвет (т.е. красный 100%, зеленый 100% и синий 100%), то энергопотребление секции составит около 60мА. Теперь, можно легко посчитать потребление тока всей ленты. Итак, если длина ленты составляет 1 метр. В ленте 10 секций (по 10 см каждая). Потребление ленты при белом цвете составит 60мА*10=600мА или 0.6А.

Рассмотрим пример подключения светодиодной ленты к контроллеру Arduino. Для подключения, можно использовать недорогие и популярные мосфеты STP16NF06. Можно также использовать и обычные биполярные транзисторы, к примеру TIP120. Но по сравнению с мосфетом, у него больше потери напряжения, поэтому все же рекомендуется использовать первые.
На схеме ниже показано подключение RGB светодиодной ленты при использовании N-канальных мосфетах. Затвор мосфета подключается к pin1 контроллера, сток к pin2 и исток к pin3.
667cb80f79620b92b00c1e326f725fb6.png
Ниже, показана схема подключения при использовании обычных биполярных транзисторов (например TIP120). База транзистора подключается к pin1 контроллера, коллектор к pin2 и эмиттер к pin3. Между базой и выводом контроллера необходимо поставить резистор сопротивлением 100-220 Ом.
33a9d4a83184cdcf19fda5a8ae623458.png
В роли драйвера я использовал MOSFET STP16NF06 с большим запасом по току в корпусе DIP 220, далее уже дёргать мосфетом с помощью прерываний контроллера( аналог управление шаговыми моторами), открывать или закрывать затвор для подачи тока. Находим свободные ШИМ порты, я выбрал D4,D5,D6, на следующей схеме приведено подключение к RAMPS 1.4 и за одно подключение индукционного NPN датчика для калибровки.
b56737b68b218c92b7af508d107cc91b.GIF
И за одно сделал небольшую разводку макетной платы.
f56698d5914dac442fe5326e157b6640.GIF
В итоге немного манипуляций с кодом и получаем что RGB подсветка является индикатором нагрева рабочего стола и/или экструдера. Светодиоды переходят в режим «пульсации» с плавным изменением интенсивности свечения красного цвета. Чем выше текущая температура стола и/или экструдера, тем быстрее и ярче пульсация. Настройка осуществляется как через панель управления принтера, так и через передачу специального G-coda с ПК. Реализована функция с помощью прерываний Широтно Импульсной Модуляции, настройки моментально сохраняются в энергонезависимую память(EPROM), поэтому не придётся каждый раз настраивать яркость и цвет при новом включении. Установлена светодиодная RGB лента, 60 светодиодов на метр. Функцию можно полностью отключить при желании.
Управление через панель управления 3D принтера. Для перехода в режим управления «Светодиодной подсветкой», необходимо: Перейти в раздел «Светодиоды», далее необходимо выбрать режим из «Режим печати», «Режим ожидания»:
-режим печати — режим для настройки подсветки во время печати, он активируется после прогрева нагреваемой платформы и экструдера, активен до окончания печати, изменять настройки можно как в Режиме ожидания так и в режиме печати. После перехода в раздел «Режим печати», появляется 3 раздела для настройки каждого цвета отдельно и формировании цветовой матрицы, управляется он в процентном соотношении от 0(минимум), до 100(максимум);
-режим ожидания — режим для настройки подсветки во время неактивной печати, он активируется после включения принтера, активен до его выключения, изменять настройки можно как в «Режиме ожидания» так и в «Режиме печати». После перехода в раздел «Режим ожидания», появляется 3 раздела для настройки каждого цвета отдельно и формировании цветовой матрицы, управляется он в процентном соотношении от 0(минимум), до 100(максимум);
-чтобы отключить или включить светодиодную подсветку, необходимо зайти в раздел «Светодиоды» далее выбрать пункт «Вкл/выкл светодиодов»;
чтобы сбросить настройку светодиодов до заводских параметров( по 20% каждого цвета), необходим зайти в раздел «Светодиоды», далее выбрать пункт «Сбросить светодиоды».
Управление через G -cod:
M580 –Команда управления светодиодами. Свечение светодиодов в режиме нагрева зависит от температуры стола и/или экструдера. Настройка свечения светодиодов в других режимах производится командой M580 [P/W] R000 G000 B000, где W – режим ожидания, P – режим печати. Значения R, G, B должны быть целыми числами и выражаются процентами. Например, чтобы включить в режиме печати 100% красного цвета, 50% зеленого и 0% синего, необходимо ввести команду “M580 P R100 G50 B0”.
Сниппет из файла ultralcd . cpp . Задача этого кода – обработка режима светодиодов в зависмости от текущего режима работы принтера (“нагрев”, “печать”, “ожидание”), а также плавное изменение интенсивности свечения светодиодов в режиме “нагрев”.

#ifdef LED_ENABLE

void change_LED_status () { //изменение статуса светодиодов

if (led_timer_set && mytimer_should_turnoff) {MsTimer2::stop (); led_timer_set = false;}

if (LED_turnoff_flag)
{
analogWrite(REDPIN, 0);
analogWrite(GREENPIN, 0);
analogWrite(BLUEPIN, 0);
return ;
}

if (LED_status == HEATING)
{
if (!led_timer_set) { //обработка таймера на плавное изменение интенсивности свечения
mytimer_should_turnoff = false;
led_timer_set = true;
MsTimer2::set (10, svetilo);
MsTimer2::start ();
}
return ;
}
/* analogWrite(REDPIN, thermalManager.current_temperature [0]);
analogWrite(GREENPIN, 0);
analogWrite(BLUEPIN, 0);
}*/

if (LED_tuning_flag) //непосредственное включение светодиодов, управление PWM
{
analogWrite(REDPIN, (int) (LED_mode [tuned_LED_status] [RED] * 2.55));
analogWrite(GREENPIN, (int) (LED_mode [tuned_LED_status] [GREEN] * 2.55));
analogWrite(BLUEPIN, (int) (LED_mode [tuned_LED_status] [BLUE] * 2.55));
}
else {
if (led_timer_set && mytimer_should_turnoff) {MsTimer2::stop (); led_timer_set = false;}
analogWrite(REDPIN, (int) (LED_mode [LED_status] [RED] * 2.55));
analogWrite(GREENPIN, (int) (LED_mode [LED_status] [GREEN] * 2.55));
analogWrite(BLUEPIN, (int) (LED_mode [LED_status] [BLUE] * 2.55));
}
}

void reset_LED_tuning_flag () { //изменение режима светодиодов при переключении меню
LED_tuning_flag = false;
change_LED_status ();
}

void set_LED_to_default () { // сброс настроек светодиодов

for (int i = 0; i<=2; i++)
{
for (int ii = 0; ii<=2; ii++)
{
LED_mode [i] [ii] = 20;
}
}

LED_status = WAITING;

#if ENABLED (EEPROM_SETTINGS)
save_LED_eeprom (); //сохранение настроек светодиодов на EEPROM
#endif
}

void feedrate_from_buffer () {
feedrate_percentage_buffer = speedIndicator;
}

int retrieveColor (const char * firstLetter) { //управляет режимами свечения светодиодов

if (firstLetter == "К") return RED;
if (firstLetter == "З") return GREEN;
if (firstLetter == "С") return BLUE;

}

bool isHeatingFlag (void)
{
return heating_flag;
}

void svetilo () { //обеспечивает плавное изменение интенсивности свечения светодиодов //в режиме “нагрев”

my_time = millis ();
float interval_led_ms;
float step_led = 3;
unsigned int low_limit = 11;
unsigned int top_limit = 40;
float interval_step;
float interval_percent;
int curr_bed = thermalManager.current_temperature_bed;
int targ_bed = thermalManager.target_temperature_bed;
int curr_ext = thermalManager.current_temperature [0];
int targ_ext = thermalManager.target_temperature [0];
unsigned int max_led;
bool led_skip = false;

if ((curr_bed < targ_bed) && (curr_ext < targ_ext))
//контроль целевой и текущей температуры нагревательных
//элементов для определения последовательности работы алгоритма по выбору //интенсивности свечения
{
led_skip = true;
float bed_step = targ_bed / 100.0;
float bed_percent = curr_bed / bed_step;
float ext_step = targ_ext / 100.0;
float ext_percent = curr_ext / ext_step;
float common_percent = (ext_percent + bed_percent) / 2;
if (common_percent > 95) {common_percent = 95.0;}
interval_step = (top_limit - low_limit) / 100.0;
interval_percent = 100.0 - common_percent;
interval_led_ms = (interval_step * interval_percent) + low_limit;
max_led = common_percent * 2.5;
}

if (!led_skip) { //учет температуры стола в интенсивности свечения
if (bed_is_heating) {
float bed_step = targ_bed / 100.0;
float bed_percent = curr_bed / bed_step;
if (bed_percent > 95) {bed_percent = 95.0;}
interval_step = (top_limit - low_limit) / 100.0;
interval_percent = 100.0 - bed_percent;
interval_led_ms = (interval_step * interval_percent) + low_limit;
step_led = 2.1;
max_led = bed_percent * step_led;
}

else if (ext_is_heating) { //учет температуры экструдера в интенсивности свечения
float ext_step = targ_ext / 100.0;
float ext_percent = curr_ext / ext_step;
if (ext_percent > 95) {ext_percent = 95.0;}
interval_step = (top_limit - low_limit) / 100.0;
interval_percent = 100.0 - ext_percent;
interval_led_ms = (interval_step * interval_percent) + low_limit;
max_led = curr_ext;
} else return ;
}

if (my_time > buff_my_time) //обработка таймера
{
buff_my_time = my_time + interval_led_ms;
if (go_down == true) {
pwm_led -= step_led;
if (pwm_led <= 2)
{
go_down = false;
}
} else
if (go_down == false)
{
pwm_led += step_led;
if (pwm_led >= max_led)
{
go_down = true;
}

}
analogWrite(GREENPIN, 0);
analogWrite(BLUEPIN, 0);
analogWrite(REDPIN, pwm_led);
}
}

#endif
Сниппет из файла ultralcd . cpp . Задача этого кода – отрисовка меню для настройки светодиодов.

#if ENABLED (LED_ENABLE)
void LED_control_menu () {
START_MENU ();
MENU_ITEM (back, MSG_MAIN, lcd_status_screen);
/* MENU_ITEM (submenu, MSG_LED_HEATING, LED_heating_mode );*/
MENU_ITEM (submenu, MSG_LED_PRINTING, LED_printing_mode );
MENU_ITEM (submenu, MSG_LED_WAITING, LED_waiting_mode );
MENU_ITEM (function, MSG_LED_TURNOFF, LED_turnoff );
if (!planner.movesplanned() && !IS_SD_PRINTING) {
MENU_ITEM (function, MSG_LED_RESET, set_LED_to_default);
}
END_MENU ();

}

void LED_turnoff () {
if (LED_turnoff_flag)LED_turnoff_flag = false; else LED_turnoff_flag = true;
}

/* void LED_heating_mode () {
LED_setting_flag = true; //нужен, чтобы менять интенсивность свечения в реальном времени. Устанавливается в функции LED_**_mode, обращение к нему происходит menu_edit_type, сброс там же по нажатию на энкодер.
LED_tuning_flag = true; //нужен, чтобы не сбился режим светодиодов при смене режима работы принтера во время настройки цветов. Устанавливается в функции LED_**_mode, обращение к нему происходит в change_LED_status, сбрасывается в reset_LED_tuning_flag ().
tuned_LED_status = HEATING;
change_LED_status ();
START_MENU ();
MENU_ITEM (back, MSG_MAIN, LED_control_menu);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_RED_PERCENT, &LED_mode [HEATING][LED_color = RED], 0, 100, change_LED_status);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_GREEN_PERCENT, &LED_mode [HEATING][LED_color = GREEN], 0, 100, change_LED_status);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_BLUE_PERCENT, &LED_mode [HEATING][LED_color = BLUE], 0, 100, change_LED_status);
END_MENU();
}*/

void LED_waiting_mode () {
LED_setting_flag = true;
LED_tuning_flag = true;
tuned_LED_status = WAITING;
change_LED_status ();
START_MENU ();
MENU_ITEM (back, MSG_MAIN, LED_control_menu);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_RED_PERCENT, &LED_mode [WAITING][RED], 0, 100, change_LED_status);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_GREEN_PERCENT, &LED_mode [WAITING][GREEN], 0, 100, change_LED_status);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_BLUE_PERCENT, &LED_mode [WAITING][BLUE], 0, 100, change_LED_status);
END_MENU();
}

void LED_printing_mode () {
tuned_LED_status = PRINTING;
LED_setting_flag = true;
LED_tuning_flag = true;
change_LED_status ();
START_MENU ();
MENU_ITEM (back, MSG_MAIN, LED_control_menu);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_RED_PERCENT, &LED_mode [PRINTING][RED], 0, 100, change_LED_status);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_GREEN_PERCENT, &LED_mode [PRINTING][GREEN], 0, 100, change_LED_status);
MENU_ITEM_EDIT_CALLBACK (int3, MSG_LED_BLUE_PERCENT, &LED_mode [PRINTING][BLUE], 0, 100, change_LED_status);
END_MENU();
}

#endif //!LED_ENABLE

Всем спасибо за внимание!
Патент программы для ЭВМ №2018611221

Подписаться на 3Dtoday
14
Комментарии к статье

Комментарии

11.01.19 в 21:44
1
Прикольно наверное, а где видео демо?
11.01.19 в 22:42
1
Есть старые тесты, в не очень хорошем качестве, я года 2 назад это делал, могу собрать после 14-го числа повторно
11.01.19 в 23:03
3
Заниженный ТАЗ радует глаз!
11.01.19 в 23:26
2
Некоторые принтеры Hercules New, как например - мой, от 2016-го года, были стандартно укомплектованы не только MEGA2560+RAMPSбургером, но и RGB-LED-лентой подсветки, скоммутированной на белый свет в режиме вкл/выкл.

Так что думаю всем Геркулесоводам - есть смысл воплотить рекомендации ТС этого поста.

Благодарю!
Долгожданная информация!

С Уважением,
Ski.

P.S. У меня к автору программы - только один вопрос:
в полной версии программы для Марлина - реализована ли ярко белая подсветка для "медитации первого слоя",
или это - опционально, по желанию ТС - и в будущих планах?
12.01.19 в 09:21
0
В посте представлена полная версия кода данной функции, что-за такая "медитации первого слоя"? Как она должна работать? Уже честно говоря больше года не работал над ней, сейчас вот опять появилась нужда. А для Hercules по сути можно оставить эту же СД ленту и подключить только 1 пин, как к красному цвету, и она будет пульсировать при нагреве и ей можно будет управлять в момент печати, главное исходники прошивки найти и добавить 1 драйвер в схему и пару проводков.
12.01.19 в 09:56
1
Ws2812b и не надо рисовать никаких плат. Поддержка в марлин есть
12.01.19 в 10:02
0
Недавно сделали они поддержку, на момент когда реализовывалась эта функция Marlin не поддерживал RGB, честно не смотрел ещё как они реализовали. Ws2812b интересно, не видел ещё такого чуда, дороговат сегмент всё равно, а если тебе ставить 10-20? От одного толку то?
12.01.19 в 11:28
0
Ws2812b
А где это покупают?
12.01.19 в 11:29
1
Я у китайцев на aliexpress покупал
12.01.19 в 11:39
0
дороговат сегмент всё равно
я б не сказал
этого добра навалом, с разной плотностью светодиодов
но информации по реализации в принтере не нашел, искатель видать из меня никакой :)
12.01.19 в 21:42
1
Весь ваш код можно оформить в виде диффа на гитхабе, и сделать статью более приятной
12.01.19 в 21:52
1
Спасибо, да нужно много всего туда выложить, руки не доходят, да и оформлять статьи не особо хорошо получается, будем работать над этим.
15.01.19 в 23:33
0
Интересная задумка. Не сложная реализация. Немного красоты в суровую угловатость 3D принтера!
Автору спасибо за идею и подробное описание.
Может быть руки дойдут и реализую.

Для написания комментариев, пожалуйста, авторизуйтесь.

Читайте в блогах

Стальной "кубик". Tough-steel, или вот что бывает, когда недоступен в заказ ZAV mini.

Принтер А6 и минимоделизм. Первый пост в 2019 году.

Собор святого Александра Невского

Почти все настройки, необходимые для нормальной печати Cura 3.6. Часть 3

Розыгрыш Resin Tank для участников Formlabs Club от компании iGo3D Russia!

Истории участников 3Dtoday Fest: Кирилл Григорьев