Arduino + Temperature Sensor + WiFi Shield = Quick Demo Material


#1

We received an interesting question from one of our users asking how to blend of couple of our demos together. In particular he had the single wire temperature sensor and a WiFI shield on hand. This is what he said:

We are showcasing Exosite and the data connection from an Arduino UNO
rev3. We want to use a WIFI shield to simulate to our sales reps that
it is using Cellular. This is going to be showcased next week to all of
our sales reps at an all hands on meeting talking about the importance
of data/cloud + M2M integration. I have followed all the instructions
and I can get the WIFI to provision but I all the code for the Temp
Monitor is based on Ethernet. I have been trying to edit the code
between the examples you have provided to no avail. Please help!

If you are not already familiar with them, here are links to the code contained within each demo.

##Temperature Demo

##WiFi Demo

What our user wants to do is totally feasable and won’t take much time to implement. Here we are going to walkthrough the steps to modify the example code to implement the WiFi Shield. What is important to do is include the WiFi library in your code and change the initial setup of communication.

The Ethernet example’s setup function looks like this:

class EthernetClient client;
Exosite exosite(cikData, &client);

// The 'setup()' function is the first function that runs on the Arduino.
// It runs completely and when complete jumps to 'loop()'

void setup() {
   Serial.begin(9600);
   Serial.println("Boot");
   // Start up the OneWire Sensors library
   sensors.begin();
   delay(1000);
   Serial.println("Starting Exosite Temp Monitor");
   Serial.print("OneWire Digital Pin Specified: ");
   Serial.println(ONEWIRE);
   Ethernet.begin(macData); 
   // wait 3 seconds for connection
   delay(3000);
 }

To use the accomplish the same goals using the WiFi shield we can re-use the setup function from the Wifi Demo but include initializing the temperature sensor. When it is all said and done your new setup function will look like:

// Be sure to include the WiFi Library along with the neccessary Sensor Libraries.
#include <WiFi.h>

You can delete your unused Ethernet Library.

unsigned char errorCount = reprovisionAfter; // Force Provision On First Loop
char macString[18]; // Used to store a formatted version of the MAC Address
byte macData[WL_MAC_ADDR_LENGTH];
int status = WL_IDLE_STATUS;

class WiFiClient client;
Exosite exosite(&client);

void setup() {
  Serial.begin(9600);
  Serial.println("Boot");

  //Start One Wire Sensors Library     
  sensors.begin()
  delay(1000)
  Serial.print("OneWire Digital Pin Specified: ");
  Serial.println(ONEWIRE);

  // Create MAC Address String in the format FF:FF:FF:FF:FF:FF
  WiFi.macAddress(macData);
  snprintf(macString, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
    macData[5], macData[4], macData[3], macData[2], macData[1], macData[0]);
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
 // attempt to connect to Wifi network:
 while ( status != WL_CONNECTED) {
   Serial.print("Attempting to connect to SSID: ");
   Serial.println(ssid);
   // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
  status = WiFi.begin(ssid, pass);
 }
 Serial.println("Connected to Access Point");

 // Print Some Useful Info
 Serial.print(F("MAC Address: "));
 Serial.println(macString);
 Serial.print(F("IP Address: "));
 Serial.println(WiFi.localIP());
}

With these changes you will be ready to send information with the Dallas temperature sensor over WiFi. Don’t forget to setup a device within Exosite, and double check you have your MAC address typed correctly. In this case we didn’t explicitly detail on how to gather sensor information from the sensor, but lucky for us that is covered top-to-bottom within the Temperature Demo linked above.


#4

We are close! I did exactly as you said and got the compiler to pass all the code.+1. However when it goes to connect to Exosite to send the data it comes back saying “Error communicating with Exosite.” I just renewed my CIK and added that and nothing, still the same error. See the image link below for my screenshot. Not sure how to update my entire code here so you can see. Didn’t change anything I shouldn’t have. Well I’m pretty sure.


#5

If you can post your code (use the ‘pre-formatted text’ format to make it readable), making sure to remove your CIK, we can take a look at it.

I have noticed an issue with the Arduino Ethernet shield not able to connect with Exosite the first couple of attempts, but after the third it usually works. This seems to be related to a local network thing, if I change the MAC address it works instantly the first time with the new MAC. I have not verified this with the WiFi Shield.

You can also quickly check if you can easily get outside of your office network (if you are in an office) by using this code which just prints out the current unix timestamp using a GET request. No CIK is needed to make this call. http://m2.exosite.com/timestamp

#include <EEPROM.h>
#include <SPI.h>
#include <WiFi.h>
#include <Exosite.h>

String cikData = "0000000000000000000000000000000000000000";  //  CIK not needed for this API call to get TIME, can leave as is here
char macString[18]; // Used to store a formatted version of the MAC Address
byte macData[WL_MAC_ADDR_LENGTH];
int status = WL_IDLE_STATUS;

class WiFiClient client;
Exosite exosite(cikData, &client);

/*==============================================================================
* setup
*
* Arduino setup function.
*=============================================================================*/
void setup(){  
  Serial.begin(9600);
  delay(1000);
  Serial.println("Boot");
  Serial.println("Network Setup - start");
  // Create MAC Address String in the format FF:FF:FF:FF:FF:FF
  WiFi.macAddress(macData);
  snprintf(macString, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
    macData[5], macData[4], macData[3], macData[2], macData[1], macData[0]);
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
 // attempt to connect to Wifi network:
 while ( status != WL_CONNECTED) {
   Serial.print("Attempting to connect to SSID: ");
   Serial.println(ssid);
   // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
  status = WiFi.begin(ssid, pass);
 }
 Serial.println("Connected to Access Point");
 Serial.println("Network Setup - Done");

 // Print Some Useful Info
 Serial.print(F("MAC Address: "));
 Serial.println(macString);
 Serial.print(F("IP Address: "));
 Serial.println(WiFi.localIP());
}

/*==============================================================================
* loop 
*
* Arduino loop function.
*=============================================================================*/
void loop(){
  //Write to "uptime" and read from "uptime" and "command" datasources.
  Serial.println("get unixtime from m2.exosite.com/timestamp");
  exosite.time();
  delay(10000); //delay for 10 seconds for loop
}

Thanks,
-Mike


#7

Boom! Your above sketch worked and it grabs the timestamp. So the network is good.

http://i.imgur.com/oABNFEH.jpg

Here is the code for the temperature monitor that errors out on me. Let me know what you think! I feel we are close…

/* Exosite Arduino Basic Temp Monitor 2 (updated to use Exosite library)

This sketch shows an example of sending data from a connected
sensor to Exosite. (http://exosite.com) Code was used from various
public examples including the Arduino Ethernet examples and the OneWire
Library examples found on the Arduino playground.
(OneWire Lib credits to Jim Studt, Tom Pollard, Robin James, and Paul Stoffregen)

This code keeps track of how many milliseconds have passed
and after the user defined REPORT_TIMEOUT (default 60 seconds)
reports the temperature from a Dallas Semi DS18B20 1-wire temp sensor.
The code sets up the Ethernet client connection and connects / disconnects
to the Exosite server when sending data.

Assumptions:

Hardware:

  • Arduino Duemilanove or similiar
  • Arduino Ethernet Shield
  • Dallas Semiconductor DS18B20 1-Wire Temp sensor used in parasite power mode (on data pin 7, with 4.7k pull-up)

Version History:

  • 1.0 - November 8, 2010 - by M. Aanenson
  • 2.0 - July 6, 2012 - by M. Aanenson
  • 3.0 - October 25, 2013 - by M. Aanenson - Note: Updated to use latest Exosite Arduino Library
    */
#include <EEPROM.h>
#include <SPI.h>
#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Exosite.h>

// Pin use
#define ONEWIRE 7 //pin to use for One Wire interface

// Set up which Arduino pin will be used for the 1-wire interface to the sensor
OneWire oneWire(ONEWIRE);
DallasTemperature sensors(&oneWire);

/*==============================================================================

  • Configuration Variables
  • Change these variables to your own settings.
    =============================================================================/
    char ssid[] = “VZW Developers”; // <-- Fill in your network SSID (name)
    char pass[] = “…”; // <-- Fill in your network password

String cikData = “db0d…bf6a2b65e53e”; // <-- FILL IN YOUR CIK HERE! (https://portals.exosite.com -> Add Device)

// User defined variables for Exosite reporting period and averaging samples
#define REPORT_TIMEOUT 30000 //milliseconds period for reporting to Exosite.com
#define SENSOR_READ_TIMEOUT 5000 //milliseconds period for reading sensors in loop

// Number of Errors before we try a reprovision.
const unsigned char reprovisionAfter = 3;

/*==============================================================================

  • End of Configuration Variables
    =============================================================================/
    unsigned char errorCount = reprovisionAfter; // Force Provision On First Loop
    char macString[18]; // Used to store a formatted version of the MAC Address
    byte macData[WL_MAC_ADDR_LENGTH];

int status = WL_IDLE_STATUS;
class WiFiClient client;
Exosite exosite(&client);

void setup(){
Serial.begin(9600);
Serial.println(“Boot”);

//Start One Wire Sensors Library
sensors.begin();
delay(1000);
Serial.print("OneWire Digital Pin Specified: ");
Serial.println(ONEWIRE);

// Create MAC Address String in the format FF:FF:FF:FF:FF:FF
WiFi.macAddress(macData);
snprintf(macString, 18, “78:c4:0e:02:5c:48”,
macData[5], macData[4], macData[3], macData[2], macData[1], macData[0]);

// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println(“WiFi shield not present”);
// don’t continue:
while(true);
}
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
}
Serial.println(“Connected to Access Point”);

// Print Some Useful Info
Serial.print(F("MAC Address: "));
Serial.println(macString);
Serial.print(F("IP Address: "));
Serial.println(WiFi.localIP());
}

//
// The ‘loop()’ function is the ‘main’ function for Arduino
// and is essentially a constant while loop.
//
void loop() {
static unsigned long sendPrevTime = 0;
static unsigned long sensorPrevTime = 0;
static float tempF;
char buffer[7];
String readParam = “”;
String writeParam = “”;
String returnString = “”;

Serial.print("."); // print to show running

// Read sensor every defined timeout period
if (millis() - sensorPrevTime > SENSOR_READ_TIMEOUT) {
Serial.println();
Serial.println(“Requesting temperature…”);
sensors.requestTemperatures(); // Send the command to get temperatures
float tempC = sensors.getTempCByIndex(0);
Serial.print(“Celsius: “);
Serial.print(tempC);
Serial.println(” C …DONE”);
tempF = DallasTemperature::toFahrenheit(tempC);
Serial.print(“Fahrenheit: “);
Serial.print(tempF);
Serial.println(” F …DONE”);

sensorPrevTime = millis();

}

// Send to Exosite every defined timeout period
if (millis() - sendPrevTime > REPORT_TIMEOUT) {
Serial.println(); //start fresh debug line
Serial.println(“Sending data to Exosite…”);

readParam = "";        //nothing to read back at this time e.g. 'control&status' if you wanted to read those data sources
writeParam = "temp="; //parameters to write e.g. 'temp=65.54' or 'temp=65.54&status=on'
String tempValue = dtostrf(tempF, 1, 2, buffer); // convert float to String, minimum size = 1, decimal places = 2
writeParam += tempValue;    //add converted temperature String value
//writeParam += "&message=hello"; //add another piece of data to send
if ( exosite.writeRead(writeParam, readParam, returnString)) {
  Serial.println("Exosite OK");
  if (returnString != "") {
    Serial.println("Response:");
    Serial.println(returnString);
  }
}
else {
  Serial.println("Exosite Error");
}
sendPrevTime = millis(); //reset report period timer
Serial.println("done sending.");

}
delay(1000); //slow down loop
}


#9

Got it working! Here is the full code. Copy and Paste-rino! Thanks for you all your help. Had to write additional code from what you suggested. It was really close thou.

/*
 Exosite Arduino Basic Temp Monitor 2 (updated to use Exosite library)
  
 This sketch shows an example of sending data from a connected
 sensor to Exosite. (http://exosite.com) Code was used from various
 public examples including the Arduino Ethernet examples and the OneWire
 Library examples found on the Arduino playground. 
 (OneWire Lib credits to Jim Studt, Tom Pollard, Robin James, and Paul Stoffregen)
  
 This code keeps track of how many milliseconds have passed
 and after the user defined REPORT_TIMEOUT (default 60 seconds)
 reports the temperature from a Dallas Semi DS18B20 1-wire temp sensor.
 The code sets up the Ethernet client connection and connects / disconnects 
 to the Exosite server when sending data.
  
 Assumptions:
 - Tested with Aruduino 1.0.5
 - Arduino included Ethernet Library
 - Arduino included SPI Library
 - Using Exosite library (2013-10-20) https://github.com/exosite-garage/arduino_exosite_library
 - Using OneWire Library Version 2.0 - http://www.arduino.cc/playground/Learning/OneWire
 - Using Dallas Temperature Control Library - http://download.milesburton.com/Arduino/MaximTemperature/DallasTemperature_372Beta.zip
 - Uses Exosite's basic HTTP API, revision 1.0 https://github.com/exosite/api/tree/master/data
 --- USER MUST DO THE FOLLOWING ---
 - User has an Exosite account and created a device (CIK needed / https://portals.exosite.com -> Add Device)
 - User has added a device to Exosite account and added a data source with alias 'temp', type 'float'
 
  
 Hardware:
 - Arduino Duemilanove or similiar
 - Arduino Ethernet Shield
 - Dallas Semiconductor DS18B20 1-Wire Temp sensor used in parasite power mode (on data pin 7, with 4.7k pull-up)
 
Version History:
- 1.0 - November 8, 2010 - by M. Aanenson
- 2.0 - July 6, 2012 - by M. Aanenson
- 3.0 - October 25, 2013 - by M. Aanenson - Note: Updated to use latest Exosite Arduino Library

*/
  

#include <EEPROM.h>
#include <SPI.h>
// #include <Ethernet.h>
#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Exosite.h>
 
// Pin use
#define ONEWIRE 7 //pin to use for One Wire interface

// Set up which Arduino pin will be used for the 1-wire interface to the sensor
OneWire oneWire(ONEWIRE);
DallasTemperature sensors(&oneWire);
 
/*==============================================================================
* Configuration Variables
*
* Change these variables to your own settings.
*=============================================================================*/
String cikData = "41352fb0bb000000000000000000000000000000";  // <-- FILL IN YOUR CIK HERE! (https://portals.exosite.com -> Add Device)
// byte macData[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02};        // <-- FILL IN YOUR Ethernet shield's MAC address here.

char ssid[] = "VZW Developers"; // <-- Fill in your network SSID (name)
char pass[] = "6125907309"; // <-- Fill in your network password

// User defined variables for Exosite reporting period and averaging samples
#define REPORT_TIMEOUT 30000 //milliseconds period for reporting to Exosite.com
#define SENSOR_READ_TIMEOUT 5000 //milliseconds period for reading sensors in loop

// Number of Errors before we try a reprovision.
const unsigned char reprovisionAfter = 3;

/*==============================================================================
* End of Configuration Variables
*=============================================================================*/
unsigned char errorCount = reprovisionAfter; // Force Provision On First Loop
char macString[18]; // Used to store a formatted version of the MAC Address
byte macData[WL_MAC_ADDR_LENGTH];

int status = WL_IDLE_STATUS;
class WiFiClient client;
// class EthernetClient client;
Exosite exosite(cikData, &client);

//
// The 'setup()' function is the first function that runs on the Arduino.
// It runs completely and when complete jumps to 'loop()' 
//
void setup() {
  Serial.begin(9600);
  Serial.println("Boot");
  // Start up the OneWire Sensors library
  sensors.begin();
  delay(1000);
  Serial.println("Starting Exosite Temp Monitor");
  Serial.print("OneWire Digital Pin Specified: ");
  Serial.println(ONEWIRE);
  
//  Ethernet.begin(macData);
  // wait 3 seconds for connection
//delay(3000); 
  // Create MAC Address String in the format FF:FF:FF:FF:FF:FF
  WiFi.macAddress(macData);
  snprintf(macString, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
    macData[5], macData[4], macData[3], macData[2], macData[1], macData[0]);
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
 // attempt to connect to Wifi network:
 while ( status != WL_CONNECTED) {
   Serial.print("Attempting to connect to SSID: ");
   Serial.println(ssid);
   // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
  status = WiFi.begin(ssid, pass);
 }
 Serial.println("Connected to Access Point");

 // Print Some Useful Info
 Serial.print(F("MAC Address: "));
 Serial.println(macString);
 Serial.print(F("IP Address: "));
 Serial.println(WiFi.localIP());
}
 
//
// The 'loop()' function is the 'main' function for Arduino 
// and is essentially a constant while loop. 
//
void loop() {
  static unsigned long sendPrevTime = 0;
  static unsigned long sensorPrevTime = 0; 
  static float tempF;
  char buffer[7];
  String readParam = "";
  String writeParam = "";
  String returnString = "";  
   
  Serial.print("."); // print to show running
 
 // Read sensor every defined timeout period
  if (millis() - sensorPrevTime > SENSOR_READ_TIMEOUT) {
    Serial.println();
    Serial.println("Requesting temperature...");
    sensors.requestTemperatures(); // Send the command to get temperatures
    float tempC = sensors.getTempCByIndex(0);
    Serial.print("Celsius:    ");
    Serial.print(tempC);
    Serial.println(" C ..........DONE");
    tempF = DallasTemperature::toFahrenheit(tempC);
    Serial.print("Fahrenheit: ");
    Serial.print(tempF);
    Serial.println(" F ..........DONE");
     
    sensorPrevTime = millis();
  }
 
  // Send to Exosite every defined timeout period
  if (millis() - sendPrevTime > REPORT_TIMEOUT) {
    Serial.println(); //start fresh debug line
    Serial.println("Sending data to Exosite...");
    
    readParam = "";        //nothing to read back at this time e.g. 'control&status' if you wanted to read those data sources
    writeParam = "temp="; //parameters to write e.g. 'temp=65.54' or 'temp=65.54&status=on'
    
    String tempValue = dtostrf(tempF, 1, 2, buffer); // convert float to String, minimum size = 1, decimal places = 2
    
    writeParam += tempValue;    //add converted temperature String value
    
    //writeParam += "&message=hello"; //add another piece of data to send

    if ( exosite.writeRead(writeParam, readParam, returnString)) {
      Serial.println("Exosite OK");
      if (returnString != "") {
        Serial.println("Response:");
        Serial.println(returnString);
      }
    }
    else {
      Serial.println("Exosite Error");
    }
 
    sendPrevTime = millis(); //reset report period timer
    Serial.println("done sending.");
  }
  delay(1000); //slow down loop
}

#10

Thanks cssmacs01 for posting the working code – Glad you got it up and running!