Sunteți pe pagina 1din 7

IMPLEMENTACION DE PID CON

ATMEGA8
LABORATORIO
PID y PWM Utilizando el lenguaje C en AVR studio6.

La idea es controlar / ajustar la temperatura deseada en un objeto mediante el control de


la velocidad del ventilador

#ifndef F_CPU
#define F_CPU 1000000UL // 1 MHz
#endif
#include <inttypes.h>
#include<avr/io.h>
#include<util/delay.h>
#include <avr/interrupt.h>

#define STEP_SIZE 0x0008


#define COUNTER_LOWER_LIMIT 0x0090
#define COUNTER_UPPER_LIMIT 0x00f8

//------global var
unsigned int prev_error = 0;
unsigned int Kp=1, Ki=0, Kd=0;
int p=0, i=0, d=0, PID = 0;
//------------------------A/D Coverter Function--------------------------

void adc_set(void)
{
ADCSRA |= (1 << ADPS1) | (1 << ADPS0); //1MHZ / div by 8 ADC prescaler = 125kHz ADC clk
ADMUX |= (1 << REFS0); // Set ADC reference to AVCC
ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading

// No MUX values needed to be changed to use ADC0

ADCSRA |= (1 << ADFR); // Set ADC to Free-Running Mode


ADCSRA |= (1 << ADEN); // Enable ADC
ADCSRA |= (1 << ADIE); // Enable ADC Interrupt
sei(); // Enable Global Interrupts
ADCSRA |= (1 << ADSC); // Start A2D Conversions
}
//-------------------------PID Function-----------------------------------
int pid_calc(int error)
{

p = Kp*error; //Proportional
i = Ki*prev_error; //Integral , will see if this part is usefull!****
d = Kd* (error - prev_error);//Derivative

PID = p+i+d; //SUMA DE TRES TERMINOS


prev_error = error; // guardar el valor de error ANTERIOR para ser utilizado por parte de derivada
_delay_ms(500);
return PID;
}

//--------------------------PWM Function-------------------------------------
void pwm (int duty)
{
OCR2 = duty; // Write to the Output ! (must indicate the pin)****
_delay_ms(1);
}
//---------------------------Main Function------------------------------------
int main ()
{
TCCR2 = 0x6A;
DDRB = 0x01;// PB0 (pin 5) output !
PORTB = 0x00; // SET ALL PINS TO ZERO
OCR2 = 0;
adc_set(); //call the A/D Converter Function
_delay_ms(100);
int reduced_temp = 64; // La retroalimentación se iniciará a partir 0degree pero el sistema (10-20)!
int error = 0;
int pwm_output = 128, sensor=0, tmp_sensor=0;
pwm(pwm_output); // Call DUTY CYCLE function (to Output!) at start

while(1)
{
ISR(ADC_vect)
ADMUX |= (1<<MUX0); // Switch to ADC1
_delay_ms(100); // waiting for the conversion !
tmp_sensor = ADCH;
_delay_ms(20);
sensor = tmp_sensor - reduced_temp;
ADMUX &= ~(1<<MUX0); // Switch to ADC0
_delay_ms(100);
desired = ADCH;
error = sensor - desired;
if(error <= 8)
{
_delay_ms(1000); // La retroalimentación se iniciará a partir 0degree pero el sistema (10-20)!
}
else
{
pwm_output = pid_calc(error); //pid function call
_delay_ms(100);
}

pwm(pwm_output); // Call DUTY CYCLE function (to Output!)


_delay_ms(50000); //
} //END While loop
return 0;
} //END Main()

S-ar putea să vă placă și