Rob, here is the code where I last left off. Basically, I'm feeding a variable input called StepNumber (which is either a 0,1, or 2) to call one of the three different Case functions. We figured out that it's getting stuck when the Timer component tries to rebuild the solution that it's trying to continually re-open the port.
Sub RunScript(ByVal StepNumber As Integer)
Select Case StepNumber
Case 0
OpenPort()
print("Port has been opened")
Case 1
print(storedvalue)
Case 2
ClosePort()
print("Port has been closed")
End Select
End Sub
#Region "Additional methods and Type declarations"
' I wrapped this in a class, but you would need to work it into the grasshopper class
Private WithEvents CPort As IO.Ports.SerialPort 'port with events
Private TempBuffer As String = String.Empty 'holds the input between events until we get a new line
Private Delegate Sub HandleComPortDelegate() 'allows com port to run in a background thread without blocking
Private StoredValue As String = String.Empty 'holds value from port until you call for it
Sub OpenPort() 'called early in the app, before the port is ever needed. This attaches the port, and opens it to listen.
CPort = New IO.Ports.SerialPort
Try
CPort = My.Computer.Ports.OpenSerialPort("COM3", 9600)
Catch ex As Exception
MessageBox.Show("no port")
End Try
End Sub
'this would be better as a property, but I don't know how Grasshopper handles properties
Function GetValue() As String
Return StoredValue
End Function
'this is fired by the port when it has data
Private Sub CPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles CPort.DataReceived
Dim HndlComPort As New HandleComPortDelegate(AddressOf HandleComPort) 'declare thread
HndlComPort.Invoke() ' invoke a new delegate to digest the events
End Sub
Private Sub HandleComPort() 'background handler for com port
TempBuffer &= CPort.ReadExisting 'append into tempbuffer
If (Strings.Right(TempBuffer, 2) = vbCrLf) Then 'if end of item 'this may need to be changed, since Arduino's println may use cr or lf only. I can't remember at this point.
StoredValue = TempBuffer 'offload
TempBuffer = String.Empty 'reset
End If
End Sub
'should be called when the port is no longer needed.
Private Sub ClosePort()
If CPort.IsOpen = True Then
CPort.Close()
End If
CPort.Dispose()
End Sub
#End Region