-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
124 lines (100 loc) · 3.31 KB
/
main.cpp
File metadata and controls
124 lines (100 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <Windows.h>
#include "snap7.h"
#include <chrono>
#include <thread>
#include <mutex> // For synchronization
using namespace std;
TS7Client* Client;
int Rack = 0;
int Slot = 1;
int DB_NUMBER = 32;
const char* Address = "192.168.1.5";
// Define buffer size
const int BufferSize = 64;
byte MyDB35[BufferSize]; // Buffer to hold data
int readStart = 256;
int writeStart = 0;
int stringLength = 32;
std::mutex mtx; // Mutex for synchronizing read/write access
// Function to connect to the PLC
void plc_Connect() {
Client = new TS7Client;
int result = Client->ConnectTo(Address, Rack, Slot);
if (result == 0) {
cout << "Connected to PLC." << endl;
} else {
cout << "Failed to connect to PLC. Error: " << CliErrorText(result) << endl;
delete Client;
exit(1);
}
}
// Function to disconnect from the PLC
void plc_Disconnect() {
Client->Disconnect();
delete Client;
cout << "Disconnected from PLC." << endl;
}
// Asynchronous read function
void asyncRead(int length) {
TS7DataItem readItem;
readItem.Area = S7AreaDB;
readItem.WordLen = S7WLByte;
readItem.Result = 0;
readItem.DBNumber = DB_NUMBER;
readItem.Start = readStart;
readItem.Amount = length;
readItem.pdata = MyDB35;
// Lock the mutex to prevent simultaneous access
std::lock_guard<std::mutex> lock(mtx);
int result = Client->ReadMultiVars(&readItem, 1);
if (result != 0) {
cout << "ReadMultiVars failed. Error: " << CliErrorText(result) << endl;
}
}
// Asynchronous write function
void asyncWrite(const char* dataToWrite, int length) {
TS7DataItem writeItem;
writeItem.Area = S7AreaDB;
writeItem.WordLen = S7WLByte;
writeItem.Result = 0;
writeItem.DBNumber = DB_NUMBER;
writeItem.Start = writeStart;
writeItem.Amount = length;
writeItem.pdata = (void*)dataToWrite;
// Lock the mutex to prevent simultaneous access
std::lock_guard<mutex> lock(mtx);
int result = Client->WriteMultiVars(&writeItem, 1);
if (result != 0) {
cout << "WriteMultiVars failed. Error: " << CliErrorText(result) << endl;
}
}
int main() {
// Connect to the PLC
plc_Connect();
// Main loop for multi-variable reading and writing
const char* data = "OptimizedDataFlow";
while (true) {
// Start timing
auto start = std::chrono::high_resolution_clock::now();
// Perform asynchronous read and write sequentially
std::thread readThread(asyncRead, stringLength);
std::thread writeThread(asyncWrite, data, stringLength);
// Wait for both threads to complete
readThread.join();
writeThread.join();
// End timing and calculate the cycle time
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> cycleTime = end - start;
// Calculate and print the update frequency
if (cycleTime.count() > 0) {
double frequency = 1000.0 / cycleTime.count(); // Frequency in Hz
cout << "Cycle time: " << cycleTime.count() << " ms, Frequency: " << frequency << " Hz" << endl;
}
// Optional: Add a short sleep to reduce CPU load (adjust or remove as needed)
//Sleep(1);
}
// Disconnect from the PLC
plc_Disconnect();
return 0;
}