USART.WaitFor Question

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

USART.WaitFor Question

Post by Widgetman » Mon Apr 14, 2008 12:38 am

Hi All,
Does anyone know how to wait for a specific sequence of characters coming in on a USART. I am trying to use the USART.WaitFor() routine, but it only takes 1 character as a trigger. Any thoughts would be appreciated.
Thanks

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Mon Apr 14, 2008 11:39 am

Hello, if its a string then use WaitForStrTimeout as below:-

Code: Select all

result=USART2.WaitForStrTimeout("#QSS: 0,1",100)'look for return string and timeout if failed
If its unknown length decimal data then read it into an array and use the timeout or a specific character to end the receive period.
I use the timeout method to great effect in random length data reception.

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Post by Widgetman » Mon Apr 14, 2008 2:40 pm

Hi DOJ,
I have been playing with it and discovered it works using the USART.WaitFor($8A) as a example. The issue I am seeing is it works the first time I use the call, but other calls below the first one seem intermittent at best. I suspect there is a flag gettin cleared in the first trigger, and does not get reset unless I init the ISSRX stuff again. I will keep digging into it. Ultimately I am trying to figure out how to trigger on 2 hex bytes using the USART.WaitFor routine. I want to trigger on a two byte pattern which is not a string. A example would be $8A $0D

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Tue Apr 15, 2008 12:40 am

Hello Widgetman, this sounds like a typical example of buffer overflow.
As far as I know, and experienced, when I did all my 232 work on the current project is the two byte buffer in the USART will stop receiving bytes unless at least one byte of the buffer is clear, therefore you need to make sure the buffer is clear before you start a read or you may not get what you expect.

For example, if the buffer has one byte in it and you do not know its there,
then you send it off to receive two bytes but do not clear the buffer out first it will never see the last expected byte, you will then try to read two bytes and you will not have the ones you want.

I always clear the RX buffer before my routine, I found that using CREN toggle (ClearOverrun) simply did not work, and manipulating the registers did nothing(there is a longish thread about this somewhere on here).

Also do not use super high speeds to do tests as that in itself is a disaster waiting to happen, start down at 9600 and work it up, experience talking there! I dont recall really needing high speed in any of my little jobs, I keep it as slow as possible so I can use the inbuilt oscilator.

I now use one of 2 methods.
One is simple, turn off the serial module and turn it back on(USART2 here):-

Code: Select all

Public Sub CLEAR_RX_2()
    RCSTA2.4=0                                      'disable serial port 2 receive
    RCSTA2.4=1                                      'enable serial port 2 receive
    
End Sub
This next method keeps reading the buffer until its empty before exiting(not elegant but works for me):-

Code: Select all

Public Sub CLEAR_USART2()
    Dim result As Boolean                           'returned from USART module
    Dim clear_byte As Byte                          'holds value in USART buffer
    clear_byte=0                                    'initiate

clear_buffer:    
    result=false                                    'default to no data received
    result=USART2.DataAvailableTimeout(10)          'test for byte of data being received, timeout if not

    If result=true Then
        clear_byte=USART2.ReadByte
        GoTo clear_buffer
    EndIf
    
End Sub
When it exits the RX buffer should be clear toreceive your data.

I use the second method most as I got caught unawares with unexpected characters filling the buffer and it still not being clear when I though it should be, any noise getting in will be interpreted as data!

Best of luck.

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Post by Widgetman » Tue Apr 15, 2008 11:37 am

Hi DOJ,
Thanks a bunch I will play with that and see what I get

yudi
Posts: 10
Joined: Sat May 23, 2009 3:02 am
Location: Indonesia

Post by yudi » Tue Jun 02, 2009 2:38 am

Dear DOJ,

Can i know one example how to implement RCST to clear the RX buffer, because i never get more than 3 bytes when sending data from PC.

For example if i send "1234" ; i always get "123".

Thanks a lot for your help.

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Tue Jun 02, 2009 12:33 pm

The buffer will stop receiving data if you do not read from the buffer.
The posts above tell you how to clear the buffer before you start to receive data and be sure that both bytes are empty.

Code: Select all

Program test_SERIAL

'device=18F4620<<<< place your device here

Clock=8

Include "usart.bas"

Dim test_string As String                                           'the received data will be placed in this string
Dim result As Boolean                                               'true=data in USART
Dim string_character_position As Byte                               'position of each character in the test string

USART.SetBaudrate(br9600)                                           'this test is at 9600 baud, also initialises the USART


While 1=1

    If PORTC.7=0 Then                                               'when the serial port receives a signal run this code
        result=false                                                'default to no data received
        string_character_position=0                                 'string character starts at zero
        test_string=null                                            'default to an empty string
        While result=USART.DataAvailableTimeout(100)=true           'test for byte of data being received, timeout in 100ms
            test_string(string_character_position)=USART.ReadByte   'read the USART data into the string
            inc(string_character_position)                          'move to next character position   
        Wend
        test_string(string_character_position)=null                 'no more data so terminate the string
    
        if test_string<>null then                                   'data was received
            usart.write(test_string)                                'echo the received data on the serial port
        endif
    EndIf

Wend

Post Reply