USART.WaitFor Question
Moderators: David Barker, Jerry Messina
USART.WaitFor Question
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
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
Hello, if its a string then use WaitForStrTimeout as below:-
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.
Code: Select all
result=USART2.WaitForStrTimeout("#QSS: 0,1",100)'look for return string and timeout if failed
I use the timeout method to great effect in random length data reception.
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
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
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):-
This next method keeps reading the buffer until its empty before exiting(not elegant but works for me):-
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.
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
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
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.
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.
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