The physical connection is as follows. Each serial port is attached to multiple collectors.
Communication Protocol:
Baotou (1B) + address code (1B) + command word (1B) + Data Length (1B) + Verification Code 1 (1B) + Data body (NB) + Verification Code 2 (1B ).
Here, verification code 1 verifies the address code, command word, data length, and Verification Code 2 verifies the data body.
1.Concurrent Communication, High performance. The order in which commands are delivered may be different from the order in which data is returned. To ensure that concurrency can communicate properly, the returned data packet will not be broken in the receiving buffer, that is, data such as the first 6 bytes of Package A, the first 6 bytes of Package B, and the last 10 bytes of Package A will not appear. There may be a problem: A> will the sending buffer be messy when writing more (such as 50) commands to the sending buffer consecutively? B> how to calculate a collection device timeout? C> Can I balance the speed at which commands are sent with the speed at which data is returned?
First, you should know that multiple collection devices are connected to the same serial port through the serial rw.bus, while the bus can only allow one device to send data at a certain time, and all other devices can receive the data.
There are three prerequisites for concurrent serial communication: A> using r485 bus instead of r232; B> multiple devices are mounted on the same serial port; C> using a lower-computer to collect data takes a long time to process and return data. If a 20-channel device is mounted and each device needs to return data 10 ms after receiving the command (5 ms communication + 5 data preparation), it takes 200 ms for one round robin, such real-time performance should be acceptable. However, if 200 ms (5 ms communication + 3900 MS data preparation) is required after each command is received, a total of MS is required for One-Step round-robin. Such real-time performance is poor, it is often unable to meet the requirements. We can allow ms of concurrency at all.
Figure 4 data stream of Serial Communication
Serial Port concurrency and time are as follows:
A> send all (20) device data preparation commands in one round robin;
B> after each device receives the query command of its own address code, it starts to prepare data (MS concurrency );
C> the host machine waits for 300 ms;
D> the data of the log collector sent by the host computer;
E> after receiving a Data command from the user, a user returns B> prepared data (10 ms );
F> after receiving data from a local computer, the host computer processes and displays the data, and then executes D>
Total time consumption: 300 (wait for each route to complete 195) + 10*20 = 500 ms
Figure 2 the serial port concurrency process is actually impossible, because the control of the serial port bus can only be performed through step d-f.
The serial port synchronization time is as follows:
A> the data of the log collector is requested by the host computer;
B> prepare data (195 ms) and return data (5) After a user receives the request data command );
C> after receiving data from the lower computer, the upper computer processes and displays the data, and then executes a>
Total time consumption: (195 + 5) * 20 = 4000 Ms
2.Single-step Communication, The single-step communication performance is slightly poor. A> How can I more effectively wait for the current data to return?
CodeSection 1 (single-step serial port solution 1. The sending thread and the receiving event thread are synchronized through iswaitingreceive. Is there any problem with iswaitingreceive multi-thread control ?) :
Private bool iswaitingreceive = false;
Private void sendmediathread ()
{
While (true)
{
If (! Iswaitingreceive) // you can issue a round-robin command.
{
Sendonecmd ();
Iswaitingreceive = true;
}
Thread. Sleep (50 );
}
}
Private int curdeviceno = 0;
Private int totaldevicecnt = 20;
Private void sendonecmd ()
{
// Send a command request to the address code curdeviceno Device
M_serialport.write (BUF, offset, count );
// Poll the device
++ Curdeviceno;
If (curdeviceno> = totaldevicecnt) curdeviceno = 0;
}
Private byte [] m_rcvbuf = new byte [1, 512];
Private int rcvcnt = 0;
Private void serialport_datareceived (Object sender, serialdatareceivedeventargs E)
{
Int nlen = m_serialport.read (m_rcvbuf, rcvcnt, m_serialport.bytestoread );
Rcvcnt + = nlen;
// Search for valid and complete data packets in global m_rcvbuf to parse and process services
······
If (curdeviceno = address code in the current packet)
Iswaitingreceive = false;
}
Code Segment 2 (single-step serial port solution 2, which processes sending and receiving in the same thread ):
Private int totaldevicecnt = 20;
Private void comcmdthread ()
{
Byte [] Barr = NULL;
While (true)
{
For (INT I = 0; I <totaldevicecnt; I ++) // round robin
{
Barr = sendonecmd (I );
If (Barr! = NULL)
{
Dealdata (Barr );
}
}
Thread. Sleep (200 );
}
}
Private byte [] sendonecmd (INT curno)
{
Byte [] brcv = NULL;
M_serialport.discardinbuffer (); // clear unnecessary data before the receiving Cache
M_serialport.write (BUF, offset, count); // send a command to the curno Device
Thread. Sleep (50); // latency, waiting for the lower computer to return data
Int nstarttime = environment. tickcount;
While (true)
{
If (environment. tickcount-nstarttime> 100) // timeout
{
Console. writeline ("waiting for timeout ...");
Break;
}
If (m_serialport.bytestoread> = 25) // If a complete data packet is fixed to 25 bytes
{// If it is not a fixed length, you can enter the global Buf and then find and parse valid data packets
Brcv = new byte [25];
Int nlen = m_serialport.read (brcv, 0, 25); // these three 25 values can be replaced by other variables.
Break;
}
// Thread. Sleep (10); // check whether the requirement is allowed.
}
Return brcv;
}
Private void dealdata (byte [] data)
{
// Analyze and verify the validity of data packets
······
// Process the business data of a valid package
······
}