2

Xively Arduino API を使用しています。xivelyclient.get() 呼び出しがデータを返すのに 1 分かかることを除いて、これまでに使用したすべての API 呼び出しは期待どおりに機能しています。

これは予想される動作ですか?

以下は私のコードです。ご覧のとおり、これは基本的に Arduino API for Xively に付属する例の 1 つです。実行するために私がしたことは、xivelyKey と 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);
 }

シリアル モニターの出力は期待どおりです。

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

約 1 分 10 秒で応答が返されます。

4

1 に答える 1

1

デバッグを行ったところ、XivelyClient.cpp (API の一部) の xivelyclient.get() の実装が次の while ループでハングしていることがわかりました。

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

このループから抜け出した唯一の理由は、サーバーによって接続が閉じられているためだと思います。

関数を機能させるために、if ステートメントの最後の 2 行を while ループのすぐ上に追加し、while ループを削除しました。

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;
}

これはエレガントなソリューションではないと確信していますが、今のところうまくいきます...

于 2013-05-16T11:52:26.793 に答える