Программно аппаратный комплекс сбора данных


Что делать, если нужно регулировать мощную нагрузку?

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

Гальваническая развязка MCP3201 оптопарами. Atmega 8

Гальваническая развязка COM порта ШИМ, питание.

Независимое управление с ПИД регулятора. Компьютер может принимать данные:

1. Температуру с АЦП

2. Напряжение на регуляторе.

3. Скважность ШИМ.

На микроконтроллер поступают установки необходимой температуры, далее он ее поддерживает самостоятельно.

Кусок кода с микроконтроллера ATmega 8. Усреднение за 5 периодов.

Чтение данных с АЦП MCP3201 в atmega8:

...
#define ACP_DDR		DDRD
#define ACP_Dout 	PD4 // вход
#define ACP_Scl_On  PORTD |=(1<<PD6); // 1
#define ACP_Scl_Off PORTD &=~(1 << PD6); //0
#define ACP_Cs_On  PORTD |=(1 << PD5);
#define ACP_Cs_Off PORTD &=~(1 << PD5);
...
void acp_mcp3201 (void){
ACP_Cs_Off;
ACP_Scl_Off;
mpc3201_TMP=0;
_delay_us(TIME_CICLE_MCP3201);
ii=0;
ACP_Scl_On;
_delay_us(TIME_CICLE_MCP3201);
// 2й импульс
ACP_Scl_Off;
_delay_us(TIME_CICLE_MCP3201);
ACP_Scl_On;
_delay_us(TIME_CICLE_MCP3201);
// 3й импульс
ACP_Scl_Off;
_delay_us(TIME_CICLE_MCP3201);
ACP_Scl_On;
_delay_us(TIME_CICLE_MCP3201);
// читаем разряд порта с Dout, должен быть 0.
if (bit_is_clear(PIND, ACP_Dout)) // 0?
{// все ок.
// основной цикл чтения 12 разр. в переменную.
while (ii<12){
ACP_Scl_Off;
_delay_us(TIME_CICLE_MCP3201);
ACP_Scl_On;
_delay_us(TIME_CICLE_MCP3201);
// тут читаем.
mpc3201_TMP<<=1;
if (!(bit_is_clear(PIND, ACP_Dout))){ // 0?
mpc3201_TMP |= 1;
}
ii++;
}
LED_1; // помигаем светодиодом.
} else {buff_error[3]=ii;}
mpc3201=mpc3201_TMP;
ACP_Cs_On;
ACP_Scl_On;
// в цикле заносим в массив, для вычисления среднего.
ii_int_cikl=0;
while (ii_int_cikl < 4){
sma_mpc3201[ii_int_cikl]=sma_mpc3201[ii_int_cikl+1];
ii_int_cikl++;
}
sma_mpc3201[4]=mpc3201;
ii_int_cikl=0;
mpc3201_TMP=0;
//вычисляем среднее
while (ii_int_cikl < 5){
mpc3201_TMP+=sma_mpc3201[ii_int_cikl];
ii_int_cikl++;
}
if (mpc3201_TMP<=0) {sma_mpc3201_out=0;} else sma_mpc3201_out=mpc3201_TMP/5; // среднее значение, за 5 периодов.
}

ПИД регулятор:

void pid_regulator (void) {
Error = Target - mpc3201;
P_Term = Kp * Error;
if (Integral > MaxIntegral) {Integral = MaxIntegral;}
else if (Integral < - MaxIntegral) {Integral = - MaxIntegral;}
else Integral += (Error);
I_Term = (Ki * Integral);
if ((I_Term > 0) & (I_Term < 0)) I_Term=I_Term/100;
D_Term = Kd * (PrevValue - mpc3201);
PrevValue = mpc3201;
// проверка
//PrevValue++;
//Integral++;
Out = (P_Term + I_Term - D_Term);
if(Out > 0xFF) { OCR2 = 0xFF; }
else if(Out < 0) { OCR2 = 0; Out=0;}else if(Out == 0) { OCR2 = 0;}
else OCR2 = Out;
// в цикле заносим в массив, для вычисления среднего.
sma_OCR2[3]=sma_OCR2[4];
sma_OCR2[2]=sma_OCR2[3];
sma_OCR2[1]=sma_OCR2[2];
sma_OCR2[0]=sma_OCR2[1];
sma_OCR2[4]=Out;
//вычисляем среднее
ii_int_cikl=0;
mpc3201_TMP=0;
mpc3201_TMP=sma_OCR2[4];
mpc3201_TMP=mpc3201_TMP+sma_OCR2[3];
mpc3201_TMP=mpc3201_TMP+sma_OCR2[2];
mpc3201_TMP=mpc3201_TMP+sma_OCR2[1];
mpc3201_TMP=mpc3201_TMP+sma_OCR2[0];
ii_int_cikl=0;
if (mpc3201_TMP==0) {
  sma_OCR2_out=0;
  } else if (mpc3201_TMP>=1275)
    {sma_OCR2_out=0xFF;} else {
    ii_int_cikl=mpc3201_TMP/5; // среднее значение, за 5 периодов.
    sma_OCR2_out=ii_int_cikl;
    }
}

Если кому нужно, опубликую полностью программу.

Ваше мнение

Используйте нормальные имена, комментарий будет опубликован после проверки.

Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий email. При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где вы сможете изменить свои данные, включая ник, описание, контакты и т.д., а также подписку на новые комментарии.

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

(обязательно)