Контроллер паяльного фена-2 (по мотивам OlegK)
- Войдите на сайт для отправки комментариев
Втр, 09/10/2018 - 14:29
Вдохновившись проектом ОлегК
(http://arduino.ru/forum/proekty/kontroller-payalnogo-fena)
решил сделать себе паяльный фен.
Заказал фен на али за 700руб. Пока посылка шла, определился со схемой устройства.
Основные принципы исходя из которых делал:
- Элементная база – из запасов, покупать только в крайнем случае. (запасы имеются хорошие J)
- Программу пишу сам, соответственно устройство делает все как я хочу. (с программированием проблем нет)
- Между крутым (красивым модным) и практичным выбираю практичность. (сенсорное управление, графические дисплеи и т.д. всем наигрался, применить не проблема, но только когда это оправдано).
Схема
Измерение температуры.
Выполнил по схеме OlegK. Понравилось установка начального смещения на термопаре при комнатной температуре. Я применил ОУ какой был под руками и решил подать на него такое питающее напряжение при котором при перегрузке по входу на выходе ОУ получается 4.6-4.8 В. Соответственно диапазон напряжений при измерении получается в интервале 0,2-4,4В. Подобрал стабилитрон КС170. Кстати узнал, что он симметричный. Настройка аналогично как у OlegK.
Питание.
Подобрал трансформатор чтобы после диодного моста и конденсатора при включении вентилятора фена получилось 23,5В (на холостом ходу 26,5В). Поэтому 24В не стабилизированные.
Управление нагревателем.
Сперва начал собирать детали как у OlegK. Но тут подобрал пару плоских ТВ на разборку. Выломал с них высоковольтные диодные мосты, полевики, конденсаторы. И решил - а почему не попробовать подавать на нагреватель постоянное напряжение 300В и регулировать его ШИМом? Не получиться – всегда под руками комплект с тиристором и детектором нуля.
Вылезла проблема: если ставить после выпрямителя конденсатор большой емкости надо ограничивать бросок тока при зарядке конденсатора при включении. Если маленький кондер – напряжение на нагрузке не постоянное, а пульсирующее. Решил не городить схему с ограничением зарядного тока, а поставить кондер не большой емкости. Поставил на 68мкФ. Подключил лампу накаливания на 150Вт. Согрел полевик. Совсем забыл что при начальном включении спираль лампы накаливания холодная и ток гораздо больше рабочего. Подключил лампу без полевика, напрямую. Пульсации порядка 40В. Прикинул что не критично и продолжил эксперименты. Дальше подводных камней не было. ШИМ ограничил максимум 40% . Собрал макет, запустил. Транзистор греется прилично, радиатор для него взял так же с раскуроченного ТВ. Диодный мост сразу был на радиаторе, с ним и применил. Но он почти не греется.
Взял железный корпус от сгоревшего маршрутизатора, в него все запихал.
Платы я не травил – собрал на макетках.
Почитал про ПИД регулирование. Поэкспериментировал с коэффициентами. Пропорциональный и Интегральный определил опытным путем, Дифференциальный эффекта не дал.
Интервал регулировки ставил 100 и 50 мСек – разницы нет.
Вентилятор регулирую от 50 до 100% ШИМ.
Вне зависимости от скорости вентилятора температура на ТП поддерживается с точностью 1-3 отсчета АЦП. Переодически отклонение уплывает до 7-10. При одной и той же температуре на ТП и при разной скорости вентилятора (50 и 100%) разница в температуре воздуха на выходе из фена градусов в 10-15. Причем температура выше при максимальной скорости вентилятора. Получается при малой скорости вентилятора воздух остывает пока дойдет до выхода. Сейчас ввожу поправочный коэффициент в зависимости от скорости вентилятора.
Помучился с семисигментным индикатором. При включении рэле, индикатор от помех полностью перестает нормально работать – тупо светятся все сегменты. Поставил металлический экран между силовой и слаботочной частью, Понатыкал кондеров, даже индуктивности ставил. После танцев с бубнами выяснил что индикатор зависает при включении рэле с одновременной подачей напряжения на нагреватель. Получается рэле не успевало окончательно замкнуть контакты, а через него уже пытался идти ток на нагреватель – получался разрядник. Сделал паузу в 2 сек между включением рэле и подачей ШИМа на нагреватель – помогло.
Функции которые сделал:
- Время работы 10 мин, за 1 мин до окончания каждые 15 сек звуковой сигнал. Если нажать кнопку старт или изменить температуру или скорость вентилятора – отсчет начинается с начала.
- Продувка после окончания работы до охлаждения до 50 грС. И потом контрольная додувка 30 сек. Если дуем 10 мин и не остыл – сообщение об ошибке, зумер и дуть не перестаем.
- контролируем обрыв термопары и превышение максимально допустимой температуры.
- во время работы показываем заданную температуру и фактическую на термопаре (с учетом поправки на скорость вентилятора.)
Доделываю:
- звуковой сигнал
- коррекцию температруры в зависимости от скорости вентилятора.
Геркон использовать не стал – не хватило контактов в разъеме.
Программа
/* Фена паяльный температура от 40 до 400 грС пищалка за 1 мин до отключения */ #include <LedControl.h> // LED 7-сегментный 8 сим // ПОРТЫ ВВ ======================================================= // 2,3,4 - LED #define PIN_RELE 2 #define PIN_KNOPKA_RABOTA 6 #define PIN_KNOPKA_STOP 7 #define PIN_SIGNAL 8 #define PIN_VKL_REG_NAGR 9 #define PIN_VKL_REG_VENT 10 #define PIN_ACP_TC A0 #define PIN_ZAD_VENT A1 #define PIN_ZAD_TEMP A2 // константы ===================================== #define VENT_PROC_MIN 50 // задание мощности вентилятра резистором #define VENT_PROC_MAX 100 #define VENT_ACP_MIN 10 #define VENT_ACP_MAX 1010 #define TEMP_ZAD_MIN 40 // задание температуры фена резистором #define TEMP_ZAD_MAX 400 #define TEMP_ACP_ZAD_MIN 10 #define TEMP_ACP_ZAD_MAX 1010 #define KOEF_ACP_TO_GR 1.72 // 2.14 коэфф пересчета значений АЦП ТП в градусы //временные интервалы ======================================= #define TIME_REG_TEMP 50ul // (мс) период контроля темп и регулировки #define TIME_POKAZ_INFO 500 // (мс) интервал отображения инфо #define TIME_RABOTA_AUTO_OFF 10 //10 (мин) работа до автоматической остановки (за 1 мин до выкл начинает пищать звук) #define TIME_PRODUV_MAX 10 // (мин) мax время продувки после окончания прогрева (при превышении этого времени - ошибка) #define TIME_PRODUV_DOPOL 30000ul // (мс) время дополнительной продувки после остывания меньше 50 грС int iRerimTek; // текущий режим работы #define REGIM_WORK 5 #define REGIM_ERR 9 #define REGIM_PRODUV 8 #define REGIM_OFF 1 #define REGIM_TEST 2 #define REGIM_OTLADKA 91 //коды текстовых сообщений сообщений на 7сегментном индикаторе #define KOD_TEXT_ERR 9 #define KOD_TEXT_TEST 2 #define KOD_TEXT_RAB 5 #define KOD_TEXT_OFF 1 #define KOD_TEXT_PRODUV 8 //коды ошибок 1ХХ - при включении 2ХХ при работе 3ХХ - при выключении #define KOD_ERR_ACP_TP_MAX 101 //- не работает ТП (обрыв) #define KOD_ERR_TEMP_MAX 201 //- превышена макс температура #define KOD_ERR_PROD_MAX_TIME 301 //- превышено макс время продувки #define KOD_ERR_STOP_PRI_GORIACH 302 //- остановка при горячем фене // время ============================== unsigned long ulTimeRegTemp; // период опроса температуры unsigned long ulTimePokazInfo; // контроль периода отображения инфо unsigned long ulTimeProduv; // время продувки unsigned long ulTimeProduvDopol; // время продувки дополнительной после остывания примерно 30 сек unsigned long ulTimeWork; // время до автоматического отключения (за 1 мин звуковой сигнал каждые 15 сек) // ПИД ===================================================== #define NAGR_SIG_REG_MAX 40 #define TP_MAX_TEMP 400 #define TP_ACP_ERR 900 #define PID_KOEF_P 1.1 //1.3 #define PID_KOEF_I 0.01 //0.01 #define PID_KOEF_D -0.05 //-0.05 float flPIDInSig,flPIDInSig_1,flPIDDiSig,flPIDPrSig; int iPIDRaz,iPIRaz_1; int iErrKod; // параметры регулировки =============================== int iACP_Tp; int iACPTP_ZAD,iACPTP_ZAD_OLD ; // задаваемое значение АЦП ТП int iVentVklProc,iVentVklProcOld; int iNagrVklProcent; // индикатор LedControl led8=LedControl(3,5,4,1); // 3,5,4 LedControl(dataPin, clkPin, csPin, numDevices=1); // звуковой сигнал #define ZVUK_1K_SIG 1 // один короткий #define ZVUK_1D_SIG 2 // один длинный #define ZVUK_3K_SIG 3 // три коротких #define ZVUK_1P_SIG 4 // постоянно гудит int iZvukVid,iZvukTek; // вид сигнала и этап переключения звука int iZvukTimeWork15; // счетчик подачи сигналов перед выключением по таймеру unsigned long ulZvukTime; // время с начала подачи сигнала // отладка int iPrintPort=0; //===================================================================================== void setup() { Serial.begin(9600); // настройка портов pinMode(PIN_VKL_REG_NAGR, OUTPUT); pinMode(PIN_VKL_REG_VENT, OUTPUT); pinMode(PIN_RELE, OUTPUT); pinMode(PIN_SIGNAL, OUTPUT); digitalWrite(PIN_VKL_REG_NAGR, LOW); digitalWrite(PIN_VKL_REG_VENT, LOW); digitalWrite(PIN_RELE, LOW); digitalWrite(PIN_SIGNAL, LOW); pinMode(PIN_KNOPKA_RABOTA, INPUT_PULLUP); pinMode(PIN_KNOPKA_STOP, INPUT_PULLUP); // инициализация индикатора led8.shutdown(0,false); led8.setIntensity(0,5); // яркость дисплея led8.clearDisplay(0); // очистить дисплей // переменные по времени ulTimePokazInfo=ulTimeRegTemp=0; // настройка ШИМ flPIDInSig=flPIDInSig_1=flPIDDiSig=flPIDPrSig=0.0; iACP_Tp=TempTpACPGet(); // iErrKod=0; iVentVklProcOld=iVentVklProc=0; iACPTP_ZAD=iACPTP_ZAD_OLD=0; // включение вентилятора на 2 сек // digitalWrite(PIN_RELE, HIGH); VentVklSkorost(100); // digitalWrite(PIN_RELE, HIGH); // HIGH //PrintText4L(KOD_TEXT_ERR,1); delay(50);PrintText4L(KOD_TEXT_TEST,1); delay(50);PrintText4L(KOD_TEXT_RAB,1); delay(50);PrintText4L(KOD_TEXT_OFF ,1); delay(50);PrintText4L(KOD_TEXT_PRODUV ,1); delay(50); digitalWrite(PIN_RELE, LOW); // HIGH VentVklSkorost(0); // при включении режим стоп RegimSet(REGIM_OFF); //???? RegimSet(REGIM_OTLADKA); // если при включении нагреватель горячий - режим продувка if(TempTpToGrad(TempTpACPGet())>70) RegimSet(REGIM_PRODUV); // короткий сигнал при включении ZvukStart(ZVUK_1K_SIG); } //=============================================================================== void loop() { int i,iD,iM,iMF,iMR,i2; long lTime2; while(true) { // нажатие на кнопок ПУСК/СТОП if(digitalRead(PIN_KNOPKA_RABOTA)==LOW) { if(iRerimTek!=REGIM_WORK) RegimSet(REGIM_WORK); else TimeSetWorkOff(); // обнуление счетчика для отключения работы по таймеру ZvukStart(ZVUK_1K_SIG); } if(digitalRead(PIN_KNOPKA_STOP)==LOW&&(iRerimTek!=REGIM_PRODUV&&iRerimTek!=REGIM_OFF)) { RegimSet(REGIM_PRODUV); ZvukStart(ZVUK_1K_SIG); } // контроль неисправности ТП // неисправность ТП -идем на продувка по таймеру if(TempTpACPGet()>TP_ACP_ERR) {iErrKod=KOD_ERR_ACP_TP_MAX;RegimSet(REGIM_ERR);} //первышение максимальной температуры if(TempTpGradGet()>=TP_MAX_TEMP+20) {iErrKod=KOD_ERR_TEMP_MAX;RegimSet(REGIM_ERR);} // режимы работы switch(iRerimTek) { // ВЫКЛ ===================================================== case REGIM_OFF: // digitalWrite(PIN_RELE, LOW); NagrevSetMosh(0); VentVklSkorost(0); break; // ПРОДУВКА ===================================================== case REGIM_PRODUV: // продувка перед выключением digitalWrite(PIN_RELE, LOW); NagrevSetMosh(0); VentVklSkorost(100); i=TempTpToGrad(TempTpACPGet()); if(i<50) { if(ulTimeProduvDopol==0) ulTimeProduvDopol=millis(); // засекаем время доп продувки else { if(millis()-ulTimeProduvDopol>TIME_PRODUV_DOPOL) RegimSet(REGIM_OFF); // переход в режим OFF } } else { if(millis()-ulTimeProduv>60000ul*TIME_PRODUV_MAX) // дуем не более 10 мин { iErrKod=KOD_ERR_PROD_MAX_TIME; RegimSet(REGIM_ERR); } ulTimeProduvDopol=0; } break; // ОТЛАДККА ===================================================== case REGIM_OTLADKA: RegimSet(REGIM_OFF); break; // РАБОТА ===================================================== case REGIM_WORK: // работа if(millis()-ulTimeRegTemp>TIME_REG_TEMP&&millis()>ulTimeRegTemp) // регул темп { ulTimeRegTemp=millis(); // задание скорости вентилятора iVentVklProc=VentGetProc(); VentVklSkorost(iVentVklProc); if(iVentVklProc!=iVentVklProcOld) { iVentVklProcOld=iVentVklProc; TimeSetWorkOff(); // обнуление счетчика для отключения работы по таймеру } //if(iPrintPort!=0){ Serial.print(" iVentVklProc = "); Serial.print(iVentVklProc); } // измерение температуры i=TempTpACPGet(); // заданая темп i2=TempZadGet(); iACPTP_ZAD=TempZadFromGrToAcp(i2); if(iACPTP_ZAD!=iACPTP_ZAD_OLD) { iACPTP_ZAD_OLD=iACPTP_ZAD; TimeSetWorkOff(); // обнуление счетчика для отключения работы по таймеру } // корректировка заданного значения АЦП при изменении (уменьшении) силы потока воздуха i2=TempZadKorrVen(iACPTP_ZAD,iVentVklProc); //if(iPrintPort!=0){ Serial.print(" iVentVklProc = "); Serial.print(iVentVklProc); Serial.print(" iACPTP_ZAD = "); Serial.print(iACPTP_ZAD);Serial.print(" iACPTP_KORR = "); Serial.println(i2);} //if(iPrintPort!=0){ Serial.print(" TempZadGet = "); Serial.println(i2); } if(iACP_Tp-i<30&&iACP_Tp-i>-30) iACP_Tp=i; // проверка большого отклонение АЦП если большое отклонение - считываем еще раз else iACP_Tp=TempTpACPGet(); // iD=iACPTP_ZAD-iACP_Tp; // разница // расчет ПИД iMR=PIDRaschet(iD); if(iD<-20||iMR<0) iMF=0; else { if(iMR>NAGR_SIG_REG_MAX) iMF=NAGR_SIG_REG_MAX; else iMF=iMR; } NagrevSetMosh(iMF); //if(iPrintPort!=0&&1==1) //{ Serial.print(" iACPTP_ZAD = "); Serial.print(iACPTP_ZAD);Serial.print(" iACP_K = "); Serial.print(i2); Serial.print(" ACP = "); //Serial.print(i); Serial.print(" iD = "); Serial.print(iD); Serial.print(" iMF = "); Serial.print(iMF); //Serial.print(" iVent = "); Serial.print(iVentVklProc); Serial.println(" "); } } // проверка времени режима REGIM_WORK lTime2=ulTimeWork+60000ul*(TIME_RABOTA_AUTO_OFF)-millis(); // разница между когда закончить и текущим временем <0 - время вышло // звуковой сгнал за одну минуту до окончания if(iZvukTimeWork15==0&&lTime2<60000l) {iZvukTimeWork15=1;ZvukStart(ZVUK_1D_SIG); } // звуковой сгнал за 45 сек до окончания if(iZvukTimeWork15==1&&lTime2<45000l) { iZvukTimeWork15=2; ZvukStart(ZVUK_1D_SIG); } // звуковой сгнал за 30 сек до окончания if(iZvukTimeWork15==2&&lTime2<30000l) { iZvukTimeWork15=3; ZvukStart(ZVUK_1D_SIG); } // звуковой сгнал за 15 сек до окончания if(iZvukTimeWork15==3&&lTime2<15000l) { iZvukTimeWork15=4; ZvukStart(ZVUK_1D_SIG); } // останов по таймеру if(lTime2<0) { RegimSet(REGIM_PRODUV); } break; // ОШИБКА ===================================================== case REGIM_ERR: // ошибка показываем код, продуваем по таймеру и ТП NagrevSetMosh(0); VentVklSkorost(100); ZvukStart(ZVUK_1D_SIG); break; // TEST ===================================================== case REGIM_TEST: // проверяем состояние устройства ; break; } // отображение информации ============================= if(millis()-ulTimePokazInfo>TIME_POKAZ_INFO) { ulTimePokazInfo=millis(); // инициализация индикатора led8.shutdown(0,true); delay(5); led8.shutdown(0,false); led8.clearDisplay(0); // очистить дисплей switch(iRerimTek) { case REGIM_OFF: // выключено PrintText4L(KOD_TEXT_OFF ,1); break; case REGIM_PRODUV: // продувка перед выключением PrintText4L(KOD_TEXT_PRODUV ,1); // текущая темп i=TempTpToGrad(TempTpACPGet()); LED8Print4Poz(i,1,0,0); // число, показ нулей, позиц с права, обнуление всего индикатора break; case REGIM_WORK: // работа // надпись в левой части // темп факт i2=TempZadGet(); LED8Print4Poz(i2,1,4,0); // надпсь в правой части // текущая темп i=TempTpToGrad(TempTpACPGet()); LED8Print4Poz(i,1,0,0); // число, показ нулей, позиц с права, обнуление всего индикатора break; case REGIM_ERR: // ошибка показываем код, продуваем по таймеру и ТП PrintText4L(KOD_TEXT_ERR,1); // надпсь в правой части LED8Print4Poz(iErrKod,1,0,0); // число, показ нулей, позиц с права, обнуление всего индикатора break; } // i=RegimTekGet(); PrintText4L(KOD_TEXT_RAB,1); // if(iTekRegim==2) PrintText(KOD_TEXT_RAB,1); // LED8Print4Poz(i,1,4,0); // текущий режим работы в левой части // LED8Print4Poz(i,1,0,0); // текущяя температура // текущая темп выше или ниже установленой в правом индикаторе // led8.setRow(0,4,B00011100); // ниже заданой // led8.setRow(0,4,B01100010); // выше заданой // led8.setRow(0,4,B00000001); // требуемая темп // if(iACP_T12<iACP_Zad-10) led8.setRow(0,3,B00011100); // ниже заданой на 15 гр // if(iACP_T12>iACP_Zad+10) led8.setRow(0,3,B01100010); // выше заданой на 15 гр //Serial.print("T ZAD= "); Serial.print(iTempZadGr); Serial.print(" T TEK= "); Serial.print(iTempTek); Serial.println(""); } // звуковые сигналы ============================= ZvukPley(); // конец постоянного цикла } } //===================================================== // кооректировка значения заданого АЦП температруры в зависимости от скорости вентилятора // при скорости вентилятора 50% поднимаем темпеартуру на нагревателе на 5 % int TempZadKorrVen(int iACP,int iVentPr) { int i2,iA=iACP; if(iVentPr!=100) { i2=iACP*(10-(iVentPr/10))/100; iA=iACP+i2; } return(iA); } //===================================================== // Сброс таймера авт отключения void TimeSetWorkOff(void) { ulTimeWork=millis(); // обнуление счетчика для отключения работы по таймеру iZvukTimeWork15=0; } //===================================================== // запуск подачи звук сигнала выключение постоянного сигнала iVid=0; void ZvukStart(int iVid) { iZvukVid=iVid; iZvukTek=0; ulZvukTime=millis(); noTone(PIN_SIGNAL); } //===================================================== // остнов подачи звук сигнала void ZvukStop(void) { iZvukVid=0; iZvukTek=0; } //===================================================== // получение текщуго значения сигнала int ZvukGetTekVid(void) { return(iZvukVid); } //===================================================== // переключение динамика звук сигнала void ZvukPley(void) { if(iZvukVid!=0) { switch(iZvukVid) { case ZVUK_1K_SIG: // один короткий tone(PIN_SIGNAL,1000,500); ZvukStop(); break; case ZVUK_1D_SIG: // один длинный tone(PIN_SIGNAL,1000,2000); ZvukStop(); break; case ZVUK_3K_SIG: // три коротких if(iZvukTek==0) { tone(PIN_SIGNAL,1000,500);iZvukTek=1;} if(iZvukTek==1&&ulZvukTime+1000<millis()) { tone(PIN_SIGNAL,1000,500);iZvukTek=2;} if(iZvukTek==2&&ulZvukTime+2000<millis()) { tone(PIN_SIGNAL,1000,500); ZvukStop(); } break; case ZVUK_1P_SIG: // постоянно гудит выключение ZvukStart(0); tone(PIN_SIGNAL,1000); ZvukStop(); break; } } } //===================================================== // получение текущего режима int RegimTekGet(void) { return(iRerimTek); } //===================================================== // переключение режима void RegimSet(int iRegim) { int i; switch(iRegim) { case REGIM_WORK: iRerimTek=iRegim; TimeSetWorkOff(); digitalWrite(PIN_RELE, HIGH); //включить рэле // переходные процессы перед подачей напряжения на нагреватель, чтоб индикатор не зависал ulTimeRegTemp=millis()+2000; // delay(100); if(iPrintPort!=0){ Serial.println("REGIM_WORK "); } break; case REGIM_OFF: iRerimTek=iRegim; digitalWrite(PIN_RELE, LOW); if(iPrintPort!=0){ Serial.println("REGIM_OFF "); } break; case REGIM_ERR: iRerimTek=iRegim; digitalWrite(PIN_RELE, LOW); if(iPrintPort!=0){ Serial.println("REGIM_ERR "); } break; case REGIM_PRODUV: iRerimTek=iRegim; ulTimeProduv=millis(); // засеккаем время начала продувки ulTimeProduvDopol=0; digitalWrite(PIN_RELE, LOW); if(iPrintPort!=0){ Serial.println("REGIM_PRODUV "); } break; case REGIM_TEST: iRerimTek=iRegim; if(iPrintPort!=0){ Serial.println("REGIM_TEST "); } break; case REGIM_OTLADKA: iRerimTek=iRegim; if(iPrintPort!=0){ Serial.println("REGIM_OTLADKA "); } break; } } //===================================================================================== // расчет ПИД сигнала управления по значению разности АЦП на термопаре // результат в интервале от 0 до 100% // P (t) = Koef_Pr * Raznost (t); // I (t) = I(t — 1) + Koef_In * Raznost (t); // D (t) = Koef_Di * { Raznost (t) — Raznost (t — 1)}; int PIDRaschet(int iRaz) { int iPIDSig; // значение ошибки iPIDRaz=iRaz; // пропор сотав flPIDPrSig=PID_KOEF_P*iPIDRaz; // интеграль состав flPIDInSig=flPIDInSig_1+PID_KOEF_I*iPIDRaz; if(flPIDInSig<15.0&&flPIDInSig>-15.0) flPIDInSig_1=flPIDInSig; // ограничение интегральной составляющей чтоб большая не накопилась при отключении нагревателя // дифф состав flPIDDiSig=PID_KOEF_D*(iPIDRaz-iPIRaz_1); // пред ошибка iPIRaz_1=iPIDRaz; // сумма управляющих сигналов iPIDSig=flPIDPrSig+flPIDInSig+flPIDDiSig; ///???? //int i; //i=flPIDPrSig; Serial.print("flPIDPrSig = "); Serial.print(i); //i=flPIDInSig; Serial.print(" flPIDInSig = "); Serial.print(i); //i=flPIDDiSig; Serial.print(" flPIDDiSig = "); Serial.println(i); // ограниение в интервал от 0 до 100 //????/ // if(iPIDSig<0) iPIDSig=0; // if(iPIDSig>100) iPIDSig=100; return(iPIDSig); } //===================================================== // получение значения температуры термопары в градусах int TempTpGradGet(void) { int i; i=TempTpToGrad(TempTpACPGet()); return(i); } //===================================================== // получение значения температуры термопары в градусах из АЦП int TempTpToGrad(int iAcp) { int i; float flTemp; // пересчет значения термопары в градусы flTemp=iAcp/KOEF_ACP_TO_GR; // 2.12 коэф пресчета i=flTemp; return(i); } //===================================================== // получение значения АЦП термопары int TempTpACPGet(void) { int i; // получение температуры i= analogRead(PIN_ACP_TC); //if(iPrintPort!=0){ Serial.print("TempTpACPGet = "); Serial.println(i); } return(i); } //===================================================== // пересчет заданой температуры в значяения АЦП ТП int TempZadFromGrToAcp(int iTempGr) { int i; float flAcp; // пересчет значения flAcp=iTempGr*KOEF_ACP_TO_GR; // 2.12 коэф пресчета i=flAcp+1; return(i); } //===================================================== // получение заданой температуры с округлением до 10 int TempZadGet(void) { int i,i2; float flPr1,flP,flA; // получение температуры i=ACPZadTemp(); if(i<TEMP_ACP_ZAD_MIN) return(TEMP_ZAD_MIN); if(i>TEMP_ACP_ZAD_MAX) return(TEMP_ZAD_MAX); flP=TEMP_ZAD_MAX-TEMP_ZAD_MIN; flA=TEMP_ACP_ZAD_MAX-TEMP_ACP_ZAD_MIN; flPr1=flA/flP; flA=i; flP=flA/flPr1; i=flP+TEMP_ZAD_MIN; i2=i/20; i=i2*20; //if(iPrintPort!=0){ Serial.print("TempZadGet = "); Serial.println(i); } return(i); } //===================================================== // получение значение АЦП с регулятора температуры int ACPZadTemp(void) { int i; // получение температуры i=(analogRead(PIN_ZAD_TEMP)+analogRead(PIN_ZAD_TEMP)+analogRead(PIN_ZAD_TEMP))/3; //if(iPrintPort!=0){ Serial.print("iTempM[0] = "); Serial.println(iTempM[0]); } return(i); } //===================================================== // получение процентов мощности с регулятора скорости вентилятора int VentGetProc(void) { int i,i2; float flPr1,flP,flA; // получение температуры i=ACPZadVent(); flP=VENT_PROC_MAX-VENT_PROC_MIN; flA=VENT_ACP_MAX-VENT_ACP_MIN; flPr1=flA/flP; flA=i; flP=flA/flPr1; i=flP+VENT_PROC_MIN; i2=i/10; i=i2*10; //if(iPrintPort!=0){ Serial.print("VentGetProc = "); Serial.println(i); } return(i); } //===================================================== // получение значение АЦП с регулятора скорости вентилятора int ACPZadVent(void) { int i; // получение температуры i=analogRead(PIN_ZAD_VENT); //if(iPrintPort!=0){ Serial.print("iTempM[0] = "); Serial.println(iTempM[0]); } return(i); } //===================================================== // задание мощности вент от 50 до 100% void VentVklSkorost(int iProcent) { int i; float flOb; if(iProcent<0||iProcent>100) return; if(iProcent<50) digitalWrite(PIN_VKL_REG_VENT, LOW); if(iProcent>=50&&iProcent<100) { flOb=2.55*iProcent; i=flOb; analogWrite(PIN_VKL_REG_VENT, i); //if(iPrintPort!=0){ Serial.print(" VentSetSkorost PWM = "); Serial.println(i); } } if(iProcent==100) digitalWrite(PIN_VKL_REG_VENT, HIGH); iVentVklProc=iProcent; //if(iPrintPort!=0){ Serial.print("VentSetSkorost = "); Serial.println(iProcent); } } //===================================================== // задание мощности нагревателя void NagrevSetMosh(int iProcent) { int i; float flOb; if(iProcent<0||iProcent>100) return; if(iProcent<1) digitalWrite(PIN_VKL_REG_NAGR, LOW); if(iProcent>0&&iProcent<100) { flOb=2.55*iProcent; i=flOb; analogWrite(PIN_VKL_REG_NAGR, i); } if(iProcent==100) digitalWrite(PIN_VKL_REG_NAGR, HIGH); iNagrVklProcent=iProcent; //if(iPrintPort!=0){ Serial.print("NagrevSetMosh = "); Serial.println(iProcent); } } //================================================================================= // отображение числа в 4-х разрядах с позиции iPozStart (0-7) // iPokazZero==0 - не показывать нули вообще, ==1 показывать только один 0, >показывать нули с переди // iClr!=0 - сброс всего индикатора void LED8Print4Poz(int iData,int iPokazZero,int iPozStart,int iClr) { int i,i2,i9; int iCif[4]={0,0,0,0}; if(iClr!=0) {// led81.shutdown(0,false); led8.clearDisplay(0); } i9=iData; if(i9>0) { i2=i9/10; iCif[0]=i9-i2*10; i9=i2; if(i9>0) { i2=i9/10; iCif[1]=i9-i2*10; i9=i2; if(i9>0) { i2=i9/10; iCif[2]=i9-i2*10; i9=i2; if(i9>0) { i2=i9/10; iCif[3]=i9-i2*10; } } } } i9=0; for(i=3;i>=0;i--) { if(i+iPozStart<8) { if(iCif[i]!=0||i==0&&iPokazZero==1) // показывать младший ноль { i9=1; led8.setDigit(0,iPozStart+i,iCif[i],false); } else { if(iPokazZero>1||i9==1) led8.setDigit(0,iPozStart+i,iCif[i],false); else led8.setRow(0,iPozStart+i,B00000000); } } } } //================================================================= // отображение на экране слева 4 поз сообщения по его номеру // iClear4!=0 отчищаем все 4 знакоместа, иначе только те в кторые печатем void PrintText4L(int iKodInfo,int iClear4) { switch(iKodInfo) { case KOD_TEXT_ERR: // надпись Err в левой части led8.setRow(0,7,0x00);led8.setRow(0,6,0x00);led8.setRow(0,5,0x00); if(iClear4) led8.setRow(0,4,0x00); led8.setRow(0,7,0x4F); led8.setRow(0,6,0x05); led8.setRow(0,5,0x05); break; case KOD_TEXT_TEST: // tESt led8.setRow(0,7,0x00); led8.setRow(0,6,0x00); led8.setRow(0,5,0x00); led8.setRow(0,4,0x00); led8.setRow(0,7,0x0F); led8.setRow(0,6,0x4F); led8.setRow(0,5,0x5B); led8.setRow(0,4,0x0F); break; case KOD_TEXT_RAB: // РАБ 67 77 5F (DF-"Б" с точкой) led8.setRow(0,7,0x00);led8.setRow(0,6,0x00);led8.setRow(0,5,0x00); if(iClear4) led8.setRow(0,4,0x00); led8.setRow(0,7,0x67); led8.setRow(0,6,0x77); led8.setRow(0,5,0xDF); break; case KOD_TEXT_OFF: // OFF 7E 47 47 led8.setRow(0,7,0x00);led8.setRow(0,6,0x00);led8.setRow(0,5,0x00); if(iClear4) led8.setRow(0,4,0x00); led8.setRow(0,7,0x7E); led8.setRow(0,6,0x47); led8.setRow(0,5,0x47); break; case KOD_TEXT_PRODUV: // 67 05 7E 3D led8.setRow(0,7,0x00);led8.setRow(0,6,0x00);led8.setRow(0,5,0x00); led8.setRow(0,4,0x00); led8.setRow(0,7,0x67); led8.setRow(0,6,0x05); led8.setRow(0,5,0x7E); led8.setRow(0,4,0x3D); break; } }Все заработало. Устройством доволен. Повыпаивал кучу полевиков . Пока не включил корректировку температуры в зависимости от мощности вентилятора, т.к. и от диаметра насадки есть зависимость. Будет желание - поэксперементирую.
Геркон можно добавить ?
Геркон можно добавить ?
А какой режим по геркону включать? Вентилятор на 50%, температуру понизить до 100-200 грС ?
Температуру понизить до 100 С , после остывания вентилятор 30%
Дисплей на TM1637 подойдет ?
Дисплей на TM1637 подойдет ?
Надо менять библиотеку и править функции вывода.
И обычно на 1637 4 знакоместа. У меня индикация заточена на 8 знакомест. Предпологается исползование двух 1637?
Температуру понизить до 100 С , после остывания вентилятор 30%
Понятно. Но меньше 50% я вентилятор не делал. Если меньше то в моем фене он почти не дует и как то совсем жалобно хрипит :-(
Таймер автоматического отключения (10 мин) продолжает тикать или включение/выключение геркона его обнуляет?
Просто мне геркон не нужен. И логику его использования я не продумывал. И раньше у меня фена не было.
Один дисплей 1637, таймер обнулять при выключении геркона.
Подключение геркона как будет время добавлю.
А переделывать индикацию на один 1637 пробуйте сами. Индикцию я делал в отдельных функциях там не сложно. :-)
Я не умею програмировать , так правельно
Да.
Ничего не получаетса не знаю что тут изминить
Ты на правильном пути
Замени код между коментариями "отображение информации" и "звуковые сигналы" на приведеный ниже
И удали из программы вызов функций и сам код функций
- PrintText4L
- LED8Print4Poz
// отображение информации ============================= if(millis()-ulTimePokazInfo>TIME_POKAZ_INFO) { ulTimePokazInfo=millis(); // инициализация индикатора disp.clearDisplay(); // очистить дисплей // текущая темп i=TempTpToGrad(TempTpACPGet()); disp.display(i); } // звуковые сигналы =============================