1

I need to read data from COM in Form1 and then In Form2 again too.

What will be the best way?

In Form1 read the COM data, then mySerialPort.Close();, and in Form2 open new connection?
If like this, where in my code above should I close it?

Or don't close the COM? If don't close, how can I read the data in Form2?

namespace portreader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            SerialPort mySerialPort = new SerialPort();
            mySerialPort.PortName = "COM3";
            mySerialPort.BaudRate = 9600;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived);
            mySerialPort.Open();
        }

        string _buffer;
        private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (this.InvokeRequired)
            {
                // Using this.Invoke causes deadlock when closing serial port, and BeginInvoke is good practice anyway.
                this.BeginInvoke(new EventHandler<SerialDataReceivedEventArgs>(mySerialPort_DataReceived), new object[] { sender, e });
                return;
            }
            SerialPort sp = (SerialPort)sender;
            string data = sp.ReadExisting();

            _buffer += data;
            if (_buffer.Length >= 8)
            {
                int chipnumber = Int32.Parse(_buffer, System.Globalization.NumberStyles.HexNumber);
                Form2 form2 = new Form2(chipnumber);
                form2.ShowDialog(this);
                _buffer = null;
            }
        }
    }
}
DeanOC
  • 7,142
  • 6
  • 42
  • 56
nordscan
  • 137
  • 1
  • 11
  • 1
    Personally, I'd create a class that specifically handles comm port communication for the application and have both forms use that. – itsme86 Mar 05 '17 at 21:03

2 Answers2

2

you need to make a class that both form1 and form2 can use, then give form1 and form2 a reference to that class.

Ideally, the forms don't have any idea there is a serial port at all. They just use your class/service to ask questions and get answers, and encapsulated in that class is the logic for going to the serial port and doing the queries.

This is one of the basic design principles of software, separating your UI from your application logic.

see my answer on another related post

Serial Port Polling and Data handling

Community
  • 1
  • 1
Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
1

You could simply wrap the ComPort in a class like

public class DataInput
{
    public event Action<string> DataReceived;

    private readonly SerialPort mySerialPort;

    public DataInput(string portName)
    {
        mySerialPort = new SerialPort();
        mySerialPort.PortName = portName;
        mySerialPort.BaudRate = 9600;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 8;
        mySerialPort.Handshake = Handshake.None;
        mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived);
        mySerialPort.Open();
    }

    private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        string received = mySerialPort.ReadExisting();
        DataReceived?.Invoke(received);
    }
}

Now every form (and also other components of your software) can suscribe the event DataReceived of an instance of DataInput. So every component can handle the data the way it likes. Therefore you simply have to create an instance of DataReceived and use it in your forms like:

public partial class Form1 : Form
{
    private readonly DataInput dataInput;

    public Form1()
    {
        InitializeComponent();
        dataInput = new DataInput("COM3");
        dataInput.dataReceived += OnDataReceived;
    }

    private void OnDataReceived(string Data)
    {
        //Do whatever you want with the data
    }
}

Now you can pass dataInput to your second form and you are able to use the dataReceived event again.

Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49