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

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

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

    Dmitrysh Гуру

    Да вы правы, я имел в виду коэффициенты занимают 1 байт.
     
  2. Yurik-o

    Yurik-o Нерд

    Получается что в разных вариантах "нашей" общей станции по разному обращаются к библиотеке ПИД.
     
  3. bamik

    bamik Нерд

    Я заметил, что используются 2 версии библиотки ПИД. Версии PID_v1.h и PID_v2.h.
    Я разбираю sketch_feb07a1_work.ino, т.к. он мне подходит по железу.
    Совершенно не вникал в вопросы целесообразности использования точных значений. Если есть у кого опыт в этом, то просьба сделать список переменных из скетча с предполагаемой длиной.
    Теоретически типа int должно на все хватать с запасом, т.к. внутренний АЦП 10тиразрядный, а внешние максимум 14тиразрядные.
    Если температуру хранить в градусах, то хватит byte. 255 градусов вполне хватит. А можно хранить относительную температуру, например, относительно 50 градусов. Тогда диапазон нагрева будет от 50 до 305 градусов.
    profileSteps - это количество шагов в профайле?
    Setpoint2 - это для чего? Текущая точка останова?
     
  4. Здравствуйте. Я у себя в коде пины кнопок объявлял через подстановку #define
    Код (C++):

    //Назначаем пины кнопок управления
    #define BTN_DOWN 13  // кнопка
    #define BTN_UP 12  // кнопка
    #define BTN_OK 11 // кнопка
    #define BTN_PREV 10 // кнопка
    #define BTN_NEXT 9 // кнопка
    #define BTN_CANSEL 8 // кнопка  
    Пишут, что так правильней - не спутаешь с отдельными переменными
    Так же для проверки короткого и долгого нажатий пользуюсь классом do_btn_long( мне помогли его сделать). Класс написан через millis и поэтому 10 раз его дублировать как это сделано здесь не вижу смысла. Советую им также воспользоваться, удобно.
    Код (C++):

    Cl_do_btn_long Btn_down(BTN_DOWN);
    Cl_do_btn_long Btn_up(BTN_UP);
    Cl_do_btn_long Btn_ok(BTN_OK);
    Cl_do_btn_long Btn_prev(BTN_PREV);
    Cl_do_btn_long Btn_next(BTN_NEXT);
    Cl_do_btn_long Btn_cansel(BTN_CANSEL);

    // кнопка 1
    void press_down() { /*обработчик короткого*/
      updown(false);
    }
    void longPress_down() { /*обработчик длинного*/
      long_updown(false);
    }
    // кнопка 2
    void press_up() { /*обработчик короткого*/
      updown(true);
    }
    void longPress_up() { /*обработчик длинного*/
      long_updown(true);
    }
     

    Вложения:

    Последнее редактирование: 26 апр 2018
  5. Общение с компьютером удобно делать через директивы условной компиляции. serialenabled можно в нужный момент закомментировать и serial соединение не будет занимать память. Смотрите по коду что я прикрепил выше my1.5.3.ino
    Код (C++):
    //#define serialenabled // раскомментировать для выдачи в порт отладочной инфы
    Код (C++):
    void setup() {
      #ifdef serialenabled
         Serial.begin(9600);
      #endif
    Буду доделывать на основе sketch_feb07 и остальных наработок на этом форуме
     
    SOLOway нравится это.
  6. ШИМ с частотой 5 Гц. Сделал у себя в коде на основе станции myscu

    Код (C++):

    void mode_PWM1(uint8_t Output1) {
      static unsigned long prevTime = 0;
      if ((state_bottom == 0) && ((millis() - prevTime) >= 200 * (100 - Output1) / 100)) {
        state_bottom = 1;
        PORTC |= 1 << RELAYPIN_H;
        prevTime = millis();
      }
      if ((state_bottom == 1) && ((millis() - prevTime) >= 200 * Output1 / 100)) {
        state_bottom = 0;
        PORTC &= ~(1 << RELAYPIN_H);
        prevTime = millis();
      }
    }

    void mode_PWM2(uint8_t Output2) {
      static unsigned long prevTime = 0;
      if (TopStart && (state_top == 0) && ((millis() - prevTime) >= 200 * (100 - Output2) / 100)) {
        state_top = 1;
        PORTC |= 1 << RELAYPIN_B;
        prevTime = millis();
      }
      if (TopStart && (state_top == 1) && ((millis() - prevTime) >= 200 * Output2 / 100)) {
        state_top = 0;
        PORTC &= ~(1 << RELAYPIN_B);
        prevTime = millis();
      }
    }
     
    Последнее редактирование: 26 апр 2018
  7. Часто поьзуюсь F
    Код (C++):
    lcd.print(F("SAVE and EXIT")); // согласие на сохранение результата/изменений
    Записывает строки во флеш, а не в RAM. RAM всего то 2 Кб на Uno, nano. Флеш 32 Кб - 'экономия очевидна
     
    Последнее редактирование: 26 апр 2018
  8. typedef enum REFLOW_STATE : byte // по умолчанию int - все работает и с byte -> экономнее
    {
    REFLOW_STATE_IDLE,
    REFLOW_STATE_MENU_STEPS,
    REFLOW_STATE_MENU_BOTTOM_HEAT,
    REFLOW_STATE_MENU_BOTTOM_PWR,
    REFLOW_STATE_MENU_STEP_RAMP,
    REFLOW_STATE_MENU_STEP_TARGET,
    REFLOW_STATE_MENU_TOP_PWR,
    REFLOW_STATE_MENU_STEP_DWELL,
    REFLOW_STATE_MENU_BOTTOM_P,
    REFLOW_STATE_MENU_BOTTOM_I,
    REFLOW_STATE_MENU_BOTTOM_D,
    REFLOW_STATE_MENU_TOP_P,
    REFLOW_STATE_MENU_TOP_I,
    REFLOW_STATE_MENU_TOP_D,
    REFLOW_STATE_STEP_RAMP,
    REFLOW_STATE_STEP,
    REFLOW_STATE_STEP_DWELL,
    REFLOW_STATE_COMPLETE,
    REFLOW_STATE_ERROR,
    REFLOW_STATE_MENU_RESET
    }
    reflowState_t;

    Над остальным еще думаю, прошивку станции переделываю под свое меню( дисплей 4 строки 20 символов). Поэтому только советую что сам узнал в Си++
     
    Последнее редактирование: 26 апр 2018
  9. bamik

    bamik Нерд

    Ваш вариант уже хорошо перелопаченный вариант sketch_feb07a1_work. Буду на него ориентироваться.
    Вы область с коэффициентами во флеше выделили подальше от термопрофилей. Это логично. Т.к. коэффициенты ПИДа будут одни для всех профилей. Но:
    Код (C++):
    double kp1, kd1, ki1; // коэффициенты пид "НИЖНЕГО" нагревателя
    double kp2, kd2, ki2; // коэффициенты пид "ВЕРХНЕГО" нагревателя
     
    потому в:
    Код (C++):
      kp1 = EEPROM.read(480);
      ki1 = EEPROM.read(481);
      kd1 = EEPROM.read(482);
      kp2 = EEPROM.read(483);
      ki2 = EEPROM.read(484);
      kd2 = EEPROM.read(485);
     
    неизвестно что читается. А запись во флеш у Вас заремблена. Я думаю, что нужно использовать
    Код (C++):
    byte kp1, kd1, ki1; // коэффициенты пид "НИЖНЕГО" нагревателя
    byte kp2, kd2, ki2; // коэффициенты пид "ВЕРХНЕГО" нагревателя
     
    и
    Код (C++):
    EEPROM.get(480, kp1);
    EEPROM.get(481, ki1);
    EEPROM.get(482, kd1);
    EEPROM.get(483, kp2);
    EEPROM.get(484, ki2);
    EEPROM.get(485, kd2);
     
  10. Коэффициенты нужны именно double, этот тип занимает 8 байт.
    У меня старая версия IDE 1.6.0, функция put и get там нет.
    Спасибо, указали на ошибку.
    Тогда допускаю так:
    Код (C++):
     const int OFFSET = 8;
      kp1 = EEPROM.read(480+ OFFSET);
      ki1 = EEPROM.read(480 +2*OFFSET);
      kd1 = EEPROM.read(480 + 3* OFFSET);
      kp2 = EEPROM.read(480+ 4* OFFSET);
      ki2 = EEPROM.read(480+ 5* OFFSET);
      kd2 = EEPROM.read(480+ 6* OFFSET);
     
    Последнее редактирование: 27 апр 2018
  11. Есть пример
    Код (C++):
    #include <EEPROM.h>
    const int OFFSET = 10;
    byte readByte;

    void setup(){
          Serial.begin(9600);
          //sum = 0;
          byte  values[10] = {1, 3, 5, 12, 43, 23, 5, 124, 99, 55};
          for (int i=0; i<10; i++){
                //EEPROM.write(i+OFFSET, values[i]);
                if(EEPROM.read(i+OFFSET) != values[i] ){
                     EEPROM.write(i+OFFSET, values[i]);
                }
          }
       
          for (int i=0; i<10; i++){
                //byte readByte = EEPROM.read(i+OFFSET);
                readByte = EEPROM.read(i+OFFSET);
                Serial.println(readByte);
          }
    }

    void loop(){
    }
         
     
  12. Dmitrysh

    Dmitrysh Гуру

    Практика показала что экономии кода нет, плюс теряем возможность блокировать кнопки. Но вообще так правильнее.
    Если такой подход дает экономию кода,тогда можно.
    Так то оно так, но связь по uart это изначально известная вещь, если не надо можно просто убрать код из скетча.
    Поддерживаю, экономнее.
     
  13. Dmitrysh

    Dmitrysh Гуру

    Если коэффициенты улаживаются в byte, то будет читаться то что нужно. Проверено на практике.
    Если коэффициенты определены как byte, то в EEPROM.get/put нет смысла ибо компилятор подставляет вместо него EEPROM.read/write.
     
  14. SOLOway

    SOLOway Гуру

    Это только для галогенок открытых, либо спиралек в кварце. Если плита алюминиевая, или стеклокерамика на преднагревателе - 255 мало. Плита и поверхность стеклокерамики разогреваются до 350*С, поэтому правильнее сделать запас - не 255 конечная, а 512*С. Плюсом будет, если кто захочет в качестве верха применить воздух (фен) - там как раз 380-450*С требуются.
     
  15. bamik

    bamik Нерд

    Почему именно double? Вроде как уже есть переписанная на int библиотека PID.
     
  16. bamik

    bamik Нерд

    Значит, только int. И можно холодильник прикрутить. Хошь плавь, хошь замораживай. :)
     
  17. Точность. Не уверен, что все коэффициенты в процессе работы подойдут целые.;)
     
  18. Dmitrysh, надеюсь с этим вы не поспорите, можете проверить и убедиться - размер RAM (динамической памяти) сократится, зато немного увеличится размер флеш (же 32 кБ)
     
  19. Dmitrysh

    Dmitrysh Гуру

    profileSteps это количество шагов в профиле, а Setpoint2 - температура нижнего излучателя(нижнего нагревателя.)
     
  20. bamik

    bamik Нерд

    При которой включается ВИ?
     
Статус темы:
Закрыта.