views:

1055

answers:

4

I'm at a brick wall!

I have a teperature PCB that reports the temp back via serial port.

I can open Hyper Terminal and receive all the data I want - so I know the unit is working... but I want to create a VB app so I can use the data received.

When I run the program I get this error:

System.TimeoutException: The operation has timed out.
   at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
   at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count)
   at System.IO.Ports.SerialPort.InternalRead(Char[] buffer, Int32 offset, Int32 count, Int32 timeout, Boolean countMultiByteCharsAsOne)
   at System.IO.Ports.SerialPort.ReadTo(String value)
   at System.IO.Ports.SerialPort.ReadLine()
   at Temperature.Form1.ReadFromCom() in C:\Documents and Settings\asamuel\Desktop\VB Project Sollutions\Temperature2\Temperature\Form1.vb:line 43

Can someone PLEASE help me! I'm going mad!

In hyper terminal the data comes through like this:

R V1.0 2002-01-06 20:37:37 C
1 0027.00
2 0027.00
3 0027.06
4 0027.18
1 0027.00
2 0027.00
3 0027.06
4 0027.18
1 0027.00
2 0027.06

My VB app code looks like this:

Imports System
Imports System.IO.Ports
Imports System.Threading

Public Class Form1

    Dim SerialPort1 As New SerialPort
    Dim readThread As Thread = New Thread(AddressOf ReadFromCom)
    Dim abortThread As Boolean

    Public Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Button1.Text Is "Start Capture" Then
            Try
                abortThread = False
                SerialPort1.Open()
                readThread.Start()
                Button1.Text = "Stop Capture"
            Catch ex As Exception
                MsgBox("Another program is already using COM1." & vbCrLf & vbCrLf & _
                       "Please try again later", MsgBoxStyle.OkOnly + MsgBoxStyle.Information, "COM1 Not Available")
            End Try

        ElseIf Button1.Text Is "Stop Capture" Then
            abortThread = True
            Button1.Text = "Start Capture"
        End If
    End Sub

    Public Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        With SerialPort1
            .PortName = "COM1"
            .BaudRate = 2400
            .Parity = Parity.None
            .DataBits = 8
            .StopBits = 1
            .ReadTimeout = 500
        End With
    End Sub

    Public Sub ReadFromCom()
        While abortThread = False
            Try
                Dim message As String = SerialPort1.ReadLine
                updateStatus("Received: " & message)
            Catch ex As TimeoutException
                updateStatus(ex.ToString)
            End Try
        End While            
    End Sub

    Public Delegate Sub updateStatusDelegate(ByVal newStatus As String)
    Public Sub updateStatus(ByVal newStatus As String)
        If Me.InvokeRequired Then
            Dim upbd As New updateStatusDelegate(AddressOf updateStatus)
            Me.Invoke(upbd, New Object() {newStatus})
        Else
            TextBox1.Text = newStatus & vbCrLf & vbCrLf & TextBox1.Text
        End If
    End Sub
End Class
+1  A: 

You might wanna drop your design in favor of using the DataReceived-Event() of the SerialPort-Class.

The DataReceived-Event will be fired if a certain amount of data has arrived (DataReceivedThreshold-Property, I think). But the event will be fired on another thread, so make sure that you use Invoke() if you try to change any controls.

Bobby

Bobby
+1 - I would also suggest looking at the end of line character that the PCB is sending to make sure that it matches what the Serial port class expects in the ReadLine() function, although I agree with @Bobby that the event based model is the way to go.
Miky Dinescu
@Miky D: +1 for mentioning the ReadLine()/NewLine-Character thing...I always forget that. :D
Bobby
I've changed toPrivate Sub DataReceived1(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived MsgBox("W") ListBox1.Invoke(New myDelegate1(AddressOf updatelistBox1), New Object() {})but nothing happensI added the msgbox to see if the sub ever fires - it doesn't?
Blind Trevor
How do I work out what line feed to give it?
Blind Trevor
@Blind Trevor: Read the documentation of the device. ;) Did you declare SerialPort1 as WithEvents?
Bobby
@Bobby: I didn't have the documentation - I had to trawl the web to find it.I needed to set the DTR to enabled - makes sense when you think about it!
Blind Trevor
A: 

Maybe THIS post can help you. You need to change the open statement to

...
open "COM1:" for Input as #1
Input #1, MyString
...

Hope this helps

Good Luck MikeD

MikeD
Ahm...I don't wanna be rude, oh god no...but that's like using a wooden log as screwdriver...at least within DotNET (the post you link is for VBA, which is way more limited).
Bobby
This code doesn’t even work in .NET.
Konrad Rudolph
true Konrad ... sorry - I was just too deep in my VBA stuff
MikeD
A: 

I found the answer!!!

I needed to set searialport1.DTREnable to true!

It now works - that's a 2 month headache gone!

Thanks for everyone's help :)

Blind Trevor
A: 

can we use the same code in ASP.NET also?

nitin
I have no idea - but I would suggest that it would be roughly the same!The biggest problem with serial ports is understanding them! and I still don't!!Also, not sure if you can query the COM ports directly from a web browser (though I may be wrong) assuming you are writing a web app??
Blind Trevor