Announcement

Collapse
No announcement yet.

Problem reading data from serial port

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem reading data from serial port

    Hello, I have a program that connects to an electronic
    device and communicates via the serial port. Data comes
    "real time" from the electronic device and my program reads this
    data from the serial port.

    My program works fine for a while and then stops reading the data
    from the serial port. The time it takes before it stops reading
    data is variable. I've been unable to determine any trends. I've
    also tested that their is data still being transfered from the
    electronic device by using a break out box. The code is rather
    short, so I will paste it.

    If anyone can see what I'm doing wrong, I would greatly appreciate
    it. Thanks a ton!

    Code.........

    Rem For Polling PS680 in "INLINE Mode" (B8 = On)
    Rem Also must set PS680 command = "INLINEHSK DTR"
    $CPU 80386
    $COM 15000
    $ERROR ALL ON
    $DEBUG MAP ON
    $DEBUG PBDEBUG ON
    Rem
    Close ':ON ERROR GOTO ERROUTINE
    Key OFF: Cls
    Rem LOCATE 16,18,1:PRINT "PRESS 'Q' AT ANY TIME TO QUIT DATA COLLECTION"
    Y% = 1
    I% = 1
    Open "COM1:1200,N,8,1" For Random As #2
    Open "CALLDATA" For Append As #3
    DELAY 3
    Rem
    Rem ********* BEGIN DATA COLLECTION ***********
    Rem
    MAIN:
    For Z = 1 To 20000

    If Loc(2) > 20 Then
    I% = 1
    Y% = 1
    Line Input #2, INPUTRECORD$
    Print #3, INPUTRECORD$
    Print INPUTRECORD$
    ElseIf INSTAT Then
    GoSub KEYBOARD
    Else
    I% = I% + 1
    Rem ** 30 SECONDS WITHOUT A call record **
    If Y% > 10 Then
    GoTo REST
    Else
    DELAY 3
    End If
    End If
    Y% = Y% + 1
    Rem ** 1000 Calls max at one time **
    If Y% > 1000 Then
    GoTo REST
    End If
    Next Z

    REST:
    Close
    Cls
    LOCATE 16, 21, 1: Print "PRESS ANY KEY TO TERMINATE AUTO-POLLING"
    SLEEP 60
    Rem 3600 = 1 HOUR ********
    Rem
    If INSTAT Then
    GoTo ENDAUTOPOLL
    Else
    End If
    Close: System

    ENDAUTOPOLL:
    INK$ = INKEY$
    If INK$ = Chr$(81) Then
    Open "DUMMY" For Output As #1
    Else
    Open "DUMMY" For Output As #1
    End If
    Close: System

    KEYBOARD:
    INK$ = INKEY$
    If INK$ = Chr$(81) Then
    Print #2, Chr$(27); Chr$(27); Chr$(27)
    Open "DUMMY" For Output As #1
    Close: System
    Else
    End If
    Return

    ERROUTINE:
    If Err = 57 Then Resume Next
    ERRMSG$ = "CAN'T RESUME AT " + Str$(Erl) + " ERR CODE = " + Str$(Err)

    Print ERRMSG$
    Close: End

    ------------------

  • #2
    Bob,

    what I see at the first glance is you use LINE INPUT #2 to get the Rx stream: this means the statemnet will wait until a CR char is received. If for some reason the CR lacks, or the program doesn't read it correctly, the program will be locked. Better input the Rx data on a single char basis, and build the Rx record yourself. This gives you the possibility to discard wrong data and manage timeouts.

    Aldo


    ------------------
    Rgds, Aldo

    Comment


    • #3
      Another thought. You open the line FOR RANDOM. I never used this option on a serial comm - I use it on disk files to access fixed length record files. For your application is enough to open the com somethilng like
      Code:
      Open "COM1:1200,N,8,1" As #2
      Be careful about the options for the status line handling. Since the line is slow (1200 baud) you can try
      Code:
      Open "com2:1200,n,8,1,cs,rs,ds,cd" as #2
      ------------------

      [This message has been edited by Aldo Cavini (edited September 18, 2003).]
      Rgds, Aldo

      Comment


      • #4
        OPEN FOR RANDOM is perfectly appropriate here.

        ------------------
        Tom Hanlin
        PowerBASIC Staff

        Comment


        • #5
          Ok, Tom... but, what does it mean? It is not described under the OPEN COM statement; on the other hand, under the normal OPEN statement I read the following:
          record size is an integer expression ranging from 1 to 32767, specifying the length in bytes of each record in a random access file. The default record size is 128 bytes.
          Hence, if I open a comm FOR RANDOM without declaring the record size, will the program work on a 128 byte length record basis? How can work LINE INPUT (CR terminated record) with a fixed length record? Can I use LINE INPUT on a RANDOM (not sequential) opened file?

          I've carefully read the manual, and still have doubts about the strange options on COMM opening. As stated above, the FOR RAMDOM mode with the related RECORD SIZE. FOR OUTPUT: why can I open a comm FOR OUTPUT and also read the incoming chars? The WIDTH statement associated to a comm: how does it work? (the question is still unanswered from a previous forum).

          Explanation needed!

          Aldo

          ------------------

          [This message has been edited by Aldo Cavini (edited September 26, 2003).]
          Rgds, Aldo

          Comment


          • #6
            aldo,

            if i open a comm for random without declaring the record size, will the program work
            on a 128 byte length record basis?
            in my understanding, the answer is yes if one uses get# and put#. otherwise, the file / port
            should be considered as simply opened for input / output, so - for instance - a line input#
            would read from the current position up to the first end-of-line (cr and/or lf), and a print#
            would write from the current position.

            can i use line input on a random (not sequential) opened file?
            i think so; it certainly works on comm ports, as do input$() and input#.

            why can i open a comm for output and also read the incoming chars?
            i think the answer is the one from tom in http://www.powerbasic.com/support/pb...ead.php?t=1131 :
            "...it's an undocumented and unexpected result of an oversight or bug, and can't be relied on
            in any particular."

            the width statement associated to a comm: how does it work
            i join to this question . i'm sure that it works as expected for "lptn:":
            if a line is longer than n chars, the line gets broken by inserting a cr (or cr+lf ?)
            after the nth char. i was supposing it was working the same way for com, but the
            above thread would suggest that this isn't necessarily so.

            ------------------
            davide vecchi
            [email protected]

            Comment


            • #7
              Davide,

              my questions are bacause I prefer not to try undocumented syntaxes. Until now I always used a RANDOM file with only GET#/PUT#, BYNARY files with only GET$/PUT$, INPUT files with INPUTs and OUTPUT ones with PRINTs. All other combinations seem not to be documented, hence even trying them I can't be sure the behavior will remain unchanged on the next compiler versions.

              For instance, if I GET# or PUT# a record to a random opened file, a subsequent PRINT will write the data to the current seek position or to the end of the file?

              About COMMs, two possibilities.[list=1][*]FOR RANDOM is a dummy clause which doesn't matter at all[*]it does mean something. In this case, what? Can I GET# or PUT# to a COMM? Which LOCation will be Tx or Rx?[/list=a]

              May be my questions are phylosophycal ones, but I'd like to know what does it mean Tom's declaration: "OPEN FOR RANDOM is perfectly appropriate here". In other words, what is the difference between opening the comm using the clause FOR RANDOM or not?

              ------------------

              [This message has been edited by Aldo Cavini (edited September 26, 2003).]
              Rgds, Aldo

              Comment


              • #8
                Sorry, too much of a rush to elaborate much. Here's what I use in an
                app that reads a depth sounder at 6 pings (approx 12 bytes per ping)
                every second. Runs for hours, never a hitch. BTW runs on 25Mhz 486,
                and is actually ON COM / event driven.

                I think that setting the ignore errors flags is a good idea. I check for
                valid input content/sequences myself elsewhere.

                Code:
                hcomm$ = "COM2:9600,N,8,1,RS,CS,DS,CD,ME,FE"
                OPEN hcomm$ FOR RANDOM AS #6
                
                do...
                
                IF NOT EOF(6) THEN hd$ = hd$ + INPUT$(LOC(6), 6)
                
                ...somthing with the data...
                
                ...loop.

                ------------------
                What can go wrong will go wrong.
                Anything can go wrong.
                What hasn't?!?!
                What can go wrong will go wrong.
                Anything can go wrong.
                What hasn't?!?!

                Comment


                • #9
                  Aldo, it's a legacy thing. BASIC comm support has been around longer
                  than BINARY file mode. The only other mode that supports both input
                  and output is RANDOM. So, you use FOR RANDOM if you need to open a
                  device for both input and output.

                  Record sizes and file seek positions are not meaningful when dealing
                  with comm devices. INPUT$ and PRINT# are fine here.

                  ------------------
                  Tom Hanlin
                  PowerBASIC Staff

                  Comment


                  • #10
                    My own personal experience from ham radio data communications:
                    Enter one byte at a time and concanotate the string. i.e.:
                    Code:
                    open "COM2:9600,N,8,1,RS,CS,DS,CD" as #1 'ferget 'bout RANDOM, BINARY, or anything else
                    do
                    if not eof(1) then 
                    get$ #1,1,a$              '<-- One byte at a time
                    if a$ = chr$(13) or _     '<-- Carrage return or
                       a$ = chr$(10) then     '<-- Line feed
                    call DoSomething
                    else
                    t$ = t$ + a$
                    end if
                    end if
                    loop
                    The above example gives you control absolute over incoming data.
                    If nothing is in the port, go on to something else. If data is
                    there, get it and process it.

                    [opinion]
                    I have found that when dealing with block input, there could be
                    a control character (Xon/Xoff, Cr$, Lf$, whatever) imbedded in
                    the string that would require additional code to parse out and
                    take whatever action is needed. The one-byte-at-a-time eliminates
                    this and makes for very simpler coding.
                    [/opinion]


                    ------------------
                    There are no atheists in a fox hole or the morning of a math test.
                    If my flag offends you, I'll help you pack.

                    Comment


                    • #11
                      Tom,

                      thanks for the reply. A question more: I never used PRINT or INPUT$ on a FOR RANDOM opened disk file. Is there a by-design behavior? Will PRINT add chars to the end of the file (as FOR APPEND), or to the beginning (as FOR OUTPUT)? If to the beginning, will the file be truncated? Will the current seek position (or current record) affect the INPUT/OUTPUT statements?

                      All this is for curiosity; but I think it'd be useful to know what is by design and what is a side effect on this stuff, which is not declared on the manual.

                      Aldo

                      ------------------
                      Rgds, Aldo

                      Comment


                      • #12
                        Files and devices do not play by the same rules. I would not suggest
                        using PRINT# or INPUT$ with a file opened FOR RANDOM.

                        ------------------
                        Tom Hanlin
                        PowerBASIC Staff

                        Comment

                        Working...
                        X