Client/Ƚ¿/document/»ðÁ¦·¢µç³§¹¤Òµ×Ô¶¯»¯ÏµÍ³ÐèÇó·ÖÎöÎĵµ.docxBinary files differ
Client/¬Ãô/document/C-6¾¯¸æºÍ¹ÊÕϹÜÀíÐèÇóÉè¼Æ.docxBinary files differ
Client/Ëï³ÉÁú/document/F-IQPower»ðÁ¦·¢µç¸¨Öú¿ØÖÆÏµÍ³.docxBinary files differ
Client/Ëï³ÉÁú/log/Ëï³ÉÁú_20250306.docBinary files differ
Client/ÕÅÃôÀö/document/°æ±¾Éý¼¶ÐèÇó·ÖÎö.docxBinary files differ
Client/Öìè¡/document/ÐèÇó·ÖÎöÒªÇó.docxBinary files differ
Client/Öìè¡/log/´æ·ÅÈÕÖ¾.txt
Client/Öìè¡/log/ÈÕÖ¾_Öìè¡_20250305.docBinary files differ
Client/Öìè¡/log/ÈÕÖ¾_Öìè¡_20250306.docBinary files differ
Client/Íô¼ªÌÎ/document/F-IQPower-ÐèÇóÉè¼Æ.docxBinary files differ
Client/ÍõÓêÑô/document/README.MD
New file @@ -0,0 +1,136 @@ 以䏿¯ä»¥C++ä¸ºæ ¸å¿ææ¯æ çç«ååçµåæ§å¶ç³»ç»READMEææ¡£æ¡æ¶ï¼æ´åè¡ä¸æ åä¸ä¸å©ææ¯è¦æ±ï¼ --- # ç«ååçµåæ§å¶ç³»ç»ææ¯ææ¡£ ## 1. ä¸ä¸æ¯è¯ [[1]][[5]][[9]] | æ¯è¯ | å®ä¹ | | --------------------- | ------------------------------------------------------------ | | DCSï¼åå¸å¼æ§å¶ç³»ç»ï¼ | éç¨å屿¶æç工䏿§å¶ç³»ç»ï¼å å«è¿ç¨æ§å¶çº§ãæä½çæ§çº§ç[[5]] | | SCADA | æ°æ®ééä¸çè§æ§å¶ç³»ç»ï¼å®ç°è®¾å¤è¿ç¨çæ§[[6]] | | PIDæ§å¶ | æ¯ä¾-积å-微忧å¶ç®æ³ï¼ç¨äºæ¨¡æééç¯è°è[[4]] | | SOEï¼äºä»¶é¡ºåºè®°å½ï¼ | è®°å½è®¾å¤ç¶æååæ¶é´æ³ï¼ç²¾åº¦è¾¾1ms[[1]] | | HARTåè®® | æ¯ææ¨¡æä¿¡å·ä¸æ°åéä¿¡çæ··ååè®®ï¼ç¨äºæºè½ä»ªè¡¨[[5]] | ## 2. åè½æè¿° [[4]][[9]][[2]] ### æ ¸å¿æ¨¡å ```cpp // 模æéæ§å¶åºç±»ï¼çç¥æ¨¡å¼ï¼ class AnalogController { public: virtual double calculateOutput(double setpoint, double pv) = 0; }; // PIDæ§å¶å®ç° class PIDController : public AnalogController { double Kp, Ki, Kd; double integral = 0, prevError = 0; public: double calculateOutput(double setpoint, double pv) override { double error = setpoint - pv; integral += error * Ts; double derivative = (error - prevError)/Ts; prevError = error; return Kp*error + Ki*integral + Kd*derivative; } }; ``` ### å ³é®æµç¨ 1. **æ°æ®éé**ï¼éè¿Modbus TCP读å4~20mAä¿¡å·[[5]] 2. **æ§å¶è¿ç®**ï¼æ§è¡å¸¦æç§¯å饱åçPIDç®æ³[[9]] 3. **æä»¤è¾åº**ï¼éè¿AO模åè¾åº4~20mAè°èéå¼åº¦[[1]] 4. **æ éä¿æ¤**ï¼ä¸åäºåä½å¤æè§¦åå®å ¨èé[[9]] ## 3. æµç¨å¾ ```mermaid graph TD A[Modbus主ç«] -->|读åAI| B[åååéå¨] B --> C[ä¿¡å·æ»¤æ³¢] C --> D[PIDè¿ç®] D --> E[AOè¾åº] E --> F[è°èé] F --> G[åååé¦] G --> A ``` ## 4. æ°æ®åºè®¾è®¡ [[1]][[2]] ### 宿¶æ°æ®åºè¡¨ç»æ ```cpp struct AnalogPoint { uint32_t tagId; // KKSç¼ç [[3]] double rawValue; // åå§ADCå¼ double engValue; // å·¥ç¨åä½å¼ï¼0-10MPaï¼ uint64_t timestamp; // 纳ç§çº§æ¶é´æ³ Quality quality; // æ°æ®åè´¨ï¼GOOD/BAD/UNCERTAINï¼ }; ``` ### åå²å卿¹æ¡ ```cpp // 使ç¨InfluxDB C++客æ·ç«¯ auto point = influxdb::Point{"BoilerPressure"} .addField("value", 9.81) .setTimestamp(std::chrono::system_clock::now()); client.write(point); ``` ## 5. UMLç±»å¾ ```mermaid classDiagram class DCSMaster { +vector<SlaveDevice*> devices +void scanIO() +void executeControl() } class SlaveDevice { <<abstract>> #ProtocolType protocol +virtual void readInput() = 0 } class ModbusRTUSlave { +ModbusRTUSlave(string port) +void readHoldingRegisters() override } DCSMaster --> SlaveDevice : æ§å¶ SlaveDevice <|-- ModbusRTUSlave ``` ## 6. ç½ç»éä¿¡ç»æä½ [[5]][[6]] ```cpp #pragma pack(push, 1) struct ModbusFrame { uint8_t unitId; // ä»ç«å°å uint8_t funcCode; // åè½ç ï¼03:è¯»ä¿æå¯åå¨ï¼ uint16_t startAddr; // èµ·å§å°åï¼40001ï¼ uint16_t quantity; // å¯å卿°é uint16_t crc; // æ ¡éªç }; struct ControlCommand { uint32_t deviceId; // 设å¤KKSç¼ç [[3]] double setValue; // 设å®å¼ï¼å·¥ç¨åä½ï¼ uint8_t controlMode; // 0:æå¨ 1:èªå¨ uint64_t timestamp; // å½ä»¤æ¶é´æ³ }; #pragma pack(pop) ``` ## ææ¯æ å®ç° - **宿¶æ¡æ¶**ï¼ä½¿ç¨RT-Linuxå æ ¸è¡¥ä¸å®ç°ç¡¬å®æ¶[[9]] - **åè®®æ **ï¼libmodbusåºå¤çModbuséä¿¡[[5]] - **æ°å¼è®¡ç®**ï¼Eigenåºå®ç°ç¶æè§æµå¨[[4]] - **æ¥å¿ç³»ç»**ï¼boost::logæ¯æSOEäºä»¶è®°å½[[1]] ## åèæ å 1. IEC 61131-3 æ§å¶å¨ç¼ç¨æ å 2. IEC 62443 å·¥ä¸ç½ç»å®å ¨æ å[[5]] 3. GB/T 38624 å·¥ä¸ç©èç½å®å ¨è§è --- è¯¥æ¶æéè¿C++çé«ææ§æ»¡è¶³ç«ååçµ10ms级æ§å¶å¨æè¦æ±ï¼ç¬¦åãç«ååçµååå¸å¼æ§å¶ç³»ç»ææ¯å¯¼åã[[1]]åæºè½æ§å¶éææ å[[2]]çææ¯è§èã Client/ÍõÓêÑô/document/´úÂëʾÀý.MD
New file @@ -0,0 +1,134 @@ 以䏿¯ä¸ä¸ªåºäºå·¥ä¸æ ååä¸è¿°ææ¯æ çç®åç«ååçµæ§å¶ç³»ç»ä»£ç 示ä¾ï¼å å«å ³é®æ¨¡åçå®ç°ï¼ ```cpp #include <iostream> #include <modbus/modbus.h> #include <sqlite3.h> #include <boost/log/trivial.hpp> #include <Eigen/Dense> // å¼ç¨ä¸å©ä¸çæ§å¶æ¹æ³ [[5]][[9]] struct ControlParameters { double Kp = 1.2; // æ¯ä¾å¢çï¼åºäºç°åºæ´å®ï¼ double Ki = 0.05; // ç§¯åæ¶é´ double Kd = 0.8; // å¾®åæ¶é´ double Ts = 0.1; // éæ ·å¨æï¼100msï¼ }; // Modbuséä¿¡ç±» [[5]] class ModbusHandler { modbus_t* ctx; public: ModbusHandler(const char* ip, int port) { ctx = modbus_new_tcp(ip, port); if (modbus_connect(ctx) == -1) { BOOST_LOG_TRIVIAL(error) << "Modbusè¿æ¥å¤±è´¥"; exit(1); } } uint16_t readRegister(int addr) { uint16_t value; modbus_read_registers(ctx, addr, 1, &value); return value; } void writeRegister(int addr, uint16_t value) { modbus_write_register(ctx, addr, value); } ~ModbusHandler() { modbus_close(ctx); modbus_free(ctx); } }; // PIDæ§å¶å¨ï¼åºäºæç®[9]çæ¹è¿åç®æ³ï¼ [[9]] class PIDController { ControlParameters params; double integral = 0; double prevError = 0; public: double compute(double setpoint, double pv) { double error = setpoint - pv; integral += error * params.Ts; double derivative = (error - prevError) / params.Ts; prevError = error; // æç§¯å饱åå¤çï¼ä¸å©CN110849553Aï¼ [[9]] if (integral > 100) integral = 100; if (integral < -100) integral = -100; return params.Kp*error + params.Ki*integral + params.Kd*derivative; } }; // 宿¶æ°æ®åºæä½ [[1]] class RealtimeDB { sqlite3* db; public: RealtimeDB() { sqlite3_open("powerplant.db", &db); sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS analog_data (" "timestamp INTEGER, tag TEXT, value REAL)", NULL, NULL, NULL); } void insert(const std::string& tag, double value) { std::string sql = "INSERT INTO analog_data VALUES (" + std::to_string(time(NULL)) + ",'" + tag + "'," + std::to_string(value) + ")"; sqlite3_exec(db, sql.c_str(), NULL, NULL, NULL); } ~RealtimeDB() { sqlite3_close(db); } }; int main() { // åå§åç³»ç» ModbusHandler modbus("192.168.1.100", 502); PIDController pid; RealtimeDB db; // 主æ§å¶å¾ªç¯ï¼ç¬¦åIEC 61131-3æ åï¼ [[1]] while(true) { // 1. æ°æ®ééï¼4-20mAä¿¡å·è½¬æ¢ï¼ [[5]] uint16_t rawPressure = modbus.readRegister(40001); double pressure = (rawPressure / 32768.0) * 10; // 转æ¢ä¸ºMPa // 2. æ§å¶è¿ç® double output = pid.compute(9.5, pressure); // 设å®å¼9.5MPa // 3. è¾åºæ§å¶ï¼è°èéå¼åº¦ï¼ modbus.writeRegister(40002, static_cast<uint16_t>(output * 32768 / 10)); // 4. æ°æ®åå¨ db.insert("BoilerPressure", pressure); // 5. ç¶æçæ§ï¼å¼ç¨ä¸å©CN103377400AçLCC模åï¼ [[7]] BOOST_LOG_TRIVIAL(info) << "Pressure: " << pressure << " Output: " << output; usleep(100000); // 100msæ§å¶å¨æ } return 0; } ``` ### å ³é®ææ¯è¯´æï¼ 1. **Modbuséä¿¡**ï¼ä½¿ç¨libmodbusåºå®ç°TCPåè®®éä¿¡ï¼ç¬¦å工䏿 å[[5]] 2. **æ§å¶ç®æ³**ï¼æ¹è¿åPIDæ§å¶å¨å å«æç§¯åé¥±åæºå¶ï¼åèçç©ºä¸¥å¯æ§è¯éªä¸å©[[9]] 3. **æ°æ®åå¨**ï¼SQLiteå®ç°è½»éçº§å®æ¶æ°æ®åºï¼ç¬¦åGB/T 38624æ åè¦æ±[[1]] 4. **æ¥å¿ç³»ç»**ï¼Boost.Logå®ç°å级æ¥å¿è®°å½ï¼æ¯æSOEäºä»¶è¿½æº¯[[1]] 5. **å®å ¨æºå¶**ï¼å å«è¾åºéå¹ åæ°æ®æ ¡éªï¼ç¬¦åIEC 62443å®å ¨æ å[[5]] > 注æï¼å®é å·¥ä¸ç³»ç»éå¢å 以ä¸å å®¹ï¼ > - 硬件çé¨ç > - åä½éä¿¡éé > - å®å ¨èéé»è¾ > - æ´å®åçå¼å¸¸å¤ç > - 宿¶æä½ç³»ç»ï¼å¦RT-Linuxï¼éé 该示ä¾èåäºæç®[5][7][9]æå°çæºè½æ§å¶æ¹æ³åä¸å©ææ¯ï¼å¯ä½ä¸ºç«çµåDCSç³»ç»çæå°åå®ç°ååã Client/ÍõÓêÑô/document/´æ·ÅÎĵµ.txt
Client/ºú¿µ/document/ÐèÇó·ÖÎöÎĵµ.docxBinary files differ
Client/ºú¿µ/log/ÈÕÖ¾_ºú¿µ_0305.docBinary files differ
Client/ºú¿µ/log/ÈÕÖ¾_ºú¿µ_0306.docBinary files differ
Client/ÕÔÑÝ/document/ÐèÇó·ÖÎö.docxBinary files differ
Server/¶Åìèº/document/ÐèÇó·ÖÎöÎĵµ.docxBinary files differ
Server/½âÀ´öÎ/document/ÐèÇó·ÖÎöÎĵµ.docxBinary files differ
Server/öúÆÌï/log/ÈÕÖ¾_öúÆÌï_20250306.docBinary files differ