This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem with GSM switch and 89c51

I have to make this project for my school but i can't make it run. I've problems with message extraction and with the interrupt. Please help.
This is my code

#include <reg51.h>
#include <string.h>

sbit Water=P2^0;
sbit Window=P2^1;

//declarations

void clear(void);
void tx0(unsigned char);
void delay_sms (unsigned int);
void SMSString(char*text) ;
void init();
void read_text(unsigned char * , unsigned char * , unsigned char *);

unsigned char j,abc;
unsigned char idata msg1[150];
unsigned char rec_no[20];
unsigned char time_date[20];
unsigned char choice=0;
unsigned char idata tmp10[16];

void serial () interrupt 4
{
msg1[abc]=SBUF;
abc++;
RI=0;
}

void main (void)
{
clear();
init();

Window=0;
Water=0;


SMSString("AT\r"); // AT commands to initialize gsm modem
delay_sms(1000);

SMSString( "ATe0\r"); // turn off echo
delay_sms(1000);

SMSString( "AT&W\r"); // save settings
delay_sms(1000);

SMSString( "AT+CMGF=1\r"); // select text mode for sms
delay_sms(1000);

SMSString( "AT+CNMI=2,1,0,0,0\r"); // notification of new sms
delay_sms(1000);

SMSString( "AT+CMGR=1\r"); // AT command to read sms
delay_sms(1000);

do
{
IE=0X90;   // Enable serial interrupt
delay_sms(1000);

// i get a response like this

// +CMGR: "REC UNREAD","+3069********",,"11/04/09,11:26:48+12"
// Window on
// OK
// I think that's the format the 8051 get +CMTI: "SM",1\r+CMGR: "REC UNREAD","+306982037789",,"11/04/09,11:26:48+12"\rStatus\n\rOK\r
// read sms and store in buffer msg1

read_text(msg1,rec_no,time_date);

if(strncmp("Water on",msg1,8)==0)
{
Water=1;
strncpy(tmp10,"Water   Window  ",16);
tmp10[6]=Water;
tmp10[15]=Window;
SMSString("AT+CMGS=\"");
SMSString(rec_no);
SMSString("\"+<CR>");
delay_sms(1000);
SMSString(tmp10);
SMSString("\n\r");
delay_sms(1000);
}
else  if(strncmp("Water off",msg1,9)==0)
{
Water=0;
strncpy(tmp10,"Water   Window  ",16);
tmp10[6]=Water;
tmp10[15]=Window;
SMSString("AT+CMGS=\"");
SMSString(rec_no);
SMSString("\"+<CR>");
delay_sms(1000);
SMSString(tmp10);
SMSString("\n\r");
delay_sms(1000);
}
else  if(strncmp("Window on",msg1,9)==0)
{
Window=1;
strncpy(tmp10,"Water   Window  ",16);
tmp10[6]=Water;
tmp10[15]=Window;
SMSString("AT+CMGS=\"");
SMSString(rec_no);
SMSString("\"+<CR>");
delay_sms(1000);
SMSString(tmp10);
SMSString("\n\r");
delay_sms(1000);
}
else  if(strncmp("Window off",msg1,10)==0)
{
Window=0;
strncpy(tmp10,"Water   Window  ",16);
tmp10[6]=Water;
tmp10[15]=Window;
SMSString("AT+CMGS=\"");
SMSString(rec_no);
SMSString("\"+<CR>");
delay_sms(1000);
SMSString(tmp10);
SMSString("\n\r");
delay_sms(1000);
}
else  if(strncmp("Status",msg1,6)==0)
{
strncpy(tmp10,"Water   Window  ",16);
tmp10[6]=Water;
tmp10[15]=Window;
SMSString("AT+CMGS=\"");
SMSString(rec_no);
SMSString("\"+<CR>");
delay_sms(1000);
SMSString(tmp10);
SMSString("\n\r");
delay_sms(1000);
}
else
{
SMSString("AT+CMGS=\"");
SMSString(rec_no);
SMSString("\"+<CR>\r");
delay_sms(1000);
SMSString("Wrong Command");
SMSString("\n\r");
delay_sms(1000);

SMSString(rec_no);
delay_sms(1000);

SMSString(msg1);
delay_sms(1000);
}
SMSString("AT+CMGD=1\r");
delay_sms(1000);

IE=0X00;   // Disable serial interrupt
delay_sms(1000);

}
while(1);
}

void init(void)
{
j=0;
abc=0;
TL1=0XFD; //9600 @ 11.0592
TH1=0xFD;
TMOD=0x20;
SCON=0x50;
TR1=1;
}

void SMSString(unsigned char* text) //function to send SMS using GSM modem
{
while (*text)
{
tx0(*text++);
}
}


void tx0(unsigned char x) //send data to serial port 0
{
EA=0;
SBUF=x;
while(TI==0);
TI=0;
EA=1;
}


void delay_sms (unsigned int count)
{
unsigned int i;
    while(count) {
        i = 115;
                while(i>0) i--;
        count--;
}
}

void read_text( unsigned char *msg,unsigned char *no ,unsigned char *time)
{
unsigned char *temp;
temp=msg;

do
msg++;
while(*msg!='+');

do
msg++;
while(*msg!='+');

do
msg++;
while(*msg!='+');         //  reaching number

do
*no++=*msg++;
while(*msg!='"');         // reaching time

*no++='\0';
msg++;
msg++;
msg++;
do
*time++=*msg++;
while(*msg!='"');         // reaching message
*time='\0';
do
msg++;
while(*msg!='\r');
msg++;
do
*temp++=*msg++;
while(*msg!='\n');       // reaching the end of message
*temp='\0';
}

void clear(void)
{
unsigned char a;
for(a=0;a<100;a++)
msg1[a]=0x00;
}

Parents
  • void serial () interrupt 4 {
        msg1[abc]=SBUF;
        abc++;
        RI=0;
    }
    


    abc being a meaningful name "advanced buffer counter" or what?

    It most definitely seems to be the insert position in your receive buffer for serial data. So why name it something like that?

    And msg1 seems to be your receive buffer for serial data, so why not name it something like that?

    You have msg1 defined as 150 characters large - your interrupt handler doesn't check where you are. What happens if you receive 151 characters? Would that be good?

    You initialize abc to zero. But how do you get your receive interrupt to reuse msg1 for receiving data after you have processed some received data?

    strncpy(tmp10,"Water   Window  ",16);
    tmp10[6]=Water;
    tmp10[15]=Window;
    


    You are mixing ASCII and binary data in the same string. Do you think that is good? What about instead doing sprintf() to create a fully ASCII string with the values of "Water" and "Window" inserted?

    Your read_text() function is more or less a random noise.

    Don't you think you should process your answers line-by-line, and then look at the start of each received line to figure out what command you are decoding? Then it would be much better to split the parameters on the commas (while remembering that a comman can exist within a "" string too) when trying to locate the time and message.

    SMSString("AT+CMGS=\"");
    SMSString(rec_no);
    SMSString("\"+<CR>");
    


    On one hand - don't you think some things deserves to be a specific function, that does know to send a command and also does know to check for expected - or unexpected - answers? And what is "<CR>"?

    What is delay_sms(1000)? Wouldn't it be better to implement a delay function that has a known property like creating delays in ms resolution, and then do delay_ms(POWER_ON_SETTLE_TIME) or similar? In your case, you have zero documentation what delay_sms() does that makes it meaningful to be called or to have "sms" as part of the name.

    And why do you have so many hard-coded delays? Don't you think you should be more dynamic - send an SMS command and then listen for the characters being received from the modem on the fly? All you need is a timeout value when to give up. But if you get the answer much faster, then you don't have any reason to continue waiting. After all - how do you know what is a reasonable time to wait? Will that wait time always be true? Even with another operator or with overloaded network or with bad signal strength?

Reply
  • void serial () interrupt 4 {
        msg1[abc]=SBUF;
        abc++;
        RI=0;
    }
    


    abc being a meaningful name "advanced buffer counter" or what?

    It most definitely seems to be the insert position in your receive buffer for serial data. So why name it something like that?

    And msg1 seems to be your receive buffer for serial data, so why not name it something like that?

    You have msg1 defined as 150 characters large - your interrupt handler doesn't check where you are. What happens if you receive 151 characters? Would that be good?

    You initialize abc to zero. But how do you get your receive interrupt to reuse msg1 for receiving data after you have processed some received data?

    strncpy(tmp10,"Water   Window  ",16);
    tmp10[6]=Water;
    tmp10[15]=Window;
    


    You are mixing ASCII and binary data in the same string. Do you think that is good? What about instead doing sprintf() to create a fully ASCII string with the values of "Water" and "Window" inserted?

    Your read_text() function is more or less a random noise.

    Don't you think you should process your answers line-by-line, and then look at the start of each received line to figure out what command you are decoding? Then it would be much better to split the parameters on the commas (while remembering that a comman can exist within a "" string too) when trying to locate the time and message.

    SMSString("AT+CMGS=\"");
    SMSString(rec_no);
    SMSString("\"+<CR>");
    


    On one hand - don't you think some things deserves to be a specific function, that does know to send a command and also does know to check for expected - or unexpected - answers? And what is "<CR>"?

    What is delay_sms(1000)? Wouldn't it be better to implement a delay function that has a known property like creating delays in ms resolution, and then do delay_ms(POWER_ON_SETTLE_TIME) or similar? In your case, you have zero documentation what delay_sms() does that makes it meaningful to be called or to have "sms" as part of the name.

    And why do you have so many hard-coded delays? Don't you think you should be more dynamic - send an SMS command and then listen for the characters being received from the modem on the fly? All you need is a timeout value when to give up. But if you get the answer much faster, then you don't have any reason to continue waiting. After all - how do you know what is a reasonable time to wait? Will that wait time always be true? Even with another operator or with overloaded network or with bad signal strength?

Children