확인을 클릭하면 문제가있는 스크립트의 관련 부분 만 격리하려고 시도하고 테스트를 위해 완전히 새로운 도구 모음을 만들었습니다. 다음은이 새로운 툴바의 전체 코드입니다. 하나는 연결/측정 단추이고 상태/결과를 표시하는 레이블입니다. 나는 그것을 읽을 수 있도록 코드에 주석을 넣어 보았는데, 잘하면이 도움이된다.
이 새 도구 모음이 올바르게 작동하는 것 같습니다. Invoke 메서드 (Visual Studio가 Excel2013과 함께 사용하기 위해 약간 변경됨)와 함께 DataReceived 이벤트 처리기를 올바르게 사용하는 것에 대해서는 아직 확실하지 않습니다. 아무도 내가 아직 명확하지 않은 방식으로 이러한 이벤트를 사용하고 있는지와 내가 더 잘 만들 수있는 방법에 대한 제안을 제공했는지에 관해 의견을 제시해 주실 수 있습니까?
도움을 받으려면 다시 한번 감사드립니다. 정말 감사.
Imports Microsoft.Office.Tools.Ribbon
Imports System.IO.Ports
Public Class Measure2x_COM
Dim mySerialPort As New SerialPort
Dim CMD As String = "M" & vbCr 'statement telling instrument to measure
Dim measureNo As Integer = 0 'counts the number of measure commands sent to the instrument
Private Delegate Sub UpdateFormDeligate()
Private UpdateFormDeligate1 As UpdateFormDeligate
Dim sngReading As Single 'this is the reading received from the instrument as a single data type
Private Sub setupConnectCOM()
'Open COM and send measure command - this part works correctly
'first, check if serial port is open
If mySerialPort.IsOpen Then 'send measure command
mySerialPort.Write(CMD) 'the instrument will generally take 15.1 sec to perform a measurement before sending the result back
Else
'if serial port is not open, set it up, then open, then send command
'Setup COM --this part works correctly
With mySerialPort
.PortName = "COM3"
.BaudRate = 1200
.DataBits = 7
.Parity = Parity.None
.StopBits = StopBits.Two
.Handshake = Handshake.None
.ReadTimeout = 16000
End With
Try
mySerialPort.Open()
Catch ex As Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
Exit Sub 'exit sub if the connection fails
End Try
Threading.Thread.Sleep(200) 'wait 0.2 sec for port to open
mySerialPort.Write(CMD) 'send measure command after serial port is open
End If
measureNo = 1
lblResult.Label = "Measuring"
End Sub
Private Sub Measure2x_COM_Load(ByVal sender As System.Object, ByVal e As RibbonUIEventArgs) Handles MyBase.Load
AddHandler mySerialPort.DataReceived, AddressOf mySerialPort_DataReceived
End Sub
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
'Handles serial port data received events
UpdateFormDeligate1 = New UpdateFormDeligate(AddressOf UpdateDisplay)
'Read data as it comes back from serial port
'I had to do this in two steps because it, for some reason needs to read
'the +/- symbol as a Byte, then needs to read the ASCII measurement number
'the third part concatenates the data and converts it to a single type
'part 1 - read +/- symbol
Dim comBuffer As Byte()
Dim n As Integer = mySerialPort.BytesToRead 'find number of bytes in buff
comBuffer = New Byte(n - 1) {} 're-dimension storage buffer (n - 1)
mySerialPort.Read(comBuffer, 0, n) 'read data from the buffer
'part 2 - read ASCII measurement number
Dim comBuffer2 As String
comBuffer2 = mySerialPort.ReadTo(vbCr)
'part 3 - concatenate read data and convert to single type
Dim txtReading As String = Nothing
txtReading = System.Text.ASCIIEncoding.ASCII.GetString(comBuffer) & CStr(CInt(comBuffer2)/10)
sngReading = CSng(txtReading)
'Call the update form deligate
'Visual Studio slightly changed this from the example on Microsoft's website that used a Windows Form
'I tried the code in a windows form and I get the same results
Me.Invoke(UpdateFormDeligate1) 'call the deligate
End Sub
Private Sub Invoke(updateFormDeligate1 As UpdateFormDeligate)
lblResult.Label = sngReading 'set the Result label in the ribbon to equal the received data value
'now place the data received in the active cell in the worksheet
Dim myApp As Excel.Application = Globals.ThisAddIn.Application
Dim currentCell = myApp.ActiveCell
currentCell.Value = sngReading
'advance cell to the next cell
Dim newCell = currentCell
newCell = myApp.ActiveCell.Offset(1, 0)
newCell.Select()
currentCell = newCell
'check if this was the first reading from the instrument
'if it was the first reading, then send a second read command
If measureNo = 1 Then
measureNo = 2 'make sure to change measurement number to 2 to avoid infinite loop
mySerialPort.Write(CMD) 'send command to measure to instrument
End If
End Sub
'the usage of this section changed from the Microsoft Windows Form example
'in function, the mySerialPort_DataREceived(), Invoke(), and UpdateDisplay() functions do appear to be
'working with the same results and same hangups
Private Sub UpdateDisplay()
End Sub
Private Sub btnMeasure_Click(sender As Object, e As RibbonControlEventArgs) Handles btnMeasure.Click
setupConnectCOM() 'connect to COM and send first measure command
End Sub
End Class
버그가 많습니다. 가장 심각한 버그는 이벤트 처리기 내에서 Close()를 호출하는 것입니다. 첫 번째 명령 후에 쇼가 끝납니다. –
감사합니다. 한스. 나는 첫번째 쓰기 후에 시리얼 포트를 다시 열었다면 중요하다는 것을 알기 위해 가까이에 추가했다. 직렬 포트가 닫혀있는 경우 직렬 포트를 여는 루틴이 쓰기 명령에 있습니다. 두 개의 쓰기/읽기를 시도하기 위해 포트를 열어 두어도 문제가없는 것 같습니다. 닫은 경우 다시 열었습니다. – user3566911