Project tutorial
Cellular Wardriving and Other IoT Shenanigans

Cellular Wardriving and Other IoT Shenanigans © MIT

A guide for the Arduino MKR 1400 GSM workshop for IoTDevFest PHX 2019.

  • 20 respects

Components and supplies

Apps and online services

About this project

What are we doing?!

We're going to explore various uses of the Arduino MKR 1400 GSM for cellular projects! From wardriving for cell towers to connecting to IoT platforms!


  • Activate SIM card
  • Install Arduino IDE along with MKR 1400 board definition, MKRGSM and ArduinoMQTTClient libraries
  • Set up the Arduino MKR 1400
  • Test SMS and GPRS connections (to verify everyone is in a workable state)
  • Cellular wardriving example
  • Network hopping
  • Use MQTT over cellular to connect to an IoT platform

Hologram Network is a cellular network provider perfect for makers. At $0.60 /mo plus $0.40 per mb, you'll have plenty of data for most IoT projects. You can get a free SIM card by going to and then activate it at

We'll provide Free Credit codes, so you wont have to put in any billing information for this workshop!

Its important to do this part first so that your SIM has time to activate as we set up our coding environment.

Install Arduino IDE

Download the Arduino IDE at the following link. We will not be using the online code editor for this project.

Install MKR 1400 Board Definition

  • Open Arduino IDE
  • Go to Tools > Board > Boards Manager
  • Search MKR and an entry for "Arduino SAMD Boards" will show up, install that

Install Arduino Libraries

  • Open the Arduino IDE
  • Go to Sketch > Include Library > Manage Libraries
  • Search for MKRGSM and install it
  • Search for ArduinoMqttClient and install it

Connecting the Arduino MKR 1400

  • Insert the SIM card into the Arduino MKR 1400 as shown above
  • Attach the antenna
  • Plug in the battery (Needs to be at least 1500 maH)
  • Connect the USB cable
  • Open the Arduino IDE, select "Arduino MKR 1400" in Tools > Board
  • In Tools > Port select your board (it should be obvious which one to select)

GSM Network Jumper Example

This example demonstrates quickly jumping to different carriers on the fly. It scans and prints available carriers to the serial monitor and waits for user input.

The custom function "jumpCarrier" sends AT commands directly to the modem.

Available Commands:

"att" - AT&T 3G

"tmo2" - T-Mobile 2G

"tmo3" - T-Mobile 3G

Copy the code from the above link into a new sketch, upload, and open the Serial Monitor and give it a try!

A combination of this method and the Wardriving example could be used for some interesting network exploration shenanigans...

Test SMS

  • In Arduino, open Examples > MKRGSM > Receive SMS
  • Click upload!
  • Click the magnifying lens icon to open the Serial Monitor

  • Go back to and select your device
  • Click the "via SMS" tab under "Send a Message"
  • Type some arbitrary message and hit send!

You should see output in the Serial Monitor similar to this!

SMS Messages Receiver

GSM initialized

Waiting for messages

Message received from:


Hello World!




This code will simply attempt to connect to GSM and GPRS and confirm success or fail.

APN Information

When connecting to a GPRS network you typically need to include an Access Point Name and login credentials. In the case of the network you simply need to include "hologram" as the APN and leave login credentials blank!

  • In Arduino, click File > New
  • Paste in the code from below
  • Upload!
  • Open the Serial Monitor
#include <MKRGSM.h>
const char PINNUMBER[] = " ";
// APN data
const char GPRS_APN[] = "hologram";
const char GPRS_LOGIN[] = " ";
const char GPRS_PASSWORD[] = " ";
// initialize the library instance
GPRS gprs;
GSM gsmAccess;
void setup() {
 // initialize serial communications and wait for port to open:
 while (!Serial) {
   ; // wait for serial port to connect. Needed for native USB port only
 Serial.println("Starting Arduino web client.");
 // connection state
 boolean connected = false;
 // After starting the modem with GSM.begin()
 // attach to the GPRS network with the APN, login and password
 while (!connected) {
    Serial.println("Begin GSM Access");
   //Serial.println(gsmAccess.begin()); //Uncomment for testing
   if ((gsmAccess.begin() == GSM_READY) &&
     connected = true;
     Serial.println("GSM Access and GPRS Success");
   else {
     Serial.println("Not connected");
void loop() {

Output should look like this

Starting Arduino web client.

Begin GSM Access

GSM Access and GPRS Success


Ever been curious about the locations of cell towers and coverage?

There are plenty of awesome utilities and functions available in the MKRGSM Library (See Reference), we'll be using the Location and Scan Networks instances for this example. The expected output is triangulated GPS location along with any nearby carriers and their signal strength.

Example Output:

GSM networks scanner

Starting GSM location.

Modem IMEI: 357520074233053

> T-Mobile

> AT&T

Current carrier: 0041005400260054

Signal Strength: 13 [0-31]

Location: 38.0000000, -97.0000000

Altitude: 0m

Accuracy: +/- 4100000m

Connecting to MQTT

MQTT (Message Queuing Telemetry Transport) is probably the most commonly used messaging protocol for the Internet of Things. We're going to connect the Arduino MKR 1400 to an MQTT broker to create a very basic IoT application!

Thankfully, the MKRGSM library gives us a client object that is interchangeable with WiFi or Ethernet clients. Meaning we can just drop it into existing network libraries.

We'll be creating an MQTT connection to a public MQTT broker and using it to publish and subscribe to topics. The example sketch provided will print out incoming messages from the subscribed topic to the serial console. It will also periodically publish a sensor value to a separate topic.

We'll use to interact with the Arduino remotely! Chirpers is essentially a fork of node-red that runs entirely client-side in the browser and lets you interact with hardware and web services to build IoT applications visually!

Program the sketch!

The secrets file has all your credentials for GPRS, in this case we only need the APN which is already set to Hologram. We're going to add the MQTT server credentials next.


Port: 1883

topic: hologram-YOUR-NAME/to (this is for messages to your device)

publishTopic: hologram-YOUR-NAME/from (messages from your device)

Upload the code and open the Serial Monitor!


We don't need to create an account to use . Since it runs in your browser, it also saves everything in your local storage.

  • Go to
  • Drag in an inject node. This is basically a trigger to kick off a message. By default it outputs a timestamp.
  • Drag in an MQTT out node. This lets us publish messages. Connect the inject node to it.
  • Double click on the MQTT out node. Click the edit icon to add a new broker.

Broker Settings

Server: wss://

  • Click update
  • Add your hologram/to topic in the topic field.

  • Do the same with an MQTT out node to a Debug node but use your hologram/from topic.
  • Click Run!

Clicking the inject should send a timestamp to your Arduino MKR which will reflect on the Serial Monitor.

Sensor values from your Arduino MKR should show in the Debug tab on Chirpers!

Your main loop is where you can change what messages you are sending. Bonus points if you do something interesting ;)

void loop() {
 // call poll() regularly to allow the library to receive MQTT messages and
 // send MQTT keep alives which avoids being disconnected by the broker
 // Set the rate at which we send our values
 // read the first Analog pin
 int sensorVal = analogRead(0);
 // Publish our sensor value

This function at the end of the sketch handles incoming messages

void onMqttMessage(int messageSize) {
 // we received a message, print out the topic and contents
 Serial.println("Received a message with topic '");
 Serial.print("', length ");
 Serial.println(" bytes:");
 // use the Stream interface to print the contents
 while (mqttClient.available()) {

Chirpers Flow

If you wanna cheat you can copy this and import it into your flow from the menu. Just be sure to change the topics to match yours!

[{"id":"5199e666.cafc58","type":"mqtt-broker","z":"91xN7kD2zjI","server":"wss://","clientId":"","username":"","password":""},{"id":"SDgXjXm8EXM","type":"mqtt in","z":"91xN7kD2zjI","name":"","topic":"hologram/from","broker":"5199e666.cafc58","x":96,"y":117,"wires":[["q-msFzzDVmw"]]},{"id":"q-msFzzDVmw","type":"debug","z":"91xN7kD2zjI","name":"","active":true,"console":"false","complete":"false","x":287,"y":116,"wires":[]},{"id":"mib-Z2IUCWQ","type":"inject","z":"91xN7kD2zjI","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"allowDebugInput":false,"x":101,"y":39,"wires":[["TCHX2DIYKn4"]]},{"id":"TCHX2DIYKn4","type":"mqtt out","z":"91xN7kD2zjI","name":"","topic":"hologram/to","broker":"5199e666.cafc58","x":267,"y":39,"wires":[]}]


changeBand functionArduino
Call changeBand(GSM_MODE_GSM850_PCS); in setup to change band.
void changeBand(String newBandName) {
  // Use GSM_MODE_GSM850_PCS for USA

  GSMBand band;
  Serial.println("Restarting modem...");
  Serial.println("Modem restarted.");

  String bandName = band.getBand(); // Get and print band name
  Serial.print("Current band:");

  bool operationSuccess;
  operationSuccess = band.setBand(newBandName);
  if (operationSuccess) {
    String bandName = band.getBand(); // Get and print band name
    Serial.print("New band:");
  } else {
    Serial.println("Error while changing band");
Code Examples
This includes the Wardriving and MQTT examples


Similar projects you might like

Cellular IoT with Blynk & Hologram

by Moheeb Zara

  • 29 respects

Use Losant on a Cellular Arduino

by Moheeb Zara

  • 1 comment
  • 8 respects

IoT Node with STM32F4 Discovery, MKR1000 and Azure IoT Hub

Project tutorial by vincent wong

  • 6 respects

SCADA Using Cellular IoT with MKR GSM 1400

Project tutorial by Emile Ackbarali

  • 12 respects

IoT Blink - Getting started with IoT

Project showcase by AppShed Support

  • 1 comment
  • 26 respects
Add projectSign up / Login