Figure 1: SMS Controlled Security Access Control Boom Gate

Remotely controlled and monitored systems are becoming increasingly popular these days. Smart controlled devices, such as SMS vending machines, parking ticket payment stations, home automation, security access controls are becoming part of our everyday lives.

In this project we are going to learn how  to control a relay with an SMS. This relay could be used in many applications to Switch ON or OFF devices such as an electric bulb, or opening a security boom gate like in this example. A security access control can be implemented at apartments or housing complexes, when a visitor arrives at the gate, he/she can phone the visited person who can send an SMS: “OPEN” to the gate cellphone number, upon receiving this message from the GSM module, the PIC will trigger the relay to open the gate and then close automatically the gate after a short delay or after the car has entered the into the housing complex (Infrared beam detectors could be used to detect if a car has passed the gate).

In this project we are going to use a GSM modem, a PIC microcontroller and a relay.

A GSM modem is a wireless modem that works with a GSM wireless network. GSM stands for Global System for Mobile communications, this architecture is used for mobile communication in most of the countries in the world. 

A wireless modem acts basically like the traditional dial-up modem, the main difference is that a dial-up modem sends and receives data through a fixed telephone line while a wireless modem sends and receives data through radio waves. Besides the dial-up connection, GSM modem can also be used for sending and receiving SMS which is also one of the key features of GSM modem.

To learn more about interfacing GSM modem with PIC microcontrollers, please read more the article:

Interfacing GSM/GPRS Modem with PIC Microcontroller

To learn more about interfacing a Relay with PIC microcontrollers, please read more the article:

Interfacing a Relay with PIC Microcontroller

Circuit Diagram

Figure 2: SMS Controlled Relay with PIC Microcontroller

Buy GSM Modem, PIC, Development board, Relay, Accessories from our Online Store

Online Store: StudentCompanion

Construction

If you would like to build this project as a prototype for your soon to be improved project, we would advise to create a PCB for this project as you won’t be able to work well with relays on a breadboard, you don’t have to worry about the cost even if you are a student or with limited budget, these days it’s really cheaper to get quality professional PCB or PCB SMD component assembly relatively cheap.

There are many PCB companies in the world that can make you good quality PCBs, One of those companies we can recommend is PCBWay a china based PCB manufacturer specializing in PCB prototyping, small volume production and PCB assembly service all under one roof with more than a decade of experience.

They are now running an unbelievable SMD component assembly for only $30 USD this is for 1-20pcs plus free shipping worldwide!!!

You won’t get this offer anywhere with great SMT quality, so try them and verify their SMT services quality, maybe they could become your future partner with your prototyping. They produce also PCBs of great quality from only $5 USD for 10 pcs 1-2 layers.

To find out more about this great offer or to learn more about their services, please click on the image below:

MikroC Code

In this project, we are going to receive an SMS by using the Polled Response. In this mode, an AT command is sent t the modem to list any new Unread messages instead of getting a notification from the modem:

AT+CGMF=1              //Set SMS text mode
AT+CMGL="REC UNREAD"   // List UNREAD messages

If we assume that there is only one unread message, the modem may respond:

+CMGL:1,"REC UNREAD","0123456789",,"15/07/19,00:01:00+35"

1 is the index number. After receiving, we could delete all messages from the memory to be ready to receive new messages.

We are going to enable to UART interrupts so that when a character is received from the modem the program jumps straight to the interrupt service routine.

/*****************************************************************************
Project: SMS Controlled Relay with PIC Microcontroller
www.studentcompanion.co.za
Date:   July, 2019
******************************************************************************/
//
// Modem responses
//
#define OK  0
#define ON  1
#define OFF 0
//
// AT commands used in the program
//
char AT[] = "AT";
char No_Echo[] = "ATE0";
char Mode_Text[] = "AT+CMGF=1";
char Delete_All[] = "AT+CMGD=1,4";
char Get_Message[] = "AT+CMGL=\"REC UNREAD\"";
char Relay;
char SMS_Arrived;
//
// States and State variables
//
char State = 0;
char response_rcvd = 0;
short responseID = -1;
short response = -1;

//
// This function returns the modem response
//
short Modem_Response()
{
   if(response_rcvd)
   {
     response_rcvd = 0;
     return responseID;
   }
   else
     return -1;
}

//
// This function waits for a modem response
//
void Wait_Modem_Response(char resp)
{
   while(Modem_Response() != resp);
}

//
// This function sends a command to the modem. The command must be a string i.e.
// it must be terminated with a NULL character. After ending teh command the
// carriage return character is sent
//
void Send_To_Modem(char *s)
{
   while(*s)
   {
     Uart1_Write(*s++);
   }
   Uart1_Write(0x0D);
}


//
// This function initializes the GSM click board
//
void Init_GSM(void)
{
   UART1_Init(9600);                              // Set UART to 9600 Baud
   Delay_Ms(3000);                                // Wait a while
}

//
// This is the interrupt service routine. Modem responses are checked in this
// routine in the form of a State machine. The program jumps to this routine
// every time a character is received through the UART. A State machine code
// is implemented inside this routine to check the modem response. The keywords
// checked from the modem response are: OK, #ON and #OFF. Variable SMS_Arrived
// is set to 1 when an SMS message is received from the mobile phone. An endless
// loop in the main program controls the relay accordingly
//
void interrupt()
{
   char Dat;
   
   if(PIR1.RC1IF == 1)                          // If this is a UART1 interrupt
   {
      Dat = Uart1_Read();                       // Read he UARt1 data
      
      switch(State)                             // Start of the State machine
      {
        case 0:                                 // State 0
        {
           response = -1;
           if(Dat == 'O')State = 1;             // Response starts with 'O'
           if(Dat == '#')State = 100;           // Next State is 100
           break;
        }
        
        case 1:                                 // State 1
        {
           if(Dat == 'K')                       // Next response char is 'K'
           {
              response = OK;                    // Response is 'OK'
              State = 2;                        // Next State is 2
           }
           break;
        }
        
        case 2:                                 // State 2
        {
           if(Dat == 0x0D)                      // A carriage return ?
             State = 3;                         // Next State is 3
           else
             State = 0;                         // Next State is 0
           break;
        }
        
        case 3:                                 // State 3
        {
           if(Dat == 0x0A)                      // A line feed ?
           {
              response_rcvd = 1;                // Response received flag is set
              ResponseID = response;            // Response ID is set
           }
           State = 0;                           // Next State is 0
           break;
        }
        
        case 100:
        {
           if(Dat == 'O')State = 101;           // So far #O detected
           break;
        }
        
        case 101:
        {
           if(Dat == 'N')                       // #ON detected
           {
             Relay = ON;                        // Relay to be turned ON
             SMS_Arrived = 1;                   // SMS arrived flag
             State = 0;
           }
           if(Dat == 'F')State = 102;           // #OF detected
           break;
        }
        
        case 102:
        {
           if(Dat == 'F')                       // #OFF detected
           {
              Relay = OFF;                      // Relay to be turned OFF
              SMS_Arrived = 1;                  // SMS arrived flag
              State = 0;
           }
           break;
        }

        default:                                // Otherwise...
        {
           State = 0;                           // Next State is 0
           break;
        }
      }
   }
}

//
// This function enables (initializes) the UART1 interrupts. Thus, whenever a
// character is received from the serial port, the program jumps to the
// interrupt service routine
//
void Init_UART1_Interrupts(void)
{
   PIE1.RC1IE = 1;
   INTCON.PEIE = 1;
   INTCON.GIE = 1;
}


//
// Start of MAIN program
//
void main()
{
   TRISB_bit = 0;                                // Set RB0 as output for relay
   PORTB.RB0 = 0;                                 // Relay deactivated to start with
   Delay_Ms(5000);                                // Wait until GSM board is stabilized
   Init_GSM();                                    // Initialize the GSM click board
   Init_UART1_Interrupts();                       // Initialize UART1 interrupts
//
// Auto-baud detect. Keep sending AT commands and wait until "OK" is received
//
   while(1)
   {
     Send_To_Modem(AT);
     Delay_Ms(200);
     if(Modem_Response() == OK)break;
   }
//
// At this point the modem baud rate is set to 9600
// We can now start sending our AT commands to the modem

//
//
// Disable Echo
//
   Send_To_Modem(No_Echo);
   Wait_Modem_Response(OK);
//
// Set SMS mode to text
//
   Send_To_Modem(Mode_Text);
   Wait_Modem_Response(OK);
//
// The following is an endless loop where the program looks for an SMS message
// from the mobile phone. The program works in polled mode
//
//
// Delete all messages to start with
//
   Delay_Ms(5000);
   SMS_Arrived = 0;
   Send_To_Modem(Delete_All);
   Wait_Modem_Response(OK);
//
// Entering the endless loop where teh program looks for an SMS message and then
// controls the Relay accordingly. The comamnd #ON activates the Relay. On the
// other hand the command #OFF deactivates th Relay. Any electrical equipment
// conencted to the Relay is thus controlled remotely from a mobile phone
   while(1)
   {
      Send_To_Modem(Get_Message);            // Check if any SMS arrived
//
// Wait until modem is ready
//
      while(1)
      {
        Send_To_Modem(AT);
        Delay_Ms(1000);
        if(Modem_Response() == OK)break;
      }
      //
      // Check if a message has arrived
      //
      if(SMS_Arrived == 1)                   // A new SMS arrived
      {
        SMS_Arrived = 0;                     // Clear SMS arrived flag
        
        if(Relay == ON)
        {
        PORTB.RB0 = 1;                     // Activate the Relay
        }

        else if(Relay == OFF)
          PORTB.RB0 = 0;                     // Deactivate the relay

//
// Delete all messages
//
        Send_To_Modem(Delete_All);           // Delete all existing messages
        Wait_Modem_response(OK);             // Wait until modem is ready
      }
      Delay_Ms(10000);
   }
}

This code just demonstrate the basics of receiving an SMS then control a relay, there are many ways we could improve this code:

  • We could improve this by instead of sending a new SMS to close the gate, we could simply use a short delay like 10 seconds to close the gate automatically or even use infrared beam detectors to detect the presence of a car and only close the gate automatically once the car enters the area.
  • Add a send function to send to the user the status of the gate. gate open or closed to make sure the command was executed
  • Check the telephone number of the sender to make sure only numbers from authorized users can open the gate.