Click here to Skip to main content
15,884,085 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi All,

seek for help on the serial port datarecevied.

I have a file stored multiple commands.
I need to send the command one by one to serial port and wait for reply and display for continue sending the other command.

I'm using thread.sleep between each command send but it does not work.

please help.

Thanks

What I have tried:

I'm using thread.sleep between each command send but it does not work. 
Posted
Updated 29-May-18 16:22pm

Stop playing with Thread.Sleep: it probably won't help you.
The way I would do it is to set up a Queue of commands, and use the DataReceived event to get the response. When the response is complete, take the next command off the queue, and send that, and let the DataReceived event process it's response when it arrives.
When the Queue is empty, the set of commands is complete.
 
Share this answer
 
Comments
Member 13627097 29-May-18 22:21pm    
I will read a list of commands from the file and send each command using foreach loop.
I noticed that somehow before data received / display, the next command is send out. And i Believe that caused the issue seeing few commands send and received the reply at the same time.
May I know how the queue is work?
Any sample code?
In general all asynchronous IO operations should be performed in own threads to avoid blocking the application. Otherwise you will have lags in the GUI or the GUI would be blocked completely in the worst case.

For your case you would need at least one thread for receiving replies and transmitting the queued commands.

The receiving thread should buffer data until a full response has been received. How to do this depends on the data (e.g. line feed with text data or after receiving the number of bytes that has been announced in a protocol header).

Once a full response has been received, this is signaled to other threads. In your case this will be the main (GUI) thread to show the response and the transmit queue to enable sending of the next command. Note that passing data from a thread to GUI elements requires special treatment.

The transmit thread can simply send using a blocking call because it has to wait anyway. After sending it has to wait for the response received signal.

You can put sending and receiving into one or two threads.

Pseudo code for receiving (assuming text data):
C#
// Check for kill (terminate thread) event (wait with no timeout)
while (!KillEvent)
{
    do 
    {
        // Blocking call until a character is available
        // Should have a timeout and corresponding handling (break here)
        rxChar = ReceiveChar();
        Buffer += rxChar;
    }
    while (rxChar != '\n');
    // Signal other threads that a response has been received
    // Pass a copy of Buffer to the main thread for display
}

In the transmit thread, after sending a command call the above or wait for the event when receiving is done in an own thread.

Using threads and events you avoid calling sleep which should be generally avoided and ensure that no system time is wasted.
 
Share this answer
 
My SerialDevice class here:
Multithreaded communication for GPIB/Visa/Serial interfaces[^]
implements exactly the process described in Solution2 above: with asynchronous commands the I/O is done in a separate thread which uses simple blocking calls for write/read.

One comment on the solution 1: the DataReceived event is called on a non-UI thread therefore you need to learn something about threading anyway if you want to use it (e.g. the DataReceived handler can call a synchronized callback to avoid problems with shared fields or UI components).
 
Share this answer
 
Between I figured out a solution without using DataReceived handler.
Just write command to the serial port and then read the reply from serial port after the write.
and its working as per what i looking for.

But not sure if this is a right way to do.
Example:
Write();
Read();
 
Share this answer
 
Comments
Pawel Wzietek 30-May-18 3:52am    
Of course it will work, the only problem is that "Read()" will block the thread until the response is received (UI will not respond) this is why we use events. But even without using the DataReceived handler you can make the app more responsive if you set a short timeout and repeat the Read until you get data, something like:

serialport.ReadTimeout=1;
string response = null;
do
Application.DoEvents(); //keep the UI responsive
try
{response = serialport.ReadLine();}
catch (TimeoutException ){}
while (response == null && !abort); //may add an "abort" variable

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900