Cancellino

Control everything with a SINGLE phone call.

Components and Supplies

About This Project

This project shows how to use an Arduino to receive a call and compare the calling number with numbers saved in the microSD card, without answering! This solution works also with a plain SIM with no data plan.

It's also possible to save new authorized numbers via SMS.

What You Need

The project is based on an Arduino MKR GSM 1400, an antenna, a LiPo battery pack, an Arduino MKR MEM shield, a microSD card, an Arduino MKR Connector Carrier, a Grove Relay Module, one SIM card, and of course, a phone!

  • The Arduino MKR GSM 1400 executes the sketch and supports the GSM connection that allows the call and SMS receiving features required by our project;
  • Antenna and battery pack are respectively used to allow the connection to the cellular network with a good signal and to power the device when other power supplies are not available;
  • The Arduino MKR MEM shield and microSD card (formatted as FAT16 or FAT32) are used to store a file with all the authorized phone numbers;
  • Arduino MKR Connector Carrier is used to easily connect other electronics module as the Grove Relay Module;
  • The SIM card is required to access the GSM network;
  • PIN, is required to use the sim card.

Hardware Setup

All components

Insert microSD in the MKR MEM shield card holder and put it on the MKR Connector Carrier.

The antenna, the SIM and the battery pack should be connected to their own connector on the head and the tail of the MKR GSM 1400.

Then connect the Grove Relay to the MKR Connector Carrier at D2 header.

The LiPo battery is optional, but it allows to cope with the peaks of current that the GSM module might require in particular conditions of poor coverage.

Component connected

How It Works

This project uses the MKRGSM library to manage the incoming calls and SMS messages.

When a call is received, the Arduino code catches the number and hangs the call. So the calling number is checked to find out if it's an authorized number. If it's authorized, the digital port 2 (D2) is turned ON for one second in order to activate the relay. The authorized numbers list is loaded from the numbers.txt file (located in the microSD card) on Arduino startup or when a new number is added to the list.

When an SMS is received, if the sender is the admin and the message respects this format

SET<+XXXXXXXXXXX>
, the sent number is added to the numbers.txt file (stored in the microSD).

For security reasons, the sketch checks the number of the admin and this information must be stored in the arduino_secrets.h file.

The Sketch

The first code section is used to include the libraries required by the application;

MKRGSM.h
include all the GSM connection functionalities, these are available through the object
GSMClient
and
GSM.

SD include all the SD read and write functionalities.

arduino_secrets.h
contains the sensitive data as SIM PIN and the Admin phone number

1// Include the GSM an SD library
2#include <MKRGSM.h>
3#include <SPI.h>
4#include <SD.h>
5// Include file with your sensitive data
6#include "arduino_secrets.h"
7// Max stored numbers
8#define MAX_NUMBERS 5
9// Relay pin number
10#define GATE_PIN 2

Create and initialize the objects (GSM and SD) and variables

1// Initialize the library instance
2GSM gsmAccess;
3GSMVoiceCall vcs;
4GSM_SMS sms;
5// File object
6File myFile;
7// Pin number and Admin phone number from external file
8const char PINNUMBER[] = SECRET_PINNUMBER;
9String adminphone = SECRET_ADMINNUMBER;
10// Array to hold the phone number for the incoming sms and call
11char callnumber[20];
12char smsnumber[20];
13// phone numbers array
14String numbers[MAX_NUMBERS];
15int numberindex = 0;

Setup function, get the phone number list from numbers.txt and connect to the GSM network.

1void setup() {
2 // initialize serial communications and wait for port to open
3 Serial.begin(9600);
4 // USE ONLY WITH A COMPUTER CONNECTED AND SERIAL MONITOR OPENED
5 while (!Serial) {
6 ; // wait for serial port to connect. Needed for native USB port only
7 }
8 // set up the pin as output and put it down
9 pinMode(GATE_PIN, OUTPUT);
10 digitalWrite(GATE_PIN, LOW);
11 Serial.println("GSM Open Gate Sketch starting...");
12 // Init SD card
13 if (!SD.begin(4)) {
14 Serial.println("initialization failed!");
15 return;
16 }
17 // retrieve number from file stored in SD
18 myFile = SD.open("numbers.txt");
19 if (myFile) {
20 // read from the file until there's nothing else in it
21 while (myFile.available()) {
22 // read a line and delete \r\n
23 String reading = myFile.readStringUntil('\n');
24 reading.trim();
25 // add to numbers array
26 if (numberindex < MAX_NUMBERS) {
27 numbers[numberindex] = reading;
28 numberindex++;
29 }
30 }
31 // print the numbers
32 if (numberindex > 0) {
33 for (int i = 0; i < MAX_NUMBERS; i++) {
34 Serial.print(i);
35 Serial.print(" - ");
36 Serial.println(numbers[i]);
37 }
38 }
39 numberindex = 0;
40 // close the file:
41 myFile.close();
42 } else {
43 // if the file didn't open, print an error:
44 Serial.println("error opening test.txt");
45 }
46 // connection state
47 bool connected = false;
48 // Init GSM shield
49 while (!connected) {
50 if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
51 connected = true;
52 } else {
53 Serial.println("Not connected");
54 delay(1000);
55 }
56 }
57 // This makes sure the modem correctly reports incoming events
58 vcs.hangCall();
59 Serial.println("Waiting for a call");
60}

Loop function contains two main blocks. The first one takes care of the incoming call and catches the phone number. The second one is triggered when an SMS is received and then it extracts the message.

1void loop() {
2 // Check the status of the voice call
3 switch (vcs.getvoiceCallStatus()) {
4 case IDLE_CALL:
5 // Nothing is happening
6 break;
7 case RECEIVINGCALL:
8 //Someone is calling us
9 Serial.println("RECEIVING CALL");
10 // Retrieve the calling number
11 vcs.retrieveCallingNumber(callnumber, 20);
12 // Check if it's the adminphone
13 if (adminphone.equals(callnumber)) {
14 Serial.println("Admin phone, open gate!");
15 // open the gate and after 1 second close it
16 digitalWrite(GATE_PIN, HIGH);
17 delay(1000);
18 digitalWrite(GATE_PIN, LOW);
19 }
20 // Check if it's an authorized number
21 else {
22 for (int i = 0; i < MAX_NUMBERS; i++) {
23 if (numbers[i].equals(callnumber)) {
24 Serial.println("Authorized, open gate!");
25 // open the gate and after 1 second close it
26 digitalWrite(GATE_PIN, HIGH);
27 delay(1000);
28 digitalWrite(GATE_PIN, LOW);
29 break;
30 }
31 }
32 }
33 // Put down the call
34 vcs.hangCall();
35 break;
36 case TALKING:
37 // In this case the call would be established
38 // Nothing to do here
39 break;
40 }
41 // Check if there are any SMSs available
42 if (sms.available()) {
43 Serial.println("Message received from:");
44 // Get remote number
45 sms.remoteNumber(smsnumber, 20);
46 Serial.println(smsnumber);
47 // Read message bytes, save and print them
48 int c;
49 String smsmessage = "";
50 while ((c = sms.read()) != -1) {
51 // Serial.print((char)c);
52 smsmessage += (char)c;
53 }
54 // Only the admin can edit the number list
55 // example sms => SET <+00123456789>
56 if (adminphone.equals(smsnumber)) {
57 // Check the command
58 if (smsmessage.indexOf("SET") > -1) {
59 // Check for a phone number and add to the stored file
60 int startindex = smsmessage.indexOf("<");
61 int endindex = smsmessage.indexOf(">");
62 String newnumber = smsmessage.substring(startindex + 1, endindex);
63 myFile = SD.open("numbers.txt", FILE_WRITE);
64 if (myFile) {
65 Serial.print("Number to add: ");
66 Serial.println(newnumber);
67 // write number in the file
68 myFile.println(newnumber);
69 // close the file:
70 myFile.close();
71 Serial.println("saved.");
72 // add to the local numbers list
73 if (numberindex < MAX_NUMBERS) {
74 newnumber.trim();
75 numbers[numberindex] = newnumber;
76 numberindex++;
77 }
78 else {
79 Serial.println("Too many saved numbers!");
80 }
81 } else {
82 // if the file didn't open, print an error:
83 Serial.println("error opening numbers.txt");
84 }
85 }
86 }
87 Serial.println("\nEND OF MESSAGE");
88 // Delete message from modem memory
89 sms.flush();
90 Serial.println("MESSAGE DELETED");
91 }
92 delay(1000);
93}

How to Use It

Be sure to have a numbers.txt file stored in the microSD. It can be blank or formatted in this way:

1+00XXXXXXXXXX
2+00XXXXXXXXXX
3+00XXXXXXXXXX

It's important to have a newline after the last number.

Double check that your phone number is properly stored in the

arduino_secrets.h
file, then upload the sketch and open the Serial Monitor to verify that the module properly connects to the network.

Now you are able to call or send SMS to the Arduino.

Complete Sketch

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.