Hi everyone.
I am doing this project where I perform real time event operation using 8051. I am using GSM module to send/ and receive text from a hand held device to instruct operations that my 8051 needs to perform. It is basically a home based automation system using GSM module.
Now my question is how do I read only relevant part of the text? When I use GSM module by PC using Hyper terminal with following instruction: AT OK AT+CMGF=1 OK AT+CMGR=1 >+CMTI:........... .................. Hi. How are you
OK
I only want to read "Hi. How are you" part of the and nothing else. How do I design my code to do it? This is the part that is bugging me a lot. I would really appreciate your help in it.
Thank You
Oh... Alright....
So I will take the string in reverse order and use following logic:
Do { Msg[++i]=SBUF; } While(msg[i]!='\0');
For (i=i; i>=0; i--) If ((msg[i]=='K') && (msg[i-1]=='O')) Do { Data[++j]=msg[i-2]; } While(msg[i-3]!='"'); //to only extract data
I am using this logic to extract data by taking the entire message in reverse order so that it is easier to perform.
Tell me if this logic is wrong.
Are you sure you should do a pre-increment?
Msg[++i]=SBUF
Most people would write a state machine that do a ping-poing communication with the module.
So the program would send
AT
Then listen for individual text lines received from the unit until it gets an ok or error.
The AT is echo data so can be throw away. The OK informs that the module is done with the AT command. If the command failed, you would have gotten an ERROR.
Time to send
AT+CMGF=1
The AT+CMGF=1 line received is just echo so can be thrown away. The OK informs that the module is done with this command.
AT+CMGR=1
The AT+CMGR=1 line is just echo so can be thrown away. Then you get a response +CMGR with parameters. Then on next line follows text data.
Your +CMTI is unsolicited data informing that the module have received an SMS. While you process text lines one-by-one from the module, you need to be prepared for a number of unsolicited text lines you can receive from the module - i.e. text lines that doesn't relate to commands you are sending to the module but to other things happening to the module that it wants to inform about. So a modem might say RING. Or in this case a +CMTI line tells of a new incomming SMS and the memory location where it's stored.
In short - when you are in "normal" mode (i.e. not busy extracting messages) you can directly throw away lines starting with AT - they are echo. And you can always react to OK or ERROR - they inform that you can end your loop because you have the final result of the last sent command. Any other responses you get requires custom processing - like +CMGR to get meta info about the SMS you are reading out and then the actual text message.
So a simple program might look like (meta code):
... if (!send_modem_command("AT")) return false; // modem accessible? if (!send_modem_command("AT+CMGF=1")) return false; // set SMS format text if (!send_modem_command("AT+CMGR=1")) return false; // ask for first SMS if (!send_modem_command("AT+CMGD=1")) return false; // delete first SMS ... bool send_modem_command(char *cmd) { send_command(cmd); send_linebreak(); return wait_for_modem_ok(); } bool wait_for_modem_ok() { for (;;) { if (timeout) { report_timeout(); return false; } if (have_error) { // maybe too long text line??? return false; } process_incomming_uart_characters(); if (have_line) { have_line = false; if (is_ok()) return true; if (is_error()) return false; if (is_plus_cmti()) { inform_new_sms(); continue; } if (is_plus_cmgr()) { if (!read_sms()) return false; // unexpected error, timeout, ... } } } } bool read_sms() { extract_sms_phone_date_size_etc(); for (;;) { if (have_all_sms_text_data()) { inform_received_sms(); return true; } if (timeout) return false; } }