Home > OS >  Serial Communication (C# Windows Forms)
Serial Communication (C# Windows Forms)

Time:06-13

Okay so I'm trying to do a two-way communication from C# to Arduino (using FTDI232) and viceversa, from Arduino to C#. Here's the code:

public partial class Form1 : Form
    {
        public SerialPort myPort;
        private DateTime dateTime;
        private string inData;
        const string com = "COM8";
       
        public Form1()
        {
            InitializeComponent();
        }
        private void start_btn_Click(object sender, EventArgs e) // TURN ON LED
        {
            myPort = new SerialPort();
            myPort.BaudRate = 9600;
            myPort.PortName = com;
            try
            {
                myPort.Open();
                myPort.WriteLine("A");
                myPort.Close();
                error_tb.Text = "";
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Errore");
            }
        }
        private void stop_btn_Click(object sender, EventArgs e) // TURN OFF LED
        {
            myPort = new SerialPort();
            myPort.BaudRate = 9600;
            myPort.PortName = com;
            try
            {
                myPort.Open();
                myPort.WriteLine("B");
                myPort.Close();
                error_tb.Text = "";
            }
            catch (Exception exc2)
            {
                MessageBox.Show(exc2.Message, "Error");
            }
        }
        void MyPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            inData = myPort.ReadLine();
            this.Invoke(new EventHandler(displayData_event));
        }
        private void displayData_event(object sender, EventArgs e)
        {
            dateTime = DateTime.Now;
            string time = dateTime.Hour   ":"   dateTime.Minute   ":"   dateTime.Second;
            values_tb.Text = time   "\t\t\t\t\t"   inData;
        }
        private void Form1_Load(object sender, EventArgs e) // PRESS PHYSICAL BUTTON TO SEND DATA
        {
            myPort = new SerialPort();
            myPort.BaudRate = 9600;
            myPort.PortName = com;
            myPort.Parity = Parity.None;
            myPort.DataBits = 8;
            myPort.StopBits = StopBits.One;
            myPort.DataReceived  = MyPort_DataReceived;

            try
            {
                myPort.Open();
                values_tb.Text = "";
            }
            catch (Exception exc3)
            {
                MessageBox.Show(exc3.Message, "Error");
            }

        }
        


        private void exit_btn_Click(object sender, EventArgs e) // Exit from Application
        {
            Application.Exit();
        }

        private void button2_Click(object sender, EventArgs e) 
        {
            try
            {
                myPort.Close();
            }
            catch (Exception exc4)
            {
                MessageBox.Show(exc4.Message, "Error");
            }
        }
    }

I have three problems. One is when I want to close the application, I want the Serial Communication to turn off, because I made it automatically open using Form1_Load, as soon as you start the debug, it also opens Serial Communication, and it remains on, but I don't want to use a button that I have to click first to close the application. I need to close Serial Communication automatically after I close the application.

The second problem is with the Serial Port that denies the communication, what I mean is that I need to switch from Receiving Data to Sending Data. Here's a picture of what it looks like: Application Image

The the third problem is the LED one. Well its similar to the second one, but this time when I click the button OFF, I want it to switch back to Receiving Data. Here's the picture: Application Image 2

EDIT : This code is only temporary. I needed it to turn off the Serial Communication

private void button2_Click(object sender, EventArgs e) 
        {
            try
            {
                myPort.Close();
            }
            catch (Exception exc4)
            {
                MessageBox.Show(exc4.Message, "Error");
            }
        }

CodePudding user response:

You are initializing and opening the port many times. This is not allowed. Use a single initialization and keep the member. This makes the code much smoother, too.

public partial class Form1 : Form
    {
        public SerialPort myPort;
        private DateTime dateTime;
        const string com = "COM8";
       
        public Form1()
        {
            InitializeComponent();
        }
        private void start_btn_Click(object sender, EventArgs e) // TURN ON LED
        {
            try
            {
                myPort.WriteLine("A");
                error_tb.Text = "";
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Errore");
            }
        }
        private void stop_btn_Click(object sender, EventArgs e) // TURN OFF LED
        {
            try
            {
                myPort.WriteLine("B");
                error_tb.Text = "";
            }
            catch (Exception exc2)
            {
                MessageBox.Show(exc2.Message, "Error");
            }
        }
        void MyPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var inData = myPort.ReadLine(); // Use local variable
            displayData_event(inData);
        }
        private void displayData_event(string data)
        {
            dateTime = DateTime.Now;
            string time = dateTime.Hour   ":"   dateTime.Minute   ":"   dateTime.Second;
            values_tb.Text = time   "\t\t\t\t\t"   data;
        }
        private void Form1_Load(object sender, EventArgs e) // PRESS PHYSICAL BUTTON TO SEND DATA
        {
            myPort = new SerialPort();
            myPort.BaudRate = 9600;
            myPort.PortName = com;
            myPort.Parity = Parity.None;
            myPort.DataBits = 8;
            myPort.StopBits = StopBits.One;
            myPort.DataReceived  = MyPort_DataReceived;

            try
            {
                myPort.Open();
                values_tb.Text = "";
            }
            catch (Exception exc3)
            {
                MessageBox.Show(exc3.Message, "Error");
            }

        }
    
        private void exit_btn_Click(object sender, EventArgs e) // Exit from Application
        {
            Application.Exit();
        }

        private void button2_Click(object sender, EventArgs e) 
        {
            try
            {
                myPort.Close();
                myPort = null;
            }
            catch (Exception exc4)
            {
                MessageBox.Show(exc4.Message, "Error");
            }
        }
    }

I think I also fixed your event handling. One handler that gets the data and then forwards the received text is enough. You would also not really require the exception handling around WriteLine now, since that cannot really fail.

  • Related