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сек, а не каждую секунду.
Понял. Спасибо! Буду пробовать