Remotely Play MP3 with Twilio, Go and Arduino MKR GSM 1400

Remotely Play MP3 with Twilio, Go and Arduino MKR GSM 1400 © MIT

How to play an MP3 file with Twilio Programmable Wireless, Go and the Arduino MKR GSM 1400.

  • 858 views
  • 0 comments
  • 5 respects

Components and supplies

Apps and online services

About this project

The new MKR family of Arduino boards are going to change the landscape of rapid prototyping IoT solutions. The Arduino MKR GSM 1400 is a great solution for anyone looking to expand the scope of their IoT projects using cellular connectivity. By integrating a modem with a microcontroller a new all-in-one communication solution has started to emerge. This paired with the Twilio Programmable Wireless SIM makes it possible to communicate around the globe using machine to machine commands. “Things” can now be connected in ways previously impossible with WiFi or Bluetooth.

This tutorial demonstrates how to send a machine to machine command from the Arduino MKR GSM 1400 to a server written in Go. When the machine to machine command is received server-side an audio file will play a .mp3 saying “hello." If you want to jump ahead the completed project can be found on the TwilioIoT GitHub.

What is the Arduino MKR GSM 1400?

The Arduino MKR GSM 1400 is a development board that combines the functionality of the Arduino Zero with global GSM connectivity using the u-blox SARAU201 modem. Traditionally communicating with a modem is done using AT commands using a separate module. This model board ships with a library that makes AT commands more accessible via function calls.

Hardware Requirements

Software Requirements

Setting up the Twilio SIM

Remove the Twilio SIM from it’s packaging. Next register and activate your SIM in the Twilio Console.

Software side of things

Before programming the hardware we need to install a few pieces of software to make it work. To be able to send M2M commands using the on-board modem we will need the MKRGSM library.

Open the Arduino IDE and go to Sketch > Manage Libraries. This is where Arduino and 3rd party libraries can be installed into the Arduino IDE.

When the Library Manager window pops up search for the MKRGSM library and press install. The MKRGSM library wraps AT commands into functions, making it easier to communicate with the modem. It’s phonetabulous trust me.

After the library is installed we need to install the Arduino MKR GSM 1400 board cores. The Arduino MKR GSM 1400 uses a different chipset than traditional Arduinos that use AVR ATmega chipsets. This board uses the SAMD21 Cortex-M0+ and it requires a different set of cores. The cores do not come with the Arduino IDE and they are needed for the computer to recognize the board when connected.

Locate the Board Manager under Tools > Board > Board Manager.

When the Board Manager window appears search for the Arduino SAMD Boards and install the cores.  

Restart the Arduino IDE to complete the installation.

Great! Time to move on to the hardware setup.

Hardware side of things

To send M2M commands over the network we need to install the Twilio SIM. Break out the Micro SIM from the Twilio SIM card

Insert the Twilio SIM into the SIM slot underneath the board.

Next, attach the GSM antenna to the board.

Connect the board to the computer using a Micro-USB cable and you are geared up to connect to the network.

Creating the Arduino sketch

In the Arduino IDE create a new Arduino sketch (File > New). A template is provided that look something like this.

void setup(){
}
void loop(){
}

Instantiate the base class GSM for all of the GSM functions. To send and receive SMS messages the GSM SMS class needs to be instantiated as well. This happens before the setup() function.

#include <MKRGSM.h>
GSM gsmAccess;
GSM_SMS sms;

In the setup() function create a serial connection with a baud rate of 115200. The baud rate determines the speed of data over a specific communication channel.

Serial.begin(115200);

Use the gsmAccess.begin() function to connect to the cellular network that is identified on the Twilio SIM.

gsmAccess.begin();
Serial.println("GSM initialized");

In the loop() function define the phone number where the M2M command will be sent using the beginSMS function. The number we will use is “2936”. This is a special Twilio shortcode that is reserved for exchanging M2M commands between Twilio SIMs. It uses the SMS transport to send M2M commands over a cellular network. When a Twilio SIM creates a M2M command a Webhook is generated, we will discuss this shortly.

sms.beginSMS("2936");

Pass a char array to the function sms.print() to create a new message to be queued.

sms.print("hello world");
Serial.println(“Sending M2M Command”);

After a message is created and queued use the endSMS() function to tell the modem the process is complete. Once this happens the “hello world” message will then be sent.

sms.endSMS();
Serial.println("M2M Command Sent!");

The last bit of code is a while loop that will capture the program and place it in an infinite loop. The purpose of this is to ensure the M2M command is only sent once.

while(1) {
    delay(4000);
}

Complete Arduino sketch:

#include <MKRGSM.h>
GSM gsmAccess;
GSM_SMS sms;
void setup(){
    Serial.begin(115200);
    gsmAccess.begin();
    Serial.println("GSM initialized");
}
void loop(){
    sms.beginSMS("2936");
        sms.print("hello world");
        Serial.println(“Sending M2M Command”);
       sms.endSMS();
       Serial.println("M2M Command Sent!");
       while(1) {
               delay(4000);
       }  
}

Double check that the board has been selected under Tools > Board. If it is not selected the compiler will throw an error when you try to upload the code.

Save the new sketch as "SayHelloArduinoGSM.ino". Before uploading the new sketch to the board let’s create a server to receive the M2M command using Go.

Spinning up an audio response server with Go and Beep

Create a new Go program named “SayHelloArduinoGSM.go” using the template below.

package main
import ( 
)
func main(){
}

Next add the following libraries to the import section. This is where you link external libraries like Beep to a Go program. If you haven't installed Go yet do so now using Homebrew

package main
import (
        "fmt"
    "github.com/faiface/beep"
    "github.com/faiface/beep/mp3"
    "github.com/faiface/beep/speaker"
    "log"
    "net/http"
    "os"
    "time"
)

Inside the main function create a new server route using HandleFunc() from the net/http library. This will generate a new server-side route (“/helloworld”) for receiving M2M commands from the “2936” shortcode. When an M2M command is received it will then be funneled to the helloworld function. Open up a port and listen for incoming connections using the ListenAndServe() function on port 9999.

func main(){
    http.HandleFunc("/helloworld", helloworld)
    http.ListenAndServe(":9999", nil)
}

Fantastic. Now we have to create the helloworld function. The HTTP request received by this function will be represented by the http.Request type.

func helloworld(w http.ResponseWriter, r *http.Request) {
}

When the request is received the M2M command needs to be parsed. Use the ParseForm() function to parse the request body as a form.

 if err := r.ParseForm(); err != nil {
        log.Printf("Error parsing form: %s", err)
        return
    }

The data from the body can be extracted using the PostFormValue() function by passing it a key. The key will give you the value associated with the named component in the JSON response. In this case we are looking for the value of the “Command” key.

 pwCommand := r.PostFormValue("Command")
    fmt.Println("pwCommand : ", pwCommand)

And to add a little spice let’s at some Beep code to play an audio file through your system’s audio when the command successfully reaches the server.

 f, err := os.Open("helloworld.mp3")
    if err != nil {
        log.Fatal(err)
    }
    s, format, _ := mp3.Decode(f)
    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
    playing := make(chan struct{})
    speaker.Play(beep.Seq(s, beep.Callback(func() {
        close(playing)
    })))
    <-playing

Complete Go program:

package main
import (
    "fmt"
    "log"
    "net/http"
    "os"
    "time"
    "github.com/faiface/beep"
    "github.com/faiface/beep/mp3"
    "github.com/faiface/beep/speaker"
)
func main() {
    http.HandleFunc("/helloworld", helloworld)
    http.ListenAndServe(":9999", nil)
}
func helloworld(w http.ResponseWriter, r *http.Request) {
    if err := r.ParseForm(); err != nil {
        log.Printf("Error parsing form: %s", err)
        return
    }
    pwCommand := r.PostFormValue("Command")
    fmt.Println("incoming Command from Arduino MKR GSM 1400 : ", pwCommand)
    fmt.Println("Playing audio file!")
    f, err := os.Open("helloworld.mp3")
    if err != nil {
        log.Fatal(err)
    }
    s, format, _ := mp3.Decode(f)
    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
    playing := make(chan struct{})
    speaker.Play(beep.Seq(s, beep.Callback(func() {
        close(playing)
    })))
    <-playing
}

Start the server.

go run SayHelloArduinoGSM.go

Constructing the bridge with ngrok

Currently the hardware and software pieces exist individually. ngrok will be used to bridge the gap.

When the SIM sends a M2M command to Twilio a Webhook is sent to a user-defined url called the Commands Callback Url. We will use ngrok to receive this Webhook and then route it to the server running on our own machine. To make the connection, start a new ngrok instance on the same port where the server is running.

ngrok http 9999

Copy the Forwarding url that was created with ngrok (http://xxxxxxxx.ngrok.io)

Navigate to Programmable Wireless in the Twilio console. Locate the SIM that you previously registered under SIMs. Under the Configure tab you will find the Commands Callback Url. Paste the ngrok Forwarding address into text box and add the previously created server route to the end of the url.

http://xxxxxxxx.ngrok.io/helloworld 

Press Save.

Send messages through the sky

Go back to the Arduino IDE and press upload.

Once uploaded, double check to see if the command was sent properly using the Serial Monitor.

  • Navigate to Tools > Serial Monitor

Once the M2M command is sent from the “2936” shortcode it is then routed to ngrok and onto the go application using the Commands Callback Url.

And finally the M2M command reaches the server and the “helloworld.mp3”

Celltactular!

Continue to connect things

You just sent your first M2M command using magic.

This M2M command model is a foundational piece of how to use Twilio to send M2M commands from a remote hardware device. With the integrated modem and software for sending AT commands as functions, it makes the Arduino MKR GSM 1400 an ideal piece for any IoT prototyping kit.

If you are interested in learning about other pieces of hardware that can send M2M commands check out the Wireless Machine to Machine Quickstarts. This project, along with other projects, can be found on the TwilioIoT GitHub.

Feel free to reach out with any questions or curiousity. If you have any cool IoT projects you have built or are planning on building drop me a line.

Authors

Please enable JavaScript to view the

Comments powered by Disqus.

Code

Code snippet #1Plain text
void setup(){

}

void loop(){

}
Code snippet #9Plain text
#include <MKRGSM.h>

GSM gsmAccess;
GSM_SMS sms;

void setup(){
    Serial.begin(115200);

    gsmAccess.begin();
    Serial.println("GSM initialized");
}

void loop(){
    sms.beginSMS("2936");

        sms.print("hello world");
        Serial.println(“Sending M2M Command”);

       sms.endSMS();
       Serial.println("M2M Command Sent!");

       while(1) {
               delay(4000);
       }  
}
Code snippet #10Plain text
package main

import ( 

)

func main(){
}
Code snippet #11Plain text
package main

import (
        "fmt"
    "github.com/faiface/beep"
    "github.com/faiface/beep/mp3"
    "github.com/faiface/beep/speaker"
    "log"
    "net/http"
    "os"
    "time"
)
Code snippet #16Plain text
    f, err := os.Open("helloworld.mp3")
    if err != nil {
        log.Fatal(err)
    }
    s, format, _ := mp3.Decode(f)
    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
    playing := make(chan struct{})
    speaker.Play(beep.Seq(s, beep.Callback(func() {
        close(playing)
    })))
    <-playing
Code snippet #17Plain text
package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
    "time"

    "github.com/faiface/beep"
    "github.com/faiface/beep/mp3"
    "github.com/faiface/beep/speaker"
)

func main() {
    http.HandleFunc("/helloworld", helloworld)
    http.ListenAndServe(":9999", nil)
}

func helloworld(w http.ResponseWriter, r *http.Request) {
    if err := r.ParseForm(); err != nil {
        log.Printf("Error parsing form: %s", err)
        return
    }

    pwCommand := r.PostFormValue("Command")
    fmt.Println("incoming Command from Arduino MKR GSM 1400 : ", pwCommand)

    fmt.Println("Playing audio file!")
    f, err := os.Open("helloworld.mp3")
    if err != nil {
        log.Fatal(err)
    }
    s, format, _ := mp3.Decode(f)
    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
    playing := make(chan struct{})
    speaker.Play(beep.Seq(s, beep.Callback(func() {
        close(playing)
    })))
    <-playing
}
Github
https://github.com/faiface/beep
Github
https://github.com/arduino-libraries/MKRGSM
Gist
https://gist.github.com/cskonopka/fc82bbf81a47e901011a4281402178ea
Github
https://github.com/cskonopka/TwilioIoT

Schematics

Arduino MKR GSM 1400 setup
Arduinogsm full km6osdloap

Comments

Similar projects you might like

Arduino MKR GSM 1400 and DTMF

by Arduino_Genuino

  • 17,394 views
  • 0 comments
  • 29 respects

Publish Any Event to Wia Using Your MKR GSM 1400

Project tutorial by Spivey

  • 1,000 views
  • 0 comments
  • 2 respects

MKR GSM 1400 Send Sensor Data to ThingSpeak via JSON

Project tutorial by smgs

  • 1,488 views
  • 0 comments
  • 2 respects

Arduino MKR DIN Rail Mount

Project showcase by hwhardsoft

  • 2,288 views
  • 0 comments
  • 7 respects

GSM based Home Automation

Project tutorial by Team Brink.IO

  • 18,691 views
  • 45 comments
  • 39 respects

Program MKR Over-the-Air + Goodies: Voice Control, etc.

Project tutorial by Flower Platform

  • 10,230 views
  • 7 comments
  • 37 respects
Add projectSign up / Login