Ламинатор FGK-230

Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ответить
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

Во всяком случае, во всех 3D-принтерах сделано именно так.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15686
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Так в данном случае релейный вариант не особо от обычного регулятора на паре операционных усилителей по результатам отличаться будет...
Минимальная доза энергии в одну полуволну... Или "выкусывание" энного количества полуволн. Будет ли разница меду простым релейным с мостовой схемой для датчика (плюс усиление сигнала рассогласования) и таким решением... Т.е. есть ли смысл в усложнении?
:roll:
Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

Для меня это не усложнение, а просто десяток лишних строк кода.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

Собрал.
https://cloud.mail.ru/public/23WU/xmHzhCLv5
В работе.
https://cloud.mail.ru/public/sxE8/8bcUbNAuF
Подбирать оптимальную температуру для плат буду позже.
Реклама
Эиком - электронные компоненты и радиодетали
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

Кот:

Код: Выделить всё

//------------------------
//
//  Регулировка температуры ламинатора (или подобного прибора) в диапазоне 25-220°С
//  Massaraksh7 17.07.2026
//
//------------------------
#include <EEPROM.h>
#include <math.h>
#include <avr/pgmspace.h>

//---таблица кодов температуры от 0 до 220°С для термистора NTC 100k B3950
const int ntc[221] ={1009,1008,1007,1007,1006,1005,1004,1003,1002,1001,1000,999,997,996,995,994,992,991,989,988,986,984,983,981,
979,977,975,973,971,969,966,964,962,959,957,954,951,949,946,943,940,937,933,930,927,923,920,916,912,908,905,901,896,892,888,884,
879,875,870,865,860,855,850,845,840,835,830,824,819,813,807,802,796,790,784,778,772,766,759,753,747,740,734,727,721,714,707,701,
694,687,680,674,667,660,653,646,639,632,625,618,611,604,597,590,583,576,569,562,556,549,542,535,528,521,515,508,501,495,488,481,
475,468,462,456,449,443,437,430,424,418,412,406,400,395,389,383,377,372,366,361,355,350,345,340,335,329,324,319,315,310,305,300,
296,291,287,282,278,274,269,265,261,257,253,249,245,241,238,234,230,227,223,220,216,213,209,206,203,200,197,194,191,188,185,182,
179,176,174,171,168,166,163,161,158,156,153,151,149,146,144,142,140,138,136,134,132,130,128,126,124,122,120,119,117,115,113,112,
110,108,107,105,104};

int ttemp;          //---Целевое значение температуры
int seg7;           //---Счётчик сегментов
int rate;           //---Режим =0-работа, =1-программирование
int val_to_show;    //---Значение, которое показываетя на индикатореЮ в зависимости от режима
float lastval;      //---Последнее сглаженное значение температуры
int countr;         //---Счётчик
int btn1;           //---Счётчик кнопки prog 
int btn2;           //---Счётчик кнопки -
int btn3;           //---Счётчик кнопки + 
int load;           //---Управление нагрузкой

float kf_exp=0.9;        //---Коэффициент экспоненциального фильтра
double integral = 0.0;   //---Накопление интегральных данных
double prevError = 0.0;  //---Предыдущая разница
double prevTemp = 0.0;   //---Предыдущая температура
const int outMin = 0;    //---Ограничения
const int outMax = 255;  //---по выходу
//---Коэффициенты для ПИД-регулятора
float kf_p=10.0;          
float kf_i=0.028;  // 0.023 циклилось на 146-147-148,  0,033 - 151-152
float kf_d=305.0;

//---Индикация одной цифры
void drawDigit(int dig) {
PORTD &= 3;
PORTB &= 0xFC;
switch (dig)
   {
   case 0: PORTD |= 0x7C; PORTB |= 2; break;
   case 1: PORTD |= 4;    PORTB |= 2; break;
   case 2: PORTD |= 0x74; PORTB |= 1; break;    
   case 3: PORTD |= 0x54; PORTB |= 3; break;
   case 4: PORTD |= 0x0C; PORTB |= 3; break;
   case 5: PORTD |= 0x58; PORTB |= 3; break;
   case 6: PORTD |= 0x78; PORTB |= 3; break;
   case 7: PORTD |= 0x14; PORTB |= 2; break;
   case 8: PORTD |= 0x7C; PORTB |= 3; break;
   case 9: PORTD |= 0x5C; PORTB |= 3; break;
   case 10: break;
   }
if (rate |= 0) PORTD |= (1 << 7); 
}

//---Выбор номера разряда
void setNumber(int n) {
PORTB |= 0x1C;
switch (n) 
   {
   case 0: PORTB &= ~4;break;
   case 1: PORTB &= ~8;break;
   case 2: PORTB &= ~16;break;
   }
}

//---Показать температуру на индикаторе
void showValue(int seg){
int n;  
switch (seg)
   {
   case 0: n=val_to_show / 100; if (n==0) n=10; break;
   case 1: n=(val_to_show / 10) % 10; break;
   case 2: n=val_to_show % 10; break;
   }
drawDigit(n);   setNumber(seg);
}

//--Основной цикл 256 Гц
void setTimer0() {
cli();  
TCCR0A = (1 << WGM01);
TCCR0B = 0;
TCCR0B |= (1 << CS02) | (1 << CS00); // 16000000/1024=15625
OCR0A = 61;                          // 15625/61 ~ 256
TIMSK0 |= (1 << OCIE0A);
sei();
}

//---Читать целевую температуру из EEPROM
void readTTemp() {
int eeaddr=0;
ttemp = EEPROM.read(eeaddr); 
if (ttemp==255)
   {
   ttemp=100;
   writeTTemp(); 
   }
}

//---Записать целевую температуру в EEPROM
void writeTTemp() {
int eeaddr=0;
EEPROM.write(eeaddr,ttemp);
}

//
//---Бинарный поиск значения температуры в массиве кодов
//
float BinarySearch(int code) {
int amin,amax,amid,i;
float t;
amax = 220; amin = 0;
//---Бинарный поиск
while (amax>amin) 
   {
   amid = (amin+amax)/2;
   if (code==ntc[amid]) return(amid);
   if (code>ntc[amid]) amax=amid; else amin = amid+1;
   }
//---Точного значения не нашли, интерполяция
if (code>ntc[amid]) amid--;
if (amid<0) return(0);
if (ntc[amid]==ntc[amid+1]) return(amid);
t = amid+(code-ntc[amid])/(ntc[amid+1]-ntc[amid]);
return(t);
}

//---Читать код с NTC100k и применить экспоненциальное сглаживание
void ReadAndSmooth() {
  int code;
  float tval;
code = analogRead(A5); //
tval = BinarySearch(code);
prevTemp=lastval;
lastval = tval*kf_exp+lastval*(1-kf_exp);
}

//---ПИД-регулятор
int PID (void){
double error = ttemp - lastval;
//---Интегральная часть
integral += error;
const double integralMax = 5000.0;
if (integral > integralMax) integral = integralMax;
if (integral < -integralMax) integral = -integralMax;
//---Дифференциальная часть
double derivative = (error - prevError);
prevError = error;

double output = kf_p * error + kf_i * integral + kf_d * derivative;
//---Ограничение выхода
if (output > outMax) output = outMax;
else if (output < outMin) output = outMin;
return (int)output;
}

//---Установки
void setup() {
//-Порты  
DDRB=0x3F;PORTB=0x00;
DDRD=0xFC;PORTD=0x00;
DDRC=0x01;PORTC=0x1A;
//--Нач. значения
integral=0;
prevError=0;
prevTemp=0;
val_to_show = 0;
seg7=0;rate=0;countr=0;lastval=0;
btn1=0;btn2=0;btn3=0;load=0;
readTTemp();
val_to_show=777;
//---Запуск таймера
setTimer0();
}

//--256 Гц - основной цмкл
ISR(TIMER0_COMPA_vect) {
  byte inp;
//---показать одну из цифр
showValue(seg7);  
seg7++;if (seg7>=3)seg7=0;
//---Программирование целевой температуры
if (rate == 1)
   {
   val_to_show = ttemp;
   inp = PINC; if (!(inp & (1 << PC3))) btn2++; else btn2=0;
   inp = PINC; if (!(inp & (1 << PC4))) btn3++; else btn3=0;
   inp = PINC; if (!(inp & (1 << PC1))) btn1++; else btn1=0;
   if (btn1>=256) {btn1=0;writeTTemp();rate=0;return;}
   if (btn2>=25) {btn2=0;if (ttemp>=25)ttemp--;val_to_show = ttemp;}
   if (btn3>=25) {btn3=0;if (ttemp<=220)ttemp++;val_to_show = ttemp;}
   return;
   }
//---считывание кода 1 раз в секунду   
countr++;
if (countr==256)
   {
   countr=0; 
   ReadAndSmooth();
   val_to_show=lastval;
   if (rate==0) val_to_show = lastval;
//---ПИД-регулятор   
   load = PID();
   }
//---Вход в режим программирования целевой температуры
inp = PINC; if (!(inp & (1 << PC1))) btn1++; else btn1=0;
if (btn1>=256) {btn1=0;rate=1;}
//--- Реализация расчёта ПИД
if (countr==0){PORTB |= (1<<PB5);PORTC |= (1 << PC0);}
if (countr>=load){PORTB &= ~(1<<PB5); PORTC &= ~(1 << PC0);}
}

void loop() {
  while(1){};
}
Реклама
Друг Кота
Аватара пользователя
Сообщения: 44135
Зарегистрирован: Пн ноя 30, 2009 03:00:01
Откуда: Нерезиновая

Сообщение АлександрЛ »

На счёт скорости протяжки- про ЛУТ не скажу, а вот для фоторезиста -
https://static.chipdip.ru/lib/387/DOC018387106.pdf
СпойлерИзображение
фоторезист.PNG
(69.58 КБ) 85 скачиваний
Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

Два прохода, один раз медью вверх, другой раз медью вниз.
160°С
https://cloud.mail.ru/public/7QYx/BjrmN1y9X
180°С
https://cloud.mail.ru/public/jky5/tumHMFdts
200°С
https://cloud.mail.ru/public/AioA/WkDn9rLhg
210°С
https://cloud.mail.ru/public/Q1r7/b5MBaK7YH
Друг Кота
Аватара пользователя
Сообщения: 44135
Зарегистрирован: Пн ноя 30, 2009 03:00:01
Откуда: Нерезиновая

Сообщение АлександрЛ »

210 градусов- уже хорошо, ещё бы градусов 10 прибавить!
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

215°С, 4 прохода. По-моему, уже перебор местами.
https://cloud.mail.ru/public/qpSg/wfyvVTD2R
Друг Кота
Аватара пользователя
Сообщения: 44135
Зарегистрирован: Пн ноя 30, 2009 03:00:01
Откуда: Нерезиновая

Сообщение АлександрЛ »

Massaraksh7 писал(а): Сб июл 18, 2026 22:53:20 Два прохода, один раз медью вверх, другой раз медью вниз.
210°С
https://cloud.mail.ru/public/Q1r7/b5MBaK7YH
Massaraksh7 писал(а): Вс июл 19, 2026 01:14:35 215°С, 4 прохода. По-моему, уже перебор местами.
https://cloud.mail.ru/public/qpSg/wfyvVTD2R
Так, может, 4 прохода много?
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

АлександрЛ писал(а): Вс июл 19, 2026 01:22:45 Так, может, 4 прохода много?
Или 215°С много. Проверю.
Друг Кота
Аватара пользователя
Сообщения: 44135
Зарегистрирован: Пн ноя 30, 2009 03:00:01
Откуда: Нерезиновая

Сообщение АлександрЛ »

Ну, вообще- 5 градусов - непонятно, много или мало.
У меня, например, для прикатки фоторезиста- (по встроенному индикатору температуры) 95 градусов- мало, а 100 градусов- много. :dont_know:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

Ну вот, 210°С, 4 прохода, почти идеально.
https://cloud.mail.ru/public/14vr/nNFXZqGwm
Друг Кота
Аватара пользователя
Сообщения: 44135
Зарегистрирован: Пн ноя 30, 2009 03:00:01
Откуда: Нерезиновая

Сообщение АлександрЛ »

:beer: :beer: :beer: :))) :))) :)))
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

:)
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

BOB51 писал(а): Пт июл 17, 2026 19:35:00 Так в данном случае релейный вариант не особо от обычного регулятора на паре операционных усилителей по результатам отличаться будет...
Проверил, интереса ради, релейный вариант, как без гистерезиса, так и с ним.
BOB51 писал(а): Пт июл 17, 2026 19:35:00 Т.е. есть ли смысл в усложнении?
Есть. Температура плавает на ±3-5-7 °С (и чем больше инерционность объекта, тем выше), а это может повлиять на качество перевода рисунка.
В случае же ПИД температура стоит ровно, сколько нужно, если правильно подобрать коэффициенты. Правда, при прохождении платы температура падает (нагреватель отдаёт ей тепло), но нужно просто подождать, пока она восстановится (секунд 10-30, в зависимости от размера платы), и тогда пихать следующий проход.
Друг Кота
Аватара пользователя
Сообщения: 15686
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Собственно и требовалось учитывать как температуру, так и скорость прокатки и толщину (плюс свойства) материала для платки.
А это, в свою очередь, требует управления скоростью привода валов и, вероятно, бесконтактного датчика температуры поверхности платы (плюс коррекция на теплоотдачу в окружающую среду - исходная температура платки до валов ламинатора)...
Хорошая задачка для тренировки мозгов.
:tea:
На практике для мелкосерийного еще оправдано, для одной платки в месяц - уже под вопросом.
А для ленивых (типа меня) и дырчатые заготовки с "паутинкой" проволочками вполне достаточны...
:sleep:
Вот так из лени (да ЖАБЫ) и деградируем помаленьку, теряя интерес к самоделкам.
8)
Датчики у ламинатора удобно оборачивать кусочком пленки от нагревательного блока копириовалок типа кенона FC200 - обычно на сервисе порванных в избытке было... а далее ставим прижатым через ту пленку к резине вала, чтоб и скользил не "протираясь" и температуру точнее показывал (та пленка в термоблоке копировального аппарата напрямую между нагревателем и бумагой пробегает хорошей теплопередачей и износостойкостью обладает)... Но то так давно было... Сейчас может и бесконтактное чего попридумывали...
:dont_know:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

BOB51 писал(а): Пн июл 20, 2026 14:12:25 Вот так из лени (да ЖАБЫ) и деградируем помаленьку, теряя интерес к самоделкам.
Угу. У меня ещё с юношеского возраста с регулярностью примерно раз в 5-7 лет возникает обострение интереса к электронным поделкам, длится короткий период, а потом снова затухает... до следующего цикла.
Друг Кота
Аватара пользователя
Сообщения: 15686
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

:beer:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 194
Зарегистрирован: Ср июн 03, 2026 18:51:39
Откуда: Воронеж

Сообщение Massaraksh7 »

:beer:
Хотя, коты не пьют. :))
Ответить

Вернуться в «Arduino»