In using WaitForStrTimeout in the USART module, I put togther the following subroutine. The idea is that once a return response header from a modem is detected, I grab the rest of the string after this detected header and put it into a string array. Trouble is, sometimes WaitForStrTimeout is missing the beginning of the array, and I have to make the request again. Maybe I'm just using it wrong, but here is the essential code I pulled out of the main program:
Code: Select all
Device = 18F66J16
Clock = 32
#option USART_BRGH = true
//#option USART_BRG16 = true //doesn't compile in this test for some reason, although it works in my main code-get a "constant expression violates subrange bounds" error on set baud below
#option RX_PRIORITY = IPLow
Include "usart.bas"
Include "usart2.bas"
Include "convert.bas"
Include "string.bas"
Dim
Modem_response_code As String(5),
i As Byte,
temp As Word,
Modem_result As String(81),
RC2IP As IPR3.5, // RC2IP, EUSART2 receive interrupt priority (0 = low)
BRGH16_1 As BAUDCON1.3 // set 16 bit baud register enable bit
Sub get_USART1(pStringIn As String, Timeout As Word)
USART.WaitForStrTimeout(pStringIn,Timeout)
i = 0
Repeat
Modem_result(i) = USART.ReadByte
temp = StrToDec(Modem_result(i))
Inc(i)
If i = 81 Then i = 0 EndIf //size of array is 80 bytes ("bound" didn't work here, maybe because it's a string array?)
If temp = 0 Then Exit EndIf //exit if end of string encountered
If temp < 20 Then Dec(i) EndIf //do not accept nonprinting characters
Until Not USART.DataAvailableTimeout(10)
End Sub
//Set up serial ports
// Set up EUSART2, for the GPS. The EUSART2 module settings don't seem to work in the module with the modified NMEA code, so they are set here.
USART2.SetBaudrate(br9600)
RCSTA2 = %10010000
TXSTA2 = %00100100
BAUDCON2.5=0 // RX data polarity set to active high = 0, non-inverted to the receiver, since going coming in directly at TTL level with no RS232 level shifter
BAUDCON2.4=0 // TX clock idle state is high = 0 (since going to an external RS232 level shifter as debug output)
RC2IP = 0 // set EUSART2 interrupt priority to low
//set up EUSART1, for the modem, to 19200 bps
RCSTA1 = %10010000
TXSTA1 = %00100100
BRGH16_1 = 1
SPBRGH1=$01 '32 MHz ((32,000,000/19200)/4) - 1 = 415 = $019F for 19200 bps
SPBRG1=$9F '32 MHz 9600 = $1A high, $09 low
//calling the subroutine:
get_USART1("+REQ:",10000)
Modem_response_code = Mid(Modem_result,0,1)
USART2.Write("Modem_response_code is: ",Modem_response_code)
get_USART1("+REQL:",10000)
Modem_response_code = Mid(Modem_result,1,1)
USART2.Write("Modem_response_code is: ",Modem_response_code)
However, when looking for the contents of the string "+REQL:", it fails about 1 out of 3 tries. The "+REQL:" response is longer than +REQ; +REQL is followed by a space, then a digit, then a comma, then a space, number, comma, 3 more times. There is always a carriage return and line feed and "OK" after this string as well. For now, I just want to capture the first digit consistently. Then I'll move on to catching each of the others later in this response string.
I've been around and around on this, and this seemed like the best variation. This is from a 900 line program that calls about a dozen modules and I've been able to plough through all of it to now, it's just this silly problem that I hope looks obvious to someone. I already am using the low priority interrupt for serial in on USART2 from a GPS using a modified NMEA user module (USART2 output is used for debug). The high priority interrupt routine contains 3 different interrupt sources and a check for key presses. These, though, are disabled when I run this sub. Any suggestions?
-Tom