본문 바로가기
공부/C#

c# 시리얼 포트 ( serial port, serialport) 원하는거 찾아서 연결하기.

by ding9 2012. 7. 10.

 

 

어제 serial port에 연결하는것 에 대해서 글을 썻는데...

 

하다보니....

 

후... 이거야원.... 잘 생각해보니까 처음에 프로그램을 실행하면 바로 내가 연결한 녀석(?) 과 통신을 해야한다......

 

그거 찾아서 설정하라고 하면 사용자가 짬뽕과 짜장을 겁나 뿌리고 다닐지도 모르기에...

 

그런데 그냥 윈도우 첨깔고 일반적인 마우스키보드를 사용하면 serialport가 딱 1개만 뜨는데...

 

마우스나 키보드가 일반적이지 않다(serialport로 잡히는 친절한 녀석들이 있음)던가....

 

아니면 다른 주변기기들로 인해서 serialport에 한개 이상이 잡혀 있다면....

 

그중에서 내가 원하는 녀석!!!! 그놈!!! 을 찾아야 한다!!!

 

방법이야 여러가지가 있겠지만...

 

처음엔 timeout에 대한 이벤트가 있겠지?? 라고 생각하고 겁나 찾앗는데 없었다...

 

그래서 난 Timer를 선택해서 했다... msdn에는 Thread예제가 있는데 Thread는 아직 안써봐서..ㅋㅋㅋㅋ

 

그리고 내가 원하는 녀석과 연결하면 바로 Timer를 끌수 있어서 간편하기에....

 

암튼 이거땜에 어제 야근 오늘 오전을 통째로 날려먹었...ㅠ.ㅠ

 

나의 예제코드는 간편을 추구하기에... 추가적인건 알아서...ㅎㅎㅎ

 

우선 이전글로 소스를 만들어 놓고 그걸 기반으로 한다....

 

http://ding9.tistory.com/373 요글임..

 

우선 폼디자인에서 timer를 추가하고 이벤트 추가하고... 소스로 돌아온다..

 

클래스멤버에 현재 테스트중인 포트를 알기 위한 변수, 전체 연결된 포트개수를 저장할 변수, 각각의 포트이름을 저장할 변수를 선언한다...

 

        int cnt;
        int si;
        string[] port_arr;


        public Form1()

 

마지막건 뭐냐 할수 있겠지만... 거기 위에 넣으란 소리임... 이정도 까지 썻는데 모르면 정말 공부 다시하삼..ㅡㅡ;;;

 

생성자에 어제 소스에 맨 밑t에 if문 삭제하고... 타이머시작구문과 cnt 0으로 초기화 ... 아 어제 소스에서 port_arr 앞에 string[] 요거 삭제...

 

그리고  si에 포트개수 넣어주고 포트 이름 넣어주고 포트 열고 포트에 일단 암거나 쓴다...

 

            port_arr = SerialPort.GetPortNames();

            foreach (string portno in port_arr)
            {
                comboBox1.Items.Add(portno);
            }

timer1.Start();

cnt = 0;

            si = port_arr.Length;

            serialPort1.PortName = port_arr[0];
            serialPort1.Open();
            serialPort1.Write("0x0f0ff0f0");

 

고럼 요렇게 하고....

 

아까 추가한 타이머 이벤트에서... 여기서 부터 중요하다...

 

이 이벤트에서는

 

1. 아까 열어서 데이터 보낸놈한테 먼저 데이터가 돌아왔는지 확인을 한다....

 

2. 있으면 끝내고 없으면 다음놈이 있는지 확인하고 그놈한테 다시 그 메시지를 보낸다...

 

그럼 이벤트가 계속 주기적으로 발생이 되기 때문에 없으면 그냥 통과하면 됨... 이 이벤트가 일종의 timeout이라고 보면된다.. 따라서 이벤트의 동작시간을 자신이 설정하려고 했던 timeout시간으로 설정하면 된다... 개인적으로 500 ~ 1000정도가 적당하다고 생각된다. 자신의 상황에 맞춰서 설정하면 된다...

 

여기서 중요한건 받은 메시지가 아까 보낸놈인지 확인하고 아까 보낸놈이 돌아온거면 Timer 종료...

 

 아니면 다음포트로 넘기되 원래 포트개수보다 많아지면 바로 에러메시지 띄우고 종료..

 

아니면 다음포트로 넘겨서 데이터를 보내고 지금 이벤트에서 탈출.. 이런 흐름으로 진행된다...

 

소스는...

 

            if (textBox2.Text.Equals("0x0f0ff0f0") == true)
            {
                cnt = 99;
            }
            else
            {
                cnt++;
            }

            if (cnt < si)
            {
                timer1.Dispose();
                MessageBox.Show("시리얼포트가 연결되어 있지 않습니다. 프로그램을 종료합니다.");
                Close();
            }

            if (cnt == 99)
            {
                textBox1.Text = serialPort1.PortName;
                timer1.Dispose();
            }
            else
            {
                int i = cnt;
                if (serialPort1.IsOpen) serialPort1.Close();

                port_arr = SerialPort.GetPortNames();    //함수가 끝나면 값이 없어져 이벤트 호출할때마다 포트리스트를 가지고옴.
                serialPort1.PortName = port_arr[i].ToString();

                serialPort1.Open();

                serialPort1.Write("0x0f0ff0f0");
            }

 

요걸 넣으면 됨...

 

만약 통신하는 보드에서 프로토콜이 있다면 받은 메시지를 확인하는 구문에 해당 값을 넣어주면된다...

 

참고로 찾는 포트가 없을때 messagebox띄우는 if문에서는 메시지박스띄우고 타이머 죽이고 윈폼죽이면....

 

메시지박스 계속 뜬다...ㅋㅋㅋ

 

serial은 통신속도가 안맞아도 데이터를 못받는 수가 생기니.. 이건 오로지 예제용으로만...ㅡㅡㅋ

 

할튼 오늘 이거 안되면 퇴근 안할라고 했는데 다행이 정시퇴근해야겠다.

 

반응형

댓글