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

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

  1. Dmitrysh

    Dmitrysh Гик

    Что то мне сдается что в нем вообще ПИДа нет, просто пропорциональный шим.
     
  2. SOLOway

    SOLOway Гик

    Он на monitor.net рассказывал, как вводил в прошивки коэффициенты ПИД, там же в меню у него есть эти вещи
     
  3. bamik

    bamik Нерд

    Смотря в каком исполнении датчик. Есть капелькой. Откуда у него инерция будет?
     
  4. Dmitrysh

    Dmitrysh Гик

    Я могу ошибаться, но мне pt100 капелькой не попадались, все были на керамической подложке или запаены в тубу.
     
  5. tssergej

    tssergej Нерд

    я имел в виду код из этого архива "sketch_TFT-320x480_dimer_V3-2_plus_hominidae_PC_soft_from_Dmitrysh"
    Там судя по коду "необычные" кнопки, если под обычными подразумеваются эта схема подключения.[​IMG]
    кусок кода из архива
    Код (C++):
    //--------настройка кнопок управления------------------------------------

    //#define A_PINS_BASE 100 // номер с которого начинается нумерация наших "псевдо-кнопок".

    #define PIN_RIGHT 100
    #define PIN_UP 101
    #define PIN_DOWN 102
    #define PIN_LEFT 103
    #define PIN_SELECT 104

    struct A_PIN_DESC{ // определяем  структуру которой будем описывать какое значение мы ожидаем для каждого псевдо-пина
       byte pinNo; // номер пина
       int expectedValue;// ожидаемое значение
    };

    A_PIN_DESC expected_values[]={ // ожидаемые значения для псевдо-кнопок
       { PIN_RIGHT,202},
       { PIN_UP,429},
       { PIN_DOWN,298},
       { PIN_LEFT,563},
       { PIN_SELECT,758}
    };
    было бы здорово, если бы выложили последнюю (готовую, так как модефицировать код по вашим пояснения выше у меня не получается ) версию кода с пояснением по схеме подключения кнопок и вашей схемой детектора нуля.
     
  6. Dmitrysh

    Dmitrysh Гик

    Выложить не проблема, надо немного мусора только выкинуть. Постараюсь завтра сделать.
     
  7. Dmitrysh

    Dmitrysh Гик

    Вот скетч с которым я сейчас работаю. Кнопки как у вас на картинке подключены к пинам 18 19 20 21. Детектор нуля самый простой, смотрите на картинке.
    В скетче использую не диммер, а фазовое управление как у snmar4enko, только без чередования периодов. Стандартные библиотеки max6675 и ПИД переписал процедурами для уменьшения кода и увеличения скорости работы. Сенсоры читаются через 220мс(это предел), ПИД считается каждые 100мс.
     

    Вложения:

    tssergej и SOLOway нравится это.
  8. SOLOway

    SOLOway Гик

    Во! Нашел чего-то про отклик фирмовых платиновых!
     

    Вложения:

    • PT106052.pdf
      Размер файла:
      99,6 КБ
      Просмотров:
      209
  9. Dmitrysh

    Dmitrysh Гик

    Судя по документации, очень медленные. Надо проводить натурные испытания.
     
  10. Здравствуйте, решил и я вставить сюда свои 5 копеек:). Если вас заботит экономия ресурсов, то более оптимально писать программы на си++, среда ардуино иде это позволяет.
    На сайте http://www.count-zero.ru/2015/spi/ показан пример подключения MAX6675 к ATmega8, и переделана библиотека MAX6675 под си код, убедитесь.
    Так вот я раньше где то на форуме узнал, что уменьшить размер компилируемого кода можно 2 способами: писать классами (объектно ориентированное программирование) или переходить на чистый си++.
    Я вашу переделанную версию maксa проверял, у меня работает не так как надо.
    Я привел код библиотеки на си++ под себя и если заинтересует, сразу посмотрите соответствие выводов микроконтроллера атмеги 328(168) и ардуино, в остальном код не отличается от вашей реализации, в setup() настраиваются порты (по распиновке разбиретесь), уже в loop() вызывается функция опроса термопары с нужным вам шагом.
    Код (C++):
    #include <avr/io.h>
    #include <util/delay.h>

    #define pSCLK   PD6
    #define pCS     PD5
    #define pMISO   PD4

    uint8_t spi_read(void);

    void setup(void)
    {
      init_ports();
    }

    void loop()
    {
      MAX6675_readCelsius();
      _delay_ms(1000); // для примера каждую секунду
    }

    void init_ports(void) {
      //  pCS:chip select
      DDRD |= (1<<pCS);
      PORTD  |= (1<<pCS);
      // clock line
      DDRD |= (1<<pSCLK);
      // data line
      DDRD &= ~(1<<pMISO);
    }

    double MAX6675_readCelsius(void) {
      PORTD &=~(1<<pCS);  //digitalWrite(pCS, LOW);
      _delay_ms(1);
      uint16_t data=0;
      data=(uint16_t)spi_read();
      data <<= 8;
      data |= (uint16_t)spi_read();
      PORTD |=(1<<pCS);  //digitalWrite(pCS, HIGH);
      if (data & 0x4) {
        return NAN;
      } else {
         data >>= 3;
         return data /= 4;
      }
    }
    uint8_t spi_read(void)
    {
      uint8_t i,ret ,value;
      ret=0;
      i=8;
      do {
        i--;
        PORTD &=~(1<<pSCLK);// digitalWrite(pSCLK, LOW);
        _delay_ms(1);
        value=PIND &(1<<pMISO);
        if (value)
        {
          //set the bit to 0 no matter what
          ret |= (1 << i);
        }
        PORTD |=(1<<pSCLK); // digitalWrite(pSCLK, HIGH);
        _delay_ms(1);
      } while (i > 0);
      return ret;
    }
    Расход памяти минимален
    Код (C++):
    Sketch uses 746 bytes (2%) of program storage space. Maximum is 32 256 bytes.
    Global variables use 9 bytes (0%) of dynamic memory, leaving 2 039 bytes for local variables. Maximum is 2 048 bytes.
     
    Для двух термопар позже приведу
     
    Последнее редактирование: 1 июн 2018
    Dmitrysh нравится это.
  11. Экономия только флеш памяти, поэтому тут останется как запасной вариант
    Код (C++):

    #include <avr/io.h>
    #include <util/delay.h>

    double Input1;
    double Input2;

    #define pSCLK   PD6
    #define pCS     PD5
    #define pCS2   PD7
    #define pMISO   PD4

    uint8_t spi_read(void);

    void setup(void)
    {
      init_ports();
    }

    void loop()
    {
      Input1 = MAX6675_readCelsius(pCS);
      Input2 = MAX6675_readCelsius(pCS2);
    }

    void init_ports(void) {
      //  pCS:chip select
      DDRD |= (1<<pCS);
      PORTD  |= (1<<pCS);
      // clock line
      DDRD |= (1<<pSCLK);
      // data line
      DDRD &= ~(1<<pMISO);
    }
    double MAX6675_readCelsius(uint8_t CS_pin) {
      PORTD &=~(1<<CS_pin);  //digitalWrite(pCS, LOW);
      _delay_ms(1);

      uint16_t data=0;
      data=(uint16_t)spi_read();
      data <<= 8;
      data |= (uint16_t)spi_read();

      PORTD |=(1<<CS_pin);  //digitalWrite(pCS, HIGH);
      if (data & 0x4) {
        return NAN;
      } else {
         data >>= 3;
         return data /= 4;
      }
    }
    uint8_t spi_read(void)
    {
      uint8_t i,ret;
      ret=0;
      i=8;
      do {
        i--;
        PORTD &=~(1<<pSCLK);// digitalWrite(pSCLK, LOW);
        _delay_ms(1);
        if (PIND &(1<<pMISO)) ret |= (1 << i);
        PORTD |=(1<<pSCLK); // digitalWrite(pSCLK, HIGH);
        _delay_ms(1);
      } while (i > 0);
      return ret;
    }
    }
    Код (C++):
    Sketch uses 800 bytes (2%) of program storage space. Maximum is 32 256 bytes.
    Global variables use 17 bytes (0%) of dynamic memory, leaving 2 031 bytes for local variables. Maximum is 2 048 bytes.
    Код (C++):
    double Input1;
    double Input2;

    #define thermoCS 5
    #define thermoCS2 7
    #define thermoCLK 6
    #define thermoDO 4

    void setup() {
      // put your setup code here, to run once:
      pinMode(thermoCS, OUTPUT);
      pinMode(thermoCS2, OUTPUT);
      pinMode(thermoCLK, OUTPUT);
      pinMode(thermoDO, INPUT);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      Input1 = max6675_read_temp (thermoCLK, thermoCS, thermoDO);
      Input2 = max6675_read_temp (thermoCLK, thermoCS2, thermoDO);
    }

    double max6675_read_temp (int ck, int cs, int so)          
    { char i;
        int tmp = 0;
       digitalWrite(cs, LOW);//cs = 0;                            // Stop a conversion in progress
       asm volatile
        (
         " nop"        "\n\t"
        );
       for (i=15;i>=0;i--)
        {  digitalWrite(ck, HIGH);
          asm volatile
        (
         " nop"        "\n\t"
        );
          if( digitalRead(so))
          tmp|=(1<<i);
     
          digitalWrite(ck, LOW);
        asm volatile
        (
         " nop"        "\n\t"
        );
        }
       digitalWrite(cs, HIGH);
       if (tmp & 0x4) {
         return NAN;
       } else
       return ((tmp>>3))*0.25;
    }
    Код (C++):
    Sketch uses 1 682 bytes (5%) of program storage space. Maximum is 32 256 bytes.
    Global variables use 17 bytes (0%) of dynamic memory, leaving 2 031 bytes for local variables. Maximum is 2 048 bytes.
     
    Последнее редактирование: 1 июн 2018
    Dmitrysh нравится это.
  12. SOLOway

    SOLOway Гик

    ...искал параметры термопар ТХА, наткнулся на Википедию:
    Наверное, это оффтоп, но пусть будет, дабы не развязывать "войну термодатчиков"...
     
    Dmitrysh нравится это.
  13. Dmitrysh

    Dmitrysh Гик

    Не согласен, с++ тут не причем.
    Практика показывает что применение классов увеличивает код и расход ОЗУ, а применение с++ не дает преимуществ перед классическим си. Это все сказано применительно к 8битным микроконтроллерам.
    Нет не минимален. Это так называемый "финт ушами" относительно "жирных" digitalWrite и digitalRead.
    Смотрите на мой скетч переписанный по вашему подобию
    Код (C++):
    #include <util/delay.h>

    #define pSCLK   PD6
    #define pCS     PD5
    #define pMISO   PD4

    void setup(void)
    {
       //  pCS:chip select
      DDRD |=B00100000;
      PORTD |=B00100000;
      // clock line
      DDRD |=B01000000;
      // data line
      DDRD &=B11101111;
    }

    void loop()
    {
     
      max6675_read_temp (pSCLK, pCS, pMISO);
      _delay_ms(1000); // для примера каждую секунду
    }

    double max6675_read_temp (int ck, int cs, int so)            
    { char i;
        int tmp = 0;
       PORTD &=~(1<<pCS);//cs = 0;                            // Stop a conversion in progress
       asm volatile
        (
         " nop"        "\n\t"
        );
       for (i=15;i>=0;i--)
        {  PORTD |=(1<<pSCLK);
          asm volatile
        (
         " nop"        "\n\t"
        );
          if( PIND &(1<<pMISO))
          tmp|=(1<<i);
       
       PORTD &=~(1<<pSCLK);
        asm volatile
        (
         " nop"        "\n\t"
        );
        }
       PORTD |=(1<<pCS);
       if (tmp & 0x4) {
         return NAN;
       } else
       return ((tmp>>3))*0.25;
    }
    Я компилирую на IDE 1.8.2. Плата arduino UNO на mega328.
    Ваш вариант
    Код (C++):
    Скетч использует 556 байт (1%) памяти устройства. Всего доступно 32256 байт.
    Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
    Мой вариант
    Код (C++):
    Скетч использует 492 байт (1%) памяти устройства. Всего доступно 32256 байт.
    Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
    А теперь загрузите ваш скетч в симуляцию и посмотрите за сколько он меряет температуру. Мой протеус показывает что ваш вариант отрабатывает за 35 МИЛИсекунды, а мой за 11 МИКРОсекунд. Не буду лукавить, здесь у вас стопор в задержках а не в программе. Но мой вариант все же меньше занимает флеша и быстрее это факт.
     
    Aleksander1997 нравится это.
  14. Получается что так. Взять ту же «прожорливую» digitalWrite, проще прямого доступа к порту, есть даже защита от дурака, но не вижу смысла пользоваться этим, поскольку модуль max6675 подключил раз и потом нет особой необходимости менять пины. Если нужно повысить производительность кода 8 битных avr лучше отказаться от языка ардуино, и как вы верно подметили постараться переходить на си (https://habr.com/post/254163/)

    Убедился в том что вы правы по вопросу быстродействию. Но версия у меня 1.6.0 поскольку дисплей с I2C и корректно отображает показания только в этой и младших версиях, то компилятор этой версии считает что ваш больше весит. Но для меня экономия этих пары сотен байт не так важна как само быстродействие, спасибо
     

    Вложения:

    • 1.png
      1.png
      Размер файла:
      25,3 КБ
      Просмотров:
      662
  15. Dmitrysh

    Dmitrysh Гик

    Полностью вас поддерживаю, и как раз сейчас переписываю скетч не используя команды digital***
     
  16. SOLOway

    SOLOway Гик

    .... Вот 6320nc прям за несколько лет до того, как у меня получилось заметить, рассказал про некоторые особенности замера температуры тут ! И еще вот тут.
     
    Последнее редактирование: 1 июн 2018
    eugen545 нравится это.
  17. bamik

    bamik Нерд

    На счет быстродействия термодатчиков, а в частности РТ100 из документации. А нас интересует с какой скоростью прогревается термодатчик? При любых раскладах датчик к моменту измерения будет прогрет до температуры объекта. Важно время работы АЦП.
    У меня созрел в голове проект своей программы. Главные принципы: модульность, дискретизация во времени, целочисленные вычисления, приведение данных с датчиков в удобочитаемый вид только при выводе на экран.
    Что требуется:
    1) Библиотеки без контроля времени. Допускаются технологические задержки при работе с чипами.
    2) Точные времена работы АЦП.
    3) Другие тайминги для работы с периферией.
    Думаю создать для этого отдельную ветку. Пока показывать особо нечего. Могу скинуть только концептуальный скелет программы.
    Главная проблема программы, рассматриваемой в этой теме та, что это больше похоже на программу для компьютера, а не для контроллера. А контроллер - это устройство управления процессами. Процессы проходят во времени. А в текущей программе контроль за временем настолько завуалирован, что неизвестно, когда что выполняется. Автор внес кучу своих недочетов. Затем наслоилась деятельность последователей. И вот уже невозможно разобраться, почему у одних все работает, а у других нет.
    Предлагаю обобщить накопленный опыт и родить вариант, который будет легок для изменений под свое железо. Например, для вывода на экран, достаточно будет переписать модуль вывода на экран, а все переменные и признаки останутся неизменными. Соответственно, не потребуется что-то менять в других частях программы. Либо получение данных о температуре. Достаточно заменить модуль чтения данных с термопары на модуль чтения данных с РТ100.
    Вот прицепил скелет.
    Прошу высказаться на счет концепции. Стоит открыть новую ветку? Поддержите проект?
     

    Вложения:

    Последнее редактирование: 1 июн 2018
    Yojiq и CLON2 нравится это.
  18. eugen545

    eugen545 Нуб

    Я почитал по ссылкам. И задумался. Поставить алюминиевую плиту, в чем плюсы и минусы, какой лучше толщины и какой тогда лучше поставить НИ? Лежит просто 5 мм лист уже практически готовый под размер стола. Или все-таки лучше просто открытые кварцевые излучатели?
     
  19. SOLOway

    SOLOway Гик

    Я предпочел-бы их. С плитой может возникнуть большой гемор из-за конструкционных ошибок - http://monitor.net.ru/forum/viewtop...&sid=2d38422036a254b134582fc1dfb7471d#5511769 и http://monitor.net.ru/forum/viewtop...&sid=2d38422036a254b134582fc1dfb7471d#5512513
    Непонятно, как и чем надо греть плиту, чтоб этого избежать и какие соотношения размеров плиты к мощности нагревателей и скорости нагрева плиты ими считать правильными... В плане избежать вертолета плиты - больше подходит стеклокерамика от плит. Хотя, у самого 6320nc в станции две плиты, примерно в размер как такие же у термопрошного НП-3424 и их греют, кмк, два воздушных ТЭНа по 800Вт - у него плиты не коробит, иначе за долгое время существования его станций, народ ему давно навтыкал-бы :). Плиты, кстати по 5мм визуально.
     
    Yojiq и eugen545 нравится это.
  20. CLON2

    CLON2 Нерд

    У хороших "фирменных" датчиков в паспорте всегда пишут тепловую постоянную времени (время за которое датчик отработает изменение температуры). Это секунды как правило от 2 до 30с и более т.к. керамическая пластина с напылением платины находится в гильзе которая должна сама прогреться, прогреть термопасту и нагреть эту пластину. Но это для нашего применения не годится во первых по габаритам во вторых по цене в третьих по избыточности точности. Предлагаю остаться на термопарах ТХА, т.к. они дешевы и в бескорпусном исполнении имеют наибольшее быстродействие (только не совсем нравится МАХ6675 надо углубиться в постройку нормального преобразователя с хорошей точьностью, помехозащищенностью и повторяемостью) или уже переходить на пиродатчики. Согласен что датчик стопудово прогреется вместе с объектом т.к. тепловая инерционность объекта гораздо больше датчика. Время работы АЦП не сильно важно. Да чем меньше тем лучше (можно лучше отфильтроваться), но не критично.

    Да, тема немного "поплыла" из разброда и шатания MEGA, UNO, NANO LCD, TFT, итд .... плюс на недоделки начали тулить обмен с ПК. Надо это все упорядочить и складывать по веткам отдельно, т.к. в этом венегрете уже трудно что либо понять, может быть задействовать яндекс диск или гугл диск и сделать папки по направлениям. Подтянулись программисты и начали бороться за байты и биты все переводить в целочисленную математику и благодаря сдвиговым операциям делать код для "простого обывателя" (которых тут 97%) вообще не читаемым. По моему борьбу за быстродействие и байты надо начинать когда чего то из них уже не хватает, пока вроде все есть. А сейчас мне кажется, как Вы и предлагаете, в программе не хватает детерминизма и стройной понятной структуры. Я "ЗА" Ваши начинания по структурированию кода. Предлагаю перед написанием каждого модуля делать описания входных и выходных переменных и функций модуля. И не выкладывать код в котором нет соответствия этому описанию. Не плохо бы для начала нарисовать общую структуру проекта.

    Предложу одну библиотеку https://github.com/sadr0b0t/arduino-timer-api (с контролем времени ;)) для обеспечения детерминизма хотя бы ввода/вывода (можно забросить в топку схему контроля 0 за ненадобностью). Ловля обязательно первого полупериода в нашей задаче с большей инерционностью объекта совсем не к чему, а в остальном контроль 0 это просто синхроимпульс для подсчета времени работы нагревателя, не более. У нас не фазовое управление (хотя, было бы неплохо его реализовать особенно для верха (вот тут и пригодились бы сэкономленные наносекунды и биты для работы с аппаратным прерыванием каждые 10мС), но как я писал ранее, делать это надо на отдельном микроконтроллере, не может быть и "жесткое управление" с аппаратными прерываниями и визуализация на одном кристалле ). Так нашу задачу можно и от прерывания по таймеру делать результат будет тот же. https://habr.com/post/337430/
     
    Yojiq нравится это.