-1

I'm on my laptop and unable to check this right now, I'm wondering if I open a COM2 connection, and add a receive event for COM2 port, then close the COM2 connection via "serial.Close()" in the program, will I still be able to receive a receive event on COM2 port? Let say if it can still receive, I think I will open the COM2 port connection at the receive event and read the data, can it be done this way?

    SerialPort serial = new SerialPort()
    {
        PortName = "com2",
        BaudRate = 9600,
        Handshake = System.IO.Ports.Handshake.None,
        Parity = Parity.None,
        DataBits = 8,
        StopBits = StopBits.One,
        ReadTimeout = 400,
        WriteTimeout = 200,
    };

 serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Receive);

    private void Receive(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {            
        using (SerialPort serialPort = serial)
        {                
            if (serialPort.IsOpen)
                serialPort.Close();
            try
            {
                serialPort.Open();
                received_data = serialPort.ReadExisting();
                Dispatcher.Invoke(DispatcherPriority.Send, new UpdateUiTextDelegate(WriteMyData), received_data);
            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (serialPort != null)
                {
                    if (serialPort.IsOpen)
                    {
                        serialPort.Close();
                    }
                    Thread.Sleep(5);
                    //serialPort.Dispose();
                }
                Thread.Sleep(5);
            }
        }
    }


    public void SerialCmdSendByte(byte[] hexstring)
    {
        using (SerialPort serialPort = serial)
        {
            if (serialPort.IsOpen)
                serialPort.Close();
            try
            {
                serialPort.Open();


                foreach (byte hexval in hexstring)
                {
                    byte[] _hexval = new byte[] { hexval };
                    serialPort.Write(_hexval, 0, 1);
                    Thread.Sleep(3);
                }                 
            }
            catch (IOException ex)
            {
            }
            finally
            {
                if (serialPort != null)
                {
                    if (serialPort.IsOpen)
                    {
                        serialPort.Close();
                    }
                    Thread.Sleep(5);
                    //serialPort.Dispose();
                }
                Thread.Sleep(5);
            }
        }            
    }

The idea is to only open a connection when I want to send from C# program and close it straight-away, but the same COM port is actually need to listen for communication from PIC-based microcontroller. Currently we are having issue where previously the program never try to close connection (unlike above code), but sometimes the receiving part from PIC-based microcontroller works but the sending part from program doesnt work. This only happens sometime, as normally the program work just fine...

Restarting the system seem to reset this OK. So I was thinking making the code like above will help in my situation(to be able to send, and listen on same COM port)?

user3663854
  • 463
  • 2
  • 8
  • 21
  • Serial ports are operated in following way: open (and keep opened), communicate, close. If it's closed - you don't receive anything nor you can send. You'll have to investigate closely why micro-controller doesn't receive signal until restart (sending from PC works, because it works after reset), could be a mistake in firmware. – Sinatr Jul 01 '15 at 15:01
  • Thanks Sinatr and others for helping me out, I was focusing on the Windows app instead of the PIC controller program. I clean up the code and put some delay here and there, shorten the communication cable, tighten the connector connection and make a check on the controller receive overflow and clearing it, so now it is OK... thanks for the help! – user3663854 Jul 02 '15 at 02:30
  • `SerialPort` class is known for bad implementation. You have too high expectations. Better don't use events. – i486 Aug 07 '23 at 13:35

4 Answers4

0

Unfortunately, no. Only 1 connection to the COM port can be open at a time.

If you have a device listening on that port, then nothing else will be able to send on it.

If you have access to the code that the microcontroller uses to listen on the device, you could always write something that allows you to send a message to the microcontroller and have that device send your COM message.

Otherwise, the only thing you could do is have the microcontroller stop listening on the port, send your message from your code, receive any response that comes back from sending your message, and then reenable the microcontroller's listen features.

EDIT:

Just a note about your code. The using statement is designed to dispose of an object after closing all of its connections when it goes out of scope.

In your code, you are creating a reference to your serial port instance in a using block. If this works as defined, that serial port instance will need to be instantiated before you can call it again.

0

As a complement to jp2code answer and since imagination is the limit, you might want to try a more "out of the box" solution, something similar to Man-In-The-Middle.

THIS POST might give you a better idea about what I'm talking about.

Community
  • 1
  • 1
tweellt
  • 2,171
  • 20
  • 28
0

You cannot communicate or listen on serial port when the port is closed. So the code you have written is absolutely wrong.

Ideally you should not turn off the COM port.

Following can be the reasons why your communication fails.

1.This one seems to be the most probable answer: If the COM port is not closed properly in the previous run, the communication will not take place. In this case you have to reset the system. This takes place when the system gets crashed in between.

  1. When the connectors are not tight, this can occur.

  2. Check if the ground connections are proper.

Let me know if you need help in changing the code.

Akshay Kekre
  • 254
  • 2
  • 10
0

8 years later... so this is probably of no use to the original poster, BUT...

This is probably an excellent use-case for the Reactive Extensions for .NET. Rx can be used to wrap a serial port and expose an IObservable<char> over the received data, which can then have multiple subscribers and be filtered in various ways using LINQ operators and expressions.

I have a whole library built around this concept that abstracts the serial port away entirely and replaces it with the concept of a Communications Channel, which can be implemented with a serial port or some other device (such as a network connection, or a device simulator). Applications don't need to know what type of device they are talking to, so it is really easy to build apps that can work with different types of connection. Configuration is stored as a connection string (an idea borrowed from SQL Server). It also has a mechanism for implementing command-response protocols based on the idea of a transaction, with the benefit of being thread-safe and keeping commands and responses in sync. I've used it with good results in several commercial projects.

Tim Long
  • 13,508
  • 19
  • 79
  • 147