Страница 1 из 1

ПИД-регулирование

Добавлено: Пт июл 15, 2011 12:41:27
ARM7
Задача у меня такая стоит-нужно сделать регулятор оборотов ДВС,привод-двигатель от стеклоочистителя будет крутить заслонку карбюратора,управа-МК AVR.Покажите какой-нибудь код на си с пид-регулированием.

Re: ПИД-регулирование

Добавлено: Пт июл 15, 2011 15:59:10
clawham

Код: Выделить всё


// переменные пида

#define P_Factor     4

#define I_Factor     3

#define D_Factor     3

signed long int error       =0;
signed long int SumError    =0;

long int temp               =0;
char i;

int lastProcessValue=0;

long int p_term     =0;
long int i_term     =0;
long int d_term     =0;

long int maxerror = (long int)(1024)<<PWMoutPresc;





Код: Выделить всё


                            error       = IsetInput-IInput;
                            if(error>1024)
                                error=1024;
                            if(error<-300)
                                error=-300;
                               
                            if(SumError>(maxerror))
                                SumError=(maxerror);
                           
                            if(SumError<(0-(maxerror)))
                                SumError=0-(maxerror);                                 
                           
                            SumError      += error;
                            //SumError    = temp;
                            if(SumError>maxerror*I_Factor)
                                SumError=maxerror*I_Factor;       
                           
                            i_term      = I_Factor * SumError;
                           
                            //i_term=i_term>>4;
                                         
                            p_term = P_Factor * error;
                           
                            d_term      = D_Factor * (lastProcessValue - IInput);
                               
                            lastProcessValue = IInput;

                            //PWMoutTemp  = (p_term + i_term + d_term);
                            temp = p_term + i_term + d_term;
                           
                            if(temp>(maxerror))
                                temp=(maxerror);
                            if(temp<(240<<PWMoutPresc))
                                temp=240<<PWMoutPresc;
                                                 
                            PWMoutTemp=temp;



Re: ПИД-регулирование

Добавлено: Пт июл 15, 2011 16:03:49
clawham
собственно исходный код регулятора тока двигателя через сигнал для сервопривода .... там в папке @Design@ есть апноут АВРовский

http://clawham.hopto.org/DriveD/PubD/67/31_moped.rar

если надо ПИД - разберетесь....только вот зачем Вам пид....для ДВСа достаточно и простого "перелет - уменьшаем / недолёт - увеличиваем"

Re: ПИД-регулирование

Добавлено: Пт июл 15, 2011 17:41:42
ARM7
clawham писал(а):для ДВСа достаточно и простого "перелет - уменьшаем / недолёт - увеличиваем"

Спасибо за код, наверно вы правы,достаточно будет наверно и простого алгоритма как вы написали.

Re: ПИД-регулирование

Добавлено: Вс июл 17, 2011 00:11:08
maglev
clawham писал(а):зачем Вам пид....для ДВСа достаточно и простого "перелет - уменьшаем / недолёт - увеличиваем"

Если уменьшаем/увеличиваем, то это не релейное управление, а вполне себе пропорциональное. Тот-же ПИД, с нулевыми И- и Д- составляющими. Работает.

Re: ПИД-регулирование

Добавлено: Вс июл 17, 2011 08:33:04
phanis
Иногда достаточно изменить угол опережения зажигания. Но только если нагрузка на ДВС не сильно изменяется..

Re: ПИД-регулирование

Добавлено: Пн июл 18, 2011 14:47:22
ARM7
Нагрузка меняется сильно-это для двигателя минитрактора.

Re: ПИД-регулирование

Добавлено: Вт июл 19, 2011 00:04:14
demiurg301
Есть у меня код, но только для каллорифера. Впринципе ПИД регулирование вещь несложная, а вот подбор П, И, Д коэфициентов уже нетривиальная задача если нет модели или практически подобрать коэффициенты нельзя. Тогда придёться снимать модель ОУ.
Завтра выложу, там кода на 20 строчек то. Коэффициенты поменяете - может заработает.

И ещё а вы уверены что вам подойдёт ПИД регулятор? Есть куда более новые виды регуляторов для спец. задач.

Re: ПИД-регулирование

Добавлено: Вт июл 19, 2011 05:27:57
ARM7
demiurg301 писал(а):если нет модели или практически подобрать коэффициенты нельзя.

Настраивать буду конечно на реальном двигателе, достаточно будет наверно пид-алгоритма, жду вашего кода тоже, наберу инфы,потом за железо возьмусь, там еще проблемка-какой привод поставить на управление дросселем карбюратора,пока вариант-мотор-редуктор от стеклоочистителя,но хотелось бы помалагабаритнее что-нибудь.

Re: ПИД-регулирование

Добавлено: Вт июл 19, 2011 08:12:48
clawham
kbxyj я думаю что в первую очередь нужно озаботиться качественным фильтрованием и подготовной сигнал адля ПИД регулятора(не любит он помех и латентности) поэтому наверное сначала стоило бы погуглить альфа-бета фильтр....ну или калмана...там тож не сложно...
ну и система сбора данных...чем вы будете мерять обороты двигателя? скорее всего стоило бы выйти на высокие частоты - например насадить на вал мотора колёсико от мышки и оттуда же оптопару взять...получите очень много импульсов даже на минимальных оборотах...как следствие - минимальную погрешность(высокие частоты мерять проще) и очень низкую латентность...

Re: ПИД-регулирование

Добавлено: Вт июл 19, 2011 09:00:55
demiurg301

Код: Выделить всё


//ОБЯЗАТЕЛЬНО ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
float Tz=22; \\значение заданной температуры
float Tt;\\значение текущей температуры
float Tp=0;\\значение предидущего измерения температуры температуры
float Ui=0;\\значение интегральной составляющей
float Up=0;\\значение пропорциональной составляющей
float Ud=0;\\значение дифференциальной сосставляющей

// функция нормирования управляющей величины- нужна для того чтобы загнать упралвение в рамки 0-100%
// Может меняться в зависимости от используемых составляющих регулятора.
// Также в ней "обнуляется" интегратор.
unsigned char normalizer(float U)
{
unsigned char result;
if (U>100){result=100;Ui=100;}; //обрезаем по MAX управления
if (U<0){result=0;Ui=0;};//обрезаем по MIN управления
if ((U>=0)&&(U<=100)){result=(unsigned char)U;}; // не трогаем, значение в возможных пределах
return result;
};

//Функция ПИД регулятора


unsigned char PID(float Ttec,float Tzad)
{
float dT;
unsigned char result;
float reg;
float Kp=0.8;
float Ki=0.1;
float Kd=0.05;
dT=Tzad-Ttec;
if (fabs(dT)>0.1) //Гистерезис на 0.1*С
        {
        if (Tzad>Ttec)  { //определяем тип управления , либо греть, либо охлаждать(выключить нагреватель).
                        Ud=Kd*(Ttec-Tp);
                        Ui=Ui+Ki*dT;
                        Up=Kp*dT;
                        reg=Up+Ui+Ud;
                        result=normalizer(reg);
                        }
                        else
                        {
                        Ud=Kd*(Ttec-Tp);
                        Ui=Ui+Ki*dT;
                        Up=Kp*dT;
                        reg=Up+Ui+Ud;
                        result=normalizer(reg);
                        };
        }
        else
        {
        // Тут присваиваеться (N-1) значение управляющей величины если текущая температура не вышла за границу Tz+\-гистерезис
        result=PWM_LEVEL;//значение ШИМ.
        };       
Tp=Tz//сохранение текущего как предидущего для работы Д составляющей
return result; 
};


Думаю вы без особого труда сможете переделать код под другое управление и регулируемую величину. Может придёться ввести свои куски кода для активного изменения величны во всех ветвях. Для этого поменяйте функцию normalizer.

Re: ПИД-регулирование

Добавлено: Вт июл 19, 2011 20:35:49
ARM7
clawham писал(а):ма сбора данных...чем вы будете мерять обороты двигателя? скорее всего стоило бы выйти на высокие частоты - например насадить на вал мотора колёсико от мышки

Хм,нежелательно допольнительное что то вешать-сигнал будет браться с датчика холла с трамблера,хотя ваши слова о высоких частотах меня вводят в размышление-так конечно лучше и точнее-но все таки хочется обойтись стандартными как говорится средствами-но время покажет.
demiurg301-спасибо-думаю без особого труда переделаю для управления реверсом двигателя,но конечно в любом случае как всегда надо будет пошевелить извилинами :)

Re: ПИД-регулирование

Добавлено: Вт июл 19, 2011 21:16:36
demiurg301
Не забудте, что период дискретности вашей САУ должен быть меньше постоянной времени переходного процесса вашего ОУ. Хотя бы раза в 3 . Иначе вместо регулирования получите автоколебательный процесс или вообще раскачаете СУ и сломаете чего нибудь. Для меня критично не было - переходные процессы по температуре длятся минуты-часы. Для сервоприводов,двигателей - это сотни миллисекунд - секунды.
Поэтому когда будете выбирать сервопривод для заслонки - смотрите на частотные характеристики. А если есть возможность снимите хотябы статику с двигателя, чтобы примерно прикинуть коэффициенты.

переделаю для управления реверсом двигателя


перечитал , может всётаки управления оборотами? К реверсу то как вы ПИД прицепите ?

Re: ПИД-регулирование

Добавлено: Ср июл 20, 2011 11:28:48
ARM7
demiurg301 писал(а):может всётаки управления оборотами? К реверсу то как вы ПИД прицепите ?

result-это с какой скоростью крутить моторчик привода значит, а ещё нужно -в какую сторону крутить с такой скоростью, это имел ввиду.

Re: ПИД-регулирование

Добавлено: Чт сен 15, 2011 18:49:28
sachok
demiurg301
можете разъяснить по коду.

Код: Выделить всё

result=PWM_LEVEL;//значение ШИМ.

я так понял что здесь мы читаем текущее значений ШИМ (например от 0 до 1023) или коэффициент заполнения (0-100%)???

Код: Выделить всё

return result;

здесь мы возвращаем результат функции ПИД от 0 до 100.

Не могу понять как связать результат работы ПИД с заполнением ШИМ.
Буду делать терморегулятор, диапазон температур 20 - 250 градусов, мерять температуру буду термопарой и оцифровывать с помощью ОУ и АЦП. В функции ПИД есть две переменные - заданная температура и текущая, что мне туда подставлять реальную температуру или результат АЦП?

Re: ПИД-регулирование

Добавлено: Пт сен 16, 2011 13:31:21
demiurg301
sachok писал(а):demiurg301
можете разъяснить по коду.

Код: Выделить всё

result=PWM_LEVEL;//значение ШИМ.

я так понял что здесь мы читаем текущее значений ШИМ (например от 0 до 1023) или коэффициент заполнения (0-100%)???

Код: Выделить всё

return result;

здесь мы возвращаем результат функции ПИД от 0 до 100.



Да, там мы читаем старое значение потомучто текущее значение не вышло за пределы гистерезиса 0.1*С.

PWM_LEVEL и выход функции - это проценты 0-100.

Моя вина, не всю функцию выложил, звиняюсь:
Вот та часть которая у меня реализует сам шим.

Код: Выделить всё

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFh

#define PWM_OUT PORTB.0
unsigned int PWM_CNT=0;
unsigned int PWM_LEVEL=0;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
PWM_CNT++;
if (PWM_CNT==1000){PWM_CNT=0;PWM_OUT=1;};
if (PWM_CNT==(PWM_LEVEL*10)){PWM_OUT=0;};
//  тут период шим 1с - период таймера 1мс, множу значение  PWM_LEVEL на 10 - получаю число от 0 до 1000 , с которым сравнивается текущее значение счётчика, если совпало  - переводим в "0", если совпало с 1000 - переводим в "1".
TCNT0=131;
TCCR0=0x03;
}

тактовая 8MГц. Если хотите можете переделать под промиле, вместо процентов. Практика показывает для терморегулятора - нет смысла...

Не могу понять как связать результат работы ПИД с заполнением ШИМ.
Буду делать терморегулятор, диапазон температур 20 - 250 градусов, мерять температуру буду термопарой и оцифровывать с помощью ОУ и АЦП. В функции ПИД есть две переменные - заданная температура и текущая, что мне туда подставлять реальную температуру или результат АЦП?


Заполнение шим сверху. Выбираете период ШИМ, а потом приводите значения процентов или промиле к реальным физическим значениям тактов или счётчика.
Лучше всего в пид регулятор заводить температуры, учитывая что регулируемая величина( выходная температура) должна быть измерена минимум на полпорядка-порядок точнее, иначе получите "биения".
Термопару я бы вам рекомендовал заменить на PT500-PT1000, т.к. проще подобрать калибровочные коээфициенты - по таблице и магазину сопротивлений - 2-3 класа точности.

Re: ПИД-регулирование

Добавлено: Вс сен 18, 2011 10:02:56
sachok
Спасибо! Теперь стало ясней)