ИК паяльная станция на Arduino Mega 2560. Доработка скетча "ARS_v2_Lilium_JSN"

Тема в разделе "Глядите, что я сделал", создана пользователем Jalnin, 2 ноя 2012.

Статус темы:
Закрыта.
  1. SOLOway

    SOLOway Гуру

    Это я бестолковый :( Руки с головой не синхронизирую никак :) У @Sema из-за этого моего косяка, возможно, не получается настроить :(
    в 1.3.4. от 05/05/2019 было так:
    Код (C++):
    byte Pid1(double temp, byte ust, byte kP, byte kI, byte kd)
    {
      byte out = 0;
      static float ed = 0;
      float e, p;
      float d;
      e = (ust - temp); //ошибка регулирования
      p =  (kP * e); //П составляющая
      integra = (integra < i_min) ? i_min : (integra > i_max) ? i_max : integra + (kI * e) / 100; //И составляющая
      d = kd * (e - ed) * 10; //Д составляющая
      ed = e;
      out = (p + integra + d < 0) ? 0 : (p + integra + d > pwr_TOP) ? pwr_TOP : p + integra + d;
      return out;
    }

    byte Pid2(double temp, byte ust, byte kP, byte kI, byte kd)
    {
      byte out = 0;
      static float ed = 0;
      float e, p;
      float d;
      e = (ust - temp); //ошибка регулирования
      p =  (kP * e); //П составляющая
      integra2 = (integra2 < i_min) ? i_min : (integra2 > i_max) ? i_max : integra2 + (kI * e) / 100; //И составляющая
      d = kd * (e - ed) * 10; //Д составляющая
      ed = e;
      out = (p + integra2 + d < 0) ? 0 : (p + integra2 + d > pwr_BOTTOM) ? pwr_BOTTOM : p + integra2 + d;
      return out;
    }
    И не работала уставка НИ выше 255° из-за byte ust, вместо int ust. Затем я решил поправить немного, и заодно заменить функцию ПИД на ПИД по измерению, как в посте #3009 @Dmitrysh . И вот тут затупил основательно. В старших версиях есть мин. и макс. мощность для ВИ и НИ, да ещё и на каждом шаге задаётся. А в версиях 1.3.х этого нет.
    Так и не смог понять, как переписать код, предложенный @Dmitrysh
    Код (C++):
    out = (p1 + integra - d1 < profile.min_pwr_TOPStep[currentStep - 1]) ? profile.min_pwr_TOPStep[currentStep - 1] : (p1 + integra - d1 > profile.max_pwr_TOPStep[currentStep - 1]) ? profile.max_pwr_TOPStep[currentStep - 1] : p1 + integra - d1;

    out = (p2 + integra2 - d2 < profile.min_pwr_BOTTOM) ? profile.min_pwr_BOTTOM : (p2 + integra2 - d2 > profile.max_pwr_BOTTOM) ? profile.max_pwr_BOTTOM : p2 + integra2 - d2;
    14 профилей по 9 шагов для ВИ, для НИ шагов не реализовано -просто ПИД с ограничением мощности через меню. Число шагов оставлено "на всякий" - в жизни ещё ни разу не требовалось больше 3.
     
    Последнее редактирование: 25 май 2020
    Sema нравится это.
  2. Sema

    Sema Нерд

    Сема из этого косяка чуть с ик станцией не поженился) в прошлом скетче 1.3.6 так же было?
     
    SOLOway нравится это.
  3. SOLOway

    SOLOway Гуру

    Да. :eek:
    Если вернуть классическую версию ПИД, как в мае 2019, она должна выглядеть в 1.3.4 так?:
    Код (C++):
    byte Pid1(double temp, byte ust, byte kP, byte kI, byte kd)
    {
      byte out = 0;
      static float ed = 0;
      e1 = (ust - temp); //ошибка регулирования
      p1 =  (kP * e1); //П составляющая
      integra = (integra < i_min) ? i_min : (integra > i_max) ? i_max : integra + (kI * e1) / 1000; //И составляющая
      d1 = kd * (e1 - ed) * 10; //Д составляющая
      ed = e1;
      out = (p1 + integra + d1 < 0) ? 0 : (p1 + integra + d1 > pwr_TOP) ? pwr_TOP : p1 + integra + d1;
      return out;
    }

    byte Pid2(double temp, byte ust, byte kP, byte kI, byte kd)
    {
      byte out = 0;
      static float ed = 0;
      e2 = (ust - temp); //ошибка регулирования
      p2 =  (kP * e2); //П составляющая
      integra2 = (integra2 < i_min) ? i_min : (integra2 > i_max) ? i_max : integra2 + (kI * e2) / 1000; //И составляющая
      d2 = kd * (e2 - ed) * 10; //Д составляющая
      ed = e1;
      out = (p2 + integra2 + d2 < 0) ? 0 : (p2 + integra2 + d2 > pwr_BOTTOM) ? pwr_BOTTOM : p2 + integra2 + d2;
      return out;
    }
    Если так, то с такой версией ПИД скетч здесь.
     

    Вложения:

  4. Dmitrysh

    Dmitrysh Гуру

    во втором ПИДе (Pid2) ошибка
    Код (C++):
    ed = e1;
    а должно быть
    Код (C++):
    ed = e2;
     
    SOLOway нравится это.
  5. Dmitrysh

    Dmitrysh Гуру

    вот так
    Код (C++):
    byte Pid1(double temp, byte ust, byte kP, byte kI, byte kd)
    {
      byte out = 0;
      static float ed = 0;
      e1 = (ust - temp); //ошибка регулирования
      p1 =  (kP * e1); //П составляющая
      integra = (integra < i_min) ? i_min : (integra > i_max) ? i_max : integra + (kI * e1) / 1000; //И составляющая
      d1 = kd * (temp - ed) ; //Д составляющая
      ed = temp;
      out = (p1 + integra - d1 < 0) ? 0 : (p1 + integra - d1 > pwr_TOP) ? pwr_TOP : p1 + integra - d1;
      return out;
    }

    byte Pid2(double temp, byte ust, byte kP, byte kI, byte kd)
    {
      byte out = 0;
      static float ed = 0;
      e2 = (ust - temp); //ошибка регулирования
      p2 =  (kP * e2); //П составляющая
      integra2 = (integra2 < i_min) ? i_min : (integra2 > i_max) ? i_max : integra2 + (kI * e2) / 1000; //И составляющая
      d2 = kd * (temp - ed) ; //Д составляющая
      ed = temp;
      out = (p2 + integra2 - d2 < 0) ? 0 : (p2 + integra2 - d2 > pwr_BOTTOM) ? pwr_BOTTOM : p2 + integra2 - d2;
      return out;
     
    Vitaliy и SOLOway нравится это.
  6. SOLOway

    SOLOway Гуру

    @Dmitrysh !!!
    Храни вас Боги!
    Переделал. В архиве два варианта 1.3.4 - с прежним ПИД и с новым ПИД. Там же полная схема и самая свежая версия вашей irsp из поста #4016 с более яркой сеткой.
     

    Вложения:

    • 250520.zip
      Размер файла:
      1,5 МБ
      Просмотров:
      337
    Vitaliy и Wzor нравится это.
  7. tssergej

    tssergej Нерд

    Уважаемый Watashi,
    сегодня протестил вашу последнюю версию SVS_09 и хотелось бы поделиться своими впечатлениями и хотелками.
    1. Защита от внештатных ситуаций в таком виде на инерционных грелках не работает. Дело в том что на инерционных нагревателях с момента старта профиля и до того момента пока термопара «почувствует» нагрев ( на моих грелках примерно 40-60сек) проходит как правило достаточно много времени, а защита срабатывает через 3-5сек, соответственно у меня при включенной защите вовсе не получается запустить профиль.

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

    SOLOway ранее уже описывал свой вариант решения этой проблемы – принудительное включение низа кнопкой.

    Может быть всё-таки лучше решить это програмно с возможностью включать/отключать преднагрев в файле Setting и там же настраивать время преднагрева?

    3. По поводу вывода графика на компьютер с этим скетчем у меня тоже проблемы – при старте профиля обмен данными с irsp прекращается. Причём иногда данные всё-таки проскакивают, очень катковременно и график скачкообразно изменяется.


    Последний пункт нужно ещё проверить, возможно у меня просто проблеммы детектором нуля
     
  8. Sema

    Sema Нерд

    А чем новый пид от старого отличается? если можно для тупых обьясните! чтоб понять в чем разница настроики старого и нового!
     
  9. Dmitrysh

    Dmitrysh Гуру

    в посте #3009
     
    Sema нравится это.
  10. Watashi

    Watashi Гуру

    Я подумаю.
     
  11. geleos27

    geleos27 Гик

    Так у вас же в 09 есть кусок кода, который прогревает нагреватели.

    Код (C++):
                if (millis() - BotStartTime < 3000) Output2 = 5; // первые 3 сек мощность низа =5%
                  else  Output2 = Pid2(Input2, bottomTemp, u.Profili.kp2, u.Profili.ki2, u.Profili.kd2);
                if (TopStart == true) Output1 = Pid1(Input1, Setpoint1, u.Profili.kp1, u.Profili.ki1, u.Profili.kd1);

    Вынести время прогрева и мощность в переменные
     
    Последнее редактирование: 25 май 2020
  12. Vigorca

    Vigorca Нерд

    Может лучше было преднагрев до определенной температуры платы ( до 35 в зависимости от толщины платы) потом старт профиля. Так делаю на своей паялке только преднагрев в ручном режиме по достижению температуры платы 30-45 гр.(зависит от тольшины) и потом стартую профиль.(Версия SVS-08 Watashi). Низ кварц с керамическим стеклом.
     
    Последнее редактирование: 25 май 2020
    tssergej нравится это.
  13. geleos27

    geleos27 Гик

    Код (C++):
             
          if (tc2 > 45) Output2 = Pid2(Input2, bottomTemp, u.Profili.kp2, u.Profili.ki2, u.Profili.kd2); // чтобы эта ветка выполнялась первой большую часть времени
           else if (millis() - BotStartTime > 3000) Output2 = 10; // если прошло больше 3 секунд от начала нагрева
              else Output2 = 5; //  Плавный старт нагревателя на 5% мощности
     
     
    Последнее редактирование: 25 май 2020
    Vigorca нравится это.
  14. sergianto

    sergianto Нерд

    Было бы супер,если бы Уважаемый Watashi в своей прошивке добавил такую функцию.Например через переменную в конце меню (где настройка часов) :0 или 1-старт стандартный то есть 3сек.на 5 %,от 2 до 50-это температура(выставляеться градусы) и потом старт профиля.П.С.Благодоря вашей теме собрал станцию на керамике,настраиваю,а также паралельно изучаю ардуино.
     
    Sema, tssergej, SOLOway и ещё 1-му нравится это.
  15. tssergej

    tssergej Нерд

    Согласен, такой вариант будет более универсальным. Будет ли преднагрев включаться через меню программы или файл Setting, всё равно. Я думаю что те, кому эта опция нужна включать её раз и навсегда.
     
  16. geleos27

    geleos27 Гик

    Я хрен знает пока как сделать сохранение данных, там много придется переписать внутри.

    Подправил баги в PortPlotter для форума и подогнал умолчания под ваш скриншот.
    PortPlotter.PNG

    Дополнительное текстовое поле снизу чуть позже сможет отправлять команды в паялку.
     
    SOLOway нравится это.
  17. SOLOway

    SOLOway Гуру

    Я несколько раз упоминал в теме промышленные станции с керамическими излучателями, в которых термопрофиль начинает исполняться только когда температура на плате достигнет 70-50°С (разница из-за способов установки датчика НИ). При фиксации платы на высоте 3см над излучателями НИ, и при температуре снизу платы 70°С поверхность самих излучателей будет, примерно, на 100°С выше. ПИДу НИ легче будет, наверное, но это надо проверить в железе, т.к. могут быть и неприятные нюансы. Да и просто вспомним, что температуры ниже 80°С мы в паялках не используем совсем, а значит условием старта профиля (штатный запуск НИ и т.д.) можно назначить температуры 70-50°С по любому из датчиков.
    Попробовал добавить преднагрев НИ с условием 20% мощи до 50°С на термопаре НИ. Ориентировался на скетч из поста #2886 . Железа нет сейчас, а светодиоды вместо твердотелок кажут, что нифига не работает, где-то я косякнул опять.
     

    Вложения:

  18. geleos27

    geleos27 Гик

    Строка 555

    Код (C++):
            reflowState = REFLOW_STATE_STEP_RAMP;

    заменить на

            reflowState = REFLOW_STATE_PRE_HEATER;
     
    SOLOway нравится это.
  19. SOLOway

    SOLOway Гуру

    И в строке 1344 заменить
    Код (C++):
    Setpoint2=tc2;
    на
    Код (C++):
    Setpoint2=SP2;
    Заработал преднагрев НИ.
    Еще заметил как-то "нервно" работает ПИД2, дёргается даже при I,D=0. Подозреваю, из-за моего детектора ноля (http://radioservice.at.ua/_fr/0/Schematic_BLOC-.pdf). Буду разбираться.

    Теперь о новшествах в этой инкарнации release_1.3.4! (Суть в том. чтобы объединить 1.3.3, 1.3.4, 1.3.5, 1.3.6. Часть работы сделана, здесь ещё один шаг к цели.)
    Если раскоментировать строку
    Код (C++):
    //#define SerialPortPlotter 1
    , контроллер выводит графики температур и мощностей в программу SerialPortPlotter, удобную версию которого предоставил @geleos27 в посте #4037
    Если оставить строку
    Код (C++):
    //#define SerialPortPlotter 1
    закоментированной - вывод графиков и их синхронизация с нолем времени при старте пайки будет по умолчанию в программу irsp © @Dmitrysh из поста #4016
     

    Вложения:

    Последнее редактирование: 27 май 2020
    geleos27 и Wzor нравится это.
  20. geleos27

    geleos27 Гик

    В Port plotter очень удобно отслеживать какой из компонент косячит.
    Код (C++):


      #ifndef SerialPortPlotter
      sprintf (buf, "$%03d %03d %03d %03d %03d %03d %03d;", int(Output1), int(Output2), tc1, tc2, int(p2), int(integra2), int(d2));
      //Serial.print(buf); //это для графиков на ПК <--- отключаем, т.к. вывод 1 раз в секунду в Dimming()
      #endif
     
    Код (C++):
    void Dimming()
    {
      if (reflowStatus == REFLOW_STATUS_ON)
      {
      OutPWR_TOP();
      OutPWR_BOTTOM();
      }
      #ifdef SerialPortPlotter
      if (Secs >= 100)
      {
      Serial.println(buf);
      Secs = 1;    //<---------------------------- надо начинать считать с 1, т.к. в первый шаг мы только присваиваем значение, но не прибавляем. если 0, то получаем 101 интервал до переключения. Секунды чуток убегают)
      }
      else Secs++;
      #endif
    }
     
    Последнее редактирование: 29 май 2020
    SOLOway и Dmitrysh нравится это.
Статус темы:
Закрыта.