Hi S,Is that one string/second, or all those strings every second? That makes a big difference in processing time.
Hi S,That is over 550 characters/sec, and at 9600baud (I'm assuming this is at 9600???), that would take well over 550mS just to receive that data every second. A huge overhead...
If you are processing and sending data strings out in the main program, you have very little time left to do anything else.
What you may want to do, is interpret the string as it comes it, looking for the one key phrase you want, and when you have the key information, turn off the UART and ignore the rest so you are not wasting time processing the other 450+ characters with the UART. When ready in the main program, turn the UART back on when ready to receive new data, whether from the GPS or the other source. Timing may still be an issue, but if you can skip a message once in a while, that may be an option.
Of course, an RX interrupt routine filtering the data and setting a flag when you get a valid string of interest would be more efficient, as interrupt can process in background all the time regardless of what the main program is doing. I know it gets complicated, but that is still a valid option.
In simple terms, it doesn’t make a bit of a difference.Hi Both,
Blimey!
To explain what's arriving at the UART!
On the PCB, is a SWITCH that can be switched between the 2x DATA sources, so only one is arriving at any one time. (NOTE a [ ? ] was added to the REMOTE $Sentences as an EOL)
'Say' the DATASWITCH is set to GPS. This is what arrives one/sec.
____________________________________________________________________________
$GPRMC,162254.00,A,3723.02837,N,12159.39853,W,0.820,188.36,110706,,,A*74
$GPVTG,188.36,T,,M,0.820,N,1.519,K,A*3F
$GPGGA,162254.00,3723.02837,N,12159.39853,W,1,03,2.36,525.6,M,-25.6,M,,*65
$GPGSA,A,2,25,01,22,,,,,,,,,,2.56,2.36,1.00*02
$GPGSV,4,1,14,25,15,175,30,14,80,041,,19,38,259,14,01,52,223,18*76
$GPGSV,4,2,14,18,16,079,,11,19,312,,14,80,041,,21,04,135,25*7D
$GPGSV,4,3,14,15,27,134,18,03,25,222,,22,51,057,16,09,07,036,*79
$GPGSV,4,4,14,07,01,181,,15,25,135,*76
$GPGLL,3723.02837,N,12159.39853,W,162254.00,A,A*7C
$GPZDA,162254.00,11,07,2006,00,00*63
_____________________________________________________________________________
I am only interested in the RED sentence and only the dark RED digits.
In simple terms, where would the [ If PIR1.RCIF = 1 ] be? In the MAIN LOOP or as I have it in a [ GET_DATA ] GOSUB?
C
Hi D,In simple terms, it doesn’t make a bit of a difference.
Let me know if you want to know why!

Dim buffer(80) As Byte
Dim rxin As Byte
Dim temp As Byte
Dim valid As Byte
Dim str_done As Byte
Dim i As Byte
Hseropen 9600
'set up interrupts
PIE1.RCIE = 1
INTCON.PEIE = 1
INTCON.GIE = 1
rxin = 0 'Initialize
valid = 0
'main loop
'---------
main:
If str_done = 1 Then 'a valid packet has arrived
Hserout "Got it", CrLf
For i = 0 To valid
Hserout buffer(i)
Next i
str_done = 0
valid = 0
Endif
WaitMs 1
Goto main
End
On Interrupt
Save System
If str_done = 1 Then
temp = RCREG
Goto fin 'Completed string has not been processed yet by MAIN program
Endif
If RCSTA.OERR = True Then 'any error reboot serial module..
RCSTA.CREN = 0
RCSTA.CREN = 1
Goto fin
Endif
temp = RCREG
'Now check for valid string to save. Must contain $GPRMC at first, then read rest until EOL
Select Case rxin
Case 0 'Must be $ sign
If temp = "$" Then
buffer(rxin) = temp
valid = 1
Else
valid = 0
rxin = 0
Endif
Case 1
If temp = "G" Then
buffer(rxin) = temp
valid = 1
Else
valid = 0
rxin = 0
Endif
Case 2
If temp = "P" Then
buffer(rxin) = temp
valid = 1
Else
valid = 0
rxin = 0
Endif
Case 3
If temp = "R" Then
buffer(rxin) = temp
valid = 1
Else
valid = 0
rxin = 0
Endif
Case 4
If temp = "M" Then
buffer(rxin) = temp
valid = 1
Else
valid = 0
rxin = 0
Endif
Case 5
If temp = "C" Then
buffer(rxin) = temp
valid = 1
Else
valid = 0
rxin = 0
Endif
Case Else
If valid = 1 Then buffer(rxin) = temp 'get character(reading clears the RCIF)
EndSelect
If buffer(rxin) = "?" Then
valid = rxin 'set length of valid string
str_done = 1 'Flag we have a completed string. Main program to check for this and process
Else
If valid = 1 Then rxin = rxin + 1
If rxin = 80 Then rxin = 0 '80 position circular buffer. If overflow, start from scratch
Endif
fin:
Resume
No, you don’t need an INTERRUPT routineHi D,
OK, either way, thanks. That's fine.
Am I correct that, if there's a [ PIR1.RCIF ] in the MAIN program LOOP I need to add an INTERRUPT routine after the END?
Am I correct that, in the attached mages, showing [ PIR1.RCIF= 0 ] when there were digits, in the UART, was more of a timing thing, and would be catered for by the INTERRUPT process?
C.
While STUFF_TO_DO
‘ do other stuff here while waiting
‘ for a message. Could be nothing
‘ or something that was being
‘ blocked by your input code
WHILE PIR1.RCIF = 1
Hserin char
‘ start a new message
If char = “$” then ‘SOM
str1(0) = “$”
rxi = 0
Endif
‘ build the message
If str1(0) = “$” then ‘ MSG
rxi = rxi + 1
str1(rxi) = char
Endif
‘ identify the desired message
If rx1=5 and char<> “C”
str1(0) = “x” ‘ discard “$”
rx1=o
Endif
‘ by overwriting the ‘$’ character,
‘ everything else will be ignored
‘ finish a message
If char = “?” or char = 0x0A then
gosub msg_eol
Endif
If rxi > 79 then ‘ Overflow
‘ do your overflow stuff
Endif
Wend
‘ no characters in buffer
‘ do something else
Wend
.....
Else
If valid = 1 Then rxin = rxin + 1
If rxin = 80 Then
rxin = 0 '80 position circular buffer. If overflow, start from scratch
valid = 0
Endif
Endif
fin:
Resume
I agree... generally.Another good option DJ. I think, however, that MSG_EOL has to be within his main program in your example. Not sure how he can branch to it, he has to figure that out. MSG_EOL can also be some flag for the main program (stuff_to_do) to check and process when it gets set....
Hi D,I agree... generally.
I see MSG_EOL as being a true subroutine (in BASIC). Which means it isn’t part of the main routine. He just has to transfer execution with a gosub, not a goto. Using goto presents other problems. Problems which are eliminated by using a BASIC gosub.
In his last posted code he used a goto but ended the routine with a return. This is s recipe for disaster. Return should only be used with a gosub in BASIC.
In C, MSG_EOL would be implemented as a function call.
Hi S,C
Ask question soon, as I'll be on holidays for most of June, with limited access to the Internet...
Regardless, study all the code submitted, and test it with your overall program. Only you can decide which way to go....
Sorry that my program didn’t work for you. It was not a complete program; just a code sample to illustrate a possible technique.Hi D,
I don't follow the MSG_EOL conversation, 'yet' but I think we can leave it till a bit later, after I've checked both of your CODES.
Regarding the RETURN at the bottom of the section I posted. This is a RETURN to the GOSUB GET_DATA in the MAIN LOOP.
While testing your CODE, there are a few Oshonsoft SYNTAX errors, that I will have to look into and correct, before testing. Not your fault!
I like the concept of passing the priority from [ $ ] to the next priority. 'If you know what I mean'
I'll let you know how I get on.
Thanks
Hi D,Sorry that my program didn’t work for you. It was not a complete program; just a code sample to illustrate a possible technique.
Glad for you that sagor’s code worked.