Cancellino
Control everything with a SINGLE phone call.
Components and Supplies
- Arduino MKR GSM 1400
- Arduino MKR MEM Shield
- Arduino MKR Connector Carrier (Grove compatible)
- Seeed Grove - Relay
- Samsung Generic MicroSD
- Li-Ion Battery 1000mAh
- USB-A to Micro-USB Cable
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
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.
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 number1// Include the GSM an SD library2#include <MKRGSM.h>3#include <SPI.h>4#include <SD.h>5// Include file with your sensitive data6#include "arduino_secrets.h"7// Max stored numbers8#define MAX_NUMBERS 59// Relay pin number10#define GATE_PIN 2
Create and initialize the objects (GSM and SD) and variables
1// Initialize the library instance2GSM gsmAccess;3GSMVoiceCall vcs;4GSM_SMS sms;5// File object6File myFile;7// Pin number and Admin phone number from external file8const char PINNUMBER[] = SECRET_PINNUMBER;9String adminphone = SECRET_ADMINNUMBER;10// Array to hold the phone number for the incoming sms and call11char callnumber[20];12char smsnumber[20];13// phone numbers array14String 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 open3 Serial.begin(9600);4 // USE ONLY WITH A COMPUTER CONNECTED AND SERIAL MONITOR OPENED5 while (!Serial) {6 ; // wait for serial port to connect. Needed for native USB port only7 }8 // set up the pin as output and put it down9 pinMode(GATE_PIN, OUTPUT);10 digitalWrite(GATE_PIN, LOW);11 Serial.println("GSM Open Gate Sketch starting...");12 // Init SD card13 if (!SD.begin(4)) {14 Serial.println("initialization failed!");15 return;16 }17 // retrieve number from file stored in SD18 myFile = SD.open("numbers.txt");19 if (myFile) {20 // read from the file until there's nothing else in it21 while (myFile.available()) {22 // read a line and delete \r\n23 String reading = myFile.readStringUntil('\n');24 reading.trim();25 // add to numbers array26 if (numberindex < MAX_NUMBERS) {27 numbers[numberindex] = reading;28 numberindex++;29 }30 }31 // print the numbers32 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 state47 bool connected = false;48 // Init GSM shield49 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 events58 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 call3 switch (vcs.getvoiceCallStatus()) {4 case IDLE_CALL:5 // Nothing is happening6 break;7 case RECEIVINGCALL:8 //Someone is calling us9 Serial.println("RECEIVING CALL");10 // Retrieve the calling number11 vcs.retrieveCallingNumber(callnumber, 20);12 // Check if it's the adminphone13 if (adminphone.equals(callnumber)) {14 Serial.println("Admin phone, open gate!");15 // open the gate and after 1 second close it16 digitalWrite(GATE_PIN, HIGH);17 delay(1000);18 digitalWrite(GATE_PIN, LOW);19 }20 // Check if it's an authorized number21 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 it26 digitalWrite(GATE_PIN, HIGH);27 delay(1000);28 digitalWrite(GATE_PIN, LOW);29 break;30 }31 }32 }33 // Put down the call34 vcs.hangCall();35 break;36 case TALKING:37 // In this case the call would be established38 // Nothing to do here39 break;40 }41 // Check if there are any SMSs available42 if (sms.available()) {43 Serial.println("Message received from:");44 // Get remote number45 sms.remoteNumber(smsnumber, 20);46 Serial.println(smsnumber);47 // Read message bytes, save and print them48 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 list55 // example sms => SET <+00123456789>56 if (adminphone.equals(smsnumber)) {57 // Check the command58 if (smsmessage.indexOf("SET") > -1) {59 // Check for a phone number and add to the stored file60 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 file68 myFile.println(newnumber);69 // close the file:70 myFile.close();71 Serial.println("saved.");72 // add to the local numbers list73 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 memory89 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+00XXXXXXXXXX2+00XXXXXXXXXX3+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.