View previous topic :: View next topic |
Author |
Message |
picsy
Joined: 01 Dec 2005 Posts: 3
|
string compare works unreliably |
Posted: Thu Dec 01, 2005 5:32 pm |
|
|
Hi all,
I have a problem with the following bit of code, which works unreliably. I'd be grateful if you could have a look at it below.
Basically I am trying to compare a modem response string (received on a RS232 port) with a predefined constant string 'SearchStr'. This result of the compare is wrong 'quite' often ...
First I output the AT command:
Code: |
clear_buffer(); // reset receive buffer
com("AT\r"); // output AT command to modem, I use TX buffer
|
Then I create the constant string as follows:
Code: |
strcpy(SearchStr,"\r\nOK\r\n");
|
Next I call the fct that should do the compare:
Code: | result = get_modem_answer(20,LF); // 20 second timeout, LF = terminating char
|
The actual fct is as follows:
Code: | get_modem_answer(int timeout, char termchar)
{
// this function searches the string 'modem_response' for 'SearchStr'
// SearchStr is a global char array and is set by the fct that called this fct
// it returns 1 if it found the string, otherwise it returns 0 (timeout)
int16 *r;
int loc=0;
ticks=0; // second ticks
do // repeat until timeout is up...
{
while (bkbhit) // new char in buffer? ( I use the interrupt driven ring buffer)
{
modem_response[loc]=bgetc(); // put received char into array
if (modem_response[loc]==termchar) // termchar received?
{
modem_response[loc+1]=0; // add temporary null to make a string (for use with strstr)
*r=strstr(modem_response,SearchStr);
if (*r!=0) // if found in 'modem_response'
{
return(1); // return 1
}
}
loc++;
}
}
while (ticks<timeout);
return(0); // indicates timeout occured
} |
The code for clear_buffer() is here:
Code: | void clear_buffer(void)
{
int m;
disable_interrupts(int_rda); // prevent incoming chars from modem
for(m=0;m<BUFFER_SIZE;m++) // clear memory
{
buffer[m]=0x30; // write '0' into each location
}
next_in = 0; // reset pointers
next_out = 0;
for(m=0;m<100;m++)
{
modem_response[m]=0x30; // clear array
}
enable_interrupts(int_rda); // allow incoming chars from modem
} |
The relevant variables are defined like this:
Code: |
char modem_response[100];
char SearchStr[50];
|
My setup is:
PCH V3.236
PIC18F8720
As I said the problem is that sometimes the string compare fct works correctly and sometimes not.
Just wondered if anyone can spot a bug here? I have been on this for days now and I am getting bonkers over this...
Could it have anything to do with the pointer *r ? (I don't know pointers very well).
Any ideas anyone?
Many Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 01, 2005 5:46 pm |
|
|
Quote: | int16 *r;
*r=strstr(modem_response,SearchStr);
if (*r!=0) // if found in 'modem_response' |
One obvious problem is that string functions return a char pointer,
not a pointer to a 16-bit variable. I'm sure you intend for your
comparison statement to operate on a byte, and not a word.
So change your declaration for 'r' to:
|
|
|
picsy
Joined: 01 Dec 2005 Posts: 3
|
|
Posted: Thu Dec 01, 2005 6:04 pm |
|
|
Many thanks for your quick reply, PCM programmer.
I have now declared *r as an 8 bit char, but unfortunately I am still getting wrong results.
hmmm... |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Thu Dec 01, 2005 6:23 pm |
|
|
Do you have any way to verify the string that the PIC is receiving? An LCD to display it on or even save it and disconnect modem and spit it back out to a PC? Have tried verifying your code with preprogrammed strings that you know are correct?
Do you have "ERRORS" in your #use rs232 statement?
Code: | #use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS) |
I would take a couple of steps back and check the links in the chain prior to your code....
Good luck,
John |
|
|
picsy
Joined: 01 Dec 2005 Posts: 3
|
|
Posted: Thu Dec 01, 2005 6:38 pm |
|
|
Thanks for your reply, John.
I am monitoring all outgoing and incoming chars on 2 separate PC comports. Comms is working well apart from this compare problem.
Regarding ERRORS, I do not use the #use rs232 directive as I set it all up individually myself, including the clearing of the errorflag, should one happen. I also use RX and TX buffers that are interrupt driven. I did not want to post the complete code as it would just be too much to wade through. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 01, 2005 7:22 pm |
|
|
I took a closer look at your code and there's another, bigger problem.
Quote: |
*r=strstr(modem_response,SearchStr);
if (*r!=0)
|
The strstr() function returns either a pointer or a NULL.
You need to put the return value into a pointer, and also
you need to be checking the pointer for a NULL.
You should be doing this:
Code: | int8 *r;
r=strstr(modem_response,SearchStr);
if (r!=0) |
I'm just looking for little "techy" errors here. I'm not trying to
look at any design issues. I don't really have the time at the
moment. |
|
|
|