How to send multiple HTTP requests to Xively

I’m currently working on an Arduino based Smoker controller that reads the input of four thermistors, and transmits that information to Xively. Then it will read an additional datastream on Xively and respond to it. I am having trouble getting HTTP requests sent to Xively. I have successfully used GET and PUT to read and write the data, but I cannot get them to work in the same program. Any help is highly appreciated.

Currently this program will transmit the data to xively successfully, but will not process the GET request to read the additional data.

The two requests:

  // Send request
  Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
  if (client.connected()) {
    Serial.println("Connected!");
    client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
    client.println("Host: api.xively.com");
    client.println("X-ApiKey: " + String(API_key));
    client.println("Content-Length: " + String(length));
    client.print("Connection: close");
    client.println();
    client.print(data);
    client.println();
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }
  if (client.connected()) {
    Serial.println("Connected!");
    client.println("GET /v2/feeds/" + String(feedID) + "/datastreams/RequestedTemp.json HTTP/1.0");
    client.println("Host: api.xively.com");
    client.println("X-ApiKey: " + String(API_key));
    //client.println("Content-Length: " + String(length));
    client.print("Connection: close");
    client.println();
    //client.print(data);
    client.println();
  }

Full Code

/*************************************************** 
  This is a sketch to use the CC3000 WiFi chip & Xively
  
  Written by Marco Schwartz for Open Home Automation
 ****************************************************/

// Libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include<stdlib.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// Define Thermo Pins
#define Thermistor1PIN 1                  // Cabinet Thermistor
#define Thermistor2PIN 2                  // Meat Thermistor 1
#define Thermistor3PIN 3                  // Meat Thermistor 2
#define Thermistor4PIN 4                  // Meat Thermistor 3

//Define Pin for the Relay
#define RelayPin 6

// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIV2); // you can change this clock speed
                                         


// WLAN parameters
#define WLAN_SSID       "XXXXXXXXX"
#define WLAN_PASS       "XXXXXXXXX"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

// Xively parameters
#define WEBSITE  "api.xively.com"
#define API_key  "XXXXXXXXXX"
#define feedID  "XXXXXXXXXXXXX"

//////Thermometer Function
float vcc = 4.91;                       // only used for display purposes, if used
                                        // set to the measured Vcc.
float pad = 109800;                     // balance/pad resistor value, set this to
                                        // the measured resistance of your pad resistor
float thermr = 222000;                   // thermistor nominal resistance

float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;  // Dual-Purpose variable to save space.

  Resistance=((1024 * pad / RawADC) - pad);
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (-0.000631535825 + (0.0003824312118 * Temp) + (-0.0000003752313105 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                     
  

  // Uncomment this line for the function to return Fahrenheit instead.
  Temp = (Temp * 9.0)/ 5.0 + 32.0;                  // Convert to Fahrenheit
  return Temp;                                      // Return the Temperature
}

////////

uint32_t ip;

void setup(void)
{
  // Initialize
  Serial.begin(115200);
  
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }
 
}

void loop(void)
{
  // Connect to WiFi network
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("Connected!"));
  
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }  

  // Get the website IP & print it
  ip = 0;
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);
  
  // Get data & transform to integers
  float temp1=Thermistor(analogRead(Thermistor1PIN));
  float temp2=Thermistor(analogRead(Thermistor2PIN));
  float temp3=Thermistor(analogRead(Thermistor3PIN));
  float temp4=Thermistor(analogRead(Thermistor4PIN));
  
  int cabinet = (int) temp1;
  int temp2a = (int) temp2;
  int temp3a = (int) temp3;
  int temp4a = (int) temp4;
  
  // Prepare JSON for Xively & get length
  int length = 0;

  String data = "";
    data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"CabinetTemp\",\"current_value\" : \"" + String(cabinet) + "\"}," 
  + "{\"id\" : \"Thermo1\",\"current_value\" : \"" + String(temp2a) + "\"}," + "{\"id\" : \"Thermo2\",\"current_value\" : \"" + String(temp3a) + "\"}]}";
  
  length = data.length();
  Serial.print("Data length");
  Serial.println(length);
  Serial.println();
  
  
  // Print request for debug purposes
  Serial.print("PUT /v2/feeds/");
  Serial.print(feedID);
  Serial.println(".json HTTP/1.0");
  Serial.println("Host: api.xively.com");
  Serial.print("X-ApiKey: ");
  Serial.println(API_key);
  Serial.print("Content-Length: ");
  Serial.println(length, DEC);
  Serial.print("Connection: close");
  Serial.println();
  Serial.print(data);
  Serial.println();
  
  // Send request
  Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
  if (client.connected()) {
    Serial.println("Connected!");
    client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
    client.println("Host: api.xively.com");
    client.println("X-ApiKey: " + String(API_key));
    client.println("Content-Length: " + String(length));
    client.print("Connection: close");
    client.println();
    client.print(data);
    client.println();
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }
  if (client.connected()) {
    Serial.println("Connected!");
    client.println("GET /v2/feeds/" + String(feedID) + "/datastreams/RequestedTemp.json HTTP/1.0");
    client.println("Host: api.xively.com");
    client.println("X-ApiKey: " + String(API_key));
    //client.println("Content-Length: " + String(length));
    client.print("Connection: close");
    client.println();
    //client.print(data);
    client.println();
  } 
  else {
    Serial.println(F("Get failed"));       
  }
  Serial.println(F("-------------------------------------"));
  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  client.close();
  Serial.println(F("-------------------------------------"));
  
  Serial.println(F("\n\nDisconnecting"));
  cc3000.disconnect();
  
  // Wait 10 seconds until next update
  delay(10000);
  
}

Hey there, I don’t have too much experience with that wifi board, I’m assuming it’s the adafruit cc3000 breakout? I do have a lot of experience with Xively though. Your request look perfectly fine, as I assume you know since they returning when you have them separated out.

I cant say for sure and can’t test because I don’t have the same hardware as you. But I have a feeling that your issue is because you are doing the GET, literally right after the PUT. This doesn’t give the client time to receive the response properly and you are probably not printing out what you think are.

I would wait to do the GET request until you have received the response from your PUT request. The way you have your code structured is a bit funky, but you could probably do this by adding a boolean to the GET request and then having a separate client.read() block after the GET.

A more traditional way to structure things would be to move the cc3000 setup to the setup() function and then use a timer instead of a delay. This would allow you to iterate through the loop constantly, checking for received data more than once. Try the way I suggest above first and see if you can get that to work for you.

I made some progress. I am able to send both of the requests, but for some reason the addition of the GET request has wiped out my data variable. I can’t figure it out.

/*************************************************** 
  This is a sketch to use the CC3000 WiFi chip & Xively
  
  Written by Marco Schwartz for Open Home Automation
 ****************************************************/

// Libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include<stdlib.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// Define Thermo Pins
#define Thermistor1PIN 1                  // Cabinet Thermistor
#define Thermistor2PIN 2                  // Meat Thermistor 1
#define Thermistor3PIN 3                  // Meat Thermistor 2
#define Thermistor4PIN 4                  // Meat Thermistor 3

//Define Pin for the Relay
#define RelayPin 6

// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIV2); // you can change this clock speed
                                         


// WLAN parameters
#define WLAN_SSID       "XXX"
#define WLAN_PASS       "XXX"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

// Xively parameters
#define WEBSITE  "XXX"
#define API_key  "XXX"
#define feedID  "XXXX"

//////Thermometer Function
float vcc = 4.91;                       // only used for display purposes, if used
                                        // set to the measured Vcc.
float pad = 109800;                     // balance/pad resistor value, set this to
                                        // the measured resistance of your pad resistor
float thermr = 222000;                   // thermistor nominal resistance

float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;  // Dual-Purpose variable to save space.

  Resistance=((1024 * pad / RawADC) - pad);
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (-0.000631535825 + (0.0003824312118 * Temp) + (-0.0000003752313105 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                     
  

  // Uncomment this line for the function to return Fahrenheit instead.
  Temp = (Temp * 9.0)/ 5.0 + 32.0;                  // Convert to Fahrenheit
  return Temp;                                      // Return the Temperature
}

////////

uint32_t ip;

void setup(void)
{
  // Initialize
  Serial.begin(115200);
  
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }
 
}

void loop(void)
{
  // Connect to WiFi network
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("Connected!"));
  
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }  

  // Get the website IP & print it
  ip = 0;
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);
  
  // Get data & transform to integers
  float temp1=Thermistor(analogRead(Thermistor1PIN));
  float temp2=Thermistor(analogRead(Thermistor2PIN));
  float temp3=Thermistor(analogRead(Thermistor3PIN));
  float temp4=Thermistor(analogRead(Thermistor4PIN));
  
  int cabinet = (int) temp1;
  int temp2a = (int) temp2;
  int temp3a = (int) temp3;
  int temp4a = (int) temp4;
  
  // Prepare JSON for Xively & get length
  int length = 0;

  String data = "";
    data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"CabinetTemp\",\"current_value\" : \"" + String(cabinet) + "\"}," 
  + "{\"id\" : \"Thermo1\",\"current_value\" : \"" + String(temp2a) + "\"}," + "{\"id\" : \"Thermo2\",\"current_value\" : \"" + String(temp3a) + "\"}]}";
  
  length = data.length();
  Serial.print("Data length");
  Serial.println(length);
  Serial.println();
  
  
  // Print request for debug purposes
  Serial.print("PUT /v2/feeds/");
  Serial.print(feedID);
  Serial.println(".json HTTP/1.0");
  Serial.println("Host: api.xively.com");
  Serial.print("X-ApiKey: ");
  Serial.println(API_key);
  Serial.print("Content-Length: ");
  Serial.println(length, DEC);
  Serial.print("Connection: close");
  Serial.println();
  Serial.print(data);
  Serial.println();
  
  // Send request
  Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
  if (client.connected()) {
    Serial.println("Connected!");
    client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
    client.println("Host: api.xively.com");
    client.println("X-ApiKey: " + String(API_key));
    client.println("Content-Length: " + String(length));
    client.print("Connection: close");
    client.println();
    client.print(data);
    client.println();
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }
  Serial.println(F("-------------------------------------"));
  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  client.close();
  Serial.println(F("-------------------------------------"));
  
  
  /////sending additional request
  Adafruit_CC3000_Client clientb = cc3000.connectTCP(ip, 80);
  if (clientb.connected()) {
    Serial.println("Connected!");
    clientb.println("GET /v2/feeds/" + String(feedID) + "/datastreams/RequestedTemp.json HTTP/1.0");
    clientb.println("Host: api.xively.com");
    clientb.println("X-ApiKey: " + String(API_key));
    clientb.print("Connection: close");
    clientb.println();
    clientb.println();
  } else {
    Serial.println(F("Get failed"));    
    
  }
  Serial.println(F("-------------------------------------"));
  while (clientb.connected()) {
    while (clientb.available()) {
      char c = clientb.read();
      Serial.print(c);
    }
  }
  clientb.close();
  Serial.println(F("-------------------------------------"));
  Serial.println(F("\n\nDisconnecting"));
  cc3000.disconnect();
  
  // Wait 10 seconds until next update
  delay(10000);
  
}

I was able to get the program to work by separating the GET and PUT into their own functions and calling them into the Void Loop.