CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

EX_SISR please help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

EX_SISR please help
PostPosted: Sun May 23, 2010 7:35 am     Reply with quote

Please help me with this program. I'm trying to use a strstr function to activate an output if a string appears within another string but it's not working and I'm stuck. I used the template from EX_SISR.
Code:

#include <16F876A.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7)

#define BUFFER_SIZE 20
#define bkbhit (next_in!=next_out)

char buffer[BUFFER_SIZE];
char s2[5]="5603";
char s3[6]="E0703";
char s4[6]="85C06";
char *ptr1;
char *ptr2;
char *ptr3;

BYTE next_in = 0;
BYTE next_out = 0;

#int_rda
void serial_isr() {
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t;           // Buffer full !!
}

BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}

void main(){
enable_interrupts(global);
enable_interrupts(int_rda);
printf("\r\n\Running...\r\n"); // The program will delay for 10 seconds and then display
                  // any data that came in during the 10 second delay
do{
ptr1=strstr(buffer, s2); // led1 on
ptr2=strstr(buffer, s3); // led1 off
ptr3=strstr(buffer, s4); // led2 on

if(ptr1)
output_high(pin_B7);

if(ptr2)
output_low(pin_B7);

if(ptr3)
output_high(pin_C4);

} while (TRUE);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun May 23, 2010 10:12 am     Reply with quote

'buffer', is not a string.
A string in C, is a _null terminated_ sequence of bytes.
There is no 'null termination' in buffer.
Also, 'buffer' is a circular buffer. The strings you are looking for, may well be split, with one or more characters at the end of the buffer, and the rest down the start. strstr, won't find the data in these cases...
A series of routes.
1) Move data from 'buffer' to a string. Null terminate it, when something like a line feed is seen. Search in this.
2) Search 'on the fly', using a state machine. More complex to write, but faster. I have in the past posted example parser's here doing this.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 23, 2010 11:26 am     Reply with quote

The key point about Ex_Sisr.c is that you're supposed to use the bgetc()
function to get chars from the buffer. You're not supposed to directly
access the buffer. You're supposed to use the bgetc() function to get
a char from the buffer.

Here are the links that Ttelmah is referring to:

From Ttelmah:
http://www.ccsinfo.com/forum/viewtopic.php?t=31144
From srhoar:
http://www.ccsinfo.com/forum/viewtopic.php?t=28159
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Sun May 23, 2010 11:29 am     Reply with quote

"1) Move data from 'buffer' to a string. Null terminate it, when something like a line feed is seen. Search in this."

Please, I don't understand how I can move the buffered data to a string and null terminate it.
Can you give a small example ?
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Sun May 23, 2010 11:36 am     Reply with quote

I've just looked at the parse method used that PCM Programmer linked me to. This is waaaayyyy beyond my level of understanding. I think I'm more comfortable using the strstsr function for now.

Can any one provide a small example just for me to use as a guide ?


Sal
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 23, 2010 11:44 am     Reply with quote

Do your incoming strings have any special character that begins the
string or that ends the string ?
For example, NMEA messages always begin with a '$' character.
They always end with a Carriage Return and a Linefeed (0x0D, 0x0A).
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Sun May 23, 2010 11:53 am     Reply with quote

As far as I know all the data to be received is in the form of messages or replies from a gsm modem.

I don't think there is any '$'. The messages are preceded and ended with
0A/0D

example:

If I send "AT" it responds

0A\0D\OK\0A\0D
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Mon May 24, 2010 5:32 am     Reply with quote

I'm trying to move the contents of the buffer to s1 and then add a NULL to s1 to make it a valid string. Again it doesn't work. The rest of the code is same as above. I've only edited the MAIN.

Code:
void main(){

char s2[4]="123";
char s3[4]="321";
char *ptr1;
char *ptr2;

enable_interrupts(global);
enable_interrupts(int_rda);

delay_ms(1000);
printf("\r\n\Running...\r\n");

ptr1=strstr(s1, s2); 
ptr2=strstr(s1, s3);                                 
while(TRUE){
delay_ms(3000);
while(bkbhit)
s1[24]=bgetc();
s1[25]='\0';

if(ptr1)
output_high(pin_c4);

if(ptr2)
output_low(pin_c4);
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon May 24, 2010 7:41 am     Reply with quote

Because you are not moving the contents of the buffer into a string....
What your new code does, is move any character that arrives, into the single location sl[24]....
You are also doing your searches, before any data is in the string.

Now, some comments. There is no point at all, in looking at the string, till the '0x0D' character is seen. This should be used as your marker for a possible new string to look for. So you need something like:
Code:

    //In your variable declarations
    char temp_line[20];
    int locn=0;
    char temp_chr;


    //Then your 'while'
    while (TRUE) {
        if (bkbhit()) {
            //Now have a character
            temp_chr=bgetc(); //get the character
            if (temp_chr=='\r') {
                //Have a carriage return
                temp_line[locn]='\0'; //null terminate string
                locn=0; //reset to start looking again
                ptr1=strstr(temp_line, s2);
                ptr2=strstr(temp_line, s3);   //Now do the searches
                if(ptr1)
                    output_high(pin_c4);

                if(ptr2)
                    output_low(pin_c4);
            }
            else {
               temp_line[locn]=temp_chr; //store the character
               if (locn<19) ++locn; //and update the counter
            }
        }
     }

Obviously you need to add the rest of the 'main' round this.

Best Wishes
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Tue May 25, 2010 2:04 pm     Reply with quote

I added the code to my main but i get a warning after comilation...

interrupts disabled during call to prevent re-entrancy: (@DIV88)

Any ideas why ?

Code:
void main(){

char s1[]="123";
char s2[]="321";
char *ptr1;
char *ptr2;
char temp_line[20];
int locn=0;
char temp_chr;

enable_interrupts(global);
enable_interrupts(int_rda);

 


    //Then your 'while'
    while (TRUE) {
        if (bkbhit) {
            //Now have a character
            temp_chr=bgetc(); //get the character
            if (temp_chr=='\r') {
                //Have a carriage return
                temp_line[locn]='\0'; //null terminate string
                locn=0; //reset to start looking again
                ptr1=strstr(temp_line, s1);
                ptr2=strstr(temp_line, s2);   //Now do the searches
                if(ptr1)
                    output_high(pin_c4);

                if(ptr2)
                    output_low(pin_c4);
            }
            else {
               temp_line[locn]=temp_chr; //store the character
               if (locn<19) ++locn; //and update the counter
            }
        }
     }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 25, 2010 2:12 pm     Reply with quote

You didn't post your interrupt routine, which is the one thing that would be
of interest. But here's a thread that has a solution:
http://www.ccsinfo.com/forum/viewtopic.php?t=33837
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue May 25, 2010 2:32 pm     Reply with quote

And we can see 'why' from the original code. BUFFER_SIZE at 20.

Best Wishes
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Tue May 25, 2010 7:02 pm     Reply with quote

Once again THANKS very much for your guidance. I changed the BUFFER_SIZE from "20" to "32" and the code compiled with no errors !
That's amazing.

Now it's time to do some testing...


Sal
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group