1

I need to send commands to a serial port to communicate with a Enfora modem. For every command, I will get a reply but the length of the reply string may vary. I need to know how write and then wait for the reply until it finishes...

So i thought of making a thread that reads from the serial port and the program only writes...

The thread function

private void thread_Handler()
{
    while(true)
        this.read();
}
private void read()
{
    if (this.rtbMessages.InvokeRequired)
    {
        try
        {
            SetTextCallback d = new SetTextCallback(read);
            this.Invoke(d);
        }
        catch{}
    }
    else
    {
        readBuffer = serialPort.ReadExisting();
        rtbMessages.AppendText(readBuffer);
    }
}

So this thread is always trying to read from the com PORT and I send the messages this way

writeBuffer = "COMMAND 1";
serialPort.Write(writeBuffer);
writeBuffer = "COMMAND 2";
serialPort.Write(writeBuffer);

However I don't get the reply from the second command I send with Write()... I tried removing the thread and using ReadExisting() after every Write() but that also didn't work.

The only way I could get it to work was to add a

System.Threading.Thread.Sleep(1000);

after every call to Write, then I get all the replies from every Write() command... But I don't want to use this, I want to know of another way to effectively write and get every reply from every command I send regardless of the length of the reply string and how long it takes for me to receive the reply message.

Sometimes I will keep getting messages forever until I send another command to stop generating messages.

Thank you!

Renato
  • 193
  • 1
  • 4
  • 16

2 Answers2

2

.Net will do all this for you.

Just create a SerialPort and subscribe to its DataReceived event. (Note that under some circumstances you may need to stitch together several chunks of data that are received in this way in order to assemble a complete data packet, but if it's a short reply from a modem command you'll probably find you always/usually get the full packet each time the event is raised.

Jason Williams
  • 56,972
  • 11
  • 108
  • 137
  • Thanks for your answer I'm using DataReceived event now but that didn't solve my problem... If i send a command I need to wait before sending another command this is because if I send two commands too quickly then the device wont finish doing the first command. So my question is how do I know when I'm ready to send another command. – Renato Sep 11 '12 at 16:25
  • There are a couple of things to consider: First, are you trying to send commands while the device is trying to respond to you? If this is happening then you probably just need to enable some form of flow control to stop both ends "talking at once" (this will depend on the device: RTS/CTS, Xon/XOff etc). – Jason Williams Sep 12 '12 at 15:21
  • Secondly, the device may not like you sending messages too fast. If it sends replies to your messages then you should wait until you receive the reply before you start sending a new message. If not, then you may have to introduce an artificial delay (e.g. using a Sleep() or Timer callback) so that you don't send messages to the device too fast (but this is unlikely to be a problem - most devices will buffer the commands you send and just dea with them as soon as they can) – Jason Williams Sep 12 '12 at 15:22
  • @JasonWilliams Can you help me in this:https://stackoverflow.com/questions/55026042/wait-for-response-from-the-serial-port-and-then-send-next-data – Prashant Pimpale Mar 11 '19 at 07:25
0

Use an Event to receive the data.

Here is an example from DreamInCode (you will have to customize it to your particular needs):

/// <summary>
/// This method will be called when there's data waiting in the comport buffer
/// </summary>
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    //determine the mode the user selected (binary/string)
    switch (CurrentTransmissionType)
    {
        //user chose string
        case TransmissionType.Text:
            //read data waiting in the buffer
            string msg = comPort.ReadExisting();
            //display the data to the user
            DisplayData(MessageType.Incoming, msg + "\n");
            break;
        //user chose binary
        case TransmissionType.Hex:
            //retrieve number of bytes in the buffer
            int bytes = comPort.BytesToRead;
            //create a byte array to hold the awaiting data
            byte[] comBuffer = new byte[bytes];
            //read the data and store it
            comPort.Read(comBuffer, 0, bytes);
            //display the data to the user
            DisplayData(MessageType.Incoming, ByteToHex(comBuffer) + "\n");
            break;
        default:
            //read data waiting in the buffer
            string str = comPort.ReadExisting();
            //display the data to the user
            DisplayData(MessageType.Incoming, str + "\n");
            break;
    }
}

http://www.dreamincode.net/forums/topic/35775-serial-port-communication-in-c%23/

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501