안녕하세요. 저는 대학교 4학년 프로그래밍 비 전공자이며 현재 시리얼 통신을 이용하여 2개의 기계 간의 통신을 이어주는 프로그램을 만들고 있습니다. 시리얼 통신 프로그램은 mfc 다이얼로그 기반으로 작성하고 있습니다. 현재 기계 A,B 를 시리얼 통신으로 이어 A에서 작업 시작이라는 명령을 내리면 B의 기계가 기능을 수행하며 작업을 시작합니다. 하나의 작업이 끝나기 전에 비상정지를 할 수 있어야 하기에 A에서 정지 명령을 내리게 됩니다. 명령의 데이터 값은 compare() 함수를 통해 비교하여 실행합니다. 다만 A에서 시작 명령을 내린 후 B의 기계가 작업을 시작하고 끝나기 전까지 다른 명령을 듣지 않습니다. 작업 종료 명령을 내려도 작업이 끝나고 난 후 정지하라는 명령 데이터가 수신 되게 됩니다. 이게 수신은 하였지만 수신 버퍼에 저장되어 작업이 끝나기 전까지 대기하다 작업이 끝나면 버퍼에 있는 데이터를 읽어오게 되는 건지 아니면 이 작업을 하는 동안 리소스를 계속 잡고 있어서 (무한루프) 그동안 데이터를 수신하지 못하는 건지, 작업 스레드의 sleep_for(100ms) 지연 시간이 짧아서 인지 갈피를 못 찾겠습니다... 시리얼 통신 보더레이트 속도는 115200을 사용하고 있습니다. 만약 데이터 수신 버퍼에 저장되는 내용을 바로 처리하지 못하는 거라면 즉각적으로 처리할 수 있는 방법이 있을까요? 시리얼 통신 예제는 http://forum.falinux.com/zbxe/index.php?_filter=search&mid=lecture_tip&search_target=title&search_keyword=mfc&document_srl=571672 님의 것을 참고하여 만들었습니다.
시리얼 통신을 수행하면서 A에서 B로 정지 명령을 내렸을 때, B가 바로 동작하지 않는 문제가 발생하고 있다고 하셨는데요. 먼저, 데이터가 B의 수신 버퍼에 저장되어 있다가 나중에 처리되는 것인지, 아니면 B가 작업을 하는 동안 명령을 수신하지 않는 것인지 확인하기 위해서 다음과 같은 몇가지 방안은 다음과 같습니다. Buffer Check B쪽에서 수신 ...
안녕하세요. Vb 완전 초보입니다.. 이런 좋은 사이트를 알게 되어 영광입니다.. 현재 저는 모회사에서 일하는 연구원입니다. 정식 프로젝트는 아닌데, 사회에 공헌을 하고자 개발하는 기기가 하나 있습니다...가스상물질 (황화수소) 측정 기기인데, 값싼 센서를 사서 저렴하게 구성하고 소프트웨어까지 필요한 곳에 뿌리려고 합니다. 그래서 기기 조립은 다 하고 센서값도 비주얼베이직 통신을 통해서 어찌어찌 받긴 했는데... 문제는 '단순화'가 되지 않는다는 겁니다. 자세한 내용은.. 1. 시리얼 통신을 통해 값을 받으면 [Serial number, concentration, temp, humidity, ... , ] 라는 센서에서 읽어들이는 한 줄이 쭈욱 들어옵니다. 2. 이후 1초마다 이 값이 Appendtext를 통해 richtextbox에 로깅되도록 만들었습니다... 3. ","로 나눠진 저 값에서 2번째 값! (Concentration)을 따로 빼내어 Label10.text에 보기 편하도록 표시하고 싶은데... UI구성은 다 해뒀습니다만, Split function이 아무리해도 먹히질 않네요...배열을 만들어봐도...인덱스를 벗어났다는 등의 메시지만... 코드를 읽어보면 [text]에 위 한 줄이 저장되는거 아닌가요?... 어떤 곳에 시리얼 값이 저장되는지 모르겠습니당.. 4. 초보라 인터넷에 있는 코드를 긁어 약간 수정한 정도입니다. 그래서 자세한 내용은 모르겠습니다.. 고수분들의 팁과 조언 부탁드리겠습니다! 감사합니다! 아래는 코드입니다. 보시기 편하도록 제가 생각할 때 주요 부분만 빨강 처리해두었습니다! Imports System Imports System.ComponentModel Imports System.Threading Imports System.IO.Ports Public Class frmMain Dim myPort As Array 'COM Ports detected on the system will be stored here Dim WithEvents kell As Timer Delegate Sub SetTextCallback(ByVal [text] As String) 'Added to prevent threading errors during receiveing of data Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'When our form loads, auto detect all serial ports in the system and populate the cmbPort Combo box. myPort = IO.Ports.SerialPort.GetPortNames() 'Get all com ports available 'cmbBaud.Items.Add(9600) 'Populate the cmbBaud Combo box to common baud rates used For i = 0 To UBound(myPort) cmbPort.Items.Add(myPort(i)) Next cmbPort.Text = cmbPort.Items.Item(0) 'Set cmbPort text to the first COM port detected 'cmbBaud.Text = cmbBaud.Items.Item(0) 'Set cmbBaud text to the first Baud rate on the list btnDisconnect.Enabled = False 'Initially Disconnect Button is Disabled Timer1.Interval = 1000 'Time interval Timer1.Enabled = True End Sub Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click SerialPort1.PortName = cmbPort.Text 'Set SerialPort1 to the selected COM port at startup SerialPort1.BaudRate = 9600 'Set Baud rate to the selected value on 'Other Serial Port Property SerialPort1.Parity = IO.Ports.Parity.None SerialPort1.StopBits = IO.Ports.StopBits.One SerialPort1.DataBits = 8 'Open our serial port SerialPort1.Open() btnConnect.Enabled = False 'Disable Connect button btnDisconnect.Enabled = True 'and Enable Disconnect button End Sub Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click SerialPort1.Close() 'Close our Serial Port btnConnect.Enabled = True btnDisconnect.Enabled = False End Sub Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click SerialPort1.Write("c" & vbCr) 'The text contained in the txtText will be sent to the serial port as ascii 'plus the carriage return (Enter Key) the carriage return can be ommitted if the other end does not need it End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click SerialPort1.Write("r" & vbCr) 'The text contained in the txtText will be sent to the serial port as ascii 'plus the carriage return (Enter Key) the carriage return can be ommitted if the other end does not need it End Sub Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived ReceivedText(SerialPort1.ReadExisting()) 'Automatically called every time a data is received at the serialPort End Sub Private Sub ReceivedText(ByVal [text] As String) 'compares the ID of the creating Thread to the ID of the calling Thread If Me.rtbReceived.InvokeRequired Then Dim x As New SetTextCallback(AddressOf ReceivedText) Me.Invoke(x, New Object() {(text)}) Else 'Label10.Text = "" rtbReceived.AppendText([text]) rtbReceived.ScrollToCaret() End If End Sub Private Sub cmbPort_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbPort.SelectedIndexChanged If SerialPort1.IsOpen = False Then SerialPort1.PortName = cmbPort.Text 'pop a message box to user if he is changing ports Else 'without disconnecting first. MsgBox(”Valid only if port is Closed”, vbCritical) End If End Sub Private Sub cmbBaud_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) If SerialPort1.IsOpen = False Then SerialPort1.BaudRate = 9600 'pop a message box to user if he is changing baud rate Else 'without disconnecting first. MsgBox(”Valid only if port is Closed”, vbCritical) End If End Sub End Class
현재 아래와 같이 되어있는 부분을
ReceivedText(SerialPort1.ReadExisting())
아래와 같이 수정하신 후,
Dim buffer As String = SerialPort1.ReadExisting()
ReceivedText(buffer)
[text]라고 되어있는 부분들을 찾아서 text로 수정해보시기 바랍니다.
...