Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Вот код...

Отправлено dm37 31 марта 2008 г. 13:21
В ответ на: Если управляющее воздействие идет в противоположном направлении - что-то тут не так. Обычный ПИД с обычными объектами так не умеет. отправлено Oldring 31 марта 2008 г. 13:06

void ControlConditioner(void)
{
unsigned char i;
unsigned char ctrl_cond_heat; // регистр управления кондиционерами нагрева
unsigned char ctrl_cond_cold; // регистр управления кондиционерами охлаждения
unsigned char num_hall;
unsigned int temp_hall;
unsigned int ust_hall;
signed int period;
signed int curr_error;
signed int last_error;
signed int ki_error;
signed long y;
signed long yp;
signed long yi;
signed long yd;

for(i=0;i<MAX_COND;i++)
{
num_hall = CondSens[i];
temp_hall = TempSens[num_hall + MAX_COND];
ust_hall = UstTempHall[num_hall];
last_error = PIDLastError[i];
ki_error = PIDIError[i];

// вычисляем ошибку
curr_error = ust_hall - temp_hall;
// обработка обрыва датчика и мертвой зоны
if((temp_hall == ERROR_SENS) ||
((temp_hall >= (ust_hall - DeadZone)) && (temp_hall <= (ust_hall + DeadZone))))
{
y = 0;
ki_error = 0;
}
else
{
// вычисляем П-коэффициент
yp = PIDCoeffs[0] * curr_error;
if(yp > LIMIT_Y) yp = LIMIT_Y;
if(yp < -LIMIT_Y) yp = -LIMIT_Y;
// вычисляем И-коэффициент
ki_error += curr_error;
yi = PIDCoeffs[1] * ki_error;
if(yi > LIMIT_Y) yi = LIMIT_Y;
if(yi < -LIMIT_Y) yi = -LIMIT_Y;
// вычисляем Д-коэффициент
yd = PIDCoeffs[2] * (curr_error - last_error);
if(yd > LIMIT_Y) yd = LIMIT_Y;
if(yd < -LIMIT_Y) yd = -LIMIT_Y;
// вычисляем полную мощность
y = (yp + yi + yd)/SCALE_FACTOR;
// ограничение мощности
period = Period/2;
if(y > period) y = period;
if(y < -period) y = -period;
}

// запрещаем работу кондиционеров
ctrl_cond_cold &= ~MaskCond[i];
ctrl_cond_heat &= ~MaskCond[i];
// включаем нагрев
if(y > 0) ctrl_cond_heat |= MaskCond[i];
// включаем охлаждение
if(y < 0) ctrl_cond_cold |= MaskCond[i];

if(y < 0) y = -y;
WorkPeriod[i] = y;
PIDIError[i] = ki_error;
PIDLastError[i] = curr_error;
}
RelaysHeat = ctrl_cond_heat; // включить кондиционеры нагрева
RelaysCold = ctrl_cond_cold; // включить кондиционеры охлождения
}


Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

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

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru