View previous topic :: View next topic |
Author |
Message |
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
I can't understand why ? HELP ! |
Posted: Tue May 09, 2006 4:20 pm |
|
|
My activation program by SMS is nearly finished but I am stopped at this point. If I active the code by deleting "//" the program does not work. I am making a lot of tests but I could not find the bug. Please I need some help.
Code: |
#include <16F876.h>
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#fuses XT,NOWDT,NOPROTECT,NOLVP
#include <string.h>
#define LENBUFF 60
int xbuff=0x00;
int i;
char cbuff[LENBUFF];
char *si_1;
char *si_2;
char *si_3;
char alarma_on[] = "4F27";
char alarma_of[]= "4FE3";
char tfno[] = "3679xxxxx";
#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) {
delay_ms(10);
printf("AT+CMGR=1\r\n");
delay_ms(1000);
si_1= strstr(cbuff,alarma_on);
si_2= strstr(cbuff,tfno);
// si_3= strstr(cbuff,alarma_of);
if (si_1 != NULL && si_2 != NULL)
{
output_high (PIN_B2);
printf("ATD6397xxxxx;\r\n");
delay_ms(10000);
printf("ATH\r\n");
}
// else if (si_3 != NULL && si_2 != NULL)
// {
// output_low (PIN_B2);
// printf("ATD6397xxxxx;\r\n");
// delay_ms(10000);
// printf("ATH\r\n");
// }
for(i=0;i<LENBUFF;i++)
{
cbuff[i]=0x00;
}
xbuff=0x00;
delay_ms(10000);
}
}
Peharps there is another way to find the phone and the substrings
Thank?s in advance.
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 09, 2006 4:34 pm |
|
|
Quote: | #define LENBUFF 60
int xbuff=0x00;
char cbuff[LENBUFF];
#int_rda
void serial_isr()
{
cbuff[xbuff]= getc();
xbuff++;
if (xbuff >= LENBUFF)
{
xbuff=LENBUFF;
}
} |
I don't know what you're trying to do, but I did see one problem.
In the code above, if you increment xbuff and it is >= 60, then
you set it to 60. So on the next interrupt, the first line in the isr
will be:
cbuff[60] = getc();
But the array only has elements from 0 to 59. In the C language,
array indexes start at 0. The last available index is always one less
than the declared array size. In your case, the last index is 59.
I don't know what you are trying to do in your program, but at least
fix it so you don't write beyond the end of your array. Example:
|
|
|
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
|
Posted: Tue May 09, 2006 4:57 pm |
|
|
You are right. I don't explain very well my problem.
First of all THE CODE WORKS FINE as you see (with comments).
Don't work if I delete the "//".
This is my problem:
The program read a SMS message in a SIM card (command AT+CMGR=1). The message is 58 chars long.
Find the phone and a substring. If is OK. make a phone call a number 639XXX (ATD639xxx..) and a led is on. After 10 segs. hung up the call (ATH).
When the led is on I am going to send another message and the program find this substring (alarma_of).
I don't know why if this code is present the program does not work (neither activation or activation).
I am very confused. |
|
|
Ttelmah Guest
|
|
Posted: Wed May 10, 2006 4:41 am |
|
|
Fix the problem that PCM programmer has pointed out first. As it stands, if the overflow happens, it'll damage the value stored in s1_1. Given this is a pointer, the damage, will then result in all sorts of other values being destroyed. Since this is being used in the area that has the problem, fix it first, and see if the problem improves.
Best Wishes |
|
|
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
|
Posted: Wed May 10, 2006 5:07 am |
|
|
Thanks all of you for the answer but the CODE DOES NOT WORK.
I modified slight the code and I comment every instruction.
Here's the code:
Code: |
include <16F876.h>
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#fuses XT,NOWDT,NOPROTECT,NOLVP
#include <string.h>
#define LENBUFF 60
int xbuff=0x00;
int i;
char cbuff[LENBUFF];
char *si_1;
char *si_2;
char *si_3;
char alarma_on[5] = "4F27";
char alarma_of[5]= "4FE3";
char tfno[11] = "36793446F8";
#int_rda
void serial_isr() // Capturing the buffer by interrupt
{
cbuff[xbuff]= getc(); // the buffer I expect has 58 chars long
xbuff++; // the last char received could be # 59
if (xbuff >= LENBUFF)
xbuff=LENBUFF-1;
}
void main()
{
enable_interrupts(global);
enable_interrupts(int_rda);
for(i=0;i<LENBUFF;i++) // here I clean the buffer
cbuff[i]=0x00;
while(True) {
printf("AT+CMGR=1\r\n"); // I read first postion of SIM
delay_ms(3000); // wait for response
si_1= strstr(cbuff,alarma_on); // searching the buffer
si_2= strstr(cbuff,tfno);
si_3= strstr(cbuff,alarma_of);
if (si_2 != NULL) // look for phone number
{
If (si_1 != NULL) // If OK following searching
{ // for activation code
output_high (PIN_B2);
printf("ATD639743648;\r\n"); // making a call
delay_ms(10000); // waiting for a call. The recipient
printf("ATH\r\n"); // ears some rings
} // and hung
else if(si_3 != NULL) // or for desactivation code
{
output_low (PIN_B2); // the same for desactivation code
printf("ATD639743648;\r\n"); // the led will be replaced for a relais
delay_ms(10000);
printf("ATH\r\n");
}
}
for(i=0;i<LENBUFF;i++) // cleanig the buffer
cbuff[i]=0x00;
xbuff=0x00; // pointing to begining of buffer
delay_ms(10000); // wainting to repeat the process
}
}
|
The buffer I expect is :
07914306090969F5040B914336793446F8000060408212645380024F27
? How I must sized cbuff ?
Some help will be well received |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed May 10, 2006 6:24 am |
|
|
Note that if you get too many chars then your buffer will not be null terminated. I would do something like this
Code: |
#int_rda
void serial_isr() // Capturing the buffer by interrupt
{
cbuff[xbuff]= getc(); // the buffer I expect has 58 chars long
xbuff++; // the last char received could be # 59
cbuff[xbuff] = 0;
if (xbuff >= LENBUFF-1)
xbuff = LENBUFF-2;
}
|
I didn't have time to look at the rest of the code that closely. |
|
|
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
|
Posted: Wed May 10, 2006 9:53 am |
|
|
I have made all the changes that all of you suggest. It does not work.
I abandon the proyect.
when programming "into" the computer, the PC, I can see what is happen inside it but with MCU imposible to see the buffer, index, etc
Thanks for your help |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 10, 2006 10:46 am |
|
|
Actually it is possible. You can use a hardware debugger such as
CCS ICD (requires PCW or PCWH) or the Microchip ICD2 (with MPLAB).
You can set breakpoints and create a Watch list of variables to watch.
If you don't want to use a hardware debugger, you can use printf to
display the value of variables. You can display the value of pointers
in hex, and then look at the symbol table created by the compiler and
see if the pointers are correct. I do most of my debugging, if I even
need to, with simple printf statements. |
|
|
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
|
Posted: Wed May 10, 2006 11:31 am |
|
|
Thanks PCM programmer.
I have an IDC hard. I've bought few day ago. I can debug the program when it's running in my PC. But when the PIC is connected to a GSM modem, what can I do ?. How can I see pointer, values and so on ?
I have copied the program in Visual C++ and it works very well. Some pointer or index is making me the life so difficult.
Thanks for your help. Perhaps I haven't sufficient experience in MCU and the project is so complicated for me. What a pity since the program was nearly finished. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 10, 2006 11:49 am |
|
|
You could setup a Watch window to watch the si_1, si_2, and si_3
varibles. Then set breakpoint on the "if() statement below them.
When it breaks, look the pointer values. Look at the symbol table
which will show the address range used by cbuff and see if the
pointer values are within the RAM used by cbuff. (Or if they are null).
Code: |
si_1= strstr(cbuff,alarma_on);
si_2= strstr(cbuff,tfno);
si_3= strstr(cbuff,alarma_of);
if (si_2 != NULL)
|
Or, you could create a software UART on an unused pin, and then use
printf statements to display the pointer values listed above. If you do
this, then you should use "streams", where each RS-232 stream has
it's own unique name.
Also, you should make other changes that have been suggested.
1. Increase the size of the cbuff array by setting LENBUFF to 80 or something. You may have to use 16-bit pointers to do this.
If so, add the line shown in bold below:
Quote: | include <16F876.h>
#device *=16
#use delay(clock=4000000) |
In that case, the Watch window pointer values will be 16-bit.
2. Add the ERRORS parameter to your #use rs232() statement.
3. Try adding Mark's suggested change.
You really have to be an intermediate level programmer to do these
things. If you don't feel comfortable or don't want to spend the time,
then maybe it's not worth it. It's your decision. |
|
|
smxabi
Joined: 29 Apr 2006 Posts: 14 Location: Spain
|
|
Posted: Fri May 12, 2006 11:58 am |
|
|
??? EUREKA !!!
It works fine. The problem: simply the chars that sends the modem is much more that I can see by Hyperterminal. ??? 84 chars !!!. I believe only 58 chars.
The CCS ICD does not help me nothing since in debbuging time when the PIC send AT+CMGR=1 the simulation is not real and stopped.
The solution: only two lines of code:
while(True) {
delay_ms(10);
printf("AT+CMGR=1\r\n");
delay_ms(1000);
for (i=0; i< LENBUFF;i++)
write_eeprom (i, cbuff[i]);
Thanks a lot for all of you that help me. |
|
|
|