Андрей Смирнов
Время чтения: ~12 мин.
Просмотров: 229

Термостат с регулировкой температуры до 1000 С° с помощью модуля MAX6675, реле и arduino.

терморегулятор.jpg

Задумал я сделать себе станок по изготовлению прутка пластика диаметром 1,75 мм  для печати на 3D принтере. И прокручивая в голове как это все будет выглядеть, изготовил “краник” состоящий из трубы 1/2″ и  заглушки с просверленным отверстием на 1,75 мм через который будет выдавливаться готовый пластик. Для этой трубы нашел нагревательные элементы, которые должны нагревать трубу до 200-250 градусов. Так как нагревательные элементы довольно простые, работающие как кипятильник у них нет регулировки по температуре, а мне же нужно держать заданную температуру. Для решил найти терморегулятор естественно пошел на Aliexpress и начал там искать подходящий. Там много “слабых” и дешевых терморегулятором, которые до 100C , но нашелся там терморегулятор и до 1000C и стоил он по моим меркам довольно много, вот ссылка: http://ali.pub/2wpnn1 Поэтому было решено сделать свой термостат. Для этого был закуплен модуль для термопары K типа MAX6675 и реле мощностью на 30A ( как раз для кипятильников)  ну и ардуинки у меня уже были закуплены на случай “апокалипсиса”. По цене это все мне обошлось довольно не дорого, так что это получился лучший вариант.

Приобрести все компоненты можно здесь:

arduino uno: http://ali.pub/2wpo97

Модуль термопары К типа max6675: http://ali.pub/2wpog0

Модуль реле: http://ali.pub/2wpp8l

LCD дисплей 16×2: http://ali.pub/2wppku

Итак все компоненты подключил по данной схеме:

Термостат-К-типа.jpg

Решил все это дело реализовать в программе FLProg.  Принцип работы будет следующий, на экране будет отображаться температура текущая измеренная термопарой К типа. С помощью кнопок мы сможем входить в меню и выбирать параметры температуры при которых реле будет включаться и выключаться. И еще можно будет выбрать Гистерезис температуры.

Блоки FLProg довольно тяжело описывать на сайте, поэтому я просто оставлю ссылку на проект в FLProg: https://yadi.sk/d/S3LleCYav6fQqA

Демонстрация работы в видео:

—>1 год назад

Начну с предыстории. Однажды мои родители, твердо решили жить в своём доме за городом. Недолго думая приобрели участок недалеко от города и в течении года там был построен дом. Но так как, мои родители всегда жили в городской среде, и переезд не обернулся разочарованием я решил, по мере своих возможностей, автоматизировать некоторые процессы управления дома и со временем превратить его в подобие «умного дома».

152874544811581240.jpg

Задумка амбициозная, объем работы колоссальный поэтому буду делать все поэтапно, и в конце все свяжу все в единую систему. Первым этапом будет отопление. Управлять им будет Arduino, это конечно не самый надёжный вариант, но для начала самое то. Тему надёжности я затрону отдельно.

Теперь к техническому вопросу. Газ не проведён, зато есть электричество — 3 фазы, поэтому отопление будет электрическим. Все нагревательные элементы равномерно распределим по фазам, чтобы избежать перекоса фаз. Зимы лютые бывают, в связи с этим мощность ТЭН должна быть с запасом, ну мало ли что.

Все должно работать так: измеряем температуру воздуха в помещении, сравниваем с заданной, и в зависимости от разницы на определённый промежуток времени включаем ТЭНы. Вроде бы все просто, но это не совсем так) трудности будем решать в программе, а для начала о железе.

Для управления отоплением выбрал плату Arduino, сердцем которой является восьми битный микроконтроллер ATmega328р, его с запасом хватит для данной задачи.

Для измерения температуры датчики: Dallas DS18B20 — это цифровые датчики температуры, их можно множество кидать на общую шину OneWire состоящего из одного провода (на датчик нужно подвести землю, питание по желанию:)), и с неплохой точностью измерять температуру. У каждого датчика есть свой уникальный адрес, и обращаясь по адресу получаем данные нужного датчика. Это очень удобно, и экономит порты контроллера.

Ввод и вывод информации осуществит LCD дисплей 16х2 символа, соединенный через i2с и 3 тактовые кнопки соединенные через делитель напряжения, для экономии пинов, и воткнутые в аналоговый вход. Почему именно три? Что бы сделать интуитивно понятное меню. Клиентоориентированность во плоти:).

Для управления нагрузкой нужно реле,электромеханические реле я посчитал не практичным и для тестирования из поднебесной заказал твердотельное реле, основой которой является симистор, который по факту рассчитан на ток вдвое меньше, чем написано на корпусе реле. Но в дальнейшем сделаю плату на которой распаяю более мощные симисторы BTA41-600B в паре с мс moc3361 которая внутри имеет оптопару для гальванической развязки, индикатор прохождения тока через ноль, и симисторный выход — полный фарш). А так же добавятся измерительные трансформаторы тока.

Для сравнения симисторы BTA41-600B в массивном корпусе TOP3 в сравнении с TO220 (Такой стоит в китайском реле)

В итоге все выглядит вот так подключил тепловентилятор на 2 кВт задал температуру, регулирует все отлично). Пока выглядит все на соплях, но для тестирования и отладки программы пойдет.

На этом пока все, в дальнейшем планирую написать про программу, изготовление платы и прочие модули, спасибо что дочитали)

PID РЕГУЛЯТОР НА ARDUINO

ПИД регулятор – мощный инструмент, позволяющий удерживать заданную величину (температура, скорость вала, положение) при помощи управляющего устройства (обогреватель, контроллер мотора, линейный привод). Вот отличная статья по теории, что такое ПИД регулятор, как он работает и как его настроить. А я предлагаю свою библиотеку для работы с PID на Arduino.

ПИД регулятор выдаёт на  выходе сигнал для плавного управления управляющим устройством (диммер, транзистор), если вам нужно реле – используйте библиотеку GyverRelay.

Алгоритм ПИД регулятора выглядит так, можете использовать его напрямую в скетче:

// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ  // величины регулятора  int setpoint = 0;   // заданная величина, которую должен поддерживать регулятор  int input = 0;      // сигнал с датчика (например температура, которую мы регулируем)  int output = 0;     // выход с регулятора на управляющее устройство (например величина ШИМ или угол поворота серво)  int pidMin = 0;     // минимальный выход с регулятора  int pidMax = 255;   // максимальный выход с регулятора    // коэффициенты  float Kp = 1.0;  float Ki = 1.0;  float Kd = 1.0;  float _dt_s = 0.1; // время итерации в секундах    // вспомогательные переменные  int prevInput = 0;  float integral = 0.0;    // ПИД  // функция расчёта выходного сигнала  int computePID() {    float error = setpoint - input;           // ошибка регулирования    float delta_input = prevInput - input;    // изменение входного сигнала    prevInput = input;    output = 0;    output += (float)error * Kp;                  // пропорционально ошибке регулирования    output += (float)delta_input * Kd / _dt_s;    // дифференциальная составляющая    integral += (float)error * Ki * _dt_s;        // расчёт интегральной составляющей    // тут можно ограничить интегральную составляющую!    output += integral;                           // прибавляем интегральную составляющую    output = constrain(output, pidMin, pidMax);   // ограничиваем выход    return output;  }

БИБЛИОТЕКА GYVERPID

GyverPID v2.2

pidLogo.png

Библиотека классического PID регулятора для Arduino

  • Быстрая и лёгкая библиотека
  • Время одного расчёта около 70 мкс
  • Режим работы по величине или по её изменению (для интегрирующих процессов)
  • На выбор целочисленная или float модель вычисления
  • Возвращает результат по встроенному таймеру или в ручном режиме

Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции)

ДОКУМЕНТАЦИЯ

Документация

Логика работы

ПИД регулятор принимает на вход две величины:

  • Входной сигнал input – сигнал с датчика: температура, скорость, положение, и т.д;
  • Установку setpoint – величина, к которой регулятор будет стараться регулировать входной сигнал (температуру, скорость, положение…)

С ПИД регулятора выходит выходной (управляющий) сигнал output – безразмерная величина, которая подаётся на управляющее устройство. Это может быть транзистор с ШИМ сигналом, диммер, сервопривод, и т.д. Выходной сигнал должен влиять на входной сигнал: нагреватель нагревает объект с датчиком температуры, мотор крутится и даёт значения для датчика оборотов, и т.д.

Закон управления регулятора устанавливается при помощи коэффициентов Kp, Ki и Kd. Kp – пропорциональный коэффициент, выходная величина будет увеличиваться пропорционально разнице входного сигнала и установки. Ki – коэффициент интегрирующей составляющей, отвечает за накапливающуюся ошибку, позволяет сгладить пульсации и нивелировать маленькую ошибку. Kd – коэффициент дифференциальной составляющей, отвечает за скорость изменения величины, позволяет уменьшить раскачку системы.

Инициализация

Можно инициализировать объект тремя способами:

  • GyverPID regulator;  // инициализировать без настроек (всё по нулям, dt 100 мс)
  • GyverPID regulator(kp, ki, kd);  // инициализировать с коэффициентами. dt будет стандартно 100 мс
  • GyverPID regulator(kp, ki, kd, dt);   // инициализировать с коэффициентами и dt (в миллисекундах)

Режимы и настройки

Направление регулирования: зависит от того, в какую сторону направляется управляемая величина (input) при увеличении управляющего сигнала (output). Например: охлаждение или нагрев, разгон или торможение, и т.д. По умолчанию стоит NORMAL – регулятор считает, что увеличение управляющего сигнала (output) увеличит входной сигнал (input). Устанавливается командой

setDirection(dir);   // dirNORMAL или REVERSE

Режим работы: режим регулирования по ошибке входного сигнала (ON_ERROR) или по изменению входного сигнала (ON_RATE). По умолчанию стоит ON_ERROR, его рекомендуется использовать в большинстве случаев, потому что большинство процессов – саморегулирующиеся (температура нагревателя сама установится в своём максимуме, скорость мотора – тоже). Режим ON_RATE рекомендуется использовать в интегрирующих процессах, в которых выходная величина влияет на скорость изменения входной величины, например положение моторизированного слайдера, который не остановится при управляющем сигнале, отличном от нуля. Таким процессом будет проще управлять в режиме ON_RATE. Устанавливается командой

setMode(mode);  // modeON_ERROR или ON_RATE

Пределы выхода: ограничение значения выходного сигнала, по умолчанию: 0-255 (для 8 бит ШИМ). Может быть установлено 0-180 для угла сервопривода, и т.д. Устанавливается командой

setLimits(min, max);  // установить пределы

Время итерации: время итерации можно изменить в процессе работы (не знаю, зачем, но возможность есть). Время устанавливается в миллисекундах и влияет на функцию getResultTimer, которая с этим периодом делает новый расчёт управляющего сигнала. Также это время входит в расчёт управляющего сигнала (в И и Д составляющей). Устанавливается командой

setDt(dt);  // установка времени итерации в мс

Установка/чтение параметров

Основные величины регулятора можно менять в любом месте программы любым удобным способом (кнопки, энкодер, передача через UART/GSM/WiFi, как угодно). Коэффициенты регулятора Kp, Ki и Kd можно устанавливать и читать напрямую как члены класса, например

regulator.Kp = 1.5;        // установить  regulator.Ki += 0.7;       // изменить  lcd.print(regulator.Kd);   // читать

Время итерации меняется при помощи метода setDt() (см. выше).

Величины регулятора (вход, установка, выход) также являются членами класса и к ним можно обратиться напрямую для чтения и записи:

regulator.input = 10;     // ВХОД регулятора, например текущая температура  regulator.setpoint = 20;  // УСТАНОВКА регулятора, например необходимая температура  analogWrite(regulator.output);  // ВЫХОД с регулятора можно подавать напрямую на ШИМ или серво

Тип вычислений

Библиотека имеет режим целочисленных вычислений. Скорость вычислений особо не меняется, но код занимает меньше места и всё-таки должен выполняться быстрее. По умолчанию стоит режим чисел с плавающей точкой, в заголовочном файле библиотеки смотрите ключевое слово datatype, datatype будет float или int в зависимости от настройки: это некоторые переменные и функции. Настройка осуществляется дефайном перед подключением библиотеки:

#define PID_INTEGER  #include "GyverPID.h"

Как работать с библиотекой?

Нужно скормить регулятору текущее значение величины в input, нужное значение в setpoint, провести расчёт при помощи getResult или getResultTimer, и после этого выходную величину output подать на управляющее устройство. Делать это нужно часто для быстрых процессов (стабилизация частоты оборотов шпинделя станка под нагрузкой: dt берём около 10-50 мс), и не очень часто для медленных процессов (удержание заданной температуры бойлера: dt можно взять пару секунд, процесс очень инерционный). Функция getResult делает расчёт в каждый свой вызов и возвращает output, а getResultTimer делает расчёт только при срабатывании встроенного таймера. То есть getResult нужно вызывать по своему таймеру (для продвинутых пользователей), а getResultTimer нужно вызывать как можно чаще, он посчитает только тогда, когда это будет нужно по своему таймеру. После расчёта можно подавать управляющий сигнал (выходную величину output) на управляющее устройство. Смотрите пример!

Как настроить коэффициенты?

Подбор коэффициентов ПИД регулятора – индивидуальная задача, зависящая от конкретных условий и “железа”. Можно почитать статьи на эту тему: например эту, вот эту попроще, и вот эту посложнее. Первым делом нужно установить dt – об этом я писал выше. Маленький dt для быстрых процессов и побольше для медленных (инертных). Dt влияет на расчёты при неизменных коэффициентах, поэтому dt лучше не менять во время настройки, чтобы не пришлось пересчитывать все остальные коэффициенты. Диапазон коэффициентов: 0.01 – 100, т.е. довольно широк и зависит напрямую от инертности системы и выбранного времени dt. Коэффициенты должны быть положительные, противоположное направление регулирования задаётся в setDirection.

Интегральная составляющая

В версии 2.1 интегральная составляющая вынесена в публичный доступ как член класса, к ней можно обратиться как regulator.integral. Интегральная составляющая суммирует ошибку по времени, и при слишком сильном накоплении может приводить к перерегулированию. Для наблюдения за её состоянием можно прочитать integral, и при необходимости например ограничить её диапазон (regulator.integral = constrain(regulator.integral, -50, 50);) или даже обнулить (regulator.integral = 0;).

Список функций и методов библиотеки из файла .h

// ==== datatype это float или int, в зависимости от выбранного (см. пример integer_calc) ====  GyverPID();  GyverPID(float new_kp, float new_ki, float new_kd, int16_t new_dt = 100);   // kp, ki, kd, dt    datatype setpoint = 0;     // заданная величина, которую должен поддерживать регулятор  datatype input = 0;        // сигнал с датчика (например температура, которую мы регулируем)  datatype output = 0;       // выход с регулятора на управляющее устройство (например величина ШИМ или угол поворота серво)    datatype getResult();      // возвращает новое значение при вызове (если используем свой таймер с периодом dt!)  datatype getResultTimer(); // возвращает новое значение не ранее, чем через dt миллисекунд (встроенный таймер с периодом dt)    void setDirection(boolean direction);    // направление регулирования: NORMAL (0) или REVERSE (1)  void setMode(boolean mode);              // режим: работа по входной ошибке ON_ERROR (0) или по изменению ON_RATE (1)  void setLimits(int min_output, int max_output);    // лимит выходной величины (например для ШИМ ставим 0-255)  void setDt(int16_t new_dt);              // установка времени дискретизации (для getResultTimer)    float Kp = 0.0;  float Ki = 0.0;  float Kd = 0.0;

ПРИМЕРЫ

Демо — все возможности библиотеки с комментариями

/*     Пример работы ПИД регулятора в автоматическом режиме по встроенному таймеру     Давайте представим, что на 3 пине у нас спираль нагрева, подключенная через мосфет,     управляем ШИМ сигналом     И есть какой то абстрактный датчик температуры, на который влияет спираль  */  #include "GyverPID.h"    GyverPID regulator(0.1, 0.05, 0.01, 10);  // коэф. П, коэф. И, коэф. Д, период дискретизации dt (мс)  // или так:  // GyverPID regulator(0.1, 0.05, 0.01);// можно П, И, Д, без dt, dt будет по умолч. 100 мс    void setup() {    regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL    regulator.setLimits(0, 255);    // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255    regulator.setpoint = 50;        // сообщаем регулятору температуру, которую он должен поддерживать      // в процессе работы можно менять коэффициенты    regulator.Kp = 5.2;    regulator.Ki += 0.5;    regulator.Kd = 0;  }    void loop() {    int temp;                 // читаем с датчика температуру    regulator.input = temp;   // сообщаем регулятору текущую температуру      // getResultTimer возвращает значение для управляющего устройства    // (после вызова можно получать это значение как regulator.output)    // обновление происходит по встроенному таймеру на millis()    analogWrite(3, regulator.getResultTimer());  // отправляем на мосфет      // .getResultTimer() по сути возвращает regulator.output  }  

УСТАНОВКА БИБЛИОТЕКИ

Если вы не знаете, как установить библиотеку – читайте отдельный урок по работе с библиотеками!

ОСТАЛЬНЫЕ БИБЛИОТЕКИ

libs-1.png

У меня есть ещё очень много всего интересного! Смотрите полный список библиотек вот здесь.

Используемые источники:

  • http://psenyukov.ru/термостат-с-регулировкой-температур/
  • https://pikabu.ru/story/kontroller_otopleniya_doma_na_arduino_5960701
  • https://alexgyver.ru/gyverpid/

Рейтинг автора
5
Подборку подготовил
Максим Уваров
Наш эксперт
Написано статей
171
Ссылка на основную публикацию
Похожие публикации