How to stop a program HSERIN blocking

Discussion in 'Embedded Systems and Microcontrollers' started by camerart, May 8, 2019.

  1. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi,
    EDITED:
    I'm using HSERIN an a program, but it blocks
    How do I stop this please?
    As this has been edited, some early replies, may look confusing.
    Camerart.
     
    Last edited: May 24, 2019
  2. ericgibbs

    Moderator

    Jan 29, 2010
    8,527
    1,713
    hi C,
    You could check for a character in the serial buffer, by using an ASM statement, prior to trying HSERIN.
    E
     
  3. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi E,
    I can't 'do' ASM, and as I'm tidying up, I'll leave this till later in my project.
    Thanks.
    C.
     
  4. ericgibbs

    Moderator

    Jan 29, 2010
    8,527
    1,713
    hi C,
    We already use one version in your programs.
    E

    getmsg: 'read
    If PIR1.RCIF = 0 Then Goto getmsg
    char = RCREG
    ............................
     
  5. Ian Rogers

    Well-Known Member

    Dec 12, 2012
    645
    178
    You should use HSERGET.. This is non blocking but will return 0 if nothing has arrived...
     
    JohnInTX likes this.
  6. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi E and I,
    I found the [ getmsg ] programs, and now understand how to use it.

    I tested HSERGET instead of HSERIN and it works fine, especially, as sometimes a message starts then gets garbled, and HSERGET READS it, so some DATA can be collected

    At the moment I'm checking using the Simulator and at this point;
    --------------------------------------------------------------------------------------------
    Hserget char
    If char = "$" Then 'start
    str1(0) = char
    str2(0) = char
    rxi = 1
    Else
    Goto skip1
    Endif
    ------------------------------------------------------------------------
    if I mess up the beginning of the message which starts with [ $ ] then it goes to [ skip1 ] but leaves the rest of the message blocking the [ Hardware UART sim ]
    Will this be the same LIVE (I'll be LIVE testing later.)
    Thanks,
    C.
     
  7. ericgibbs

    Moderator

    Jan 29, 2010
    8,527
    1,713
    hi C,
    As your serial inputs are not synchronised, recall what we had to do sometime ago.
    If the RX buffer gets buffer gets data and it is not Read, then the OERR flag is set, if you do not test for this flag, when you read the buffer it could be 'old' rubbish data.
    We used the following routine.

    get_neo:
    If RCSTA.OERR = 1 Then 'if over run error then flush RXD buffer
    RCSTA.CREN = 0
    RCSTA.CREN = 1
    char = RCREG
    char = RCREG
    PIR1.RCIF = 0
    Endif

    sync1: 'wait for a $ start of string
    If PIR1.RCIF = 0 Then Goto sync1
    char = RCREG
    If char <> 0x24 Then Goto sync1 '$'
    str1(1) = char
    rxi = 2
     
  8. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi E,
    We changed the [ get_neo ] to [ get_data ] where some changes were made, here is what is used at the moment:
    I notice there isn't [ PIR1.RCIF ] in the later CODE.

    Is there a reason for the second [ char = RCREG ] marked with XXXXXXXXXXXXXX
    C.
    Code (Text):
    1. ------------------------------------------------------------------------------------
    2. get_data:
    3. 'Await GPS RXD -----------------GPS RMC ----------------------
    4. ''''''PASTE: $GNRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A?
    5. '''OR PASTE: $REMOTE,1100,1200,1300,1400,1500,1600,?
    6.  
    7. If RCSTA.OERR = 1 Then  'if over run error then flush RXD buffer
    8.     RCSTA.CREN = 0
    9.     RCSTA.CREN = 1  'ENABLES RECEIVER
    10.     char = RCREG
    11.     char = RCREG  'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    12.     Hserout "RX Err!", CrLf
    13.     Goto skip1
    14. Endif
    15. 'Hserin char
    16. 'HSERGET TEST
    17. Hserget char
    18. If char = "$" Then  'start
    19.     str1(0) = char
    20.     str2(0) = char
    21.     rxi = 1
    22. Else
    23.     Goto skip1
    24. Endif
    25.  
    26. nxt_rxin:
    27.     Hserin char
    28.     If char = "?" Or char = 0x0a Then Goto msg_eol
    29.     str1(rxi) = char  'Set to only use str1 or 2
    30.     str2(rxi) = char
    31.     'Hserout str1(rxi)  'show for testing only
    32.     rxi = rxi + 1
    33. Goto nxt_rxin
    34.     'Hserout CrLf
    35.  
    36. msg_eol:  'Sends received and saved message via HSEROUT
    37.     strtim = ""
    38.     strlat = ""
    39.     strlat = ""
    40.     strlong = ""
    41.     strtp = ""
    42.     strpr = ""
    43.     msg1 = ""
    44. ------------------------------------------------------------------------------------------------------
    Mod edit: code tags
     
    Last edited by a moderator: May 9, 2019
  9. BobaMosfet

    AAC Fanatic!

    Jul 1, 2009
    734
    182
    Do you program in C? If you do, you can do assembly. Simply code the hex and jump to it.
     
  10. BobaMosfet

    AAC Fanatic!

    Jul 1, 2009
    734
    182
    Where's your flowchart. Do you understand how to actually manage trains of data, and parsing, or are you still at the spaghetti code stage?
     
  11. ericgibbs

    Moderator

    Jan 29, 2010
    8,527
    1,713
  12. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi B,
    I learnt spaghetti BASIC in the 80s by watching my son programming a Zx Spektrum, and never advanced, sadly. I can assure you that I've tried.
    I get advice from members of this type of forum, saving snippets of CODE, and pasting them into new programs, where they are corrected as in this example.
    I adapt what I want as I go along, there is no flowchart.
    P.S The program I'm [we're) on at the moment has taken a couple of years so far:)
    C
     
    Last edited: May 10, 2019
  13. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi E,
    Char = RCREG----------OK

    Am I correct that because of the above there is no need for [ PIR1.RCIF ] ?
    C.
    ---------------------------------------------------------------------
    FROM D/S:
    RCIF: EUSART Receive Interrupt Flag bit 1 = The EUSART receive buffer, RCREG, is full (cleared when RCREG is read) 0 = The EUSART receive buffer is empty
    ---------------------------------------------------------------------
     
  14. ericgibbs

    Moderator

    Jan 29, 2010
    8,527
    1,713
    hi C,
    It depends upon how your program is written.
    If you do not have the On UART RX, Interrupt Enabled and you wanted to check if a UART char had been received, the program would check the RCIF flag.
    If RCIF=1, then to ensure that an RX Bfr Over Flow Error had not occurred [ while the program had been off doing other things] check the OERR.
    If the EORR =0 then read the incoming msg until <crlf>
    ELSE
    RCSTA.CREN = 0
    RCSTA.CREN = 1
    char = RCREG
    char = RCREG
    PIR1.RCIF = 0 ; clear the RCIF flag, which had been set by the earlier ERR data.

    ; and either wait for the next incoming msg IDENT and read the full msg,,,,, OR go do something else
    E
     
  15. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi,
    In the simulator, the program isn't blocking, but the UART is.

    When there is no $ at the beginning of the sentence, it jumps to [ SKIP1 ] Is there something I could put there to clear the UART?

    C
     
    Last edited: May 10, 2019
  16. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi,
    I've tried the simulator where #15 is true.

    LIVE tests:
    Using HSERGET does keep the program flowing allowing the other modules (Compass etc) are serviced, but doesn't appear to process the CHARS so I think HSERIN has to be used. Any comments?

    Using HSERIN, as shown in the simulator the UART blocks.

    IMPORTANT NOTE:
    In the program I use a DATA SWITCH to switch between the GPS and 'BASE/REMOTE', each INPUT switches to the other as each is READ
    C
     
    Last edited: May 10, 2019
  17. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi,
    Reading #14 again, Am I correct that [ On UART RX ] would need a TIMER? If so then I don't have it set, would it be better if I did?.

    Here is the bottom of the MAIN LOOP, showing the GOTO and the SUBROUTINE.
    C.
     
  18. ericgibbs

    Moderator

    Jan 29, 2010
    8,527
    1,713
    hi C,
    You are Exiting a GOTO call to subroutine with a RETURN.
    Its the Program thats hanging not the UART
    E

    get_data:
    If RCSTA.OERR = 1 Then 'if over run error then flush RXD buffer
    RCSTA.CREN = 0
    RCSTA.CREN = 1 'ENABLES RECEIVER
    char = RCREG '1
    char = RCREG '2
    PIR1.RCIF = 0 'clear the RCIF flag, which had been set by the earlier err data.
    Hserout "RX Err!", CrLf
    Goto skip1 ' ?????????????????????????????????
    Endif
    ......................................................................
    skip1:

    For x = 0 To 79
    str1(x) = 0
    Next x

    For x = 0 To 79
    str2(x) = 0
    Next x


    Return '???????????????????????????????
     
  19. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi E,
    The RETURN is returning to the earlier [ Gosub get_data ] See #17
    C.
     
    Last edited: May 10, 2019
  20. camerart

    Thread Starter Senior Member

    Feb 25, 2013
    1,608
    42
    Hi,
    As each test using the fantastic simulator takes quite a while, I quite often loose track of what I'm testing (Even with notes) So I tend to test LIVE for this.

    Today I woke up with a FLOWCHART in my head, but while I can 'see' it, I can't tell if it would work as a program.

    Using the example in #17, I understand how each element works (Almost!) Here is what I want to try, and I think I can write it.
    -------------------------------------------------------------------------------------------------
    Use the [ If RCSTA.OERR = 1 Then ] section at the beginning.

    [ If char = "$" Then ] start LOOP of this until>
    [ If str1(1) = "R" Then ] section, then look for that sentence [ ? ]
    OR
    [ If str1(5) = "C" or "R" Then ] section, then look for that sentence [ ? ]

    (Now that sentence is in STR1 or 2) switch [ DATASWITCH ] to look for the alternate type of sentence, while processing this sentence. (This would hopefully save going though all of the approx 10x NMEA sentences when checking the GPS)

    If either type of sentence are not RECEIVED then use an INTERRUPT to switch the DATASWITCH until one or the other sentence is RECEIVED.

    I hope this is clear, I'll keep checking, while I attempt to write this, if someone would check the flow please?

    EDIT: MARKED BOLD
    C.
    ----------------------------------------------------------------------------------------------------
     
    Last edited: May 22, 2019
Loading...