Pushing Data to Data.SparkFun.com

This Tutorial is Retired!

This tutorial covers concepts or technologies that are no longer current. It's still here for you to read and enjoy, but may not be as useful as our newest tutorials.

Pages
Contributors: jimblom
Favorited Favorite 12

Arduino & WiFly Shield

The WiFly Shield is another easy solution for wirelessly connecting your Arduino to the Internet.

the WiFly shield

Check out our WiFly Shield Hookup Guide, if you haven't already, for help setting up and testing out your WiFly Shield.

Arduino Example Circuit

We'll use the same, exact circuit as that in the previous Arduino examples.

CC3000 example circuit

The output of a photocell (voltage divided with a 10kΩ resistor) connects to A0. A momentary push-button is connected to D3 on one end and ground on the other. And a SPDT switch can connect D5 to ground or let it float.

WiFly Example Sketch

This example sketch requires the WiFly Shield library. You can download it from the GitHub repository. Follow the instructions in our How to Install an Arduino Library for help installing the library.

Once you've installed the library, click here to download the example sketch, or copy/paste from below:

language:c
/*****************************************************************
Phant_WiFly.ino
Post data to SparkFun's data stream server system (phant) using
an Arduino and the WiFly Shield.
Jim Lindblom @ SparkFun Electronics
Original Creation Date: July 7, 2014

This sketch uses an Arduino Uno to POST sensor readings to 
SparkFun's data logging streams (http://data.sparkfun.com). A post
will be initiated whenever pin 3 is connected to ground.

Before uploading this sketch, there are a number of global vars
that need adjusting:
1. WiFi Stuff: Fill in your SSID, WiFi Passkey, and encryption
   setting using three variables available.
2. Phant Stuff: Fill in your data stream's public, private, and 
data keys before uploading!

This sketch requires that you install this library:
* WiFly_Shield: https://github.com/sparkfun/WiFly-Shield/tree/master/Libraries

Hardware Hookup:
  * These components are connected to the Arduino's I/O pins:
    * D3 - Active-low momentary button (pulled high internally)
    * A0 - Photoresistor (which is combined with a 10k resistor
           to form a voltage divider output to the Arduino).
    * D5 - SPST switch to select either 5V or 0V to this pin.
  * A WiFly Shield sitting comfortable on top of your Arduino.

Development environment specifics:
    IDE: Arduino 1.0.5
    Hardware Platform: RedBoard & WiFly Shield

This code is beerware; if you see me (or any other SparkFun 
employee) at the local, and you've found our code helpful, please 
buy us a round!

Distributed as-is; no warranty is given.
*****************************************************************/
// Include the WiFly library and the SPI library to support it:
#include <SPI.h>
#include <WiFly.h>
// Progmem allows us to store big strings in flash using F().
// We'll sacrifice some flash for extra DRAM space.
#include <Progmem.h>

////////////////////
// WiFi Constants //
////////////////////
char ssid[] = "SSID"; // SSID of the WiFi network
char passphrase[] = "SSID_PASSPHRASE"; // Password (if applicable)
// Security of your network. Set to true if your network uses WPA,
// otherwise (if it's open) set it to false:
boolean wpaEnabled = true;

/////////////////
// Phant Stuff //
/////////////////
const String publicKey = "6JZbNolApzF4om2l9yYK";
const String privateKey = "Ww0vPW1yrkUNDqWPV9jE";
char server[] = "data.sparkfun.com"; // Remote host site
const byte NUM_FIELDS = 3;
const String fieldNames[NUM_FIELDS] = {"light", "switch", "name"};
String fieldData[NUM_FIELDS];

//////////////////////
// Input Pins, Misc //
//////////////////////
const int triggerPin = 3;
const int lightPin = A0;
const int switchPin = 5;
String name = "WiFlyShield"; // Your/Arduino's name (no spaces)
boolean newName = true;

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

  // Setup Input Pins:
  pinMode(triggerPin, INPUT_PULLUP);
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(lightPin, INPUT_PULLUP);

  // Set up WiFi:
  setupWiFi();

  Serial.println(F("=========== Ready to Stream ==========="));
  Serial.println(F("Press the button (D3) to send an update"));
  Serial.println(F("Type your name (no spaces!), followed by '!' to update name"));
}

void loop()
{
  // If the trigger pin (3) goes low, send the data.
  if (!digitalRead(triggerPin))
  {
    // Gather data:
    fieldData[0] = String(analogRead(lightPin));
    fieldData[1] = String(digitalRead(switchPin));
    fieldData[2] = name;

    // Post data:
    Serial.println(F("Posting!"));
    postData(); // the postData() function does all the work, 
                // check it out below.
    delay(1000);
  }

  // Check for a new name input:
  if (Serial.available())
  {
    char c = Serial.read();
    if (c == '!')
    {
      newName = true;
      Serial.print(F("Your name is "));
      Serial.println(name);
    }
    else if (newName)
    {
      newName = false;
      name = "";
      name += c;
    }
    else
    {
      name += c;
    }
  }
}

void postData()
{
  WiFlyClient client(server, 80);

  if (client.connect()) 
  {
    Serial.println(F("Connected"));

    // Post the data! Request should look a little something like:
    // GET /input/publicKey?private_key=privateKey&light=1024&switch=0&time=5201 HTTP/1.1\n
    // Host: data.sparkfun.com\n
    // Connection: close\n
    // \n
    client.print("GET /input/");
    client.print(publicKey);
    client.print("?private_key=");
    client.print(privateKey);
    for (int i=0; i<NUM_FIELDS; i++)
    {
      client.print("&");
      client.print(fieldNames[i]);
      client.print("=");
      client.print(fieldData[i]);
    }
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();

    // While we're connected, print out anything the server sends:
    while (client.connected())
    {
      if (client.available())
      {
        char c = client.read();
        Serial.print(c);
      }
    }
    Serial.println();
  } 
  else // If the connection failed, print a message:
  {
    Serial.println(F("Connection failed"));
  }

  // If we're disconnected, stop the client:
  if (!client.connected()) 
  {
    Serial.println(F("Disconnecting."));
    client.stop();
  }
}

void setupWiFi()
{
  Serial.println(F("Initializing WiFly"));
  WiFly.begin();

  Serial.print(F("Connecting to "));
  Serial.println(ssid);
  if (!WiFly.join(ssid, passphrase, wpaEnabled)) 
  {
    Serial.println(F("Association failed."));
    while (1)
      ;// Hang on failure.
  }

  // Print the IP address:
  Serial.print(F("IP: "));
  Serial.println(WiFly.ip());
}

Before uploading the sketch there are a few global variables you'll need to adjust to configure it to your WiFi network. The relevant section is under the "WiFi Constants" heading:

language:c
////////////////////
// WiFi Constants //
////////////////////
char ssid[] = "SSID"; // SSID of the WiFi network
char passphrase[] = "SSID_PASSPHRASE"; // Password (if applicable)
// Security of your network. Set to true if your network uses WPA,
// otherwise (if it's open) set it to false:
boolean wpaEnabled = true;

The ssid and passphrase character arrays should be adjusted to match your WiFi network. If your network is open (no passkey), that second variable should be blank (passphrase[] = "";). Also make sure to adjust the wpaEnabled variable to match the security of your network. If it uses WPA, set that variable to true, otherwise (if it's open) set it to false.

With those correctly set, you can run the sketch. This example sketch should post to our example stream whenever you press the button connected to D3.

Configuring Data.SparkFun.com Settings

To use your own data stream, you'll want to modify the data stream keys and fields. To set it to a data stream of your own, adjust the variables under the "Phant Stuff" heading:

language:c
/////////////////
// Phant Stuff //
/////////////////
const String publicKey = "6JZbNolApzF4om2l9yYK";
const String privateKey = "Ww0vPW1yrkUNDqWPV9jE";
char server[] = "data.sparkfun.com"; // Remote host site
const byte NUM_FIELDS = 3;
const String fieldNames[NUM_FIELDS] = {"light", "switch", "name"};
String fieldData[NUM_FIELDS];

The publicKey and privateKey variables will be given to you when you create your stream. You can also adjust the number of data fields and their names here as well. The values in the fieldNames string array should match exactly what you typed when you created the stream.

Running the Sketch

After you've fixed the WiFi and datastream settings, upload the sketch. Then open the Serial Monitor and set the baud rate to 115200 bps. Some debug messages will flow by at the start. Once you see your IP address printed, your Arduino is connected and you're ready to post some data.

WiFly serial monitor example

One of the fields in this example pushes a name to the server. If you want to update the name value, type in your name into the Serial Monitor and terminate it with a '!'.

To push your data to the server, simply press the button tied to D3 (or just short that pin to ground). A few serial lines will quickly be printed. Check to make sure HTTP/1.1 200 OK is somewhere among those lines -- that means the server accepted your request.

Going Further

To further customize the sketch, you'll want to mess around with the "gathering data" stage. In this example, a trio of lines load data into the fieldData array, converting each into a string beforehand. Those values from fieldData are later used in the postData() function when the HTTP GET string is formulated.

Most of the importatnt stuff happens in the postData() function. Here you'll find an example for creating an HTTP GET, and routing it out to the server. Check out the comments for a line-by-line dissection of the code.