SMS Controlled Relay with PIC Microcontroller- MikroC
Français
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:
To learn more about interfacing a Relay with PIC microcontrollers, please read more the article:
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.