HI guys,
My project is about switching on and off of motor by sms control.. I tried to check whether my controller is working fine or not using simple blinking of LED program , its working good, no problem with oscillator and reset switch part... everythng is fine but when i try for serial programming i am not getting the output.. I checked my gsm modem using hyperterminal its working fine.but its not working with 8051.
below is my code
#include <reg51.h> void init (void); // prototype declaration void Uart_gsm (void); void delay(unsigned char); void Recievedata(); void gsminit(void); void gsmcmdsend(unsigned char *); unsigned char Rx_data(void); unsigned char message[11]; unsigned char count; unsigned char code password1[10]="device1 on"; // Commands for controlling devices unsigned char code password2[11]="device1 off";
void main() { // port initialization
init(); Uart_gsm(); // serial port initialization gsminit(); Recievedata(); // for recieving the data from modem }
void init(void) { P2 = 0xFF; }
void Uart_gsm(void) { TMOD = 0x20; TH1 = 0xFD; SCON = 0X50; TR1 = 1; } void serial_put(char c) { do{}while(!TI); TI=0; SBUF=c; }
void sms(void) //sending pump is on { char t5[]={'A','T','+','C','M','G','S','=','"','+','9','1','9','1','7','6','3','6','6','4','9','6','"'} ; char t7[]="PUMP IS ON"; unsigned int i; delay(1000); gsmcmdsend(t5); for(i=0;t7[i];i++)serial_put(t7[i]); do{}while(!TI); TI=0; SBUF=0x1A; delay(20000); }
void Recievedata() { unsigned int count,count1,i; while(1) { while(Rx_data()!='+'); // checking message format while(Rx_data()!='C'); while(Rx_data()!='M'); while(Rx_data()!='T'); while(Rx_data()!=':'); while(Rx_data()!='"'); while(Rx_data()!='\n'); for(count=0;count<11;count++) // storing msg in a buffer { message[count]=Rx_data(); if(message[count]=='\r') break; } message[count]='\0';
for(i=0;i<10;i++) //verifying message { if(message[i]==password1[i]) count++; } if(count==10) { P2 = 0x00; sms(); }
for(i=0;i<11;i++) { if(message[i]==password2[i]) count1++; }
if(count1==11)
{ P2 = 0xFF; }
} } // TO RECIEVE SERAIL DATA unsigned char Rx_data(void) { RI=0; while(RI==0); return(SBUF); }
void delay(unsigned char x) { unsigned int i,j; for(i=0;i<x;i++) for(j=0;j<2000;j++); }
void gsminit(void) { // AT COMMANDS unsigned char gsm_cmd1[]="AT"; unsigned char gsm_cmd2[]="ATE0"; unsigned char gsm_cmd3[]="AT&W"; unsigned char gsm_cmd4[]="AT+CMGF=1"; unsigned char gsm_cmd5[]="AT+CNMI=2,2,0,0,0"; gsmcmdsend(gsm_cmd1); gsmcmdsend(gsm_cmd2); gsmcmdsend(gsm_cmd3); gsmcmdsend(gsm_cmd4); gsmcmdsend(gsm_cmd5); }
void gsmcmdsend(unsigned char *cmd) { unsigned char i; for(i=0;*cmd!='\0';i++) { SBUF=*cmd; while(TI==0); TI=0; cmd++; } delay(2); SBUF=0x0A; while(TI==0); TI=0; SBUF=0x0D; while(TI==0); TI=0; while(RI==0); RI=0; }
I complied this program using KEIL complier , 0 errors and 0 warnings.
After switching On the supply, port 2 goes high..i dont whats the problem with my circuit.. :sad:
below is my code code is something that is formatted and commented what you show hardly qualify as scribbles
Erik
I am not getting any reply from gsm modem.. is there any mistake in my code??
What testing have you done to find out?
Post the code legibly, and someone might take a look for you!
Look at the instructions for posting source code right above the box where you type your message!
You do not (!) test for the reception of a string by having multiple while loops after each other like this:
while(Rx_data()!='+'); while(Rx_data()!='C'); while(Rx_data()!='M'); while(Rx_data()!='T'); while(Rx_data()!=':'); while(Rx_data()!='"'); while(Rx_data()!='\n');
How long do you think your code would have to wait if it accidentally missed to receive the initial '+' character?
What happens if no character at all is received?
What happens if a different string is received, that happens to look like:
ADDITION (+) CAN BE IMPLEMENTED AS: "1+1=2"\n
Would you really like my string to match your string comparison? So why then write a pattern matcher that does find false patterns in random noise? Have you looked at the implementation of strcmp()? Is it implemented with multiple while loops - one for each character to match?
Keil complier doesnt support strings... string header file is not available in the library....
is there any simulation available to test serial communication ??
The C language doesn't have strings.
But it has a strings library, working on zero-terminated character arrays.
And Keil most definitely do supoprt these library functions. What was the name of the header file you tried to use?
And if you really wanted to implement your own strcmp() function, a sequence of while loops after each other - one for every character in the match string - is still not a valid way.
Why no response to the fact that the string:
matches your pattern test code?
Gsm incoming message will be in this format
+CMT: "+91xxxxxxxxxx" , xxxtimestampxxxxxx actual message
my code will will test for +CMT in while loop after that again a while loop to check for \n to extract the message.
So if 2+3 is in the message it wont bother.cos program would ve come out of the while loop test for '+' symbol...
@Per Westermark : oh ya u r right i dint notice that..(sorry for the previous reply) .
so how can i extract meggase from the received message.?? can u just modify the code ??? i struggling with that logic....
Easiest way is to pick up the characters one-by-one from the serial port.
Use a simple state machine to scan for synchronization patterns. Then buffer all characters you receive until your buffer is full, or you find a terminating character.
So you may have() {
enum States { STATE_IDLE, STATE_FIND_CMT, STATE_CMT_GET_NUMBER, STATE_CMT_GET_COMMA, STATE_CMT_GET_MSG_START, STATE_CMT_GET_MSG, ... } state = STATE_IDLE; const char* pattern; char phone[25]; // Store received phone number char msg[200]; // Store received message // Take care of string '+CMT: "+91xxxxxxxxxx" , xxxtimestampxxxxxx' void process_modem_character(char ch) { switch (state) { case STATE_IDLE: if (ch == '+') { state = STATE_FIND_CMT; pattern = "CMT: \""; } break; case STATE_FIND_CMT: if (*pattern != ch) { state = STATE_IDLE; } else { pattern++; if (*pattern == '\0') { state = STATE_CMT_GET_NUMBER; inspos = 0; } } break; case STATE_CMT_GET_NUMBER: if (ch == '\"') { state = STATE_CMT_GET_COMMA; } else if (inspos >= sizeof(phone)) { // Too long phone number :( state = STATE_IDLE; } else { phone[inspos++] = ch; phone[inspos] = '\0'; } break; case STATE_CMT_GET_COMMA: if (ch == ' ') { ; // Ignore white space } else if (ch == ',') { state = STATE_CMT_GET_MSG_START; } else { // Invalid character received state = STATE_IDLE; } break; ... default: // Invalid state. state = STATE_IDLE; } // switch } // process_modem_character
A single state machine can be made that may handle any response you get from the modem - both echo from sent commands, expected response strings from commands and unsolicited messages that the modem may send, such as "RING" or similar.
And it's possible to reuse same buffers for different response strings instead of having dedicated buffers for every possible attribute you want to decode.
Note that line breaks can often be very good to use as synchronization patterns when implementing state machines. The important thing is that you want a state machine to be safe and not generate false matches if it happens to start listen in the middle of a data stream, or if the sender happens to reset in the middle of a transfer and start sending new strings.
Please read the manual: http://www.keil.com/support/man/docs/uv4/
Thanks alot Per Westermark... :)
I will modify the code accordingly and let you know the output..
actually the problem is not only receiving sms, my microcontroller is not sending any data to gsm modem..
i checked it like after sending each character port P1 should go high and then low...
while (*chr!='\0') // transmit until a null is being pointed { P1=0x00; //before transmitting a character SBUF = *chr++; // load SBUF with the data being pointed while(!TI); TI=0; P1=0xFF; //before transmitting a character for(temp=0;temp<50;temp++) delay(); }