View previous topic :: View next topic |
Author |
Message |
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
EX_SISR please help |
Posted: Sun May 23, 2010 7:35 am |
|
|
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: 19539
|
|
Posted: Sun May 23, 2010 10:12 am |
|
|
'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
|
|
|
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
|
Posted: Sun May 23, 2010 11:29 am |
|
|
"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
|
|
Posted: Sun May 23, 2010 11:36 am |
|
|
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
|
|
Posted: Sun May 23, 2010 11:44 am |
|
|
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
|
|
Posted: Sun May 23, 2010 11:53 am |
|
|
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
|
|
Posted: Mon May 24, 2010 5:32 am |
|
|
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: 19539
|
|
Posted: Mon May 24, 2010 7:41 am |
|
|
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
|
|
Posted: Tue May 25, 2010 2:04 pm |
|
|
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
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Tue May 25, 2010 2:32 pm |
|
|
And we can see 'why' from the original code. BUFFER_SIZE at 20.
Best Wishes |
|
|
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
|
Posted: Tue May 25, 2010 7:02 pm |
|
|
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 |
|
|
|