C#/기초

[C#]WPF Serial Port

딸기우유중독 2021. 12. 21. 16:10

연결 후  received함수를 스레드로.

연결까지 스레드로 넘기면 나중에 다시 연결 시도할때 if(!serial.Isopen) 을 걸어도 진입하고 충돌을 일으킴.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
using System.Diagnostics;


namespace HumanDetector
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ThreadManager thdManager;
        String[] portNumbers;
        SerialPort SP1 = new SerialPort();
        public MainWindow()
        {
            InitializeComponent();
            portNumbers = new String[4];
            portNumbers = SerialPort.GetPortNames();

        }

        private void rdoPixel32_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void rdoPixel16_Checked(object sender, RoutedEventArgs e)
        {
            if (!SP1.IsOpen)
            {
                SerialConnect(sender, e);
            }
            
        }

        private void SerialConnect(object sender, RoutedEventArgs e)
        {
            if (!SP1.IsOpen)
            {
                SP1.PortName = portNumbers[0];
                SP1.BaudRate = 115200;
                SP1.DataBits = 8;
                SP1.StopBits = StopBits.One;
                SP1.Parity = Parity.None;
                SP1.DataReceived += new SerialDataReceivedEventHandler(SP1_DataReceived);

                SP1.Open();

                Console.WriteLine("Port is Opened");
            }
            else
            {
                SP1.Close();
            }
        }

        private void SP1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            Debug.WriteLine("Data Received:");
            Debug.Write(indata);
            
            //this.Invoke(new EventHandler(MySerialReceived));
        }

        private void MySerialReceived(object s, EventArgs e)
        {
            int ReceiveData = SP1.ReadByte();

        }
    }
}

public static void Main()
{
    string name;
    string message;
    StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
    Thread readThread = new Thread(Read);

    // Create a new SerialPort object with default settings.
    _serialPort = new SerialPort();

    // Allow the user to set the appropriate properties.
    _serialPort.PortName = SetPortName(_serialPort.PortName);
    _serialPort.BaudRate = SetPortBaudRate(_serialPort.BaudRate);
    _serialPort.Parity = SetPortParity(_serialPort.Parity);
    _serialPort.DataBits = SetPortDataBits(_serialPort.DataBits);
    _serialPort.StopBits = SetPortStopBits(_serialPort.StopBits);
    _serialPort.Handshake = SetPortHandshake(_serialPort.Handshake);

    // Set the read/write timeouts
    _serialPort.ReadTimeout = 500;
    _serialPort.WriteTimeout = 500;

    _serialPort.Open();
    _continue = true;
    readThread.Start();

    Console.Write("Name: ");
    name = Console.ReadLine();

    Console.WriteLine("Type QUIT to exit");

    while (_continue)
    {
        message = Console.ReadLine();

        if (stringComparer.Equals("quit", message))
        {
            _continue = false;
        }
        else
        {
            _serialPort.WriteLine(
                String.Format("<{0}>: {1}", name, message));
        }
    }

    readThread.Join();
    _serialPort.Close();
}

public static void Read()
{
    while (_continue)
    {
        try
        {
            string message = _serialPort.ReadLine();
            Console.WriteLine(message);
        }
        catch (TimeoutException) { }
    }
}

WPF 임의적 Thread 할당선언 example

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfSerial
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        string name;
        string sMessage;
        StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
        bool tfContinue = false;
        Thread readThread;
        SerialPort sp = new SerialPort();
        //List<string> PortNameList = new List<string>();

        public MainWindow()
        {
            InitializeComponent();

            readThread = new Thread(Read);

            foreach (string comport in SerialPort.GetPortNames())
            {
                //PortNameList.Add(comport);
                cbPortList.Items.Add(comport);
            }

            cbPortList.SelectedIndex = 0;

            //cbPortList.ItemsSource = PortNameList;

            //string sPortName = cbPortList.SelectedValue as string;
            
            
        }

        public void Read()
        {
            while (tfContinue)
            {
                try
                {
                    sMessage = sp.ReadLine();
                    tbDisplay.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, new Action(
                        delegate ()
                        {
                            tbDisplay.Text = sMessage;
                        })); 
                    Debug.WriteLine(sMessage);
                }catch (Exception ex) { Debug.WriteLine(ex.Message); }
            }
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (!sp.IsOpen)
            {
                try
                {
                    sp.PortName = cbPortList.SelectedValue as string ?? "None"; // null이면 None
                    sp.BaudRate = 230400;
                    sp.Parity = Parity.None;
                    sp.DataBits = 8;
                    sp.StopBits = StopBits.One;
                    //sp.ReadBufferSize = 1024;

                    sp.ReadTimeout = 500;
                    sp.WriteTimeout = 500;

                    sp.Open();
                    tfContinue = true;

                    readThread.Start();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                sp.Dispose();
                sp.Close();
            }
        }

        private void btStop_Click(object sender, RoutedEventArgs e)
        {
            tfContinue = false;
            readThread.Join();
            sp.Write("stop\r\n");
        }

        private void btDisconnect_Click(object sender, RoutedEventArgs e)
        {
            tfContinue = false;
            readThread.Join();
            sp.Close();
        }

        private void btStart_Click(object sender, RoutedEventArgs e)
        {
            tfContinue = true;
            readThread.Join();
            sp.Write("scan\r\n");
            readThread.Start();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            tfContinue = false;
            readThread.Join();
            //readThread.Abort();
            sp.Dispose();
            sp.Close();
        }
    }
}
728x90