久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3146|回復: 1
收起左側

C語言PID控溫講解及源碼

[復制鏈接]
ID:1037617 發表于 2022-6-30 08:41 | 顯示全部樓層 |閱讀模式
參考資料:http://www.zg4o1577.cn/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();
————————————————
回復

使用道具 舉報

ID:93341 發表于 2022-9-28 22:17 | 顯示全部樓層
還有呢,能補全嗎。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级片在线免费播放 | 一区二区中文 | 精品福利在线 | 欧美黑人一级爽快片淫片高清 | 成人综合视频在线观看 | 青青草在线视频免费观看 | 国产一区二区三区免费 | 亚洲精品片 | 一级特黄网站 | 九九99久久 | 一级电影免费看 | 久久综合一区 | 精品成人| 亚洲午夜精品久久久久久app | 亚洲大片在线观看 | 日韩欧美精品在线 | 国产成人精品综合 | 91资源在线 | 日韩在线精品视频 | 久久免费高清 | 久久久xx | 一区二区三区免费 | 天天射中文 | 国产最新精品视频 | 亚洲精品一区二区三区蜜桃久 | 免费不卡一区 | 欧美日韩精品一区 | 一级黄色片免费 | 综合国产在线 | 精产国产伦理一二三区 | 夜夜草天天草 | 欧美1区2区| 日韩av免费在线电影 | 国产精品海角社区在线观看 | 中文字幕韩在线第一页 | 久久精品免费观看 | 伊人网在线播放 | 日韩视频免费 | 国产精品久久网 | 一级片免费在线观看 | 午夜天堂精品久久久久 |