Abstract: This paper introduces a communication system between a host computer and a PLC developed using VC++ and MFC. The communication principle and software design method of the system are presented. Practice has proven that the entire system operates stably and has strong practicality and scalability.
Keywords: PLC, VC++, MFC, communication mode
1 Overview
PLCs (Programmable Logic Controllers), as a new generation of industrial controllers, have been widely used in industrial measurement and control systems due to their high performance-to-price ratio. With the continuous development of microelectronics and control technology, PLCs have gradually become intelligent and integrated controllers, and distributed control systems based on PLCs are an important component of modern industrial control. In many small distributed control systems, using professional industrial control configuration software such as INTOUCH and FIX to create a monitoring interface for the host computer, and using a dedicated PLC communication interface module and the manufacturer-recommended DDE Server as the bridge between the host computer and the PLC, results in high costs and significant investment. Therefore, direct communication between the host computer and the PLC is a better technical solution.
Developing communication systems with industrial PLCs in a Windows environment can be done using C++ and the application programming interface functions provided by the Windows SDK, but this approach results in complex programs. Alternatively, Visual Basic can be used to develop serial communication programs, which are much simpler to program. However, in reality, many large application systems are developed based on the VC++ platform. VC++ is currently the most complex but also the most powerful Windows application development software. It has strong advantages in graphics processing and database management, and using it to implement low-level communication control is more efficient. Interfaces designed using MFC are as concise as those designed using Visual Basic. Therefore, we utilize the MSComm communication control provided by VC++ 6.0, using MFC to design the interface and program to construct a communication system with the PLC. The PLC in the system is a Siemens S7-200 series CPU226.
2. System Communication Principles
The Siemens S7-226 PLC is a modular, small PLC with a high performance-to-price ratio. It has two RS485 communication ports, while the host computer (industrial control computer) uses an RS232 serial port. Therefore, a Siemens-specific PC/PPI programming cable is used as the connection cable between the host and host computers. This cable enables RS232 to RS485 conversion and provides isolation and anti-interference capabilities. The overall system schematic is shown in Figure 1.
Figure 1 Communication System Principle
The CPU226's built-in RS485 communication port uses half-duplex communication, requiring only two data lines, TXD and RXD, to send and receive data. Therefore, there is no hardware handshake signal; instead, a software handshake is used to maintain data transmission synchronization. To ensure communication security, a Frame Check Sequence (FCS) must be added to the transmitted data frames. This is done by performing an XOR operation on the data in the transmitted frame byte by byte, and sending the FCS along with the data. The receiver performs the same operation and compares the result with the FCS. If they are not equal, the transmitted data is considered erroneous. Erroneous data is discarded, and a feedback signal is immediately sent to request the sender to retransmit the data. Therefore, the data formats sent by the host computer and PLC are shown in Tables 1 and 2, respectively. Control commands such as request and response signals do not require a checksum.
Table 1. Host Computer Data Format
Table 2 PLC Data Format
3. System Software Design
3.1 System Control Flow
The entire communication process is triggered by the host computer. First, the host computer sends a handshake signal. Upon receiving the handshake signal, the PLC sends a return handshake signal. Upon receiving the return handshake signal, the host computer sends a request command. The PLC receives the command and sends data to the host computer. The host computer receives the data and verifies it. If an error occurs, it requests the PLC to resend the data; otherwise, it processes the output and displays it. Figures 2 and 3 below show the communication program flowcharts between the host computer and the PLC, respectively.
Figure 2 Flowchart of the host computer program Figure 3 Flowchart of the PLC program
3.2 PLC Software Design
The S7-200 series PLC offers two communication modes: Point-to-Point (PPI) communication and a free port mode, which is fully open to the user. PPI mode is used for direct communication between PLCs, enabling network formation. Free port mode is used for wireless communication between PLCs and computers, as well as between PLCs themselves. This communication system uses free port mode. Before communication, the communication mode is selected by rewriting the SMB30 or SMB130, setting the baud rate, data length, and parity. For data transmission, the dedicated transmit instruction XMT TABLE, PORT is used. TABLE is the starting address of the transmit buffer, storing the number of bytes to be transmitted (i.e., the data length), with a maximum of 255. Subsequent addresses store the data to be transmitted, and PORT specifies the port used for transmission. For data reception, the receive instruction RCV TABLE, PORT is used. This instruction activates initialization or terminates reception, receives information through the specified port (PORT), and stores it in the data buffer (TABLE). The first data item in the data buffer indicates the number of bytes received. In the Siemens PLC programming language, there are 33 interrupt events, 6 of which are for communication ports. During communication, we use interrupts to switch between sending and receiving data. When data transmission is complete, a "send character" interrupt event is generated, and the interrupt routine switches to the receiving state. When data reception is complete, a "receive information complete" interrupt event is generated, and the interrupt routine switches back to the sending state. Since there is a certain interval between sending and receiving, a delay is necessary before sending data. We use timer interrupts to generate this delay. To generate a "receive information complete" interrupt event, the RCV instruction must be set with an end message as a condition for determining reception completion. This is done by loading a character into the SMB89 or SMB189, and this character must match the end message sent by the host computer.
The following is a portion of the PLC program:
MAIN (Main Program)
NETWORK 1
LD SM0.1
MOVB 16#09, SMB30 // Initialize free port, select 9600 baud rate, 8-bit data, no parity
MOVB 16#A0, SMB87 //RCV enabled, detects the end character of the message.
MOVB '@', SMB89 // Sets the message ending character to '@'
MOVB 10, SMB94 // Set the maximum number of characters to 10
MOVB 5, SMB34 //Timer interrupt 0 is 5ms
ATCH 0,23 // Receive completion event connected to interrupt 0
ENI // Enable global interrupts
NETWORK 2
RCV VB300, 0 // Receive data
NETWORK 3
LD SM0.0
MOVB 16,VB200 // Send 16 characters
MOVD 16#4521347E, VD201 //The following are experimental data
MOVW +9860, VW205
MOVD 16#12345678, VD207
MOVW +10562, VW211
MOVW +8568, VW213
MOVB 8, VB215
CALL SBR_0
INT_0 (Interrupt 0 subroutine)
NETWORK 1 // If the received character is 'K', continue receiving.
LDB= VB302, 'K'
RCV VB300, 0
NETWORK 2 // If the received character is 'A', 'C', or 'R', then send data.
LDB= VB302, 'A'
OB = VB302, 'R'
OB = VB302, 'C'
ATCH INT_1, 10 // Enable timer interrupt
NETWORK 3 // If the received character is "Z", then
Stop delayed transmission
LDB= VB302, 'Z'
DTCH 10
INT_1 (Interrupt 1 subroutine)
LD SM0.0
XMT VB200, 0 // Send data
DTCH 10 // Disable timer interrupt
3.3 Host Computer Software Design
The host computer software portion of the system utilizes the MSComm communication control provided by VC++, and the communication program is developed based on MFC. The MSComm communication control provides detailed guidelines for developing serial communication software using RS232, employing event-driven or polling methods to solve problems encountered during development. Event-driven programming is a powerful problem-solving approach; the tracking and handling of events in the communication control is implemented using OnComm, which includes detecting and handling communication errors, as well as data processing and display. To clearly understand the on-site working status, the content observed by the camera can be displayed on the interface in real time. For this, the images acquired by the image acquisition card need to be analyzed and processed, which will not be detailed here. Figure 4 shows the communication interface.
The programming method is as follows:
(1) Create a project: Start VC++6.0 and use the MFC AppWizard (exe) application wizard to create a dialog-based application ScommTest.
Figure 4 Communication Interface
(2) Insert the MSComm control into the project: Select the Components and Controls… option in the Add To Project submenu under the Project menu. In the pop-up dialog box, double-click the Registered ActiveX Controls item, select Microsoft Communications Control version 6.0, and click the Insert button to insert it into the Project. Accept the default options.
(3) Add controls to the dialog box: Add communication controls, buttons, text boxes, edit boxes and combo boxes to the main dialog box, some of which are shown in Table 3.
Table 3 Control Property Table
(4) Initialize the serial port: Add code to initialize the serial port parameters in the OnInitDialog() function.
// TODO: Add extra initialization here
if(m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(FALSE);
m_ctrlComm.SetCommPort(1); // Select com1
if(!m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE); // Open the serial port
else
AfxMessageBox("cannot open serial port");
m_ctrlComm.SetSettings("9600,n,8,1"); // Baud rate 9600, no parity, 8 data bits, 1 stop bit
m_ctrlComm.SetInputMode(1); //1: indicates that data is retrieved in binary mode.
m_ctrlComm.SetRThreshold(16); // Parameter 15 indicates that an OnComm event will be triggered whenever there are more than or equal to 15 characters in the serial port receive buffer.
m_ctrlComm.SetInputLen(0); // Sets the current receiving area data length to 0.
m_ctrlComm.GetInput(); // First read the buffer to clear any residual data.
(5) Write the frame verification function: First, add the public member function description to the CSCommTestDlg class.
BYTE PLCData[30]; // Define the input data storage area
Void verfun(BYTE vdata[], int n); // Define the verification function
Then write the frame check function:
void CSCommTestDlg::verfun(BYTE vdata[],int n)
{
int i;
BYTE sum = vdata[0];
for (i=1;i<=n-2;i++)
sum︿=vdata[i]; // Calculate the checksum
vdata[n] = sum; // Store the frame checksum
}
(6) Add the OnComm message handling function OnComm() to the communication control IDC_MSComm1.
void CSCommTestDlg::OnComm()
{
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; // Sets a BYTE array (an 8-bit unsigned integer).
CString strtemp;
if (m_ctrlComm.GetCommEvent() == 2) // An event value of 2 indicates that there are characters in the receive buffer.
{
variant_inp = m_ctrlComm.GetInput(); // Read the buffer
safearray_inp = variant_inp; // Convert a VARIANT type variable to a ColeSafeArray type variable
len = safearray_inp.GetOneDimSize(); // Get the effective data length
for (k=0;k
safearray_inp.GetElement(&k, rxdata+k); // Convert to BYTE array
for (k=0;k
{
PLCData[k] = rxdata[k];
}
verfun(PLCData, 16); // Calculate the checksum
if (PLCData[15]==PLCData[16])
{ //Send confirmation signal if data received correctly}
m_ctrlComm.SetOutput(COleVariant("K@")); // You can add your own data processing below.
if (!m_quit) // If no end signal is received, continue transmitting data.
m_ctrlComm.SetOutput(COleVariant("C@"));
else
m_ctrlComm.SetOutput(COleVariant("Z@"));
}
else // Data reception error, request retransmission
m_ctrlComm.SetOutput(COleVariant("R@"));
(7) Add message handling functions OnButtonStart() and OnButtonQuit() for the buttons IDC_BUTTON_START and IDC_BUTTON_QUIT.
void CSCommTestDlg::OnButtonQuit()
{
m_quit=TRUE;
}
void CSCommTestDlg::OnButtonStart()
{
m_quit=FALSE;
m_ctrlComm.SetOutput(COleVariant("A@")); // Send a request signal
}
4. Conclusion
This paper describes the development of a computer-PLC communication system using VC++ and MFC. It fully utilizes the resources of both the computer and the PLC to achieve real-time monitoring of the PLC by the host computer, enabling effective monitoring and management of the work tools. The communication system described in this paper is used in the control system of an ultra-high voltage live-line working robot. Practice has shown that the system is simple, stable, and has achieved satisfactory results.
References
[1] Li Zhihu et al. Communication between host computer and PLC based on Visual C++. Computer Engineering, 2000(8)
[2] Zhu Zhengli et al. Communication between PLC and host computer based on VC++. Electrical Drive, 2002(2).
[3] Siemens AG. Siemens S7-200 Programmable Controller System Manual, 1999