Tutorial: How to use SIM800L DTMF to Control Anything | Arduino

Introduction

In here we will learn how we can use SIM800L DTMF to control anything from simple turning On or turning Off of LED to big projects like home automation.

DTMF stands for Dual Tone Multi Frequency or more commonly known as Touch Tone. You will most likely to experience the use of DTMF when you call the customer support hotline of big companies which requires you to press a set of different numbers. I am thinking that this is to categories customer concerns and direct you to a specific person who is knowledgeable about your concern.

With DTMF, each key you press on your phones generates 2 tones of specific frequency. The tones is generated in pairs of high and low frequency groups.

Key Low Frequency High Frequency
1 697 1209
2 697 1336
3 697 1477
4 770 1209
5 770 1336
6 770 1477
7 852 1209
8 852 1336
9 852 1477
0 941 1336
* 941 1209
# 941 1477

For example when you press #1 key, you are sending a 697 Hz tone and a 1209 Hz tone. This is in order to separate DTMF from human voice.

Circuit Diagram

Video Demonstration

Source Code

  1#include "SoftwareSerial.h"
  2
  3# define SIM800L_Tx 7
  4# define SIM800L_Rx 6
  5# define RED_LED_PIN 5
  6# define GRN_LED_PIN 4
  7
  8SoftwareSerial SIM800L(SIM800L_Tx, SIM800L_Rx);
  9
 10char dtmf_cmd;
 11bool call_flag = false;
 12bool RED_LED_STATE = false;
 13bool GRN_LED_STATE = false;
 14
 15void init_gsm();
 16void update_led();
 17
 18void setup()
 19{
 20  SIM800L.begin(9600);
 21  Serial.begin(9600);
 22  pinMode(RED_LED_PIN, OUTPUT);
 23  pinMode(GRN_LED_PIN, OUTPUT);
 24  digitalWrite(RED_LED_PIN, RED_LED_STATE);
 25  digitalWrite(GRN_LED_PIN, GRN_LED_STATE);
 26  init_gsm();
 27}
 28
 29void loop()
 30{
 31  String gsm_data;
 32  int x = -1;
 33  // Store serial data from SIM800L
 34  while (SIM800L.available())
 35  {
 36    char c = SIM800L.read();
 37    gsm_data += c;
 38    delay(10);
 39  } 
 40
 41  // Check if DTMF is receive from SIM800L
 42  if (call_flag)
 43  {
 44    // Call is answered and ongoing
 45    // Wait for DTMF command
 46    // Then store the dtmf command
 47    x = gsm_data.indexOf("DTMF");
 48    if (x > -1)
 49    {
 50        dtmf_cmd = gsm_data[x + 6];
 51        Serial.println(dtmf_cmd);
 52        update_led();
 53    }
 54    
 55    x = gsm_data.indexOf("NO CARRIER");
 56    if (x > -1)
 57    {
 58      // Terminate ongoing call when call is disconnected
 59      SIM800L.println("ATH");
 60      call_flag = false;
 61    }
 62  } else {
 63    // SIM800L is in idle, just waiting for calls
 64    // answer incoming call when ringing
 65    // then process it
 66    x = gsm_data.indexOf("RING");
 67    if (x > -1)
 68    {
 69      delay(5000);
 70      SIM800L.println("ATA");
 71      call_flag = true;
 72    }
 73  }
 74}
 75
 76void init_gsm() {
 77  boolean gsm_Ready = 1;
 78  Serial.println("initializing GSM module");
 79  while (gsm_Ready > 0)
 80  {
 81    SIM800L.println("AT");
 82    Serial.println("AT");
 83    while (SIM800L.available())
 84    {
 85      if (SIM800L.find("OK") > 0)
 86        gsm_Ready = 0;
 87    }
 88    delay(2000);
 89  }
 90  Serial.println("AT READY");
 91
 92  boolean ntw_Ready = 1;
 93  Serial.println("finding network");
 94  while (ntw_Ready > 0)
 95  {
 96    SIM800L.println("AT+CPIN?");
 97    Serial.println("AT+CPIN?");
 98    while (SIM800L.available())
 99    {
100      if (SIM800L.find("+CPIN: READY") > 0)
101        ntw_Ready = 0;
102    }
103    delay(2000);
104  }
105  Serial.println("NTW READY");
106
107  boolean DTMF_Ready = 1;
108  Serial.println("turning DTMF ON");
109  while (DTMF_Ready > 0)
110  {
111    SIM800L.println("AT+DDET=1");
112    Serial.println("AT+DDET=1");
113    while (SIM800L.available())
114    {
115      if (SIM800L.find("OK") > 0)
116        DTMF_Ready = 0;
117    }
118    delay(2000);
119  }
120  Serial.println("DTMF READY");
121}
122
123void update_led()
124{
125  if (dtmf_cmd == '1') {
126    if (RED_LED_STATE) {
127      RED_LED_STATE = false;
128      digitalWrite(RED_LED_PIN, RED_LED_STATE); //relay 1 on
129      Serial.println("RELAY 1 OFF");
130    } else {
131      RED_LED_STATE = true;
132      digitalWrite(RED_LED_PIN, RED_LED_STATE); //relay 1 on
133      Serial.println("RELAY 1 ON");
134    }
135  }
136
137  if (dtmf_cmd == '2') {
138    if (GRN_LED_STATE) {
139      GRN_LED_STATE = false;
140      digitalWrite(GRN_LED_PIN, GRN_LED_STATE); //relay 2 on
141      Serial.println("RELAY 2 OFF");
142    } else {
143      GRN_LED_STATE = true;
144      digitalWrite(GRN_LED_PIN, GRN_LED_STATE); //relay 2 on
145      Serial.println("RELAY 2 ON");
146    }
147  }
148}

This source code is for Ajit Zagade as requested

  1#include "SoftwareSerial.h"
  2
  3# define SIM800L_Tx 7
  4# define SIM800L_Rx 6
  5# define RED_LED_PIN 5
  6# define GRN_LED_PIN 4
  7
  8SoftwareSerial SIM800L(SIM800L_Tx, SIM800L_Rx);
  9String number = "+ZZxxxxxxxxxx";  // Replaced the following:
 10                                  // ZZ - your country code
 11                                  // xx - 10-digit mobile number
 12char dtmf_cmd;
 13bool call_flag = false;
 14bool RED_LED_STATE = false;
 15bool GRN_LED_STATE = false;
 16
 17void init_gsm();
 18void update_led();
 19
 20void setup()
 21{
 22  SIM800L.begin(9600);
 23  Serial.begin(9600);
 24  pinMode(RED_LED_PIN, OUTPUT);
 25  pinMode(GRN_LED_PIN, OUTPUT);
 26  digitalWrite(RED_LED_PIN, RED_LED_STATE);
 27  digitalWrite(GRN_LED_PIN, GRN_LED_STATE);
 28  init_gsm();
 29}
 30
 31void loop()
 32{
 33  String gsm_data;
 34  int x = -1;
 35  
 36  // Store serial data from SIM800L
 37  while (SIM800L.available())
 38  {
 39    char c = SIM800L.read();
 40    gsm_data += c;
 41    delay(10);
 42  } 
 43
 44  // Check if DTMF is receive from SIM800L
 45  if (call_flag)
 46  {
 47    // Call is answered and ongoing
 48    // Wait for DTMF command
 49    // Then store the dtmf command
 50    x = gsm_data.indexOf("DTMF");
 51    if (x > -1)
 52    {
 53        dtmf_cmd = gsm_data[x + 6];
 54        Serial.println(dtmf_cmd);
 55        update_led();
 56    }
 57    
 58    x = gsm_data.indexOf("NO CARRIER");
 59    if (x > -1)
 60    {
 61      // Terminate ongoing call when call is disconnected
 62      SIM800L.println("ATH");
 63      call_flag = false;
 64    }
 65  } else {
 66    // SIM800L is in idle, just waiting for calls
 67    // answer incoming call when ringing
 68    // then process it
 69    x = gsm_data.indexOf("RING");
 70    if (x > -1)
 71    {
 72      delay(5000);
 73      SIM800L.println("ATA");
 74      call_flag = true;
 75    }
 76  }
 77}
 78
 79void init_gsm() {
 80  boolean gsm_Ready = 1;
 81  Serial.println("initializing GSM module");
 82  while (gsm_Ready > 0)
 83  {
 84    SIM800L.println("AT");
 85    Serial.println("AT");
 86    while (SIM800L.available())
 87    {
 88      if (SIM800L.find("OK") > 0)
 89        gsm_Ready = 0;
 90    }
 91    delay(2000);
 92  }
 93  Serial.println("AT READY");
 94
 95  boolean ntw_Ready = 1;
 96  Serial.println("finding network");
 97  while (ntw_Ready > 0)
 98  {
 99    SIM800L.println("AT+CPIN?");
100    Serial.println("AT+CPIN?");
101    while (SIM800L.available())
102    {
103      if (SIM800L.find("+CPIN: READY") > 0)
104        ntw_Ready = 0;
105    }
106    delay(2000);
107  }
108  Serial.println("NTW READY");
109
110  boolean DTMF_Ready = 1;
111  Serial.println("turning DTMF ON");
112  while (DTMF_Ready > 0)
113  {
114    SIM800L.println("AT+DDET=1");
115    Serial.println("AT+DDET=1");
116    while (SIM800L.available())
117    {
118      if (SIM800L.find("OK") > 0)
119        DTMF_Ready = 0;
120    }
121    delay(2000);
122  }
123  Serial.println("DTMF READY");
124}
125
126void update_led() {
127  if (dtmf_cmd == '1') {
128    if (RED_LED_STATE) {
129      RED_LED_STATE = false;
130      digitalWrite(RED_LED_PIN, RED_LED_STATE); //relay 1 on
131      Serial.println("RELAY 1 OFF");
132      SendSMS("RELAY 1 OFF");
133    } else {
134      RED_LED_STATE = true;
135      digitalWrite(RED_LED_PIN, RED_LED_STATE); //relay 1 on
136      Serial.println("RELAY 1 ON");
137      SendSMS("RELAY 1 ON");
138    }
139  }
140
141  if (dtmf_cmd == '2') {
142    if (GRN_LED_STATE) {
143      GRN_LED_STATE = false;
144      digitalWrite(GRN_LED_PIN, GRN_LED_STATE); //relay 2 on
145      Serial.println("RELAY 2 OFF");
146      SendSMS("RELAY 2 OFF");
147    } else {
148      GRN_LED_STATE = true;
149      digitalWrite(GRN_LED_PIN, GRN_LED_STATE); //relay 2 on
150      Serial.println("RELAY 2 ON");
151      SendSMS("RELAY 2 ON");
152    }
153  }
154}
155
156void SendSMS(String SMS) {
157  //Serial.println ("Sending Message");
158  SIM800L.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
159  delay(1000);
160  //Serial.println ("Set SMS Number");
161  SIM800L.println("AT+CMGS="" + number + ""r"); //Mobile phone number to send message
162  delay(1000);
163  SIM800L.println(SMS);
164  delay(100);
165  SIM800L.println((char)26);// ASCII code of CTRL+Z
166  delay(1000);
167}

Call To Action

I hope you and enjoy this article. If you have any question, please do not hesitate to write it in the comment box. Thank you and have a good day. Happy tinkering.



Posts in this series



No comments yet!

GitHub-flavored Markdown & a sane subset of HTML is supported.