In this tutorial we’re going to show you how you can control a 12V lamp via SMS using an Arduino UNO, a relay module, and the SIM900 GSM shield.
Before proceeding with this tutorial we recommend the following resources:
First, watch the video demonstration
Project overview
This project uses the SIM900 GSM shield to receive and send SMS with the Arduino. This projects aims to:
- turn a 12V lamp on when you send an SMS to the Arduino with the text “ON”
- turn a 12V lamp off when you send an SMS to the Arduino with the text “OFF”
- you can request the lamp state by sending an SMS to the Arduino with the text “STATE”, the Arduino should reply back with the text “lamp is on” or “lamp is off”
Parts required
In this project you need to connect the Arduino to the GSM shield and to a relay module connected to a 12V lamp. Here’s a complete list of the parts required for this project (click the links below to find the best price at Maker Advisor):
- Arduino UNO  – read Best Arduino Starter Kits
- SIM900 GSM Shield
- 5V 2A power adaptor
- Relay module
- 12V lamp
- 12V lamp holder
- Male DC barrel jack 2.1mm
- 12V power adaptor
- Breadboard
- Jumper Wires
- Optional – 12V/5V power supply
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Preparing the GSM Shield
To use the SIM900 GSM shield:
1)Â You need an active SIM card. We recommend using a SIM card with a prepaid plan for testing purposes.
2) You have to turn off the SIM card pin lock. Insert the SIM card in your smartphone and turn off the pin lock in the phone security settings.
3)Â The GSM shield should be powered using an external 5V power supply that can provide 2A, or 9V 1A, or 12V 1A.
4)Â We’re going to use software serial to communicate with the shield. So, on the serial port select, make sure the jumper cap is connected as shown in figure below to use software serial.
5)Â You can turn on/off the shield by pressing the power key, or you can turn it on automatically with the Arduino via the D9 pin. To automatically turn the shield on and off, you need to solder the R13 connections as shown in the figure below.
6)Â If this is your first time dealing with the GSM shield, we recommend you reading the Preliminary Steps in our GSM shield guide here.
7)Â Insert the SIM card into the SIM card holder.
8)Â Finally, wire the SIM900 GSM shield to the Arduino by following the schematic below.
9) You should power up the SIM900 GSM shield using the external 5V power supply. Make sure you select the external power source with the toggle switch next to the DC jack.
Note: You can test it the shield is working properly by sending AT comments from the Arduino IDE with an FTDI programmer – check Guide to SIM900 GSM GPRS Shield with Arduino
Wiring the Relay Module
In this project we control a 12V lamp. However, this project can be easily adapted to control mains voltage or other electronics appliances. Check our Guide for Relay Module with Arduino to learn how to control mains voltage with a relay.
We are using the following 12V lamp and its corresponding lamp holder.
Add the relay module and the lamp holder to the previous circuit.
For safety purposes, we’re placing our relay inside a plastic box enclosure.
Code
Below you can find the code for this project. Make sure you edit the code with the phone number the Arduino should reply to. We recommend you reading the code explanation before uploading the code.
/*
* Complete Project Details https://randomnerdtutorials.com
*/
// Include Software Serial library to communicate with GSM
#include <SoftwareSerial.h>
// Configure software serial port
SoftwareSerial SIM900(7, 8);
// Variable to store text message
String textMessage;
// Create a variable to store Lamp state
String lampState = "HIGH";
// Relay connected to pin 12
const int relay = 12;
void setup() {
// Automatically turn on the shield
digitalWrite(9, HIGH);
delay(1000);
digitalWrite(9, LOW);
delay(5000);
// Set relay as OUTPUT
pinMode(relay, OUTPUT);
// By default the relay is off
digitalWrite(relay, HIGH);
// Initializing serial commmunication
Serial.begin(19200);
SIM900.begin(19200);
// Give time to your GSM shield log on to network
delay(20000);
Serial.print("SIM900 ready...");
// AT command to set SIM900 to SMS mode
SIM900.print("AT+CMGF=1\r");
delay(100);
// Set module to send SMS data to serial out upon receipt
SIM900.print("AT+CNMI=2,2,0,0,0\r");
delay(100);
}
void loop(){
if(SIM900.available()>0){
textMessage = SIM900.readString();
Serial.print(textMessage);
delay(10);
}
if(textMessage.indexOf("ON")>=0){
// Turn on relay and save current state
digitalWrite(relay, LOW);
lampState = "on";
Serial.println("Relay set to ON");
textMessage = "";
}
if(textMessage.indexOf("OFF")>=0){
// Turn off relay and save current state
digitalWrite(relay, HIGH);
lampState = "off";
Serial.println("Relay set to OFF");
textMessage = "";
}
if(textMessage.indexOf("STATE")>=0){
String message = "Lamp is " + lampState;
sendSMS(message);
Serial.println("Lamp state resquest");
textMessage = "";
}
}
// Function that sends SMS
void sendSMS(String message){
// AT command to set SIM900 to SMS mode
SIM900.print("AT+CMGF=1\r");
delay(100);
// REPLACE THE X's WITH THE RECIPIENT'S MOBILE NUMBER
// USE INTERNATIONAL FORMAT CODE FOR MOBILE NUMBERS
SIM900.println("AT + CMGS = \"XXXXXXXXXX\"");
delay(100);
// Send the SMS
SIM900.println(message);
delay(100);
// End AT command with a ^Z, ASCII code 26
SIM900.println((char)26);
delay(100);
SIM900.println();
// Give module time to send SMS
delay(5000);
}
The code is pretty straightforward to understand. Continue reading to understand what each section of code aims to do.
Import library
The Arduino communicates with the shield using software serial communication. So, you start by including the SoftwareSerial.h library.
// Include Software Serial library to communicate with GSM #include <SoftwareSerial.h>
Software serial port
Then, you create a software serial port on pins 7 and 8 (pin 7 is set as RX and 8 as TX).
// Configure software serial port SoftwareSerial SIM900(7, 8);
Creating variables
You create a textMessage variable that will hold the text message received by the Arduino; and another variable to store the current lamp state (relay state), called lampState. The lampState variable is set to HIGH by default, because we want the relay off by default. The relay works with inverted logic, so you need to set it to HIGH to turn it off.
// Variable to store text message String textMessage; // Create a variable to store Lamp state String lampState = "HIGH";
You also assign the pin number the relay is connected to, pin 12.
// Relay connected to pin 12 const int relay = 12;
setup()
In the setup() function, you start by turning on the GSM shield. The following lines are the equivalent of pressing the shield “power” button.
digitalWrite(9, HIGH); delay(1000); digitalWrite(9, LOW); delay(5000);
The relay is set as an output, and its state is off by default.
// Set relay as OUTPUT pinMode(relay, OUTPUT); // By default the relay is off digitalWrite(relay, HIGH);
Then, you initialize serial communication with the shield, and give it some time to log on to the network.
// Initializing serial commmunication Serial.begin(19200); SIM900.begin(19200); // Give time to your GSM shield log on to network delay(20000); Serial.print("SIM900 ready...");
The shield is set to SMS mode with the following:
// AT command to set SIM900 to SMS mode SIM900.print("AT+CMGF=1\r"); delay(100); // Set module to send SMS data to serial out upon receipt SIM900.print("AT+CNMI=2,2,0,0,0\r"); delay(100);
loop()
In the loop(), you read the incoming messages and compare if those messages contain the text ON, OFF or STATE. Accordingly to the message content, the Arduino will perform different tasks.
So, you start by checking whether there are messages to read. If there are, the message will be saved on the textMessage variable. For debugging purposes, the message is displayed on the serial monitor.
if(SIM900.available() >0) { textMessage = SIM900.readString(); Serial.print(textMessage); delay(10); }
Turn the lamp on
If the message received contains the text “ON”, then the relay will be turned on, turning on the lamp. Then, you save the current lamp state on the lampState variable. Finally, you clean the textMessage variable, so that it is empty to receive new SMS.
if (textMessage.indexOf("ON") >= 0){ // Turn on relay and save current state digitalWrite(relay, LOW); lampState = "on"; Serial.println("Relay set to ON"); textMessage = "";
Turn the lamp off
On the other side, if the SMS received contains the text “OFF”, the relay will be turned off, the new state will be saved, and the textMessage is cleaned.
if (textMessage.indexOf("OFF") >= 0){ // Turn off relay and save current state digitalWrite(relay, HIGH); lampState = "off"; Serial.println("Relay set to OFF"); textMessage = "";
Returning the lamp state
Finally, if the incoming SMS contains the text “STATE”, the Arduino should send a message to a predefined phone number saying whether the lamp is currently on or off.
if (textMessage.indexOf("STATE") >= 0){ String message = "Lamp is " + lampState; sendSMS(message); Serial.println("Lamp state resquest"); textMessage = "";
The message is sent using the sendSMS() function defined at the bottom of the code.
Sending an SMS
The sendSMS() function created at the end of the code, accepts a string as an argument. That string should be the message to be sent.
The number the Arduino answers to is set at the following line:
SIM900.println("AT + CMGS = \"XXXXXXXXXXXX\"");
Replace the XXXXXXXXXXXX with the recipient’s phone number.
Note: you must add the number according to the international phone number format. For example, in Portugal the number is preceded by +351XXXXXXXXX.
After adding the phone number the Arduino should reply to, you can copy the full code to your Arduino IDE and upload it to your Arduino board.
Wrapping up
In this project we’ve shown you how you can use the SIM900 GSM shield to control a 12V lamp and to request data (the lamp state) to the Arduino.
The concepts learned in this project can be applied to control any electronics appliances you like. You can also use what you’ve learned here to request the Arduino about sensor data – for example, request the latest readings of your weather station.
You can also build a surveillance system using a PIR motion sensor and a GSM shield that sends you an SMS when unexpected motion is detected.
We hope you’ve found this project useful. If you like this project, make sure you check our Arduino course: Arduino Step-by-step Projects with 25 Projects.
Thanks for reading.
Really great project. What would be really interesting would be to adapt it so that BOTH relays could be operated by texting ON1, OFF1 and ON2, OFF2. I’m thinking of controlling heating and hot water systems separately.
Hi Dermot.
That’s a really good idea. You should be able to easily modify the code to control two relays.
Good luck with your projects.
nice project
RTFM!
You don’t need “a power supply that outputs different voltage values”.
Both arduino and GSM shield can be powered from 7..12V supply.
So 12V will be enough for all parts.
Hi Yan.
You are right. We’ve edited the project instructions.
Thank you.
Hi Sara,
Your schematic diagram is still not updated to show sharing a 12v power source with the arduino, the shield and the light. Can you please update it to make it complete?
Hi Rui,
great tutorial. Thank you!
~Thorsten
Hi Thorsten.
Thank you for your support 🙂
Hi rui
I would not recommend this power supply for amateurs. The mains input terminals are exposed and would offer a lethal shock if inadvertently touched. It would need to be mounted within enclosure to isolate terminals and provide some protection.
Regards
Hi Graham.
You are right. When dealing with that kind of power supplies you really need to know what you are doing.
Adding an enclosure is a good way to isolate the terminals and is truly recommended.
Thank you for warning us about that issue.
Regards
Sara 🙂
Hello
Excellent, very clearly written tutorial, thank you!
Few issues I’d like to point out, even I do understand the nature of an simplified tutorial:
– The state command doesn’t really tell if the lamp is burning or not. It merely tells if latest command was ON or OFF. The state command happily returns “Lamp is on” even if the lamp has burned out, 12 Volt source is not working, the relay has melted down due overcurrent… or the lamp is not really burning due to any other malfunction.
Therefore if the application is anyway critical, I’d add an photoresistor or something else to examine if the lamp is really on.
– Every relay has a maximum current. The relay module used as an example has a limit of max. 10A – a current that is easy to exceed with a couple of car headlight bulbs. I’d add an short mention of the relay max current, which a user should always check. Even the “Guide for Relay Module with Arduino” doesn’t mention the max current!
Otherwise keep up the good work 🙂
Hi.
Thank you for taking the time to share your tips with us.
Indeed, adding a photoresistor is a good solution to check out the real lamp state.
We wanted to show our readers how they request something to the Arduino. We think that after following this tutorial they can easily add the photoresistor to check out the real lamp status.
Thanks for your feedback.
Regards
Sara
really good idea
can you guide with program for adding photoresistor
You should probably note that this project will not work with a SIM900 module in Australia. There are no 2G networks in operation. You will need a 3G module – available but more expensive. Also ensure you buy one that meets the frequency range of the network you intend to use.
Hi Mike.
You are right. It only works in 2G network.
Thanks for pointing that out.
This project is great! just a question. This is for a 2g sim card correct? can this work with on 3g ?
Hi.
Do you have coverage on a GSM 850 MHz, GSM 900 MHz, DCS 1800 MHz or PCS 1900 MHz network?
GSM only works in 2G.
Very elegant! I have used GSM-shields in several solutions. Using SMS gives good reliability and is dramatically simpler than GRPS/IoT solutions. – Strings quickly eats up Uno memory, but is excellent for a few short messages.
hi
thanks
I am using different type of gsm module in my country but same sim900
there is no jumper settings, R13 connections, etc., but have 4 pins 5v, gnd, tx and rx…
what are the changes should i do?
Hi.
I don’t know what kind of module you’re using.
So, I don’t have enough info to fully answer your question.
But if you have TX and RX, you should connect them to the Arduino pins we shown on the schematic diagram.
You have to search what pin you should connect on your module to automatically turn on the shield.
However, you can always manually turn on the shield, and in that case, you just need the TX and RX connections, GND, and VCC.
I hope this helps.
i am using some different gsm module and i can send and receive sms but output pin12 continuously giving 5v without change,., need solution…
Excellent tutorials.
I followed the previous ones, and they all work great.
Is there a way to use this code to activate and deactivate a PIR motion sensor instead of a relay and make a call when motion is detected.
Have tried modifying the code but it ether does nothing or makes a call on powering up without motion.
Thanks
kind regards
when motion is detected,
Hi Richard.
I haven’t tested that particular project.
But I think you need to:
– create an Interrupt on the PIR motion sensor pin on RISING mode.
– when motion is detected the code should call a function that sends the SMS.
It may also help taking a look at interrupts with Arduino: arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
I hope this helps 🙂
That was a great tutorial, but my challenge is that after sending the first command say “ON” and it worked, the second command refused to arrive so nothing happens. What could be the problem? Thanks in anticipation
Hi Tammy.
What was the second command that you’ve sent?
Ok, thanks for your prompt reply. The second could be any, either you want to turn on a second device or even want to turn the device you turned ON, ie. First -“ON” goes, but sending another ON or OFF does not do anything again. Thanks in anticipation
Hi Tammy. Are you using our code without any changes (just changing the phone number?).
If it receives the first message, but not the second one, maybe the first message is not being “closed” or the code is stuck in some place.
If you’re using our exact code, I don’t know what can be happening. This code worked just fine for us.
I hope this helps.
how can i modify the code to control two or three relay ?
please help
Hello suleiman,
With some changes in the code and more if statements, you should be able to control as many relays as your Arduino has digital pins, but I only have this example with one relay…
Hi, does using 4g sim effects the turning on and off of relay? Or do i really need a 2g sim to make it work?
Hi.
You can use a 4G SIM.
Regards,
Sara
I forgot to tell you that I have the answer like this ” ⸮ ” in the serial monitor with send ON or OFF
Make sure you change the baud rate in your Arduino IDE serial monitor to 19200, so you can see the information in the Serial monitor (the baud rate option is located on the bottom right corner of the Serial Monitor window).
Regards,
Rui
Hello how to connect pin number on arduino Mega please? I’m connect Pin 18 and 19 for RX/TX and pin 9 sim900 to pin9 arduino mega but is not operational??
Please help me?
Would it be possible to turn the lamp on and off with a ring or always with a ring to keep it on for x seconds?
Hi Alberto.
Yes, it is possible.
Take a look at our GSM Shield Guide:
https://randomnerdtutorials.com/sim900-gsm-gprs-shield-arduino/
“Answering incoming phone calls” section and take a look at the code.
When the shield receives a phone call, it receives a “RING” message.
So you can check if the shield received the “RING” message, and then turn the lamp on or off.
I hope this helps.
Regards,
Sara 🙂
Hey this project can use gsm sim900A. not sim900 but sim 900A. can? if can, how the circuit diagram to connect gsm sim900A to arduino uno?
Hi Daniel!
This project uses the SIM900 GSM shield.
It should be compatible with the SIM900A. You just need to identify your Shield’s serial pins (RX and TX) and connect those to the Arduino as we show here. You can use the same code we use in this project.
You may find useful taking a look at our getting started guide:
– https://randomnerdtutorials.com/sim900-gsm-gprs-shield-arduino/
I hope this helps,
Regards,
Sara 🙂
What if want to display the message on led
Hi.
You just need to save the message on a variable, and then, print that value on the OLED display.
You can read the following tutorial to learn how to use the display:
https://randomnerdtutorials.com/guide-for-oled-display-with-arduino/
I hope this helps.
Regards,
Sara 🙂
great work thnks a lot
You’re welcome 🙂
Hi..
It’s really nice project…
I tried it all works good.. except it’s not return state… only shows in serial monitor…
Can you help..
I’m using sim900a
Hello, I’m not sure what you mean… What exactly do you want to do? You can create an if statement that triggers an action based on the received message… Thanks for asking!
hello can arduino read message in different languages?
Hi.
What do you mean by “different languages”?
Awesome tutorial. I am using a SIM800L module and had to fiddle with the code a bit. The line – SIM900.println(“AT + CMGS = \”XXXXXXXXXXXX\””) had spaces in the AT Code which I needed to delete before it worked.
Thanks, much appreciated!!!!
Hi.
That you for sharing that.
It may be useful for other readers.
Regards,
Sara 🙂
Hi Bart, I am planning on using the SIM800L as well. I was wondering if you had ti change anything else to the code? (except for changing SIM900 to SIM800L of course :))
Thanks in advance!
Can you share your code? I can not get a return text to my cellphone from the sim900 when I text STATE it only shows on the serial monitor
very good project,i like the way you describe each function and variable .thanks for your support
Thank you 🙂
it is always om mot even works on on i create same in the tutorial but didnt works
Hi.
I’m sorry, but I didn’t understand what you’re trying to say.
Hi,
Did your command/coding works with other SIM module for example SIM900A?
Hi Izari.
I haven’t experimented with the SIM900A.
But it seems that both boards use the same AT commands: pantechsolutions.net/blog/basic-at-commands-for-sim900a-gsmgprs-module/ so, the code should be compatible with both boards.
Regards,
Sara
Can i use it for 230V lamp with same relay
Yes.
Very nice tutorial . Thanks
Thank you 😀
what is the range of control commands
Hi.
The relay is controlled via SMS.
So, it can be controlled from anywhere as long as you have GSM.
Regards,
Sara
Hello
Great project. Everything is working BUT when I try to check STATE I do not receive anything … there is no SMS back? What is wrong?
Regards,
Nesa
Double-check that you’ve entered the right Phone number and country code
+381 64 xxxxxxx .
381= Country Code
064= Network code
XXXXXXX= phone number
Everything is correct.
I have done this project. It was successfulled. But only 30 minuts. Then I cant controll the lamp via sms. After that I disconnected power line and did connect again. it was worked. Again after few minuts , it was not work. Please help me to solve my mistake.
Hi, can i do this with Gsm 800?
Hi Jetro.
I haven’t tested it, but it should be compatible (or you’ll need to make a few modifications).
Regards,
Sara
HI,
I’m from Sri Lanka
This is an excellent and very clearly explained project. This is the clearest and the simplest tutorial which can be understood for the beginners about arduino sms power control, I have ever seen in the internet. I followed this and tried it for five bulbs. Then I tried it with triac circuit to control 230V bulbs. It was it was successful.
thank you very much for spending your valuable time to share your knowledge. And I respect to you.
I’m glad it worked sucessÃvel!
Thank you so much for following our projects!
All the best.
Sara
Hello,
Please what library did you use for the gsm/gprs sim 900 ?
Thank you.
Hi.
I didn’t need to include any library.
The shield communicates using software serial.
Regards,
Sara
Hello,
I get good values from signal strength test, and can send a text message. But I get ERROR when sending this command SIM900.print(“AT+CNMI=2,2,0,0,0\r”); What could be wrong?
Whatever was the problem, it works now. Thanks for this tutorial.
Hello
This is a great project however i would like to know how to delete the messages since when the sim card is full it wont receive messages and no command will take action.
Kindly assist
Hi.
You need to send the AT command to delete messages. The AT command is: AT+CMGD
You can check all the AT commands list here: https://simcom.ee/documents/SIM900/SIM900_AT%20Command%20Manual_V1.11.pdf
So, you need to use the following line in your code somewhere:
SIM900.print(“AT+CMGD\r”);
I hope this helps.
Regards,
Sara
Hello
Thanks for your response, i will work on that.
Glad you shared the AT commands that will help me in playing around the sim900
Will let you know how that goes
Best
Erick
The option to delete sms went well
Thanks
Hello everything works for me but the STATE return text. It give the STATE to the serial monitor when I text STATE to the Arduino but it will not return a SMS back to the phone # I input. Is there something I should look for?
// Function that sends SMS
void sendSMS(String message){
// AT command to set SIM900 to SMS mode
SIM900.print(“AT+CMGF=1\r”);
delay(100);
// REPLACE THE X’s WITH THE RECIPIENT’S MOBILE NUMBER
// USE INTERNATIONAL FORMAT CODE FOR MOBILE NUMBERS
SIM900.println(“AT + CMGS =1\r\”+12x92x2x0x8\””);
delay(100);
// Send the SMS
SIM900.println(message);
delay(100);
// End AT command with a ^Z, ASCII code 26
SIM900.println((char)26);
delay(100);
SIM900.println();
// Give module time to send SMS
delay(5000);
}
Thanks
This is very good project for controlling the appliances
I done it from the GsM 900a
And it still work
…
But I want to control the 4 appliances from the Sms
Some one can help me
I assume what you will have to do is work on the code and have different sms for different relays such as ON1 & OFF1 for relay 1, ON2 & OFF2 for relay 2 and so forth, this means each appliance will have its relay
Has anybody got this working on SIM7000 module?
Pleasee share, Are the commands the same?
I will also be following on this as well
Hi,
I used SIM800L V2 and it worked perfectly well for me. Thanks alot.
Is it possible to control the relay by sending sms from any number, or must it always be from a specific programmed number. Can I use to different phones to control the relay?
Hi.
As long as you add the right logic to the code, you can control the relay from any number.
Regards,
Sara
I’m making an integrated alarm, irrigation and lighting control system with mega arduino and sim 900.
The alarm sends a message to the mobile phone in case of intrusion.
Irrigation is switched on/off via SMS but guns autonomously, starting the cycle at sunrise and sunset, controlled by a light sensor.
This article is a good help.
That’s great!
It seems like a great project.
Regards,
Sara
Hello everyone, hope somebody can helpme; I follow all the steps very sharp of the tutorial and it dosnt work, simply do anything only recive weird characters on arduino IDE monitor serie went I send sms ON or OFF or STATE
A
? ??
?,m
++?MJ?j
++MIJJ?),m
+???*?HLK?
?il
++??
+??M?++?MJ?j
Hi.
Check the Serial Monitor baud rate.
Regards,
Sara
Hi
when i upload the program code to arduino it says sketch uses 6106 bytes (18%) of program storage space. maximum is 32256 bytes. Global variable use 477 bytes (23%) of dynamic memory, leaving 1571 bytes for local variables. Maximum is 2408 bytes. what should i do?
After trying a lot of ‘projects’ with the sim900 and arduino, finally one that goes on at first power up!
Many thanks to the author for a clear and complete description on how to reach the goal.
Ciao
Thanks.
I’m glad this tutorial was useful.
Regards.
Sara