欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3240|回復: 1
打印 上一主題 下一主題
收起左側

C語言PID控溫講解及源碼

[復制鏈接]
跳轉到指定樓層
樓主
ID:1037617 發表于 2022-6-30 08:41 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
參考資料:http://www.raoushi.com/bbs/dpj-181096-1.html

/*
功能:用軟件模擬PID控制溫度
模型一:夏天要求室內的溫度為23攝氏度左右,假定房間受室外高溫影響,1分鐘上升0.1攝氏度(上限為室外溫度37攝氏度)。
        釋放一包制冷劑可降低5攝氏度,一包制熱劑,可上升五度,溫度變化由傳感器采集,但是我用軟件模擬溫度變化,
        假設一切處于理想狀態。
*/

#include "SoftSimulation_PID_Header.h"

int main()
{
    init_PID();

    time_t timep;
    struct tm *tp;
   
    while (1)
    {
        if (pid.ActualTemperature < outdoorTemperature)
        {
            // 獲取時間
            time(&timep);
            tp = gmtime(&timep);

            AcquireTemperature(tp->tm_hour,tp->tm_min,tp->tm_sec);
        }

        PID_controlTemperature();

        /* 當溫度處于人體舒適的溫度時,則不用制冷或加熱 */
        while (fabs(pid.SetTemperature - pid.ActualTemperature) < ComfortTemperature)
        {
            // 獲取時間
            time(&timep);
            tp = gmtime(&timep);
            
            // 獲取計算機時間,10秒鐘打印一次
            printf("%d/%d/%d %d/%d/%d\n",1900+tp->tm_year,(1+tp->tm_mon),tp->tm_mday,tp->tm_hour + 8, tp->tm_min,tp->tm_sec);
            printf("Display:設定溫度為:%.2f\t室內溫度為:%f\t\n\n", pid.SetTemperature, pid.ActualTemperature);            
               
            // 獲取實時溫度            
            AcquireTemperature(tp->tm_hour, tp->tm_min, tp->tm_sec);
            
            Sleep(500);            
        }
    }
}

/* Acquire indoor Temperature */
void AcquireTemperature(int hour,int minute,int second)
{
    static int lastTime[3] = { 0 };
    static float Minute = 0;
    if (!lastTimeFlag )
    {
        lastTime[0] = hour;
        lastTime[1] = minute;
        lastTime[2] = second;
        lastTimeFlag = 1;
    }
    else
    {
        if (pid.ActualTemperature <= outdoorTemperature)
        {
            Minute = (hour - lastTime[0]) * 60 + (minute - lastTime[1]) + float(second - lastTime[2]) / 60.0;
            pid.ActualTemperature = pid.ActualTemperature + Minute * IncrementTemperature;
               
            lastTime[0] = hour;
            lastTime[1] = minute;
            lastTime[2] = second;
            //printf("Test:設定溫度為:%.2f\t室內溫度為:%f\t\n\n", pid.SetTemperature, pid.ActualTemperature);
        }
        else
        {
            // 溫度升高過快,只記錄時間,程序會在PID_controlTemperature函數中處理
            lastTime[0] = hour;
            lastTime[1] = minute;
            lastTime[2] = second;
        }
        
    }
}

/* release the refrigeration */
void Refrigeration()
{
    pid.ActualTemperature = pid.ActualTemperature - 5;
}
/* release the heating */
void Heating()
{
    pid.ActualTemperature = pid.ActualTemperature + 5;
}

/* the PID arithmetic control the temperature of indoor */
void PID_controlTemperature()
{
    if (pid.SetTemperature >= pid.ActualTemperature + TemperatureErr)        
    {
        // 室內溫度偏低,調用制熱模塊
        Heating();
    }
    // 室內溫度處于23度左右,使用PID精調
    else if (fabs(pid.SetTemperature - pid.ActualTemperature) < TemperatureErr)
    {
        IncrementPID_realize();    // 增量式PID控制
        //PositionPID_realize();    // 位置式PID控制,兩者只要一個就可以了,之所以都貼出來,為了試試兩種方式有什么不同
    }
    else if (pid.SetTemperature + TemperatureErr <= pid.ActualTemperature)
    {
        // 室內溫度偏高,調用制冷模塊
        Refrigeration();
    }
    else
    {
        printf("區間考慮不周全\n");
    }

}

/* initialize PID */
void init_PID()
{
    pid.Kp = 0.2;
    pid.Ki = 0.015;
    pid.Kd = 0.2;
    pid.SetTemperature = 23.0;
    pid.ActualTemperature = outdoorTemperature;
    lastTimeFlag = 0;
    pid.ErrVal[0] = 0;
    pid.ErrVal[1] = 0;
    pid.ErrVal[2] = 0;
    pid.Integral = 0;

    printf("accomplish initialize PID \n");
}

/*
功能:使用增量式PID調節
公式:U(k)+Kp*[E(k)-E(k-1)]+Ki*E(k)+Kd*[E(k)-2E(k-1)+E(k-2)]   
備注:網上的公式Kp乘以的東西有兩種,第一種是Kp*[E(k)-E(k-1)],第二種是Kp*([E(k)-E(k-1)]+Ki*E(k)+Kd*[E(k)-2E(k-1)+E(k-2)])
      這兩種我都測試過,都能實現功能,前者更快一些,后者慢,但是我個人喜歡第二種
*/
void IncrementPID_realize()
{
    pid.ErrVal[0] = pid.SetTemperature - pid.ActualTemperature;            // 計算設定值與實際值直接的誤差
    float Temp0 = pid.Kp * (pid.ErrVal[0] - pid.ErrVal[1]);
    //float Temp0 = (pid.ErrVal[0] - pid.ErrVal[1]);
    float Temp1 = pid.Ki * pid.ErrVal[0];
    float Temp2 = pid.Kd * (pid.ErrVal[0] - 2 * pid.ErrVal[1] + pid.ErrVal[2]);
    float Increment = Temp0 + Temp1 + Temp2;                            // 通過公式計算增量
    // float Increment = pid.Kp * (Temp0 + Temp1 + Temp2);                // 通過公式計算增量
    pid.ActualTemperature += Increment;                                    // 計算實際溫度
    pid.ErrVal[1] = pid.ErrVal[0];
    pid.ErrVal[2] = pid.ErrVal[1];
    //printf("Realize:設定溫度為:%.2f\t室內溫度為:%.2f\t\n\n", pid.SetTemperature, pid.ActualTemperature);
}

/*
功能:使用位置式PID調節
公式:Kp*(E(k)+Ki*∑E(j)+Kd*[E(k)-E(k-1)])   
備注:參考增量式的備注
*/
void PositionPID_realize()
{
    pid.ErrVal[0] = pid.SetTemperature - pid.ActualTemperature;            // 計算設定值與實際值直接的誤差
    pid.Integral += pid.ErrVal[0];
    pid.ActualTemperature = pid.Kp * pid.ErrVal[0] + pid.Ki * pid.Integral + pid.Kd * (pid.ErrVal[0] - pid.ErrVal[1]);
    pid.ErrVal[1] = pid.ErrVal[0];
}
</textarea>


頭文件如下:
#include <stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<windows.h>

typedef struct PID_Value
{
    float ErrVal[3];            // 三次誤差值
    float Kp;                    // 比例系數
    float Ki;                    // integral 系數
    float Kd;                    // derivative 系數
    float Integral;                // 積分
    float SetTemperature;
    float ActualTemperature;
}PID_ValueStr,*PID_ValueT;

PID_Value pid;

#define        outdoorTemperature        36.2
#define        TemperatureErr            3
#define        ComfortTemperature        0.5
#define        IncrementTemperature    1            // 每分鐘房間上升的溫度

int lastTimeFlag = 0;

void AcquireTemperature(int hour, int minute, int second);
void PID_controlTemperature();
void Refrigeration();
void init_PID();
void IncrementPID_realize();
void PositionPID_realize();
————————————————
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂 踩
回復

使用道具 舉報

無效樓層,該帖已經被刪除
板凳
ID:93341 發表于 2022-9-28 22:17 | 只看該作者
還有呢,能補全嗎。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表