View previous topic :: View next topic |
Author |
Message |
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
Another time I need your appreciable help |
Posted: Thu May 04, 2006 12:11 pm |
|
|
Well, following with my project now I need find a string in a SMS mesagge in the GSM modem.
The AT command to do that is AT+CMGR=1 being "1" the first position of the SMS card. This message exist and contains this information:
07914306090969F5040B914336793446F8000060408212645380024F27
To find the substring "4F27" I have made this programm but I does not work. I think the hard works fine so it can dial a number. I am testing all of this with the protoboard of CCS
What I am making bad ?
Code: |
#include <16F877A.h>
#device ICD=TRUE
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#fuses HS,NOWDT,NOPROTECT,NOLVP
#include <string.h>
int i;
int const lenbuff=59;
int xbuff=0x00;
char cbuff[lenbuff];
char *si_find;
char alarma_on[ ] = "4F27";
#int_rda
void serial_isr()
{
if(kbhit())
{
cbuff[xbuff]= getc();
xbuff++;
}
}
void main()
{
enable_interrupts(global);
enable_interrupts(int_rda);
for(i=0;i<lenbuff+1;i++)
{
cbuff[i]=0x00;
}
while(True) {
printf("AT+CMGR=1\r\n");
delay_ms(10000);
si_find= strstr(cbuff,alarma_on);
if (si_find != NULL)
{
output_low (PIN_A5);
delay_ms(5000);
output_high (PIN_A5);
}
for(i=0;i<lenbuff + 1;i++)
{
cbuff[i]=0x00;
}
}
}
Is there some way to see what I am receiving from the modem? In the case that something arriving.
Thank�s in advance
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 04, 2006 1:02 pm |
|
|
Your program has several problems, both in design and coding.
1. You should never set the buffer size to the exact size ( +1) of
the incoming string. What if the string is longer than expected ?
Set it to a value a few chars longer than the longest expected string.
2. The "lenbuff" value should be declared with a #define statement
and in should be put in all caps, since it's a constant: LENBUFF
3. You don't need to check kbhit() in the INT_RDA isr. If you get
an RDA interrupt, you must have a kbhit, by definition.
4. Your INT_RDA isr has no limit on the number of characters
that can be accepted, so if you get more than the expected
number, you will over-write RAM past the end of the cbuff array
and probably destroy other variables in your program.
5. You set xbuff to 0 at the start of the program, but then you
go through a while() loop that can continuously accept new
messages and try to store them in cbuff. But because xbuff
is never reset to 0, any new message that is received will
overwrite RAM past the end of cbuff and destroy all RAM
contents in your PIC.
6. Your method of filling the cbuff array with zeros will write past
the end of cbuff by 1 byte position. Any variable that is allocated
to that RAM location by the compiler will be destroyed by your code.
7. Your method of deciding if you have a full message in cbuff is to
wait for 10 seconds. What if the message doesn't arrive in that
time, or has only partly arrived ?
There might be other problems. |
|
|
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
|
Posted: Thu May 04, 2006 4:04 pm |
|
|
Thank�s a lot PCM Programmer.
Your help has been very useful for me.
I have modified my code following your explanations and indications an the programm WORKS VERY WELL
The longest message (for instance advertising message) could be so long that full the RAM of the pic. I am only interesting in the alarm message that it has a long of 58 chars. So I restrict the buffer. Afther the arriving of any message will be proceced an deleted. If the message has the right code will activate the alarm.
I have considered all your suggestions. The last point is some problematic to me. The programm explorer the first position of the SIM card each 10 segs. Do you suggest to do more frequently ?.
This is "your" modified code:
Code: |
include <16F877A.h>
#device ICD=TRUE
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#fuses HS,NOWDT,NOPROTECT,NOLVP
#include <string.h>
#define LENBUFF 59
int i;
int xbuff=0x00;
char cbuff[LENBUFF];
char *si_find;
char alarma_on[ ] = "4F27";
#int_rda
void serial_isr()
{
cbuff[xbuff]= getc();
xbuff++;
if (xbuff >= LENBUFF)
{
xbuff=LENBUFF;
}
}
void main()
{
enable_interrupts(global);
enable_interrupts(int_rda);
for(i=0;i<LENBUFF;i++)
{
cbuff[i]=0x00;
}
while(True) {
printf("AT+CMGR=1\r\n");
delay_ms(10000);
si_find= strstr(cbuff,alarma_on);
if (si_find != NULL)
{
output_low (PIN_A5);
delay_ms(5000);
output_high (PIN_A5);
}
for(i=0;i<LENBUFF;i++)
{
cbuff[i]=0x00;
}
xbuff=0x00;
}
}
I repit thank�s a lot
|
|
|
|
cmdrdan
Joined: 08 Apr 2005 Posts: 25 Location: Washington
|
|
Posted: Thu May 04, 2006 6:16 pm |
|
|
smxabi --
If you're only interested in the "4F27" part of the message, you could set up a simple state machine in your serial_isr to only look for that and ignore any other characters; thus saving a lot of your RAM for other purposes. Set a flag in the serial_isr() once you've received the four consecutive characters, and look for that flag inside your main() function. Using the state machine and flag will allow you to eliminate the strstr() routine, which probably uses a lot of memory also. Search through the board for "state machine" and you will find a lot of good ideas that others have contributed -- it worked for me....
Dan |
|
|
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
|
Posted: Fri May 05, 2006 2:58 am |
|
|
Thank�s for your answer Cmdrdam
No. the code I wrote is only an schematic of I have to do.
I must check the phone number that send de SMS and the disconect string.
String activation OK & phone number OK = Activation
String desactivation OK & phone number OK = Desactivation
Reading, (read is always good) the User Guide of my GSM modem I read that there is a more easy way to detect the arriving of a message. The modem notify by sending a "word of control"
I promise publish (in this site) the code when I finish all test.
The Gsm modem could be replaced for a movil phone (no all models works) |
|
|
|