Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Send and receive SMS using PIC Microcontroller

Status
Not open for further replies.

tritech

Newbie level 6
Newbie level 6
Joined
Apr 16, 2013
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,403
PIC: 18F4520
Board: PICPLC16v6 Development Board from Mikroelectronika
Modem: Quectel M95
Compiler: MikroC

Individual testing with PC Hyperterminal was done for both PIC and GSM and is working.
On using PIC and GSM together, send/receive SMS not working.

Code:
 /*Receive sms and acknowledge back by sending sms*/

// Set of basic AT commands
const char atc0[] = "AT";                        // Every AT command starts with "AT"
const char atc1[] = "ATE";
const char atc2[] = "AT+CMGF=1";                 // TXT messages
      char atc3[] = "AT+CMGS=\"+6597329728\"";   // sends SMS to desired number
const char atc4[] = "AT+CMGR=1";                 // Command for reading message from location 1 from inbox
const char atc6[] = "AT+CMGL=\"ALL\"";           // Check status of received SMS
//

// Responses to parse
const GSM_OK                       = 0;
const GSM_Ready_To_Receive_Message = 1;
const GSM_ERROR                    = 2;
const GSM_UNREAD                   = 3;
//

//

// SMS Message string
char SMS_Message[300];

// phone number string
char phone_number[20]="+6594816756"; //sim card number inserted in the gsm modem

// State machine control variables
char gsm_state = 0;
char response_rcvd = 0;
short responseID = -1, response = -1, rsp;
char set_stat = 0, clr_stat = 0;
char PORT_flag = 0;
char Digital_O = 0;
char gsm_number = 0;
char Unread_flag;
//
char status_req = 0; // Status request variable

// Send command or data to the Telit GM862 Module - (const)
void GM862_Send(const char *s)
{
// Send command or data string
   while(*s) {
    UART1_Write(*s++);
   }
// Terminatation by CR
   UART_Wr_Ptr(0x0D);
}

// Send command or data to the Telit GM862 Module - (RAM)
void GM862_Send_Ram(char *s1)   //
{
// Send command or data string
   while(*s1) {
    UART_Wr_Ptr(*s1++);
   }
// Terminatation by CR
   UART_Wr_Ptr(0x0D);
}

// Get GSM response, if there is any
short Get_response() {
    if (response_rcvd) {
      response_rcvd = 0;
      return responseID;
    }
    else
      return -1;
}

// Wait for GSM response (infinite loop)
void Wait_response(char rspns) {
char test = 1;

  while (test){
  test = Get_response();
  if ((test == rspns) || (test == GSM_ERROR))
    test = 0;
  else
    test = 1;
  }
}

// Compose Status SMS
unsigned ComposeMessage(char* Message);

// Send Status SMS
void Send_Msg(char* Msg){
  char atc[33];

  atc[0] = 0;                        // clear atc string
  strcat(atc, atc3);                 // atc3 command for sending messages
  GM862_Send_Ram(atc);               // send AT command for SMS sending
  Wait_response(GSM_Ready_To_Receive_Message); // Wait for appropriate ready signal

  GM862_Send_Ram("trial sms from pic to gsm modem");               // Send message content
  UART_Wr_Ptr(0x1A);                 // Send CTRL + Z as end character
  UART_Wr_Ptr(0x0D);                 // Send CR
  UART_Wr_Ptr(0x0A);                 // Send LF
  Wait_response(GSM_OK);             // Wait OK as confirmation that the message was sent

  
}

// Send status SMS to the cell phone number defined by the atc3 const string
void Send_Status(){
 Send_Msg(SMS_Message);
}

// 3sec pause
void Wait(){
   Delay_ms(3000);
}

// Main
void main(){

  ADCON1 |= 0x0F;                  // Configure AN pins as digital

  TRISB = 0;
  
// Setup interrupts
  RCIE_bit = 1;          // Enable Rx1 intterupts
  PEIE_bit = 1;           // Enable peripheral interrupts
  GIE_bit  = 1;           // Enable global interrupts
//

  UART1_Init(9600);
  Delay_ms(1500);
  PORTB.B1=0;
  
// Negotiate baud rate
  while(1) {
    GM862_Send(atc0);                 // Send "AT" string until GSM862 sets up its baud rade
    Delay_ms(100);                    // and gets it correctly
    if (Get_response() == GSM_OK)     // If GSM862 says "OK" on our baud rate we program can continue
      break;
      PORTB.B1=1;
  }

  Wait(); Wait();         // Wait a while till the GSM network is configured

 GM862_Send(atc2);        // Set message type as TXT
 Wait_response(GSM_OK);

 GM862_Send(atc1);        // Disable command echo
 Wait_response(GSM_OK);

 // blink as a sign that initialization is successfully completed
 PORTB.B0 = 0xFF;
 Delay_ms(500);
 PORTB.B0 = 0;

  // infinite loop
  while(1) {
    GM862_Send(atc6);        // Read status of the messages and read message it self
    Delay_ms(100);           // Wait until the message is read

    while(1) {
      GM862_Send(atc0);      // Wait until the module is ready
      Delay_ms(50);
      if (Get_response() == GSM_OK)
        break;
    }

    if (Unread_flag){
      if (PORT_flag){        // Turn ON/OFF port D LEDs if there were new commands
        PORT_flag = 0;
      }


      while(1) {
        GM862_Send(atc0);    // Wait until the module is ready
        Delay_ms(50);
        if (Get_response() == GSM_OK)
          break;
      }

      if (status_req){       // Send status SMS if it's been requested
        status_req = 0;
        Send_Status();
      }

      Unread_flag = 0;


    while(1){
      if (Unread_flag){  // if we have received message in mean time
        Unread_flag = 0;
        break;           // break from while
      }
    }
    }
    Wait();
  }
}


/******************************************************************************/



// state machine
// Reading the data from UART in the interrupt routine
void interrupt(){
char tmp;
char i;
  if (RCIF_bit == 1) {                           // Do we have uart rx interrupt request?
    tmp = UART_Rd_Ptr();                         // Get received byte

// Process reception through state machine
// We are parsing only "OK" and "> " responses
    switch (gsm_state) {
      case  0: {
                response = -1;                   // Clear response
                if (tmp == 'O')                  // We have 'O', it could be "OK"
                  gsm_state = 1;                 // Expecting 'K'
                if (tmp == '>')                  // We have '>', it could be "> "
                  gsm_state = 10;                // Expecting ' '
                if (tmp == 'E')                  // We have 'E', it could be "> "
                  gsm_state = 30;                // Expecting 'R'
                if (tmp == 'S')                  // We have 'S', it could be "Status?" or "Set"
                  gsm_state = 40;                // Expecting 't'
                if (tmp == 'R')                  // We have 'R', it could be "RDx" or
                  gsm_state = 50;                // Expecting D
                if (tmp == 'C')                  // We have 'C', it could be "Clear"
                  gsm_state = 110;               // Expecting l
                if (tmp == 'U')                  // We have 'U', it could be "UNREAD"
                  gsm_state = 120;               // Expecting l
                break;
               }
      case  1: {
                if (tmp == 'K') {                // We have 'K' ->
                  response = GSM_OK;             // We have "OK" response
                  gsm_state = 20;                // Expecting CR+LF
                }
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }
      case 10: {
                if (tmp == ' ') {
                  response_rcvd = 1;             // We have "> " response
                  response = GSM_Ready_To_Receive_Message; // Set reception flag
                  responseID = response;         // Set response ID
                }
                gsm_state = 0;                   // Reset state machine
                break;
                }

      case 20: {
                if (tmp == 13)                   // We have 13, it could be CR+LF
                  gsm_state = 21;                // Expecting LF
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }
      case 21: {
                if (tmp == 10) {                 // We have LF, response is complete
                  response_rcvd = 1;             // Set reception flag
                  responseID = response;         // Set response ID
                }
                gsm_state = 0;                   // Reset state machine
                break;
               }

      case 30: {
                if (tmp == 'R')                  // We have 'R', it could be "ERROR"
                  gsm_state = 31;                // Expecting 'R'
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }
      case 31: {
                if (tmp == 'R')                  // We have 'R', it could be "ERROR"
                  gsm_state = 32;                // Expecting 'O'
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }
      case 32: {
                if (tmp == 'O')                  // We have 'O', it could be "ERROR"
                  gsm_state = 33;                // Expecting 'R'
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }
      case 33: {
                if (tmp == 'R'){                 // We have 'R'
                  response_rcvd = 1;             // We have "ERROR" response
                  response = GSM_ERROR;          // Set reception flag
                  responseID = response;         // Set response ID
                }
                gsm_state = 0;                   // Reset state machine
                break;
                }
      case 40: {
                if (tmp == 't')                  // We have 't', it could be "Status?"
                  gsm_state = 41;                // Expecting 'a'
                else
                  if (tmp == 'e')                // We have 'e'. it could be "Set"
                    gsm_state = 100;
                  else
                    gsm_state = 0;               // Reset state machine
               }; break;
      case 41: {
                if (tmp == 'a')                  // We have 'a', it could be "Status?"
                  gsm_state = 42;                // Expecting 't'
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }
      case 42: {
                if (tmp == 't')                  // We have 't', it could be "Status?"
                  gsm_state = 43;                // Expecting 'u'
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }

       case 43: {
                if (tmp == 'u')                  // We have 'u', it could be "Status?"
                  gsm_state = 44;                // Expecting 's'
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }

       case 44: {
                if (tmp == 's')                  // We have 's', it could be "Status?"
                  gsm_state = 45;                // Expecting '?'
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }

       case 45: {
                if (tmp == '?'){                 // We have '?'
                  status_req = 1;                // Status has been requested!
                }
                gsm_state = 0;                   // Reset state machine
                break;
                }

       case 50: {
                if (tmp == 'D')                  // We have 'D', it could be "RDx"
                  gsm_state = 51;                // Expecting number
                else
                  gsm_state = 0;                 // Reset state machine
                break;
               }
       case 51: {
                if (tmp >= '0' && tmp <= '7'){   // We have pin number, it could be "RDx"
                  if (set_stat)
                    Digital_O |= 1 << (tmp - '0');
                  if (clr_Stat)
                    Digital_O &= (0xFF ^(1 << (tmp - '0')));
                }
                  PORT_flag = 1;
                  gsm_state = 0;                 // Reset state machine
               }; break;

       case 100: {
                   if (tmp == 't'){              // We have 't', we received set command
                     set_stat = 1;               // Set following bits
                     clr_stat = 0;               // Do not clear following bits
                   }
                   gsm_state = 0;
                 }; break;
       case 110: {
                   if (tmp == 'l'){              // We have 'l', it could be Clear
                     gsm_state = 111;
                   }
                   else
                     gsm_state = 0;
                 }; break;
       case 111: {
                   if (tmp == 'e'){              // We have 'e', it could be Clear
                     gsm_state = 112;
                   }
                   else
                     gsm_state = 0;
                 }; break;
       case 112: {
                   if (tmp == 'a'){              // We have 'a', it could be Clear
                     gsm_state = 113;
                   }
                   else
                     gsm_state = 0;
                 }; break;
       case 113: {
                   if (tmp == 'r'){              // We have 'r', we have received Clear
                     clr_stat = 1;               // Clear following bits
                     set_stat = 0;               // Do not set following bits
                   }
                   gsm_state = 0;
                 }; break;
       case 120: {
                  if (tmp == 'N')
                    gsm_state = 121;
                  else
                    gsm_state = 0;
                 }; break;
       case 121: {
                  if (tmp == 'R')
                    gsm_state = 122;
                  else
                    gsm_state = 0;
                 }; break;
       case 122: {
                  if (tmp == 'E')
                    gsm_state = 123;
                  else
                    gsm_state = 0;
                 }; break;
       case 123: {
                  if (tmp == 'A')
                    gsm_state = 124;
                  else
                    gsm_state = 0;
                 }; break;
       case 124: {
                  if (tmp == 'D'){
                    response_rcvd = 1;             // We have "ERROR" response
                    response = GSM_UNREAD;         // Set reception flag
                    responseID = response;         // Set response ID
                    Unread_flag = 1;
                  }
                  gsm_state = 0;
                 }; break;
      default: {                                 // Unwanted character
                gsm_state = 0;                   // Reset state machine
               }
    }
    // parse phone number on which we should reply
    switch (gsm_number) {
      case 0 :{
               if (tmp == '"'){
                 gsm_number = 1;
                 i = 0;
               }
              }; break;
      case 1 :{
               if (tmp == '+'){
                 phone_number[i] = tmp;
                 i ++;
                 gsm_number = 2;
               }
               else{
                 gsm_number = 0;
                 i = 0;
               }
              }; break;
      case 2 :{
               if (tmp >= '0' && tmp <= '9'){
                 phone_number[i] = tmp;
                 i ++;
               }
               else
                 if (tmp == '"'){
                   phone_number[i] = 0;
                   i = 0;
                   gsm_number = 0;
                 }
                 else{
                   phone_number[0] = 0;
                   i = 0;
                   gsm_number = 0;
                 }
              }; break;
      default : {
                 phone_number[0] = 0;
                 i = 0;
                 gsm_number = 0;
                }
    }
 }
}

/******************************************************************************/


Tried sending "Status?" from a different mobile number to the gsm sim card number. Since I do not have any Display to check, how I can know whether its received or not?
 
Last edited:

make a cable having max232, with db 9 port, solder rx wire to Rx pin of controller for gsm data and Tx pin of controller for controllerr command
 

Hi,

there are several test that can be done before connecting modem to microcontroller.

1. Check hardware connections
2. Use hyper-terminal to test that UART is properly sending data

If above of the two are "OK" then it is the problem with the code. I your code
Code:
const char atc0[] = "AT";
do it like
Code:
const char atc0[] = "AT\r";

Do this for rest of the AT commands. Do not send "0x0D" as carriage return as it has created problem with me in past. Hope this helps

Enjoy!
 

mikroC Code tested.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(sendsms){
                 UART1_Write_Text("AT+CMGF=1");
                 UART1_Write(13);
                 UART1_Write(10) ;
                 Delay_ms(2000);
                 UART1_Write_Text("AT+CMGS=");
                 UART1_Write(0x22);
                 UART1_Write_Text("+6597329728");
                 Delay_ms(100);
                 UART1_Write(0x22);
                 UART1_Write(13);
                 UART1_Write(10) ;
                 Delay_ms(1000);
                 UART1_Write_Text("Meter Reading is: ");
                 UART1_Write_Text(strenergy);
                 UART1_Write_Text(" kWh");
                 UART1_Write(0x0D);
                 UART1_Write(26);
                 UART1_Write(0x0D);
                 sendsms = 0;
          }


92004d1370427359-sms2.png

92005d1370427877-sms3.png
 

Attachments

  • sms2.png
    sms2.png
    58.1 KB · Views: 257
  • sms3.png
    sms3.png
    86.4 KB · Views: 243
Last edited:

Hi,

you can use some kind of trap circuit. Trap circuit means one type of MAX232 circuit whose one end connect to PC serial port and other side use only RX line which connect to Micro TX - Modem RX line. Using this type of trap circuit, you can watch command send by micro to module on your computer screen.
One other MAX232 trap circuit, you can use, whose one end connect to your second PC serial port if you have, and other side use only RX line which connect to Module Tx - Micro Rx line. by this you can also watch parallel how modem reply on your computer screen.
RX RX Trap MAX232 to PC
| |
| |
Micro TX ---|------- |---------- RX Modem
RX ----------- |---------- TX

Regards,
Ghanshyam
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top