Ver código fonte

添加了通信统计,串级PID 的输入输出记录, PID关键参数文本化并增加了设置界面

guoqiang 2 anos atrás
pai
commit
50c8e4395f
22 arquivos alterados com 1989 adições e 175 exclusões
  1. 476 0
      Calibrationpara.cpp
  2. 67 0
      Calibrationpara.h
  3. 30 0
      ComStatistics.cpp
  4. 5 0
      ComStatistics.h
  5. 1128 0
      PageCalibration.qml
  6. 11 2
      PageMain.qml
  7. 4 4
      PageSetting.qml
  8. 9 2
      PressureSensor.cpp
  9. 2 0
      PressureSensor.h
  10. 170 124
      TestService.cpp
  11. 1 0
      TestService.h
  12. 2 0
      ValveTest.pro
  13. 1 1
      ValveTest.pro.user
  14. 14 2
      ballvalve.cpp
  15. 9 0
      main.cpp
  16. 2 2
      main.qml
  17. 25 23
      pid.cpp
  18. 10 1
      pid.h
  19. 1 0
      qml.qrc
  20. 4 0
      serialui.cpp
  21. 3 11
      tank.cpp
  22. 15 3
      valve.cpp

+ 476 - 0
Calibrationpara.cpp

@@ -0,0 +1,476 @@
+#include "Calibrationpara.h"
+#include <QDebug>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QByteArray>
+#include <QFile>
+
+ParaItem::ParaItem(){
+
+     max_volume = 0;   // L per unit
+     keep_time = 0;    // s
+
+     outermax = 0;
+     outermin = 0;
+     outerkp = 0;
+     outerki = 0;
+     outerkd = 0;
+
+     innermax = 0;
+     innermin = 0;
+     innerkp = 0;
+     innerki = 0;
+     innerkd = 0;
+     innermaxI = 0;
+     innerIstep = 0;
+     innerDstep = 0;
+
+}
+ParaItem::~ParaItem()
+{
+
+}
+
+static CalibrationPara* _calibrationPara = nullptr;
+
+CalibrationPara::CalibrationPara(QObject* parent)
+    :QObject(parent)
+{
+
+}
+
+CalibrationPara::~CalibrationPara(){
+
+}
+
+CalibrationPara* CalibrationPara::instance(){
+    if(nullptr == _calibrationPara){
+        _calibrationPara = new CalibrationPara();
+    }
+
+    return _calibrationPara;
+}
+
+void CalibrationPara::init()
+{
+    load_parameters();
+    if(m_paras.empty()){
+        add_default();
+        save_parameters();
+    }
+}
+
+QJsonObject CalibrationPara::get_paras()
+{
+    QJsonArray pidArray;
+    //QJsonArray itemArray;
+    QJsonObject rootObj;
+
+    int count = static_cast<int>(m_paras.size());
+    if(count > 5){
+        count=5;
+    }
+
+    rootObj.insert("count", count);
+
+    for(int i=0; i < count; i++){
+
+        QJsonObject stdObj;
+
+        stdObj.insert("max_volume", m_paras[i].max_volume);
+        stdObj.insert("keep_time", m_paras[i].keep_time);
+
+        stdObj.insert("outermax", m_paras[i].outermax);
+        stdObj.insert("outermin", m_paras[i].outermin);
+        stdObj.insert("outerkp", m_paras[i].outerkp);
+        stdObj.insert("outerki", m_paras[i].outerki);
+        stdObj.insert("outerkd", m_paras[i].outerkd);
+
+        stdObj.insert("innermax", m_paras[i].innermax);
+        stdObj.insert("innermin", m_paras[i].innermin);
+        stdObj.insert("innerkp", m_paras[i].innerkp);
+        stdObj.insert("innerki", m_paras[i].innerki);
+        stdObj.insert("innerkd", m_paras[i].innerkd);
+        stdObj.insert("innermaxI", m_paras[i].innermaxI);
+        stdObj.insert("innerIstep", m_paras[i].innerIstep);
+        stdObj.insert("innerDstep", m_paras[i].innerDstep);
+
+        pidArray.append(stdObj);
+    }
+
+    rootObj.insert("pids", pidArray);
+
+    return rootObj;
+
+}
+
+bool CalibrationPara::set_paras(const QString& jsonStr)
+{
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8());
+    QJsonObject jsonObj = jsonDoc.object();
+
+    QJsonArray  jsonArray;
+
+    if(jsonObj.contains("pids") && jsonObj.value("pids").isArray()){
+        jsonArray = jsonObj.value("pids").toArray();
+
+         m_paras.clear();
+
+        for(int i=0; i < jsonArray.size(); i++){
+
+            ParaItem para;
+            QJsonObject childObj = jsonArray[i].toObject();
+
+            if(childObj.contains("max_volume") && childObj.value("max_volume").isDouble()){
+                para.max_volume = childObj.value("max_volume").toDouble();
+            }
+
+            if(childObj.contains("keep_time") && childObj.value("keep_time").isDouble()){
+                para.keep_time = childObj.value("keep_time").toDouble();
+            }
+
+
+            if(childObj.contains("outermax") && childObj.value("outermax").isDouble()){
+                para.outermax = childObj.value("outermax").toDouble();
+            }
+            if(childObj.contains("outermin") && childObj.value("outermin").isDouble()){
+                para.outermin = childObj.value("outermin").toDouble();
+            }
+            if(childObj.contains("outerkp") && childObj.value("outerkp").isDouble()){
+                para.outerkp = childObj.value("outerkp").toDouble();
+            }
+            if(childObj.contains("outerki") && childObj.value("outerki").isDouble()){
+                para.outerki = childObj.value("outerki").toDouble();
+            }
+            if(childObj.contains("outerkd") && childObj.value("outerkd").isDouble()){
+                para.outerkd = childObj.value("outerkd").toDouble();
+            }
+
+
+            if(childObj.contains("innermax") && childObj.value("innermax").isDouble()){
+                para.innermax = childObj.value("innermax").toDouble();
+            }
+            if(childObj.contains("innermin") && childObj.value("innermin").isDouble()){
+                para.innermin = childObj.value("innermin").toDouble();
+            }
+            if(childObj.contains("innerkp") && childObj.value("innerkp").isDouble()){
+                para.innerkp = childObj.value("innerkp").toDouble();
+            }
+            if(childObj.contains("innerki") && childObj.value("innerki").isDouble()){
+                para.innerki = childObj.value("innerki").toDouble();
+            }
+            if(childObj.contains("innerkd") && childObj.value("innerkd").isDouble()){
+                para.innerkd = childObj.value("innerkd").toDouble();
+            }
+            if(childObj.contains("innermaxI") && childObj.value("innermaxI").isDouble()){
+                para.innermaxI = childObj.value("innermaxI").toDouble();
+            }
+            if(childObj.contains("innerIstep") && childObj.value("innerIstep").isDouble()){
+                para.innerIstep = childObj.value("innerIstep").toDouble();
+            }
+            if(childObj.contains("innerDstep") && childObj.value("innerDstep").isDouble()){
+                para.innerDstep = childObj.value("innerDstep").toDouble();
+            }
+
+            m_paras.push_back(para);
+
+        }
+    }else{
+        return false;
+    }
+
+    save_parameters();
+
+    return true;
+}
+
+void CalibrationPara::load_parameters()
+{
+    QFile file("./Calibration.json");
+    if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
+        //QJsonObject jsonObject;
+        //jsonObject["name"] =""
+        qDebug() << "load_parameters file open failed ";
+        return ;
+    }
+
+    QTextStream jsonstream(&file);
+
+    jsonstream.setCodec("UTF-8");
+
+    //jsonstream.readAll();
+    qDebug() << "load_parameters enter";
+
+    QString jsonString = jsonstream.readAll();
+    file.close();
+
+
+    QJsonParseError json_error;
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &json_error);
+    if(json_error.error == QJsonParseError::NoError){
+        QJsonObject rootObj = jsonDoc.object();
+        QJsonArray  jsonArray;
+
+        if(rootObj.contains("pids") && rootObj.value("pids").isArray()){
+            jsonArray = rootObj.value("pids").toArray();
+            for(int i=0; i < jsonArray.size(); i++){
+
+                ParaItem para;
+
+                QJsonObject childObj = jsonArray[i].toObject();
+
+                if(childObj.contains("max_volume") && childObj.value("max_volume").isDouble()){
+                    para.max_volume = childObj.value("max_volume").toDouble();
+                }
+
+                if(childObj.contains("keep_time") && childObj.value("keep_time").isDouble()){
+                    para.keep_time = childObj.value("keep_time").toDouble();
+                }
+
+
+                if(childObj.contains("outermax") && childObj.value("outermax").isDouble()){
+                    para.outermax = childObj.value("outermax").toDouble();
+                }
+                if(childObj.contains("outermin") && childObj.value("outermin").isDouble()){
+                    para.outermin = childObj.value("outermin").toDouble();
+                }
+                if(childObj.contains("outerkp") && childObj.value("outerkp").isDouble()){
+                    para.outerkp = childObj.value("outerkp").toDouble();
+                }
+                if(childObj.contains("outerki") && childObj.value("outerki").isDouble()){
+                    para.outerki = childObj.value("outerki").toDouble();
+                }
+                if(childObj.contains("outerkd") && childObj.value("outerkd").isDouble()){
+                    para.outerkd = childObj.value("outerkd").toDouble();
+                }
+
+
+                if(childObj.contains("innermax") && childObj.value("innermax").isDouble()){
+                    para.innermax = childObj.value("innermax").toDouble();
+                }
+                if(childObj.contains("innermin") && childObj.value("innermin").isDouble()){
+                    para.innermin = childObj.value("innermin").toDouble();
+                }
+                if(childObj.contains("innerkp") && childObj.value("innerkp").isDouble()){
+                    para.innerkp = childObj.value("innerkp").toDouble();
+                }
+                if(childObj.contains("innerki") && childObj.value("innerki").isDouble()){
+                    para.innerki = childObj.value("innerki").toDouble();
+                }
+                if(childObj.contains("innerkd") && childObj.value("innerkd").isDouble()){
+                    para.innerkd = childObj.value("innerkd").toDouble();
+                }
+                if(childObj.contains("innermaxI") && childObj.value("innermaxI").isDouble()){
+                    para.innermaxI = childObj.value("innermaxI").toDouble();
+                }
+                if(childObj.contains("innerIstep") && childObj.value("innerIstep").isDouble()){
+                    para.innerIstep = childObj.value("innerIstep").toDouble();
+                }
+                if(childObj.contains("innerDstep") && childObj.value("innerDstep").isDouble()){
+                    para.innerDstep = childObj.value("innerDstep").toDouble();
+                }
+
+                m_paras.push_back(para);
+
+            }
+        }
+
+
+    }else{
+        qDebug() << "json_error.error occurred";
+    }
+}
+
+void CalibrationPara::save_parameters()
+{
+    QJsonArray pidArray;
+    //QJsonArray itemArray;
+    QJsonObject rootObj;
+
+
+    for(int i=0; i < static_cast<int>(m_paras.size()); i++){
+
+        QJsonObject stdObj;
+
+        stdObj.insert("max_volume", m_paras[i].max_volume);
+        stdObj.insert("keep_time", m_paras[i].keep_time);
+
+        stdObj.insert("outermax", m_paras[i].outermax);
+        stdObj.insert("outermin", m_paras[i].outermin);
+        stdObj.insert("outerkp", m_paras[i].outerkp);
+        stdObj.insert("outerki", m_paras[i].outerki);
+        stdObj.insert("outerkd", m_paras[i].outerkd);
+
+        stdObj.insert("innermax", m_paras[i].innermax);
+        stdObj.insert("innermin", m_paras[i].innermin);
+        stdObj.insert("innerkp", m_paras[i].innerkp);
+        stdObj.insert("innerki", m_paras[i].innerki);
+        stdObj.insert("innerkd", m_paras[i].innerkd);
+        stdObj.insert("innermaxI", m_paras[i].innermaxI);
+        stdObj.insert("innerIstep", m_paras[i].innerIstep);
+        stdObj.insert("innerDstep", m_paras[i].innerDstep);
+
+        pidArray.append(stdObj);
+    }
+
+    rootObj.insert("pids", pidArray);
+
+    QJsonDocument jsonDoc;
+    jsonDoc.setObject(rootObj);
+
+    QByteArray byteArray = jsonDoc.toJson(QJsonDocument::Indented);
+    QFile file("./Calibration.json");
+    if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
+    {
+        qDebug() << QString("fail to open the file: %1, %2, %3").arg(__FILE__).arg(__LINE__).arg(__FUNCTION__);
+        return;
+    }
+    QTextStream out(&file);
+    out.setCodec("UTF-8");
+    out << byteArray;
+    file.close();
+
+}
+
+
+void CalibrationPara::add_default()
+{
+    ParaItem para;
+
+    // <= 200  主要是系统自测
+    para.max_volume = 200;
+    para.keep_time = 30;
+
+    para.outermax = 0.1;
+    para.outermin = 0;
+    para.outerkp = 0.05;
+    para.outerki = 0;
+    para.outerkd = 0;
+
+    para.innermax = 200;
+    para.innermin = -50;
+    para.innerkp = 1000;
+    para.innerki = 20;
+    para.innerkd = 60;
+    para.innermaxI = 10;
+    para.innerIstep = 1;
+    para.innerDstep = 10;
+
+    m_paras.push_back(para);
+
+    //<= 1000
+    para.max_volume = 1000;
+    para.keep_time = 30;
+
+    para.outermax = 0.1;
+    para.outermin = 0;
+    para.outerkp = 0.05;
+    para.outerki = 0;
+    para.outerkd = 0;
+
+    para.innermax = 200;
+    para.innermin = -40;
+    para.innerkp = 1000;
+    para.innerki = 20;
+    para.innerkd = 60;
+    para.innermaxI = 10;
+    para.innerIstep = 1;
+    para.innerDstep = 10;
+
+    m_paras.push_back(para);
+
+    //<= 5000
+    para.max_volume = 5000;
+    para.keep_time = 60;
+
+    para.outermax = 0.1;
+    para.outermin = 0;
+    para.outerkp = 0.1;
+    para.outerki = 0;
+    para.outerkd = 0;
+
+    para.innermax = 800;
+    para.innermin = -30;
+    para.innerkp = 3000;
+    para.innerki = 25;
+    para.innerkd = 60;
+    para.innermaxI = 15;
+    para.innerIstep = 1;
+    para.innerDstep = 10;
+
+    m_paras.push_back(para);
+
+    //<= 10000
+    para.max_volume = 10000;
+    para.keep_time = 120;
+
+    para.outermax = 0.1;
+    para.outermin = 0;
+    para.outerkp = 0.2;
+    para.outerki = 0;
+    para.outerkd = 0;
+
+    para.innermax = 800;
+    para.innermin = -20;
+    para.innerkp = 5000;
+    para.innerki = 60;
+    para.innerkd = 60;
+    para.innermaxI = 30;
+    para.innerIstep = 2;
+    para.innerDstep = 10;
+
+    m_paras.push_back(para);
+
+    //<= 9000000   最大值
+    para.max_volume = 9000000;
+    para.keep_time = 300;  // 5min
+
+    para.outermax = 0.1;
+    para.outermin = 0;
+    para.outerkp = 0.2;
+    para.outerki = 0;
+    para.outerkd = 0;
+
+    para.innermax = 800;
+    para.innermin = 0;
+    para.innerkp = 8000;
+    para.innerki = 60;
+    para.innerkd = 60;
+    para.innermaxI = 40;
+    para.innerIstep = 5;
+    para.innerDstep = 20;
+
+    m_paras.push_back(para);
+}
+
+bool CalibrationPara::get_pidPara(int volume, ParaItem& item)
+{
+    int min_volme = 0;
+    bool ret_value = false;
+
+    for(std::vector<ParaItem>::iterator it = m_paras.begin(); it != m_paras.end(); it++){
+        if(it->max_volume >= volume){
+
+            if(0 == min_volme){
+                min_volme = it->max_volume;
+            }else{
+
+                if(it->max_volume < min_volme){
+                    min_volme = it->max_volume;
+                }
+            }
+
+        }
+    }
+
+    for(std::vector<ParaItem>::iterator it = m_paras.begin(); it != m_paras.end(); it++){
+        if(it->max_volume == min_volme){
+            item = *it;
+            ret_value = true;
+        }
+    }
+
+    return ret_value;
+}
+

+ 67 - 0
Calibrationpara.h

@@ -0,0 +1,67 @@
+#ifndef CALIBRATIONPARA_H
+#define CALIBRATIONPARA_H
+
+#include <QObject>
+#include <QString>
+#include <QJsonObject>
+#include <QMap>
+
+//#define MAX_PARA_ITEM  (5)
+
+class ParaItem
+{
+public:
+    ParaItem();
+    ~ParaItem();
+
+   int max_volume;   // L per unit
+   int keep_time;    // s
+
+   double outermax;
+   double outermin;
+   double outerkp;
+   double outerki;
+   double outerkd;
+
+   double innermax;
+   double innermin;
+   double innerkp;
+   double innerki;
+   double innerkd;
+   double innermaxI;
+   double innerIstep;
+   double innerDstep;
+};
+
+
+
+class CalibrationPara :public QObject
+{
+    Q_OBJECT
+public:
+    static CalibrationPara* instance();
+    ~CalibrationPara();
+
+    Q_INVOKABLE void init();
+
+    Q_INVOKABLE QJsonObject get_paras();
+    //add or modify
+    Q_INVOKABLE bool set_paras(const QString& jsonStr);
+
+    bool get_pidPara(int volume, ParaItem& item);
+
+private:
+    explicit CalibrationPara(QObject* parent = nullptr);
+
+    void load_parameters();
+    void save_parameters();
+    void add_default();
+
+    std::vector<ParaItem>  m_paras;
+
+
+};
+
+#define g_CalibrationPara  CalibrationPara::instance()
+
+#endif // CALIBRATIONPARA_H

+ 30 - 0
ComStatistics.cpp

@@ -11,6 +11,10 @@ tag_name(sensor_name)
     request_count = 0;
     crcerror_count = 0;
     timeout_count = 0;
+
+    max_recvtime = 0;
+    min_recvtime = 0;
+    total_recvtime = 0;
 }
 
 void ComStatistics::ReQuestCount_increase()
@@ -29,6 +33,20 @@ void ComStatistics::TimeoutCount_increase()
     timeout_count++;
 }
 
+void ComStatistics::Update_Recvtime(int ms)
+{
+    if(ms > max_recvtime){
+       max_recvtime = ms;
+    }
+
+    if(ms < min_recvtime){
+       min_recvtime = ms;
+    }
+
+    total_recvtime += ms;
+
+}
+
 void ComStatistics::Save2File(QString filepath)
 {
     static QMutex mutex;
@@ -47,6 +65,15 @@ void ComStatistics::Save2File(QString filepath)
     QString timeoutString;
     timeoutString = "\t TimeoutCount:" + QString::number(timeout_count) + "\r\n";
 
+    QString maxtimeString;
+    maxtimeString = "\t max_Recvtime:" + QString::number(max_recvtime) + " ms\r\n";
+
+    QString mintimeString;
+    mintimeString = "\t min_Recvtime:" + QString::number(min_recvtime) + " ms\r\n";
+
+    QString averagetimeString;
+    averagetimeString = "\t Averagetime:" + QString::number(total_recvtime/request_count) + " ms\r\n";
+
     QFile file(filepath);
     file.open(QIODevice::ReadWrite | QIODevice::Append);
 
@@ -56,6 +83,9 @@ void ComStatistics::Save2File(QString filepath)
     stream << requestString;
     stream << crcString;
     stream << timeoutString;
+    stream << maxtimeString;
+    stream << mintimeString;
+    stream << averagetimeString;
     stream << "\r\n";
 
     file.flush();

+ 5 - 0
ComStatistics.h

@@ -10,6 +10,7 @@ public:
     void ReQuestCount_increase();
     void CrcErrorCount_increase();
     void TimeoutCount_increase();
+    void Update_Recvtime(int ms);
     void Save2File(QString filepath);
 
 private:
@@ -17,6 +18,10 @@ private:
     int crcerror_count;
     int timeout_count;
 
+    int max_recvtime;  //ms
+    int min_recvtime;  //ms
+    int total_recvtime;  //ms
+
     QString tag_name;
 };
 

Diferenças do arquivo suprimidas por serem muito extensas
+ 1128 - 0
PageCalibration.qml


+ 11 - 2
PageMain.qml

@@ -19,7 +19,8 @@ Rectangle{
         enum Page_Type {
             Page_Type_Settings,
             Page_Type_Testing,
-            Page_Type_ValveTest
+            Page_Type_ValveTest,
+            Page_Type_Calibration
         }
 
         SwipeView {
@@ -46,6 +47,10 @@ Rectangle{
                 //visible: false;
             }
 
+            PageCalibration {
+                id:pagecalibration
+            }
+
 
             function changePages(compartment_num){
                 console.log("changePages num : "+compartment_num)
@@ -167,8 +172,12 @@ Rectangle{
         }
 
         Component.onCompleted: {
-            testService.init()
             StandardManager.init()
+            CalibrationPara.init()
+
+            testService.init()
+            //StandardManager.init()
+            //CalibrationPara.init()
 
         }
 

+ 4 - 4
PageSetting.qml

@@ -472,7 +472,7 @@ Item{
                                 id:rectvolume_1
                                 paraName: "1仓:"
                                 text: "0"
-                                paraLength: 60
+                                paraLength: 80
                                 validator:RegExpValidator {
                                     regExp: /[0-9]*/
                                 }
@@ -486,7 +486,7 @@ Item{
                                 id:rectvolume_2
                                 paraName: "2仓:"
                                 text: "0"
-                                paraLength: 60
+                                paraLength: 80
                                 validator:RegExpValidator {
                                     regExp: /[0-9]*/
                                 }
@@ -498,7 +498,7 @@ Item{
                                 id:rectvolume_3
                                 paraName: "3仓:"
                                 text: "0"
-                                paraLength: 60
+                                paraLength: 80
                                 validator:RegExpValidator {
                                     regExp: /[0-9]*/
                                 }
@@ -510,7 +510,7 @@ Item{
                                 id:rectvolume_4
                                 paraName: "4仓:"
                                 text: "0"
-                                paraLength: 60
+                                paraLength: 80
                                 validator:RegExpValidator {
                                     regExp: /[0-9]*/
                                 }

+ 9 - 2
PressureSensor.cpp

@@ -2,6 +2,9 @@
 #include "Modbus.h"
 #include "ComStatistics.h"
 
+#include <QTimer>
+#include <QElapsedTimer>
+
 static ComStatistics g_PS_Statistics("PressureSensor");
 
 PressureSensor::PressureSensor(SerialUi* pSerial)
@@ -12,6 +15,8 @@ PressureSensor::PressureSensor(SerialUi* pSerial)
 bool PressureSensor::Read(float& pressure)
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
 
     char zero = 0x00;
     tx_buf.append(PRESSURESENSOR_ADDRESS);
@@ -43,7 +48,7 @@ bool PressureSensor::Read(float& pressure)
 
             float* p = (float*)value;
             pressure = *p;
-
+            g_PS_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
 
@@ -63,6 +68,8 @@ bool PressureSensor::Read(float& pressure)
 bool PressureSensor::Set_Zero()
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
 
     char zero = 0x00;
     tx_buf.append(PRESSURESENSOR_ADDRESS);
@@ -85,7 +92,7 @@ bool PressureSensor::Set_Zero()
     rx_buf = m_pSerial->serialWriteReponse(tx_buf);
     if(rx_buf.size() > 0){
         if(check_crc(rx_buf)){
-
+            g_PS_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
             qDebug("PressureSensor::Set_Zero <<< check crc failed");

+ 2 - 0
PressureSensor.h

@@ -4,6 +4,8 @@
 #include "serialui.h"
 #include <QString>
 
+#define PRESSURE_DIVISION_VALUE  (10) // 10 Pa
+
 class PressureSensor
 {
 public:

+ 170 - 124
TestService.cpp

@@ -3,6 +3,7 @@
 #include "valve.h"
 #include "ballvalve.h"
 #include "PressureSensor.h"
+#include "Calibrationpara.h"
 #include<QDateTime>
 #include<QTime>
 #include<QEventLoop>
@@ -28,6 +29,7 @@ TestService::TestService(QThread *parent)
 {
 
     m_bRunning=false;
+    m_bRealEnd = true;
 
     for(int i=0; i<MAX_COMPARTMENT_NUM; i++ ){
         m_tank.m_comparts[i].m_id = i;
@@ -136,6 +138,22 @@ bool TestService::setTankinfo(const QVariantList& list)
                         break;
                     }
                 }
+#if 0
+                ParaItem pid_para;
+                g_CalibrationPara->get_pidPara(volume[i], pid_para);
+                qDebug("setTankinfo: pid max_volume:[%d]", pid_para.max_volume);
+                qDebug("setTankinfo: pid keep_time:[%d]", pid_para.keep_time);
+
+                qDebug("setTankinfo: pid outermax:[%f]", pid_para.outermax);
+                qDebug("setTankinfo: pid outermin:[%f]", pid_para.outermin);
+                qDebug("setTankinfo: pid outerkp:[%f]", pid_para.outerkp);
+                qDebug("setTankinfo: pid outerki:[%f]", pid_para.outerki);
+                qDebug("setTankinfo: pid outerkd:[%f]", pid_para.outerkd);
+
+                qDebug("setTankinfo: pid innermax:[%f]", pid_para.innermax);
+                qDebug("setTankinfo: pid innermin:[%f]", pid_para.innermin);
+                qDebug("setTankinfo: pid innerkp:[%f]", pid_para.innerkp);
+#endif
 
             }
 
@@ -159,6 +177,13 @@ bool TestService::tstart(int compartmentid, int direction)
         emit onNotice(str);
         return false;
     }
+
+    if(false == m_bRealEnd){
+        QString str = "当前有任务还未完全结束...";
+        emit onNotice(str);
+        return false;
+    }
+
     m_compartmentid = compartmentid-1;
 
     if(0 == direction)
@@ -179,7 +204,7 @@ bool TestService::tstart(int compartmentid, int direction)
         {
         case QMessageBox::Ok:
             qDebug()<<"Ok";
-            m_pTimer_1->start(1*1000);  // 1s
+            m_pTimer_1->start(1*500);  // 500 ms
             m_bRunning = true;
             start();
             break;
@@ -205,6 +230,12 @@ bool TestService::tselfstart(int compartmentid, int direction)
         return false;
     }
 
+    if(false == m_bRealEnd){
+        QString str = "当前有任务还未完全结束...";
+        emit onNotice(str);
+        return false;
+    }
+
     m_compartmentid = compartmentid-1;
 
     if(0 == direction)
@@ -402,12 +433,11 @@ QString TestService::read_PressureValue()
 {
     float pressure = 0.0;
     static int timeout_count =0;
+
     PressureSensor ps(&m_SerialUi4);
     if(ps.Read(pressure)){
-
         push_pressurelist(pressure);
         timeout_count=0;
-
     }else{
 
         pressure = calculate_averagepressure();
@@ -421,8 +451,9 @@ QString TestService::read_PressureValue()
 
     }
 
-    int _ipressure = pressure*100;
-    pressure = _ipressure/100.0;
+    int _ipressure = pressure*1000;
+    _ipressure = (_ipressure/PRESSURE_DIVISION_VALUE)*PRESSURE_DIVISION_VALUE;
+    pressure = _ipressure/1000.0;
 
     QString pressure_str = QString("%1").arg(pressure, 4,'f',2,QLatin1Char('0'));
     return pressure_str;
@@ -449,10 +480,9 @@ QJsonObject TestService::ballvalve_status()
 {
     unsigned char status;
     unsigned short value = 0;
-    QJsonObject rootObj;
 
+    QJsonObject rootObj;
     BallValve ball_v(&m_SerialUi4);
-    ball_v.GetSP(status, value);
 
     if(ball_v.GetSP(status, value)){
         switch(status){
@@ -505,15 +535,10 @@ void TestService::OnTimer1()
 {
     float pressure = 0.00;
     static int timeout_count =0;
+    static int times_count = 0;
     PressureSensor ps(&m_SerialUi4);
     if(ps.Read(pressure)){
 
-        //int _ipressure = pressure*100;
-        //if(_ipressure<100){
-        //    _ipressure=0;
-        //}
-        //pressure = _ipressure/100.0;
-
         push_pressurelist(pressure);
         timeout_count=0;
     }else{
@@ -528,38 +553,40 @@ void TestService::OnTimer1()
         }
     }
 
-    int _ipressure = 0;
-    //if(pressure >= 4.5){
-    //   _ipressure = pressure*10;
-    //    pressure = _ipressure/10.0;
-    //}else{
-        _ipressure = pressure*100;
-        pressure = _ipressure/100.0;
-    //}
+    times_count++;
 
-    //int _ipressure = pressure*100;
-    //pressure = _ipressure/100.0;
+    if(0 == times_count%2){
 
-    QString pressure_str = QString("%1").arg(pressure, 4,'f',2,QLatin1Char('0'));
+        int _ipressure = 0;
+
+        _ipressure = pressure*1000;
+        _ipressure = (_ipressure/PRESSURE_DIVISION_VALUE)*PRESSURE_DIVISION_VALUE;
+        pressure = _ipressure/1000.0;
 
-    PressureItem item;
-    //item.m_pressure = pressure_str;
-    item.m_testDirection = m_direction;
-    item.m_testStage = m_stage;
-    item.m_testStep = m_step;
+        QString pressure_str = QString("%1").arg(pressure, 4,'f',2,QLatin1Char('0'));
 
-    QVariantMap map;
-    map.clear();
+        PressureItem item;
+        //item.m_pressure = pressure_str;
+        item.m_testDirection = m_direction;
+        item.m_testStage = m_stage;
+        item.m_testStep = m_step;
 
-    map.insert("pressure", pressure_str);
-    map.insert("direction", item.m_testDirection);
-    map.insert("stage", item.m_testStage);
-    map.insert("step", item.m_testStep);
+        QVariantMap map;
+        map.clear();
+
+        map.insert("pressure", pressure_str);
+        map.insert("direction", item.m_testDirection);
+        map.insert("stage", item.m_testStage);
+        map.insert("step", item.m_testStep);
+
+
+        //QString pressure_str = QString("%1").arg(pressure, 5,'f',3,QLatin1Char('0'));
+        //m_tank.m_comparts[m_compartmentid].m_currentpressure= pressure_str.toFloat();
+        emit sigPressure(m_compartmentid+1, map);
+
+    }
 
 
-    //QString pressure_str = QString("%1").arg(pressure, 5,'f',3,QLatin1Char('0'));
-    //m_tank.m_comparts[m_compartmentid].m_currentpressure= pressure_str.toFloat();
-    emit sigPressure(m_compartmentid+1, map);
 
 }
 
@@ -578,8 +605,9 @@ void TestService::OnTimer2()
 Ret_Value  TestService::PositivePressure_Add(const TestExpect& expect, bool bSavedata)
 {
     Ret_Value ret_v = Ret_OK;
+    int interval_time = 500; // ms
     int count = 0;
-    int stable_counts = 0;
+    int delay_count = 0;
     int exceed_times =0;
 
    QElapsedTimer  timer;
@@ -590,8 +618,9 @@ Ret_Value  TestService::PositivePressure_Add(const TestExpect& expect, bool bSav
    double current_speed = 0;
    unsigned char bvstatus;
    unsigned short bvposition;
-   unsigned short bvoffset = 100;
-   int holding_time = 60;
+   unsigned short bvoffset = 150;
+   int keep_times = 60;
+   int stable_count = 0;  //稳压计数
 
    PressureSensor ps(&m_SerialUi4);
    BallValve bv(&m_SerialUi4);
@@ -603,25 +632,17 @@ Ret_Value  TestService::PositivePressure_Add(const TestExpect& expect, bool bSav
    PID* pPIDinner = NULL;
    double speed_target = 0.0;
 
-   //pPIDouter = new PID(1, 0.2, 0, 0.2, 0, 0);
 
-   if(expect.volume <= 500){
-       pPIDouter = new PID(0.5, 0.2, 0, 0.2, 0, 0);
-        pPIDinner = new PID(0.5, 200, 0, 1000, 50, 20, 50, 2);
-        holding_time = 30;
-   }else if(expect.volume <= 5000){
-       pPIDouter = new PID(1, 0.2, 0, 0.2, 0, 0);
-        pPIDinner = new PID(1, 900, 0, 3000, 50, 30, 60, 10);
-        holding_time = 60;
-   }else if(expect.volume <= 10000){
-       pPIDouter = new PID(1, 0.2, 0, 0.2, 0, 0);
-       pPIDinner = new PID(1, 900, 0, 4500, 80, 60, 60, 20);
-       holding_time = 60;
-   }else{
-        pPIDouter = new PID(1, 0.2, 0, 0.2, 0, 0);
-        pPIDinner = new PID(1, 900, 0, 4500, 40, 60, 50, 20);
-        holding_time = 30;
-   }
+    ParaItem pid_para;
+    g_CalibrationPara->get_pidPara(expect.volume, pid_para);
+
+    pPIDouter = new PID(0.5, pid_para.outermax, pid_para.outermin, pid_para.outerkp, 0, 0);
+    //pPIDouter = new PID(0.5, pid_para.outermax, pid_para.outermin, pid_para.outerkp, pid_para.outerkd, pid_para.outerki);
+    pPIDinner = new PID(0.5, pid_para.innermax, pid_para.innermin, pid_para.innerkp, pid_para.innerkd, pid_para.innerki,pid_para.innermaxI, pid_para.innerIstep, pid_para.innerDstep);
+
+    //将稳压时间转换成计数
+    keep_times = pid_para.keep_time *(1000/interval_time);
+
 
     prev_pressure = calculate_averagepressure();
 
@@ -657,14 +678,12 @@ Ret_Value  TestService::PositivePressure_Add(const TestExpect& expect, bool bSav
                 if((BALLVALVE_STATUS_OPENEND == bvstatus) || (BALLVALVE_STATUS_CLOSEEND == bvstatus) ){
                     int ps_offset = bvoffset;
                     int cu_position = bvposition;
-                    if(abs(cu_position-ps_offset) < 10){
+                    if(abs(cu_position-ps_offset) <= 10){
                         bv_ready=true;
                     }
                 }else{
                       bv.SetPosition(bvoffset);
                 }
-
-
             }
         }else{
 
@@ -676,7 +695,9 @@ Ret_Value  TestService::PositivePressure_Add(const TestExpect& expect, bool bSav
 
             if(current_pressure >=  expect.target+0.01){
 
-                count++;
+                count = 0;
+                stable_count++;
+
                 if(bOpen_intake){
 
                      qDebug(" PositivePressure_Add, in_v.Close ");
@@ -688,81 +709,96 @@ Ret_Value  TestService::PositivePressure_Add(const TestExpect& expect, bool bSav
                         //bOpen_intake = false;
                 }
 
-                if(exceed_times <= 1){
-                    stable_counts = 15;
-                }else if(2 == exceed_times){
-                    stable_counts =10;
+#if 1
+
+                if(exceed_times <= 2){
+                    delay_count = 15*(1000/interval_time);
+                }else if(3 == exceed_times){
+                    delay_count =10*(1000/interval_time);
                 }else{
-                    stable_counts =5;
+                    delay_count =5*(1000/interval_time);
                 }
 
-                //stable_counts = 15;
-
-                //系统自测及容积较小时,球阀最好归零,否则因球阀不太紧漏气, 进气阀与球阀之间的气体会压向系统,导致压力升高
-                //当容器过大时, 如果压力超出后又降下来或系统存在漏气,需要重新加压,设置 bvoffset,能让重新加压速度快起来。
-                if(expect.volume < 100){
-                    if(bv.SetPosition(0))
-                        bvposition = 0;
-                    qDebug(" PositivePressure_Add, bv.SetPosition 0");
-                }else {
-                    if(bvoffset != bvposition){
-                        if(bv.SetPosition(bvoffset))
-                            bvposition = bvoffset;
-                        qDebug(" PositivePressure_Add, bv.SetPosition bvoffset");
-                    }
-                }
 
+#endif
 
             }else{
 
+                 // stable_count 需要从第一次超出目标压力时,开始增加
+                if(stable_count > 0) stable_count++;
+
                 if(current_pressure >= expect.target && current_pressure < expect.target + 0.01){
                     count++;
+
+                    if(((false == bOpen_intake) && count >=10*(1000/interval_time))||((stable_count > keep_times)&&(false == bOpen_intake))){
+                        count = keep_times+10;
+                    }
+
+                    if(false == bOpen_intake){
+                        //在进气阀关闭,压力回落过程中,两种情况触发加压过程退出
+                        // 1. 压力值连续10秒都没有下降0.01Kpa, 说明压力基本稳定了
+                        // 2. 计数超出稳压所需计数
+
+                        if((count >=10*(1000/interval_time)) || (stable_count > keep_times) ){
+                            count = keep_times+10;
+                        }
+                    }
+
+                    // 进行阀门密闭性测试,加压过程中。 只要加压到目标压力就退出
+                    if(m_stage == Test_Stage_ValveTest){
+                        count = keep_times+10;
+                    }
+
+
                 }else{
                     count=0;
 
-                    if(stable_counts > 0){
-                        stable_counts--;
+                    if(delay_count > 0){
+                        delay_count--;
                     }
 
-                    if(false == bOpen_intake && 0 == stable_counts){
+                    if(false == bOpen_intake && 0 == delay_count){
                         bOpen_intake = in_v.Open();
                         qDebug(" PositivePressure_Add, in_v.Open 222 ");
                         pPIDinner->reset();
+                        if(bv.SetPosition(bvoffset))
+                            bvposition = bvoffset;
                     }
 
                 }
 
-                if(NULL != pPIDouter && NULL != pPIDinner && 0 == stable_counts){
+                    if(NULL != pPIDouter && NULL != pPIDinner && 0 == delay_count){
 
-                    speed_target = pPIDouter->calculate(expect.target+0.01, current_pressure);
+                        speed_target = pPIDouter->calculate(expect.target, current_pressure);
 
-                    qDebug(" PositivePressure_Add, pPIDinner speed_target:%f, current_speed:%f", speed_target, current_speed);
-                    double inc = pPIDinner->calculate(speed_target, current_speed);
+                        qDebug(" PositivePressure_Add, pPIDinner speed_target:%f, current_speed:%f", speed_target, current_speed);
+                        double inc = pPIDinner->calculate(speed_target, current_speed);
 
-                    unsigned short  position = bvoffset +inc;
+                        unsigned short  position = bvoffset +inc;
 
-                    //qDebug(" PositivePressure_Add, position : %d", position);
-                    if(bvposition != position){
-                        qDebug(" PositivePressure_Add, position : %d", position);
-                        if(bv.SetPosition(position))
-                            bvposition = position;
-                    }
+                        //qDebug(" PositivePressure_Add, position : %d", position);
+                        if(bvposition != position){
+                            qDebug(" PositivePressure_Add, position : %d", position);
+                            if(bv.SetPosition(position))
+                                bvposition = position;
+                        }
 
 
-                }else{
+                    }else{
 
-                    if(0 == stable_counts){
-                        qDebug(" PositivePressure_Add, NULL = pPIDouter NULL == pPIDinner ");
+                        if(0 == delay_count){
+                            qDebug(" PositivePressure_Add, NULL = pPIDouter NULL == pPIDinner ");
+                        }
+
+                        //qDebug(" PositivePressure_Add, NULL = pPIDouter NULL == pPIDinner ");
                     }
 
-                    //qDebug(" PositivePressure_Add, NULL = pPIDouter NULL == pPIDinner ");
-                }
 
 
             }
         }
 
-        if(count >= holding_time){ //about 60s
+        if(count >= keep_times){ //about 60s
             break;
         }
 
@@ -785,7 +821,7 @@ Ret_Value  TestService::PositivePressure_Add(const TestExpect& expect, bool bSav
 
         }
 
-        QThread::msleep(500);
+        QThread::msleep(interval_time);
 
         int remainingtime = expect.timeout*1000 - timer.elapsed();
         if(remainingtime <= 0){
@@ -993,6 +1029,7 @@ Ret_Value  TestService::Pressure_Relief(const TestExpect& expect)
     Valve vent_v(&m_SerialUi3, VALVE_VENT);
 
     float current_pressure;
+    float last_pressure = calculate_averagepressure();
 
     QElapsedTimer  timer;
     timer.start();
@@ -1000,6 +1037,7 @@ Ret_Value  TestService::Pressure_Relief(const TestExpect& expect)
 
     //打开泄压阀
     bOpen_ventv = vent_v.Open();
+    //last_pressure = calculate_averagepressure();
 
     //等待压力清零
     while(m_bRunning){
@@ -1010,19 +1048,18 @@ Ret_Value  TestService::Pressure_Relief(const TestExpect& expect)
 
         current_pressure = calculate_averagepressure();
 
-        if(current_pressure <= 0.02){
+
+        if(fabs(current_pressure - last_pressure) <= 0.01){
             qDebug(" Pressure_Relief 111  finished");
             count++;
         }else{
             count=0;
         }
 
-        if(count > 10){
-
+        if((count > 5) ||(current_pressure < 0.01)){
             //关闭泄压阀
-            if(vent_v.Close()){
-                break;
-            }
+            vent_v.Close();
+             break;
         }
 
         QThread::msleep(1000);
@@ -1079,7 +1116,7 @@ Ret_Value  TestService::Pressure_Relief()
             count=0;
         }
 
-        if(count > 5){
+        if(count > 0){
             //关闭泄压阀
             vent_v.Close();
             break;
@@ -1088,7 +1125,7 @@ Ret_Value  TestService::Pressure_Relief()
 
         QThread::msleep(1000);
 
-        int remainingtime = 200*1000 - timer.elapsed();
+        int remainingtime = 60*1000 - timer.elapsed();
         if(remainingtime < 0){
             ret_v = Ret_Timeout;
             qDebug("timeout, Pressure_Relief Timeout");
@@ -1110,8 +1147,8 @@ Ret_Value  TestService::Pressure_Keep(int keeptime, float& start_value, float& e
     Ret_Value ret_v = Ret_OK;
 
     start_value = calculate_averagepressure();
-    int _ipressure = start_value*10;
-    start_value = _ipressure/10.0;
+    int _ipressure = start_value*100;
+    start_value = _ipressure/100.0;
 
     while((count < keeptime) && m_bRunning){
        QThread::msleep(1000);
@@ -1120,8 +1157,8 @@ Ret_Value  TestService::Pressure_Keep(int keeptime, float& start_value, float& e
 
     end_value = calculate_averagepressure();
 
-    _ipressure = end_value*10;
-    end_value = _ipressure/10.0;
+    _ipressure = end_value*100;
+    end_value = _ipressure/100.0;
 
 
     if(!m_bRunning){
@@ -1235,14 +1272,16 @@ void TestService::run()
 {
     qDebug("doTest >>>enter ");
     QString notice_str;
-    QElapsedTimer  q_time;
+    //QElapsedTimer  q_time;
     int ret_btn = QMessageBox::NoButton;
     TestExpect texpect;
     bool bQuit = false;
 
-    q_time.start();
+    //q_time.start();
     Ret_Value ret_v = Ret_OK;
 
+    m_bRealEnd = false;
+
     if(m_compartmentid >= 0){
 
         if(m_direction == Test_Direction_Positive){
@@ -1404,6 +1443,14 @@ void TestService::run()
 
                             ret_v = Pressure_Keep(5*60, start_value, end_value);
 
+                            float offset = 0;
+                            //修正 强制初始压力为 0
+                            if(start_value != 0.0){
+                                offset = start_value;
+                                start_value = 0.0;
+                                end_value -= offset;
+                            }
+
                             m_tank.m_comparts[m_compartmentid].m_result.valvestart_pressure = start_value;
                             m_tank.m_comparts[m_compartmentid].m_result.valveend_pressure = end_value;
 
@@ -1431,8 +1478,6 @@ void TestService::run()
 
                         }
 
-
-
                     }
                     break;
                 case Test_Step_reliefPressure:
@@ -1445,7 +1490,7 @@ void TestService::run()
 
                         texpect.volume = 0;
                         texpect.target = 0.0;
-                        texpect.timeout = 120;//m_tank.m_comparts[m_compartmentid].get_adjust_timeout();
+                        texpect.timeout = 60;//m_tank.m_comparts[m_compartmentid].get_adjust_timeout();
                         ret_v = Pressure_Relief(texpect);
                         if(Ret_Exit == ret_v){
                             bQuit = true;
@@ -1540,8 +1585,8 @@ void TestService::run()
 
                              texpect.volume = 0;
                              texpect.target = 4.50;
-                             texpect.timeout = 3*60; //5分钟
-                             ret_v = PositivePressure_Add(texpect, true);
+                             texpect.timeout = 3*60; //3分钟
+                             ret_v = PositivePressure_Add(texpect);
 
                              if(Ret_Exit == ret_v){
                                 bQuit = true;
@@ -1692,7 +1737,8 @@ void TestService::run()
     Valve all_v(&m_SerialUi3, ALL_VALVE);
     all_v.Close();
 
-    dump_comstatistic();
+    //dump_comstatistic();
+    m_bRealEnd = true;
 
 
     qDebug("doTest >>>leave ");

+ 1 - 0
TestService.h

@@ -174,6 +174,7 @@ private:
    //QThread       m_Thread;
    int           m_compartmentid;
    bool          m_bRunning;
+   bool          m_bRealEnd;
 
    Tanker        m_tank;
    //QString       m_standardname;

+ 2 - 0
ValveTest.pro

@@ -11,6 +11,7 @@ QT += virtualkeyboard axcontainer
 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 
 SOURCES += \
+        Calibrationpara.cpp \
         ComStatistics.cpp \
         DLog.cpp \
         Modbus.cpp \
@@ -44,6 +45,7 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
 !isEmpty(target.path): INSTALLS += target
 
 HEADERS += \
+    Calibrationpara.h \
     ComStatistics.h \
     DLog.h \
     Modbus.h \

+ 1 - 1
ValveTest.pro.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 8.0.0, 2023-05-09T09:16:00. -->
+<!-- Written by QtCreator 8.0.0, 2023-05-15T11:32:56. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>

+ 14 - 2
ballvalve.cpp

@@ -64,6 +64,7 @@ bool BallValve::SetPosition(unsigned short value)
     rx_buf = m_pSerial->serialWriteReponse(tx_buf);
     if(rx_buf.size() > 0){
         if(check_crc(rx_buf)){
+            g_BallValve_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
             qDebug("SetPosition <<< check crc failed");
@@ -81,6 +82,9 @@ bool BallValve::SetPosition(unsigned short value)
 bool BallValve::GetWorkStatus(unsigned char& status)
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
+
     char zero = 0x00;
 
     tx_buf.append(BALLVALVE_BUS_ADDRESS);
@@ -108,7 +112,7 @@ bool BallValve::GetWorkStatus(unsigned char& status)
         if(check_crc(rx_buf)){
 
             status = rx_buf.at(4);
-
+            g_BallValve_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
             qDebug("GetWorkStatus <<< check crc failed");
@@ -125,6 +129,9 @@ bool BallValve::GetWorkStatus(unsigned char& status)
 bool BallValve::GetPosition(unsigned short& value)
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
+
     char zero = 0x00;
 
     tx_buf.append(BALLVALVE_BUS_ADDRESS);
@@ -154,7 +161,7 @@ bool BallValve::GetPosition(unsigned short& value)
             unsigned char dath = rx_buf.at(3);
             unsigned char datl = rx_buf.at(4);
             value = (dath << 8)|datl;
-
+            g_BallValve_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
             qDebug("GetPosition <<< check crc failed");
@@ -172,6 +179,9 @@ bool BallValve::GetPosition(unsigned short& value)
 bool BallValve::GetSP(unsigned char& status, unsigned short& value)
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
+
     char zero = 0x00;
 
     tx_buf.append(BALLVALVE_BUS_ADDRESS);
@@ -203,6 +213,8 @@ bool BallValve::GetSP(unsigned char& status, unsigned short& value)
             unsigned char datl = rx_buf.at(6);
             value = (dath << 8)|datl;
 
+            g_BallValve_Statistics.Update_Recvtime(timer.elapsed());
+
             return true;
         }else{
             qDebug("GetSP <<< check crc failed");

+ 9 - 0
main.cpp

@@ -6,6 +6,7 @@
 
 #include "TestService.h"
 #include "Standard.h"
+#include "Calibrationpara.h"
 
 #include "DLog.h"
 
@@ -16,6 +17,13 @@ QObject *standardmananger_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
     return StandardManager::instance();
 }
 
+QObject *calibrationpara_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+    Q_UNUSED(engine)
+    Q_UNUSED(scriptEngine)
+    return CalibrationPara::instance();
+}
+
 
 int main(int argc, char *argv[])
 {
@@ -33,6 +41,7 @@ int main(int argc, char *argv[])
 
 
     qmlRegisterSingletonType<StandardManager>("TService", 1, 0, "StandardManager",standardmananger_provider);
+    qmlRegisterSingletonType<StandardManager>("TService", 1, 0, "CalibrationPara",calibrationpara_provider);
 
     qmlRegisterType<TestService>("TService",1,0,"TestService");
 

+ 2 - 2
main.qml

@@ -83,7 +83,7 @@ Window {
     }
 
 
-/*
+
     Item {
         id: cornerItem
         x: 0
@@ -92,7 +92,7 @@ Window {
 
     property int activeFocusItemBottom : activeFocusItem == null ? 0 : Math.min(height, cornerItem.mapFromItem(activeFocusItem, 0, activeFocusItem.height).y + 50)
 
-*/
+
 
     Loader{
         id:myLoder

+ 25 - 23
pid.cpp

@@ -18,7 +18,7 @@ class PIDImpl
     public:
         PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki);
         PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI);
-        PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxStep);
+        PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxIstep, double maxDstep);
         ~PIDImpl();
         double calculate( double setpoint, double pv );
         double calculate_v2( double setpoint, double pv );
@@ -34,7 +34,8 @@ class PIDImpl
         double _pre_error;
         double _integral;
         double _maxI;
-        double _maxStep;
+        double _maxIstep;
+        double _maxDstep;
         double _pre_output;
 
         double _start_pv;
@@ -52,9 +53,9 @@ PID::PID( double dt, double max, double min, double Kp, double Kd, double Ki, do
     pimpl = new PIDImpl(dt,max,min,Kp,Kd,Ki,maxI);
 }
 
-PID::PID( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxStep)
+PID::PID( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxIstep, double maxDstep)
 {
-    pimpl = new PIDImpl(dt,max,min,Kp,Kd,Ki,maxI, maxStep);
+    pimpl = new PIDImpl(dt,max,min,Kp,Kd,Ki,maxI, maxIstep, maxDstep);
 }
 
 double PID::calculate( double setpoint, double pv )
@@ -92,7 +93,8 @@ PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, doubl
     _integral(0)
 {
     _maxI = 0;
-    _maxStep = 0;
+    _maxIstep = 0;
+    _maxDstep = 0;
 
     _pre_output = 0;
     _start_pv = 0;
@@ -114,7 +116,8 @@ PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, doubl
     _integral(0),
     _maxI(maxI)
 {
-    _maxStep = 0;
+    _maxIstep = 0;
+    _maxDstep = 0;
     _pre_output = 0;
     _start_pv = 0;
     _critical_output = 0;
@@ -124,7 +127,7 @@ PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, doubl
 /**
  * Implementation
  */
-PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxStep) :
+PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxIstep, double maxDstep) :
     _dt(dt),
     _max(max),
     _min(min),
@@ -134,7 +137,8 @@ PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, doubl
     _pre_error(0),
     _integral(0),
     _maxI(maxI),
-    _maxStep(maxStep)
+    _maxIstep(maxIstep),
+    _maxDstep(maxDstep)
 {
     _pre_output = 0;
     _start_pv = 0;
@@ -153,7 +157,10 @@ double PIDImpl::calculate( double setpoint, double pv )
     double Pout = _Kp * error;
 
     // Integral term
-    _integral += error * _dt;
+    if(setpoint < 0.05){
+        _integral += error * _dt;
+    }
+
 
     double Iout = _Ki * _integral;
 
@@ -176,25 +183,20 @@ double PIDImpl::calculate( double setpoint, double pv )
     //double output = Pout + Iout + Dout;
     double output = Pout + Iout ;//+ Dout;
 
-    // Restrict to max/min
-    if( output > _max )
-        output = _max;
-    else if( output < _min )
-        output = _min;
-
     // Save error to previous error
     _pre_error = error;
 
-    if(_maxStep > 0){
-
-        if(output - _pre_output > _maxStep){
-            output = _pre_output + _maxStep;
-        } else if(_pre_output - output > _maxStep){
-            output = _pre_output - _maxStep;
-        }
-
+    if(_maxIstep > 0 && output - _pre_output > _maxIstep){
+        output = _pre_output + _maxIstep;
+    }else if(_maxDstep > 0 && _pre_output - output > _maxDstep){
+        output = _pre_output - _maxDstep;
     }
 
+    // Restrict to max/min
+    if( output > _max )
+        output = _max;
+    else if( output < _min )
+        output = _min;
 
     _pre_output = output;
 

+ 10 - 1
pid.h

@@ -23,7 +23,16 @@ class PID
         //maxI - maximum value of Intergrate
         PID( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI);
 
-        PID( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxStep);
+        // Kp -  proportional gain
+        // Ki -  Integral gain
+        // Kd -  derivative gain
+        // dt -  loop interval time
+        // max - maximum value of manipulated variable
+        // min - minimum value of manipulated variable
+        //maxI - maximum value of Intergrate
+        //maxIstep  the max step of increase
+        //maxDstep  the max step of decrese
+        PID( double dt, double max, double min, double Kp, double Kd, double Ki, double maxI, double maxIstep, double maxDstep);
 
 
         // Returns the manipulated variable given a setpoint and current process value

+ 1 - 0
qml.qrc

@@ -41,5 +41,6 @@
         <file>img/shutdown_blue.png</file>
         <file>img/shutdown_red.png</file>
         <file>img/tj_icon.png</file>
+        <file>PageCalibration.qml</file>
     </qresource>
 </RCC>

+ 4 - 0
serialui.cpp

@@ -72,6 +72,10 @@ QByteArray SerialUi::serialWriteReponse(QByteArray sendData)
     bool ret = spy.wait(500);
     if(ret == true)
         data = mSerialPort->serialRead();
+    else{
+        for(int i = 0; i<sendData.length(); i++)
+            qDebug("timeout :0x%x ", sendData.at(i));
+    }
 
     //qDebug() << __TIME__;
     //qDebug("serialWriteReponse leave data.size: %d ", data.size());

+ 3 - 11
tank.cpp

@@ -47,21 +47,13 @@ int Compartment::get_addpressure_timeout()
 {
     int timeout = 0;
 
-    if(m_volume > 30000){
-        timeout = 60*60;
-    }else if(m_volume > 15000){
-        timeout = 45*60;
-    }else if(m_volume > 10000){
-        timeout = 30*60;
-    }else if(m_volume > 5000){
-        timeout = 15*60;
+    if(m_volume > 5000){
+        timeout = 10*60;
     }else if(m_volume > 1000){
         timeout = 5*60;
-    }else{
-        timeout = 3*60;
     }
 
-    timeout = 30*60;
+    timeout = 5*60;
 
     return timeout;
 }

+ 15 - 3
valve.cpp

@@ -1,5 +1,7 @@
 #include "valve.h"
 #include "Modbus.h"
+#include <QTimer>
+#include <QElapsedTimer>
 
 #include "ComStatistics.h"
 
@@ -32,6 +34,8 @@ bool Valve::check_crc(QByteArray data)
 bool Valve::Open()
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
 
     char zero = 0x00;
     tx_buf.append(RELAY_ADDRESS);
@@ -66,6 +70,7 @@ bool Valve::Open()
     if(rx_buf.size() > 0){
         if(check_crc(rx_buf)){
             //qDebug("Valve_op ok  valve_id[%d], op[%d] ", id, op);
+            g_RelayControl_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
             qDebug("Valve Open crc failed  valve_id[%d]", m_id);
@@ -82,6 +87,8 @@ bool Valve::Open()
 bool Valve::Close()
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
 
     char zero = 0x00;
     tx_buf.append(RELAY_ADDRESS);
@@ -115,6 +122,7 @@ bool Valve::Close()
     if(rx_buf.size() > 0){
 
         if(check_crc(rx_buf)){
+            g_RelayControl_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
             qDebug("Valve close crc failed  valve_id[%d]", m_id);
@@ -131,6 +139,8 @@ bool Valve::Close()
 bool Valve::ReadStatus()
 {
     QByteArray tx_buf;
+    QElapsedTimer  timer;
+    timer.start();
 
     char zero = 0x00;
     tx_buf.append(RELAY_ADDRESS);
@@ -152,11 +162,13 @@ bool Valve::ReadStatus()
     QByteArray rx_buf;
     rx_buf = m_pSerial->serialWriteReponse(tx_buf);
     if(rx_buf.size() > 0){
-        for(int i=0; i<rx_buf.size(); i++){
-            qDebug("ReadStatus rx_buf[%d]: 0x%X", i, rx_buf.at(i));
-        }
+
+        //for(int i=0; i<rx_buf.size(); i++){
+        //    qDebug("ReadStatus rx_buf[%d]: 0x%X", i, rx_buf.at(i));
+        //}
 
         if(check_crc(rx_buf)){
+            g_RelayControl_Statistics.Update_Recvtime(timer.elapsed());
             return true;
         }else{
             qDebug("Valve ReadStatus crc failed  valve_id[%d]", m_id);