2

I am using the Xively Arduino API. All the API calls I have used so far are working as expected, except the xivelyclient.get() call takes 1 minute to return with the data.

Is this the expected behaviour?

Below is my code. As you can see its basically one of the examples that come with the Arduino API for Xively. All I did to get it going is update the xivelyKey and the feedID.

#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

// MAC address for your Ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Your Xively key to let you upload data
char xivelyKey[] = "abcdefghijklmnopqrstuvwxyz";

// Define the string for our datastream ID
char temperatureId[] = "temperature";

XivelyDatastream datastreams[] = {
XivelyDatastream(temperatureId, strlen(temperatureId), DATASTREAM_FLOAT),
};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(123456789, datastreams, 1 /* number of datastreams */);

EthernetClient client;
XivelyClient xivelyclient(client);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial.println("Reading from Xively example");
  Serial.println();

   while (Ethernet.begin(mac) != 1)
   {
     Serial.println("Error getting IP address via DHCP, trying again...");
     delay(15000);
   }
 }

 void loop() {
   int ret = xivelyclient.get(feed, xivelyKey);
   Serial.print("xivelyclient.get returned ");
   Serial.println(ret);

   if (ret > 0)
   {
     Serial.println("Datastream is...");
     Serial.println(feed[0]);

     Serial.print("Temperature is: ");
     Serial.println(feed[0].getFloat());
   }

   Serial.println();
   delay(15000UL);
 }

The output on the serial monitor is as expected:

Reading from Xively example

xivelyclient.get returned 200
Datastream is...
{ "id" : "temperature", "current_value" : "23.00" }
Temperature is: 23.00

xivelyclient.get returned 200
Datastream is...
{ "id" : "temperature", "current_value" : "23.00" }
Temperature is: 23.00

The responses come at approximately 1 minute 10 seconds.

Nick
  • 31
  • 4
  • That depends on how much data it returns I guess. – leppie May 15 '13 at 08:17
  • It ends up returning what I expect. i.e, less that 100 bytes. – Nick May 15 '13 at 09:47
  • It is quite possible, may be some sort of a network issue. I'd try running this on a different network. Also, you might want to get rid of the `delay()` and count how many request a minute you can make by just looking at you Xively device workbench for a few minutes, it's pretty clear usually. I would also add a code to actually measure the exact timings. – errordeveloper May 15 '13 at 22:00
  • @errordeveloper. -Yeah I tried taking out the `delay()` and I put a `println()` on either side of the `xivelyclient.get(feed, xivelyKey);`. Thats how I know that its the part that hands for just over a minute. – Nick May 16 '13 at 09:30
  • @Nick it would be also useful to know what board/shield you are using... for example, there known issues with SPI bus and SD card (IIRC) used simultaneously with the Ethernet shield and we also have heard that WiFly shield often performs quite badly. Please update the post with some details of the actual hardware and what sort of network connection is there... As I said you might wanna try on a different network or, actually, connect just the Arduino directly to the router and disconnect everything else you may have there, as it could be something odd that affects this. – errordeveloper May 16 '13 at 09:52
  • @errordeveloper I'm using the EtherTen board which combines the Arduino Uno design and the official Arduino Ethernet Shield design onto one board. Thanks for the pointers on this issue. Luckily the xively API for the Arduino is in source code form and I was able to debug where the code was hanging. I think it's a genuine bug in code. I detail my fix in the answer below. Thanks again. – Nick May 16 '13 at 12:00

1 Answers1

1

I did some debugging and found that the implementation of xivelyclient.get() in XivelyClient.cpp (part of the API) was hanging in the following while loop:

while ((next != '\r') && (next != '\n') && (http.available() || http.connected()))
{
   next = http.read();
}

I imagine that the only reason it was ever coming out of this loop is because the connection is being closed by the server.

In order to make the function work for me I added the last two lines in the if statement just above the while loop and deleted the while loop.

if ((idBitfield & 1<<i) && (aFeed[i].idLength() == idIdx))
{
   // We've found a matching datastream
   // FIXME cope with any errors returned
   aFeed[i].updateValue(http);

   // When we get here we'll be at the end of the line, but if aFeed[i]
   // was a string or buffer type, we'll have consumed the '\n'
   next = '\n';
   http.stop();
   return ret;
}

I'm sure this is not an elegant solution but it works for me for now...

Nick
  • 31
  • 4