PID + AC = какая-то фигня. Подскажите, где ошибка.
- Войдите на сайт для отправки комментариев
Ср, 28/09/2022 - 12:24
Всем привет!
Пытаюсь настроить ПИД-регулятор на поддержку заданной температуры. В качестве нагревателя использую лампочку 220в через модуль с симистром.
Начинаю с настройки коэффициента на "P", но рост температуры ни то чтобы не образует волны, а даже не доходит до заданной и останавливается не доходя процентов 10. Коэф "P" поднимал до 100, результат ближе к заданному, но все равно не доходит до него и вообще никакого колебания нет.
График и фото прилагаю.
В чем моя ошибка?
#include <GyverPID.h> #include <PIDtuner.h> #include <PIDtuner2.h> GyverPID pid; #include <DS_raw.h> #include <microDS18B20.h> #include <microOneWire.h> MicroDS18B20 <A5> ds; #define ZERO_PIN 2 // пин детектора нуля #define INT_NUM 0 // соответствующий ему номер прерывания #define DIMMER_PIN 4 // управляющий пин симистора #include <GyverTimers.h> // библиотека таймера float dimmer; // переменная диммера int dt = 100; // помоему, нужен только для Ki void setup() { pid.Kp = 1; pid.Ki = 0; pid.Kd = 0; pid.setDt(dt); //частота опроса с датчика pid.setDirection(NORMAL); //работа на увеличение pid.setpoint = 60; //нужная температура pinMode(ZERO_PIN, INPUT_PULLUP); pinMode(DIMMER_PIN, OUTPUT); attachInterrupt(INT_NUM, isr, RISING); // для самодельной схемы ставь FALLING Timer2.enableISR(); Serial.begin(9600); } void loop() { temp(); pidControl(); } void temp() { static uint32_t timer = millis(); if (millis() - timer >= 1000) { timer = millis(); if (ds.readTemp()) { Serial.println(ds.getTemp()); } ds.requestTemp(); } } void pidControl() { static uint32_t tmr; if (millis() - tmr > dt) { tmr = millis(); pid.input = ds.getTemp(); // передаем новый измеренный сигнал с датчика pid.getResult(); //делает рассчеты, ее нужно вызывать по таймеру с периодом dt pid.output; //принимает значение управляющего сигнала dimmer = map(pid.output, 0, 125, 9300, 500); } } // прерывание детектора нуля void isr() { static int lastDim; digitalWrite(DIMMER_PIN, 0); // выключаем симистор // если значение изменилось, устанавливаем новый период // если нет, то просто перезапускаем со старым if (lastDim != dimmer) Timer2.setPeriod(lastDim = dimmer); else Timer2.restart(); } // прерывание таймера ISR(TIMER2_A) { digitalWrite(DIMMER_PIN, 1); // включаем симистор Timer2.stop(); // останавливаем таймер }
а прямо к лампочке прислонить?
или поставь -
pid.setpoint = 50;
//нужная температура
Лампочка осиливает температуру в 60 градусов. И 80 осиливает.
Если поставить 50 градусов, то будет доходить до ~45 и там останавливаться.
У тебя система настолько медленная, а опросы настолько частые, что колебаний ты не увидишь
Тут даже фазное регулирование ни к чему.
Тупо ШИМ организуй с периодом 0,1Гц и скважность регулируй с дискретностью 10мс.
как я понял, датчик температуры 18D20 чаще чем каждые 0,85 сек опрашивать бесполезно. Поэтому выставлено на 1 сек.
но какое-то решение должно же быть? как его найти?
как я понял, датчик температуры 18D20 чаще чем каждые 0,85 сек опрашивать бесполезно. Поэтому выставлено на 1 сек.
но какое-то решение должно же быть? как его найти?
Я же говорю, система медленная, а опросы слишком частые.
Пересчитыйвай, значение хотя бы раз в 10сек, а не каждую секунду.
Понял. Спасибо! Буду пробовать