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

Тема в разделе "Arduino & Shields", создана пользователем vector99, 7 дек 2016.

  1. vector99

    vector99 Нерд

    В просторах интернета нашёл контролёр для управления паяльной станции https://instructables.info/infrakrasnaya-payalnaya-stantsiya-svoimi-rukami/
    Немного почитав информации в интернете, изменил скетч под дисплей с модулем I2C, включил внутренние подтягивающие резисторы, и прошивка загрузилась в ардуинку. Вроди-бы всё заработало, но есть тут такие нестыковки которые могут убить пациента.

    Код (C++):
    [code]
          startTemp = tc1;// нужно как-то привязать к начальной температуре на каждом этапе
             
         
          lcd.setCursor(16, 1);
          lcd.print(currentStep);
          lcd.setCursor(8, 3);
          lcd.print(SP2);
          //ramp rate counter
          if ((currentMillis - previousMillis) > 1000 * rampRateStep[currentStep - 1]) { //seconds counter

            previousMillis = currentMillis;
            counter = counter + 1;
            setpointRamp = counter + startTemp;
            lcd.setCursor(8, 2);
            lcd.print("   ");      
            lcd.setCursor(8, 2);
            lcd.print(setpointRamp);
            lcd.print("  ");
            Setpoint1 = setpointRamp;

     
    А именно строка
    Код (C++):
     startTemp = tc1
    явно неправильна. Нужно "startTemp" привязать к начальной температуре на каждом этапе нагрева, а не мониторить её постоянно, потому как нет нагрева с нужной нам скоростью.
    В программировании я полный "0"!
    ARS_v2_Lilium_JSN_max6675.zip- это оригинальный код
    ARDUINO REWORK V1.2.zip- а это изменённый мной код
    Ещё при настройке параметров не сохраняются значения роста температуры если они с запятой, сбрасывается на нули.
    Прошу Вашей помощи!!!
     

    Вложения:

  2. vector99

    vector99 Нерд

    Проблему роста температуры решил простым умножением коэффициентов на 4
    Код (C++):

            rampRateStep[editStep] = rampRateStep[editStep] + 1.;
            delay(25);
            if (rampRateStep[editStep] >= 12.)  //(только целые числа) максимальная скорость роста температуры делённая на 4
            {
              rampRateStep[editStep] = 12.;  //(только целые числа) максимальная скорость роста температуры делённая на 4
            }
          }
          if (downSwitchState == HIGH)
          {
            rampRateStep[editStep] = rampRateStep[editStep] - 1.;
            delay(25);
            if (rampRateStep[editStep] <= 1.)  //(только целые числа) минимальная скорость роста температуры делённая на 4
            {
              rampRateStep[editStep] = 1.;  //(только целые числа) минимальная скорость роста температуры делённая на 4
            }

     
    Код (C++):

          if ((currentMillis - previousMillis) > 4000 / rampRateStep[currentStep - 1]) { //seconds counter

     
    а для корректного отображения на дисплее
    Код (C++):
    lcd.print(rampRateStep[editStep] / 4);
    ограничил скорость роста температуры максимум 3 градуса в секунду, минимум 0,25 градуса
     

    Вложения:

  3. vector99

    vector99 Нерд

    Решил проблему со считыванием стартовой температурой. Теперь при старте профиля температура считывается с термопары один раз.
    Код (Text):

          if (currentStep == 1 && flag == 0){
            startTemp = tc1;
            flag = 1;
          }    
          if (currentStep >1 && flag == 1){
            flag = 0;
            startTemp = temperatureStep[currentStep - 2];      
            flag = 1;
          }

     
    Флаги сбрасываются после остановки или завершении профиля.
    Код (Text):

          if (cancelSwitchState == HIGH)
          {
            currentStep = 1;
            counter = 0;
            setpointRamp = 0;
            flag = 0;         //после отановки профиля сбрасываем флаг
            reflowStatus = REFLOW_STATUS_OFF;
            reflowState = REFLOW_STATE_IDLE;
            updateScreen = true;
          }

     
    Код (Text):

    if (counter == dwellTimerStep[currentStep - 1]) {
            counter = 0;
            setpointRamp = 0;
            if (profileSteps == currentStep) {
              currentStep = 1;
              flag = 0;   //после завершения профиля сбрасываем флаг
              reflowState = REFLOW_STATE_COMPLETE;
            }
            else {          
              currentStep++;
              reflowState = REFLOW_STATE_STEP_RAMP;          
            }
          }

     
     

    Вложения:

  4. vector99

    vector99 Нерд

    Продолжим вносить изменения. Теперь после остановки нагрева и повторном запуске, профиль продолжится с текущей температуры. Тоесть если недогрели, то можно остановить пайку, внести изменения и продолжить дальше.
    Код (Text):

          if (flag == 0){
            startTemp = tc1;
            flag = 1;
          }
          if (startTemp > temperatureStep[currentStep -1]){
            for (x=1; startTemp > temperatureStep[currentStep - 1];currentStep++){
              x++;
            }
          }
          if (currentStep > x && flag == 1){
            flag = 0;
            startTemp = temperatureStep[currentStep - 2];      
            flag = 1;
          }

     
    Максимальное время перехода на следующий шаг сократил до 100 секунд, т.к 1000 секунд это слишком много.
     

    Вложения:

    Последнее редактирование: 22 дек 2016
  5. Darev

    Darev Нуб

    Спасибо огромное. Ваши корректировки прекрасно работают, станция прям ожила. Какие PID-ы у Вас вышли при наладке
     
  6. vector99

    vector99 Нерд

    Станция в стадии разработки. Поэтому наладка контроллёра идёт на лампочке, а пиды настраивать надо на готовой станции. Поэтому пидами даже не заморачивался. В планах сделать вход в меню по долгому нажатию на "ОК", убрать одну кнопку.
     
  7. vector99

    vector99 Нерд

    С прошедшими праздниками всех!
    В очередной версии я сделал вход в "МЕНЮ" по долгому нажатию (3 секунды) на кнопку "ОК".
    Заодно защиту от дребезга контактов сделал через "millis()" вместо "delay()" (все 4 кнопки)
    Код (Text):

    //фиксируем момент нажатия кнопки "ОК" + защита от дребезга
          if (okSwitchState == HIGH && !button_state && ( millis() - ms_button)>100)
          {
            ms_button =  millis();
            button_state = true;
            button_long_state = false;
          }
    //держим "ОК" 3секунды и заходим в меню настроек    
          if (okSwitchState == HIGH && !button_long_state && ( millis() - ms_button)>3000)
          {
            button_long_state = true;
            button_state = false;
            reflowState = REFLOW_STATE_MENU_STEPS;
            //update next screen
            updateScreen = true;
          }
    //включаем пайку, кнопка сработает после отпускания "ОК"    
          if (okSwitchState == LOW && button_state && ( millis() - ms_button)>100)
          {      
            ms_button =  millis();
            button_state = false;
            tone(buzzerPin, 1045, 500);  //звуковой сигнал при старте профиля
            //update next screen
            updateScreen = true;
            curCount = 0;
            nextRead2 = millis();
            reflowStatus = REFLOW_STATUS_ON;
            reflowState = REFLOW_STATE_STEP_RAMP;
          }

     
    Отключил бузер при нажатии на кнопки, пищит только при приветствии, старте и завершении профиля.
    И немного раскомментировал скетч. Т.К. эта версия с 4-мя кнопками записил как "ARDUINO REWORK v1.3"
     

    Вложения:

  8. xake

    xake Нерд

    в этом контроллере можно включить только нижний подогрев, например, на 90 градусов?
     
  9. vector99

    vector99 Нерд

    Если подключить низ к "6" пину на ардуино и удалить в скече это условие "(tc2 >= (Setpoint2-10))&&" в самом конце скетча.
    Код (Text):

    //верхний нагреватель включится ели температура "низа" достигнет (уснановленной минус 10 градусов)  
        if ((tc2 >= (Setpoint2-10))&&(Output1> millis() - windowStartTime )) digitalWrite(RelayPin1, HIGH);

     
    то низ будет отрабатывать профиль начиная с комнатной температуры до какой Вам надо (максимум 250 градусов) с заданной скоростью.
    Смотря для каких целей Вы хотите приспособить этот контроллёр. Решения могут быть разные.
     
    Последнее редактирование: 19 янв 2017
    xake нравится это.
  10. xake

    xake Нерд

    создать профиль только преднагрев
     
  11. vector99

    vector99 Нерд

    для пайки BGA, SMD, или запекания паяльной маски? если не секрет!
     
  12. xake

    xake Нерд

    преднагрев платы для замены разъема, например
     
  13. vector99

    vector99 Нерд

    Ну в таком случае, предложенный выше вариант наверное самый оптимальный.
     
  14. xake

    xake Нерд

    проще тумблером :)
     
  15. vector99

    vector99 Нерд

    По своей природе датчик МАХ6675 немного шумит (показания прыгают туда сюда), соответственно ПИДу тяжело ловить оптимальное значение. Поэтому решил его немного стабилизировать. Добавил в скетч "Фильтр Калмана" (во избежании критики, это наверное сильно упрощённый вариант, и таковым его может и трудно назвать). Возможно можно было и проще сделать, но работает неплохо.
    Код (Text):

    // переменные для калмана "ВЕРХНЕГО" нагревателя
    float varTerm1 = 0.25;  // среднее отклонение (ищем в excel)
    float varProcess1 = 0.025; // скорость реакции на изменение (подбирается вручную)
    float Pc1 = 0.0;
    float G1 = 0.0;
    float P1 = 1.0;
    float Xp1 = 0.0;
    float Zp1 = 0.0;
    float Xe1 = 0.0;

    // переменные для калмана "НИЖНЕГО" нагревателя
    float varTerm2 = 0.25;  // среднее отклонение (ищем в excel)
    float varProcess2 = 0.025; // скорость реакции на изменение (подбирается вручную)
    float Pc2 = 0.0;
    float G2 = 0.0;
    float P2 = 1.0;
    float Xp2 = 0.0;
    float Zp2 = 0.0;
    float Xe2 = 0.0;
    // переменные для калмана

     
    Код (Text):

            Input1 = filter1(thermocouple1.readCelsius());
            Input2 = filter2(thermocouple2.readCelsius());

     
    Код (Text):

      float filter1(float val_1) {  //функция фильтрации показений "Верхней" термопары
      Pc1 = P1 + varProcess1;
      G1 = Pc1/(Pc1 + varTerm1);
      P1 = (1-G1)*Pc1;
      Xp1 = Xe1;
      Zp1 = Xp1;
      Xe1 = G1*(val_1-Zp1)+Xp1; // "фильтрованное" значение
      return(Xe1);
    }
      float filter2(float val_2) {  //функция фильтрации показений "Нижней" термопары
      Pc2 = P2 + varProcess2;
      G2 = Pc2/(Pc2 + varTerm2);
      P2 = (1-G2)*Pc2;
      Xp2 = Xe2;
      Zp2 = Xp2;
      Xe2 = G2*(val_2-Zp2)+Xp2; // "фильтрованное" значение
      return(Xe2);
      }

     
    Теперь показания ведут себя вот так,
    90-100 градусов.jpg остывание.jpg комнатная.jpg нагрев.jpg
    (красная - реальные показания, желтая - отфильтрованные)
    Не совсем плавно, но более спокойно.
     

    Вложения:

    Последнее редактирование: 23 янв 2017
  16. uagreen

    uagreen Нуб

    А под нано переделать возможно?
     
  17. vector99

    vector99 Нерд

  18. dredivan

    dredivan Нуб

    как приятно что скетч для MAX6675 который я выложил в интернет получил другую жизнь. А с коэффициентами P I D кто-то разбирался?
     
  19. vector99

    vector99 Нерд

    пробовал на лампочке P=8, I=0.1, D=1
    вылет за уставку не более 2х градусов. как в боевых условиях будет неизвестно
     
  20. uagreen

    uagreen Нуб

    Еще глупый вопрос: софт какой ни будь на пк есть(монитор, редактирование профилей)?
    А то взял 2 строчный дисплей и с ним не очень удобно