Activity
Попытался реализовать ПИД-регулятор
Основная часть программы:
// требуемая скорость
#define Target 100
// коэффициент пропорционального усиления
#define Kp 5
// коэффициент интегрального усиления
#define Ki 0.3
// коэффициент дифференциального усиления
#define Kd 5
// максимальная сумма ошибок
#define MaxIntegral 1000
volatile signed int Error; // отклонение измеренной величины от заданной
volatile signed int PrevValue; // предыдущее значение измерения
volatile signed int P_Term; // пропорциональный компонент
volatile signed int I_Term; // интегральный компонент
volatile signed int D_Term; // дифференциальный компонент
volatile signed int Out; // управляющее воздействие
volatile signed int Integral; // сумма ошибок
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
Perepol++;
}
// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
TCNT1H=0xF78F >> 8;
TCNT1L=0xF78F & 0xff;
// Place your code here
VMH=Perepol;
VML=TCNT0;
Error = Target - TCNT0;
P_Term = Kp * Error;
if (Integral > MaxIntegral) {Integral = MaxIntegral;}
else if (Integral < - MaxIntegral) {Integral = - MaxIntegral;}
else Integral += Error;
I_Term = Ki * Integral;
D_Term = Kd * (PrevValue - TCNT0);
PrevValue = TCNT0;
Out = P_Term + I_Term + D_Term;
if(Out > 0xFF) { OCR2 = 0xFE; }
else if(Out < 0) { OCR2 = 0;}
else OCR2 = Out;
pwm=OCR2;
TCNT0=0;
Perepol=0;
}
В принципе кое-как работает, но слишком медленно стабилизируется и есть колебания.
Возможно стоит производить измерения скорости между импульсами с энкодера.
Если у кого есть подобный проект в Proteus с исходниками, то не могли бы вы его выложить для изучения на примере.
Добрый день.
Пытаюсь сделать простой регулятор скорости с обратной обратной связью от энкодера на Atmega8535 в Proteus.
Управление мотором через ШИМ от 2-го таймера.
Измерение скорости осуществляю подсчетом импульсов от энкодера (300 имп/об) за 0.05с таймером Т0 (до 1000 об/мин).
промежуток 0.05с формирую по прерыванию сравнения от таймера T1. В этом же прерывании произвожу корректирование скорости:
VM=TCNT0;//полученная скорость за 0.05 (до 250 если скорость <1000 об/мин)
VF=ADCH;//нужная скорость задаем с потенциометра на АЦП
if (VF>VM)
{
ER=VF-VM;
PWM=PWM+ER;
ER=0;
};
if (VF<VM)
{
ER=VM-VF;
PWM=PWM-ER;
ER=0;
};
OCR2=PWM;
Работает крайне неважно - скорость постоянно колеблется с огромной ошибкой. Я новичек в вопросе управления и регулирования. 😃
Подскажите как лучше программно реализовать измерение скорости и регулирование в данном случае.