Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / IoT

Send SMS Messages Using Twilio and Arduino on Intel® Edison

5.00/5 (1 vote)
12 Aug 2015CPOL7 min read 12.3K  
In this article, we’ll talk about sending SMS messages to your phone from Twilio phone numbers.

This article is for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers

Get access to the new Intel® IoT Developer Kit, a complete hardware and software solution that allows developers to create exciting new solutions with the Intel® Galileo and Intel® Edison boards. Visit the Intel® Developer Zone for IoT.

Introduction

Intel® Edison is the world’s smallest and most low-power computing platform that was designed for wearable technology such as Internet of Things. It is an Arduino* certified development and prototyping board. The Arduino sketch on Intel® Edison is a C++ program. The sensor technology provides real-time continuous measurements of biometric data with a high degree of accuracy and consistency. You can use the Intel® Edison to read sensors and control many things from inside to outside of your home. This document shows an example of reading the temperature sensor and send SMS messages to your phone using a Twilio* account.

Twilio allows software developers to programmatically receive SMS and MMS messages to your Twilio phone numbers and reply back with SMS and MMS messages. You can send SMS MMS messages using Twilio’s REST API, track SMS conversations and send SMS messages during phone calls. In this article, we’ll talk about sending SMS messages to your phone from Twilio phone numbers.

Contents

Hardware Components

The hardware components used in this SMS message project are listed below:

For detailed assembly and powering the Intel® Edison board, visit https://software.intel.com/en-us/assembling-intel-edison-board-with-arduino-expansion-board.

Image 1

Figure 1: Hardware Diagram

Development Board Download

Go to Intel® Edison Board Software Downloads to download the latest drivers, installers, firmware images, and Arduino IDE: https://software.intel.com/en-us/iot/hardware/edison/downloads

Downloading and Installing Twilio Library

Download Twilio C++ from https://github.com/laurentluce/twilio-cplusplus and unzip to the Arduino IDE libraries C:\Arduino\arduino-1.5.3-Intel.1.0.4\libraries. Arduino does not allow ‘-‘ in the library name, be sure to rename twilio-cplusplus to Twilio.

Image 2

Figure 2: Twilio Library

Change into the Twilio directory and rename Example.cpp to Example.cpp.org so the Example.cpp won’t invoke every time we use the Twilio library. Edit Utils.h as follow:

C++
#include <string.h>
#include <vector>

using namespace std;
Code Example 1: Utils.h

Assessing USB Mass Storage Partition from Edison

The Multifunction Composite Gadget (g_multi) is a composite gadget that makes extensive use of the composite framework to provide a multifunction gadget. It provides configuration with USB mass storage functions, Ethernet (RNDIS and/or CDC Ethernet), and ACM serial link interfaces. To manually load or remove kernel modules, we use the module command modprobe. We remove the g_multi module to disable the USB mass storage device from the Edison:

Image 3

Figure 3: From Edison - modprobe

Create a mount directory:

Image 4

Figure 4: From Edison – Mount directory

Use losetup to map the partition label "update" disk image file to a loopback device (/dev/loop0) with offset 8192. The example below mounts the loopback device as /mnt/transfer.

Image 5

Figure 5: From Edison – Mount the Device

Assessing USB Mass Storage Device from a Computer

Press the reset button and the USB mass storage will be shown in Windows Explorer as below:

Image 6

Figure 6: USB Mass Storage Device

Un-mount and add the g_multi module back:

Image 7

Figure 7: Un-mount the Device

Installing Curl and Crypto Libraries

See Assessing USB Mass Storage Partition from Edison to copy libcurl and its dependencies from Edison /usr/lib to the Arduino IDE installation root hardware\tools\edison\sysroots\core2-32-poky-linux\usr\lib:

  • libcurl.so
  • libtasn1.so.6
  • libgcrypt.so.11
  • libgnutls.so.26
  • libgpg-error.so.0

Image 8

Figure 8: From Edison – Curl and other Libraries

Image 9

Figure 9: To Windows - Curl and other Libraries

Similarly, use Assessing USB Mass Storage Partition from Edison to copy the libraries below from Edison /lib to the Arduino IDE installation root hardware\tools\edison\sysroots\core2-32-poky-linux\lib:

  • libz.so.1
  • libcap.so.2
  • libcrypto.so

Image 10

Figure 10: From Edison - Crypto and other Libraries

Image 11

Figure 11: To Windows - Crypto Libraries and other Libraries

Installing the Curl Header Files

The Curl header files should be installed into the Arduino IDE installation root hardware\tools\edison\sysroots\core2-32-poky-linux\usr\include, which looks like this:

Image 12

Figure 12: Curl Header Files

The openssl header files should be installed into the Arduino IDE installation root hardware\tools\edison\sysroots\core2-32-poky-linux\usr\include as follow:

Image 13

Figure 13: Openssl Header Files

Modifying the Compile Patterns

There are platform.*.txt files in the hardware\arduino\edison file path within the Arduino IDE installation root. Edit the file platform name that matches your build platform. If you are running the Arduino IDE for Edison on a Microsoft* Windows* system, edit platform.win.txt.

Image 14

Figure 14: platform.win.txt for Windows

To tell the linker to add libcurl and libcrypto to the list of libraries when linking the executable, add –lcurl and –lcrypto to the end of the line "recipe.c.combine.pattern".Ensure that you do not add any line breaks.

C++
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -march={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm -lpthread -lcurl –lcrypto
Figure 15: platform.win.txt – Dynamic Linking

Creating a Twilio Account

To receive SMS and MMS messages, you need an SMS-enabled Twilio phone number. To get your own dedicated phone number, sign up for a Twilio trial account. Once SMS-enabled Twilio access is successfully granted, go to "Hide API Credentials" to find your Account SID and Auth Token:

C++
// Twilio REST API version
const char API_VERSION[] = "2010-04-01";

// SMS-enabled Twilio phone number
const char CALLER_ID[] = "1480405xxxx";

// Twilio Account SID and Auth token
const char ACCOUNT_SID[] = "AC9c55339a5a070ae81e782117xxxxxxxx";
const char ACCOUNT_TOKEN[] = "59e8819f3f5b530b97b84baexxxxxxxx";
Code Example 2: Twilio Phone Number, Account SID and Auth Token Example

POST Call to Twilio

To send an SMS message, we make a POST request with URL "/SMS/Messages" to Twilio and fill out the "To", "From", and "Body". The "To" is your cell phone, the "From" is the SMS-enabled Twilio phone number, and the "body" is the SMS message being sent.

C++
// URL path = /API_VERSION/Accounts/ACCOUNT_SID/SMS/Messages
char postReqStr[150];
strcpy(postReqStr, twilioAcc);
strcat(postReqStr, "/SMS/Messages");
Serial.println(postReqStr);

// Send SMS
vars.clear();
vars.push_back(Var("To", "480-xxx-xxxx"));
vars.push_back(Var("From", "480-405-xxxx"));
vars.push_back(Var("Body", smsStr));
string response = twilioRest.request(postReqStr, "POST", vars);
Code Example 3: Send "/SMS/Messages" Example

Temperature Sensor

Now that you have access and can receive and post SMS messages, you can also create a temperature sensor reading function. A temperature sensor is used to measure the current temperature using an analog input. To learn more about the temperature sensor function, please see the data sheet http://www.seeedstudio.com/wiki/images/a/a1/NCP18WF104F03RC.pdf. An example of how to read the temperature from a sensor and return the data is below:

C++
// Connect temperature sensor to Analog pin 1
const int tempSensorPin = 1;

// Temperatuere in Fahrenheit
float degF = 0;

// This function reads the analog pin value, converts to Fahrenheit, then
// returns current temperature in Fahrenheit.
float getTemperature()
{
    int analogValue = analogRead(tempSensorPin);
  
    //Get the resistance of the sensor;
    float resistance = (float)(1023 - analogValue) * 10000/analogValue;
 
    //Convert to temperature via datasheet; 
    float degKelvin = 1/(log(resistance/10000)/B_THERMISTOR + 1/298.15);
  
    // Convert Kelvin to Celcius
    float degC = degKelvin - 273.15;
  
    // Celcius to Fahrenheit
    degF = (degC * 9.0) / 5.0 + 32.0;
        
    return degF;
}
Code Example 4: Sending SMS When Temperature Reaches Threshold

Example Sketch

Following is a complete example of sending an SMS to your cell phone when the temperature reaches a threshold of 100o Fahrenheit. The output is printed to the Arduino IDE for Galileo’s serial console.

C++
#include "WString.h"
#include <Utils.h>
#include <Rest.h>
#include <TwiML.h>
#include <vector>
#include <math.h>

using namespace twilio;

vector<Var> vars;

// Twilio REST API version
const char API_VERSION[] = "2010-04-01";

// SMS-enabled Twilio phone number
const char CALLER_ID[] = "1480405xxxx";

// Twilio Account SID and Auth token
const char ACCOUNT_SID[] = " AC9c55339a5a070ae81e782117xxxxxxxx ";
const char ACCOUNT_TOKEN[] = "59e8819f3f5b530b97b84baexxxxxxxx ";

// Response from Twilio
const char* responseStr;

// Temperature sensor variables in Fahrenheit
const int THRESHOLD_TEMP = 100;
const int WAIT = 1000000;

// B value of the thermistor
const int B_THERMISTOR = 3975;                  

int analogValue = 0;
float degKelvin = 0;
float degC = 0;
float degF = 0;
float resistance = 0;

// Connect temperature sensor to Analog pin 1
const int tempSensorPin = 1;

// This function initializes the serial debug interface.
void setup() {
    Serial.begin(9600);  
}

// This function builds: 
//     - The SMS message being sent
//     - URL path
//     - Send SMS message to your cell phone from SMS-enabled phone
// Input: float tempF - current temperature in Fahrenheit
void sendSMS( float tempF ) { 
 
    // Convert tempF to string
    char degFstr[20];
    sprintf(degFstr, "%2f", degF);
    
    // Convert THRESHOLD_TEMP to string
    char thresholdStr[20];
    sprintf(thresholdStr, "%d", THRESHOLD_TEMP);
    
    // Build the SMS message
    char smsStr[100] = "Current temperature is ";
    strcat(smsStr, degFstr);
    strcat(smsStr, " F greater than threshold temp ");
    strcat(smsStr, thresholdStr);
    strcat(smsStr, " F.");
        
    // Twilio Account = /API_VERSION/Accounts/ACCOUNT_SID
    char twilioAcc[70] = "/";
    strcat(twilioAcc, API_VERSION);
    strcat(twilioAcc, "/Accounts/");
    strcat(twilioAcc, ACCOUNT_SID);
    
    // URL path = /API_VERSION/Accounts/ACCOUNT_SID//SMS/Messages
    char postReqStr[150];
    strcpy(postReqStr, twilioAcc);
    strcat(postReqStr, "/SMS/Messages");
    Serial.println(postReqStr); 
   
    // Twilio REST
    Rest rest(ACCOUNT_SID, ACCOUNT_TOKEN);
    
    // Send SMS
    vars.clear();
    vars.push_back(Var("To", "480-xxx-xxxx"));
    vars.push_back(Var("From", "480-405-xxxx"));
    vars.push_back(Var("Body", smsStr));
    string response = twilioRest.request(postReqStr, "POST", vars);
}

// This function read the analog pin value, converts to Fahrenheit, then
// returns current temperature in Fahrenheit.
float getTemperature()
{
    analogValue = analogRead(tempSensorPin);
  
    //Get the resistance of the sensor;
    resistance = (float)(1023 - analogValue) * 10000/analogValue;
 
    //Convert to temperature via datasheet; 
    degKelvin = 1/(log(resistance/10000)/B_THERMISTOR + 1/298.15);
  
    // Convert Kelvin to Celcius
    degC = degKelvin - 273.15;
  
    // Celcius to Fahrenheit
    degF = (degC * 9.0) / 5.0 + 32.0;
        
    return degF;
}

// The main loop read the current temperature using the temperature sensor. If the current temperature is greater than the threshold value, send a SMS message.
void loop() { 
    degF = getTemperature();
    if(degF > THRESHOLD_TEMP)
    {
        sendSMS(degF);
        delay(WAIT);
    }
}
Code Example 5: Sending SMS Using Twilio Complete Example

Summary

In this article, we have experimented with the temperature sensor and sent SMS messages using a Twilio account. Try out different sensors in the Grove starter kit plus and challenge yourself with more sensors in https://software.intel.com/en-us/iot/hardware/sensors. I hope this article inspired you to conduct an interesting experiment with the Intel® Edison platform.

References

https://software.intel.com/en-us/iot/hardware/edison/downloads

https://www-ssl.intel.com/content/www/us/en/do-it-yourself/edison.html

https://software.intel.com/en-us/iot/hardware/edison

https://software.intel.com/en-us/iot/library/edison-getting-started

https://software.intel.com/en-us/iot/hardware/devkit

http://www.seeedstudio.com/wiki/images/a/a1/NCP18WF104F03RC.pdf.

About the Author

Nancy Le is a software engineer at Intel Corporation in the Software and Services Group working on the Intel® AtomTM processor scale enabling projects.

Intel® Developer Zone for IoT

Start inventing today with the Intel® IoT Developer Program which offers knowledge, tools, kits and a community of experts to quickly and easily turn your innovative ideas into IoT Solutions.

Dream it, Build it with the Intel® IoT Developer Kit for Intel® Edison and Intel® Galileo platforms. These kits are versatile, performance-optimized and fully integrated end-to-end IoT solutions supporting a variety of programming environments, tools, security, cloud connectivity and hardware.

For more resources and to learn how the new Intel® IoT Developer Kit v1.0 can help streamline your IoT projects:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)