اطلاعیه

Collapse
No announcement yet.

کنترل دمای المنت با استفاده از pid

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    کنترل دمای المنت با استفاده از pid

    سلام دوستان وقت شما بخیر
    من قصد دارم یک هویه با قابلیت تنظیم دما بسازم
    منتهی به یک مشکل برخورد کردم ممنون میشم اگر کسی میتونه کمکم کنه
    مشکل این هست که وقتی دمای المنت از دمای set point بیشتر میشه طبق کدی که نوشتم باید تزریق پالس قطع بشه و گرم کردن المنت متوقف بشه ، ولی این اتفاق نمیفته و بعد از اینکه دمای المنت از دمای set point بیشتر شد همچنان حدود 80 ولت ولتاژ دو سر هویه وجود داره .
    من از اتمگا8 استفاده کردم و فرکانس سیستم رو 8 مگاهرتز داخلی گذاشتم
    از تایمر 1 استفاده کردم که 16 بیتی هست که در واقع دو رجیستر 8 بیتی هست .
    فرکانس تایمر رو 31/250 کیلو هرتز گذاشتم و time period روی 32/768 میلی ثانیه قرار گرفته(فکر میکنم مشکل از همین قسمت باشه) و روی مدFast PWM top=0x03FF قرار دادم .
    برای تست یک لامپ به جای هویه گذاشتم و زمانی که باید مدار دستور قطع تزریق پالس رو بده این اتفاق نمیفته و لامپ روشن میشه و پر پر میزنه .
    و اینکه عملکرد مدار گذر از صفر رو با اسیلوسکوپ چک کردم درست بوده ولی وقتی برش فاز رو با اسیلوسکوپ چک کردم به این صورت بود که توی یک سیکل سینوسی برش داشتیم و بعد حدود 4 تا شیف داشتیم و دوباره یه برش فاز رخ میداد ، درواقع باید توی هر نیم سیکل یک برش داشته باشیم ولی همچین چیزی مشاهده نمیشه
    برای سنسور دما هم از ترموکوپل max6675 استفاده کردم که به صورت سریال عمل میکنه .
    ممنون میشم اگر هر کسی میتونه کمکم کنه .
    کد رو هم قرار میدم

    [IMG][/IMG]


    /************************************************** ****************************
    Chip type : ATmega8A
    AVR Core Clock frequency: 8/000000 MHz
    ************************************************** ****************************/

    #include <mega8.h>
    #include <delay.h>
    #include <stdio.h>
    #include <alcd.h>

    //************************************************** ****************************

    float error;
    float last_error;
    float last_iterm;
    float kd=1;
    float kp=0.065;
    float ki=0.00000075;
    float pterm;
    float iterm;
    float dterm;
    float D;
    float tempsetflt;
    float adcavg;
    unsigned int AmpliOFT;
    unsigned int AmpliNXT;
    unsigned int Duty;
    unsigned int LOOP;
    unsigned int adcsum;
    unsigned int tempset;
    unsigned int tempsetFIX=10;
    unsigned int adcval;
    unsigned int LD;
    unsigned int HD;
    char lcd_buff[16];
    unsigned int temp=0;
    unsigned int temperature=0;
    unsigned int temperatureMAX=0;
    int i=0;
    float FLTemp;

    //************************************************** ****************************

    #define CS PORTB.3
    #define SO PINB.4
    #define SCK PORTB.5

    //************************************************** ****************************

    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    OCR1BH=HD;
    OCR1BL=LD;
    }

    //************************************************** ****************************

    #define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<ADLAR))

    unsigned int read_adc(unsigned char adc_input)
    {
    ADMUX=adc_input | ADC_VREF_TYPE;
    delay_us(10);
    ADCSRA|=(1<<ADSC);
    while ((ADCSRA & (1<<ADIF))==0);
    ADCSRA|=(1<<ADIF);
    return ADCW;
    }

    //************************************************** ****************************

    void main(void)
    {
    // Port B initialization
    // Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=Out Bit2=Out Bit1=Out Bit0=In
    DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (0<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (0<<DDB0);
    // State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=0 Bit2=0 Bit1=0 Bit0=T
    PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 31/250 kHz
    // Mode: Fast PWM top=0x03FF
    // OC1A output: Inverted PWM
    // OC1B output: Non-Inverted PWM
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer Period: 32/768 ms
    // Output Pulse(s):
    // OC1A Period: 32/768 ms Width: 32/768 ms
    // OC1B Period: 32/768 ms Width: 0 us
    // Timer1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=(1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10);
    TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<TOIE0);

    // External Interrupt(s) initialization
    // INT0: On
    // INT0 Mode: Rising Edge
    // INT1: Off
    GICR|=(0<<INT1) | (1<<INT0);
    MCUCR=(0<<ISC11) | (0<<ISC10) | (1<<ISC01) | (1<<ISC00);
    GIFR=(0<<INTF1) | (1<<INTF0);

    // ADC initialization
    // ADC Clock frequency: 125/000 kHz
    // ADC Voltage Reference: AREF pin
    ADMUX=ADC_VREF_TYPE;
    ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
    SFIOR=(0<<ACME);

    // Alphanumeric LCD initialization
    // Connections are specified in the
    // Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
    // RS - PORTD Bit 0
    // RD - PORTD Bit 1
    // EN - PORTD Bit 3
    // D4 - PORTD Bit 4
    // D5 - PORTD Bit 5
    // D6 - PORTD Bit 6
    // D7 - PORTD Bit 7
    // Characters/line: 16
    lcd_init(16);

    //************************************************** ****************************

    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Di SOLDERING PID");

    //************************************************** ****************************

    for(LOOP=0;LOOP<15;LOOP++)
    {
    CS=0;
    temp=0;
    for(i=15;i>=0;--i)
    {
    SCK=1;
    if(SO==1) temp|=(1<<i);
    SCK=0;
    }
    CS=1;
    temp=temp/8;
    FLTemp=(float)(temp)*0.25;
    if(FLTemp>0.0&FLTemp<600.0) temperature=FLTemp;
    delay_ms(50);
    }

    //************************************************** ****************************
    //************************************************** ****************************
    //************************************************** ****************************

    while (1)
    {
    adcsum=0;
    for(LOOP=0;LOOP<60;LOOP++)
    {
    adcval=read_adc(0);
    adcsum=adcsum+adcval;
    }
    adcavg=adcsum/60.0;
    tempsetflt=adcavg/2.5575;
    tempset=tempsetflt;
    if(tempset<1) tempset=1;
    if(tempset>400) tempset=400;
    if((tempset>(tempsetFIX+1))|(tempset<(tempsetFIX-1)))
    {
    tempsetFIX=tempset;
    AmpliOFT=0;
    AmpliNXT=0;
    temperatureMAX=0;
    }

    //************************************************** ****************************

    lcd_gotoxy(0,0);
    lcd_putsf("Di SOLDERING PID");
    sprintf(lcd_buff,"SP:%iC ",tempsetFIX);
    lcd_gotoxy(0,1);
    lcd_puts(lcd_buff);
    sprintf(lcd_buff,"TP:%iC ",temperature);
    lcd_gotoxy(8,1);
    lcd_puts(lcd_buff);

    //************************************************** ****************************

    // Global disable interrupts
    #asm("cli")
    CS=0;
    temp=0;
    for(i=15;i>=0;--i)
    {
    SCK=1;
    if(SO==1) temp|=(1<<i);
    SCK=0;
    }
    CS=1;
    temp=temp/8;
    FLTemp=(float)(temp)*0.25;
    if(FLTemp>1.0&FLTemp<600.0) temperature=FLTemp;
    // Global enable interrupts
    #asm("sei")
    delay_ms(300);

    //************************************************** ****************************

    if(temperature>0)
    {
    if(temperature<=tempsetFIX)
    {
    error=tempsetFIX-temperature;
    pterm=kp*error;
    iterm=(ki*error)+last_iterm;
    dterm=(error-last_error)*kd;
    D=(pterm+iterm+dterm)*100.0;
    if(temperature>temperatureMAX) temperatureMAX=temperature;
    if(temperature<temperatureMAX-1) AmpliOFT=1; // TAQVIATE PULSE BAD AZ OFTE DAMA
    if(AmpliOFT==1 | AmpliNXT==1) D=D*12.0; // TAQVIATE PULSE
    if(D<1.0) D=1.0;
    if(D>999.0) D=999.0;
    Duty=D;
    HD=Duty/256;
    LD=Duty%256;
    last_iterm=iterm;
    last_error=error;
    }
    else
    {
    HD=0x00;
    LD=0x00;
    PORTB.2=0;
    AmpliNXT=1; // TAQVIATE PULSE BAD AZ ROSHAN SHODANE MOJADAD
    }
    }

    }
    }

    //************************************************** ****************************
    //************************************************** ****************************
    //************************************************** ****************************




    #2
    پاسخ : کنترل دمای المنت با استفاده از pid

    دوستان کسی نمیتونه کمک کنه ؟

    دیدگاه

    لطفا صبر کنید...
    X