Link to home
Start Free TrialLog in
Avatar of RickyHanna
RickyHanna

asked on

Basic comms coding

I have my serial port connected to one of my companies proprietary circuit boards.  I send for instance : MSComm1.Output = "p14" and then imediately do Temp1 = MSComm1.Input.

Temp1 being the return value.

First of all is this the corect way?

If it is surely there is a chance that my code will move to the read line when the chip on the board is still processing the write?  How an this be avoided if it is possible?
Avatar of sudhakar_koundinya
sudhakar_koundinya

instead of writing directly to the temp, wait for few seconds before calling to the next statement.

I mean like this

MSComm1.Output = "p14"
' write a code here for sleeping the application for few seconds
Temp1 = MSComm1.Input.


though this is not a correct solution, i think this solves your problem. (Because we need to do some thread related program here, where we need to do application in wait mode until the statement was witten to com port)

Regards
sudha
Avatar of GrahamSkan
There is a general problem if you don't know the protocol of knowing when to stop listening. You might, for instance,  have an idea of how long to wait, or the expected message length

When the Input buffer is read, it is emptied, so repeated tries should be concatenated to a string variable.

Const buflen = 100 'say
Const Waitcount = 10000 'say
Buffer$ = ""
i = 0
Do
      DoEvents
     i = i + 1
     Buffer$ = Buffer$ & MSComm1.Input 'concatenate
Loop Until Len(Buffer$) = buflen or i = Waitcount
MsgBox Buffer$
Avatar of RickyHanna

ASKER

Is there no OnComm event that handles this?
No, as per my knowledge
Option Explicit

'flow control variables. Strings for now. Integers taking enumerated constants would be better
'eg.
'Const phSending = 0
'Const phReceiving = 1

Dim Phase As String
Dim Stage As String

Dim ReceiveBuffer As String
Const ReceivingInterval = 100

Private Sub Command1_Click()
    Dim b As String
    Dim i As Integer
   
    MSComm1.Settings = "56000,N,8,1"
    MSComm1.CommPort = 2
    MSComm1.InputLen = 0 'Default anyway
    MSComm1.RThreshold = 1 'Fire OnComm event with a single character in input buffer
    MSComm1.PortOpen = True
    Transact "ATE0", 500   'command to tell the modem not to echo the "AT" back
    Stage = "Initialising Modem"

End Sub

Sub Transact(SendText As String, TimeOut As Integer)
    ReportIt "Sending: " & SendText
    Timer1.Interval = TimeOut 'milliseconds
    ReceiveBuffer = ""
    MSComm1.Output = SendText & vbCr
    Timer1.Enabled = True
   
    Phase = "Sending"

End Sub

Private Sub Timer1_Timer()
    Dim b As String
    ReportIt "Timer: Interval: " & Timer1.Interval & " Stage: " & Stage & " Phase: " & Phase
    Select Case Phase
        Case "Sending"
            ReportIt "Nothing Received"
           
        Case "Receiving"
            b = TrimBoth(ReceiveBuffer)
            ReportIt "Received: " & b

            Select Case Stage
                Case "Initialising Modem"
                    If Right$(b, 2) = "OK" Then
                        Transact "ATDT 12345", 30000 ' Hard coded for now
                        Stage = "Dialling"
                        Phase = "Sending"
                    Else
                        ReportIt "Modem not responding"
                    End If
                Case "Dialling"
                    Select Case Left$(b, 7)
                        Case "CONNECT"
                            'this is where you start to control the device
                           Transact "Device Command", 30000
                           Stage = "Device1"
                           Phase = "Sending"
                        Case Else
                              'some sort of error
                    End Select
            End Select
    End Select
    Timer1.Enabled = False
End Sub

Function TrimRight(Intext As String) As String
    'strip blanks, tabs, line feeds etc from end of string
    Dim Text As String
   
    Text = Intext
    If Len(Intext) > 0 Then
        Do While Asc(Right$(Text, 1)) <= 32
            Text = Left$(Text, Len(Text) - 1)
        Loop
        TrimRight = Text
    End If
End Function


Private Sub MSComm1_OnComm()
ReportIt "OnComm: " & MSComm1.CommEvent
    Select Case MSComm1.CommEvent
        Case comEvSend '1 Send event.
        Case comEvReceive '2 Receive event.
            Phase = "Receiving"
            ReceiveBuffer = ReceiveBuffer & MSComm1.Input
            ReportIt "ReceiveBuffer: " & ReceiveBuffer
            Timer1.Enabled = False
            Timer1.Interval = ReceivingInterval
            Timer1.Enabled = True
        Case comEvCTS '3 Change in clear-to-send line.
        Case comEvDSR '4 Change in data-set ready line.
        Case comEvCD '5 Change in carrier detect line.
        Case comEvRing '6 Ring detect.
        Case comEvEOF '7 End of file.
        'errors
        Case comEventBreak '1001 A Break signal was received.
        Case comEventFrame '1004 Framing Error. The hardware detected a framing error.
        Case comEventOverrun '1006 Port Overrun. A character was not read from the hardware before the next character arrived and was lost.
        Case comEventRxOver '1008 Receive Buffer Overflow. There is no room in the receive buffer.
        Case comEventRxParity '1009 Parity Error. The hardware detected a parity error.
        Case comEventTxFull '1010 Transmit Buffer Full. The transmit buffer was full while trying to queue a character.
        Case comEventDCB '1011 Unexpected error retrieving Device Control Block (DCB) for the port.
   
    End Select
End Sub

Function TrimLeft(Intext As String) As String
    Dim Text As String
    If Len(Intext) > 0 Then
    Text = Intext
    Do While Asc(Text) <= 32
        Text = Mid$(Text, 2)
    Loop
    TrimLeft = Text
    End If
End Function

Function TrimBoth(Intext As String) As String
    TrimBoth = TrimLeft(TrimRight(Intext))
End Function

Sub ReportIt(Text As String)
    'This could be modified to write to a log file
    Dim b As String
    b = TrimBoth(Text)
    If Len(b) > 0 Then
        Debug.Print Now & " " & b
    End If
End Sub
ASKER CERTIFIED SOLUTION
Avatar of GrahamSkan
GrahamSkan
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I will leave the following recommendation for this question in the Cleanup topic area:
   Accept: GrahamSkan

Any objections should be posted here in the next 4 days. After that time, the question will be closed.

Matti
Experts Exchange CleanUp volenteer