티스토리 뷰

[전자]

시리얼 직렬 통신

삼손스 2019. 1. 28. 14:55

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;


namespace SerialCommLib

{

    public class SerialComm

    {

        public delegate void DataReceivedHandlerFunc(byte[] receiveData);

        public DataReceivedHandlerFunc DataReceivedHandler;


        public delegate void DisconnectedHandlerFunc(); 

        public DisconnectedHandlerFunc DisconnectedHandler;


        private SerialPort serialPort;


        private string strRecvTemp = string.Empty;


        public bool IsOpen

        {

            get

            {

                if (serialPort != null) return serialPort.IsOpen;

                return false;

            }

        }


        private bool bCommunicating = false;


        public bool IsComm

        {

            get

            {

                return bCommunicating;

            }

            set

            {

                bCommunicating = value;

            }

        }

        

        // serial port check

        private Thread threadCheckSerialOpen;

        private bool isThreadCheckSerialOpen = false;


        public SerialComm()

        {

        }


        public bool OpenComm(string portName, int baudrate, int databits, StopBits stopbits, Parity parity, Handshake handshake)

        {

            try

            {

                serialPort = new SerialPort();


                serialPort.PortName = portName;

                serialPort.BaudRate = baudrate;

                serialPort.DataBits = databits;

                serialPort.StopBits = stopbits;

                serialPort.Parity = parity;

                serialPort.Handshake = handshake;


                serialPort.Encoding = new System.Text.ASCIIEncoding();

                serialPort.NewLine = "\r\n";

                //serialPort.ErrorReceived += serialPort_ErrorReceived;

                //serialPort.DataReceived += serialPort_DataReceived;

                serialPort.ReadTimeout = 100;

                serialPort.WriteTimeout = 1000;

                

                serialPort.Open();


                StartCheckSerialOpenThread();

                return true;

            }

            catch (Exception ex)

            {

                Debug.WriteLine(ex.ToString());

                return false;

            }

        }


        public void CloseComm()

        {

            try

            {

                if (serialPort != null)

                {

                    StopCheckSerialOpenThread();

                    serialPort.Close();

                    serialPort = null;

                }

            }

            catch (Exception ex)

            {

                Debug.WriteLine(ex.ToString());

            }

        }


        public bool Send(string sendData)

        {

            try

            {

                if (serialPort != null && serialPort.IsOpen)

                {

                    serialPort.Write(sendData);

                    IsComm = true;

                    return true;

                }

            }

            catch (Exception ex)

            {

                Debug.WriteLine(ex.ToString());

            }

            return false;

        }


        public bool Send(byte[] sendData)

        {

            try

            {

                if (serialPort != null && serialPort.IsOpen)

                {

                    serialPort.Write(sendData, 0, sendData.Length);

                    IsComm = true;

                    return true;

                }

            }

            catch (Exception ex)

            {

                Debug.WriteLine(ex.ToString());

            }

            return false;

        }


        public bool Send(byte[] sendData, int offset, int count)

        {

            try

            {

                if (serialPort != null && serialPort.IsOpen)

                {

                    serialPort.Write(sendData, offset, count);

                    IsComm = true;

                    return true;

                }

            }

            catch (Exception ex)

            {

                Debug.WriteLine(ex.ToString());

            }

            return false;

        }


        private byte[] ReadSerialByteData()

        {

            serialPort.ReadTimeout = 100;

            byte[] bytesBuffer = new byte[serialPort.BytesToRead];

            int bufferOffset = 0;

            int bytesToRead = serialPort.BytesToRead;


            while (bytesToRead > 0)

            {

                try

                {

                    int readBytes = serialPort.Read(bytesBuffer, bufferOffset, bytesToRead - bufferOffset);

                    bytesToRead -= readBytes;

                    bufferOffset += readBytes;

                }

                catch (TimeoutException ex)

                {

                    Debug.WriteLine(ex.ToString());

                }

            }


            return bytesBuffer;

        }


        private byte[] ReadSerialByteDataLinux()

        {

            serialPort.ReadTimeout = 100;

            byte[] bytesBuffer = new byte[serialPort.BytesToRead];

            int bytesToRead = serialPort.BytesToRead;

            int nReadBytes = 0;


            while ((bytesToRead - nReadBytes) > 0)

            {

                try

                {

                    bytesBuffer[nReadBytes++] = (byte)serialPort.ReadByte();


                }

                catch (TimeoutException ex)

                {

                    Debug.WriteLine(ex.ToString());

                }

            }


            return bytesBuffer;

        }


        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)

        {

            try

            {

                //byte[] bytesBuffer = ReadSerialByteData();

                byte[] bytesBuffer = ReadSerialByteDataLinux();

                string strBuffer = Encoding.ASCII.GetString(bytesBuffer);


                if (DataReceivedHandler != null)

                    DataReceivedHandler(bytesBuffer);


                Debug.WriteLine("received(" + strBuffer.Length + ") : " + strBuffer);

            }

            catch (Exception ex)

            {

                Debug.WriteLine(ex.ToString());

            }

        }


        private void serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)

        {

            Debug.WriteLine(e.ToString());

        }


        private void StartCheckSerialOpenThread()

        {

            StopCheckSerialOpenThread();


            isThreadCheckSerialOpen = true;

            threadCheckSerialOpen = new Thread(new ThreadStart(ThreadCheckSerialOpen));

            threadCheckSerialOpen.Start();

        }


        private void StopCheckSerialOpenThread()

        {

            if (threadCheckSerialOpen != null)

            {

                isThreadCheckSerialOpen = false;

                if (Thread.CurrentThread != threadCheckSerialOpen)

                    threadCheckSerialOpen.Join();

                threadCheckSerialOpen = null;

            }

        }


        private void ThreadCheckSerialOpen()

        {

            while (isThreadCheckSerialOpen)

            {

                try

                {

                    if(serialPort.BytesToRead != 0)

                    {

                        byte[] bytesBuffer = ReadSerialByteDataLinux();

                        string strBuffer = Encoding.ASCII.GetString(bytesBuffer);


                        if (DataReceivedHandler != null)

                            DataReceivedHandler(bytesBuffer);


                        Debug.WriteLine("received(" + strBuffer.Length + ") : " + strBuffer);

                    }

                    Thread.Sleep(10);

                }

                catch (Exception ex)

                {

                    Debug.WriteLine(ex.ToString());

                }

            }

        }

    }

}

'[전자]' 카테고리의 다른 글

[전자기학] Biot-Savart Law(비오사바르 법칙)  (0) 2019.09.15
Serial 통신 비교(UART vs SPI vs I2C)  (0) 2019.02.20
모터 PID 제어  (0) 2019.02.15
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크