From a22b91d874f285cefa621b13336c3c2a82d2643a Mon Sep 17 00:00:00 2001 From: Adrian McEwen Date: Mon, 25 Nov 2013 09:43:10 +0000 Subject: [PATCH 1/3] Updated to use timedRead and readStringUntil now that they're in the core Arduino IDE (tested with v1.0.5) --- XivelyDatastream.cpp | 24 +----------------------- XivelyDatastream.h | 2 -- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/XivelyDatastream.cpp b/XivelyDatastream.cpp index b5a94e7..da884dc 100644 --- a/XivelyDatastream.cpp +++ b/XivelyDatastream.cpp @@ -1,6 +1,4 @@ #include -// FIXME Only needed until readStringUntil is available in Stream -#include XivelyDatastream::XivelyDatastream(String& aId, int aType) : _idType(DATASTREAM_STRING), _valueType(aType), _idString(aId) @@ -40,31 +38,11 @@ int XivelyDatastream::updateValue(Stream& aStream) } break; case DATASTREAM_STRING: - // FIXME Change this to use readStringUntil once that's in the core - // FIMXE and remove the timedRead method in here then too - _valueString = ""; - int c = timedRead(aStream); - while (c >= 0 && c != '\n') - { - _valueString += (char)c; - c = timedRead(aStream); - } + _valueString = aStream.readStringUntil('\n'); break; }; } -int XivelyDatastream::timedRead(Stream& aStream) -{ - int c; - long _startMillis = millis(); - do { - c = aStream.read(); - if (c >= 0) return c; - } while(millis() - _startMillis < 10000UL); - return -1; // -1 indicates timeout -} - - void XivelyDatastream::setInt(int aValue) { if (_valueType == DATASTREAM_INT) diff --git a/XivelyDatastream.h b/XivelyDatastream.h index 62af191..954c90f 100644 --- a/XivelyDatastream.h +++ b/XivelyDatastream.h @@ -34,8 +34,6 @@ class XivelyDatastream : public Printable { protected: int idLength() { return (_idType == DATASTREAM_STRING ? _idString.length() : strlen(_idBuffer._buffer)); }; char idChar(int idx) { return (_idType == DATASTREAM_STRING ? _idString[idx] : (idx > strlen(_idBuffer._buffer) ? '\0' : _idBuffer._buffer[idx])); }; - // FIXME Only needed until readStringUntil is available in core - int timedRead(Stream& aStream); int _idType; String _idString; From 490b5662cec37a182dcc84431be67e12d826187a Mon Sep 17 00:00:00 2001 From: Adrian McEwen Date: Mon, 25 Nov 2013 09:44:18 +0000 Subject: [PATCH 2/3] Minor optimisations to trim some size from the compiled version --- XivelyClient.cpp | 17 ++++++++++------- XivelyClient.h | 3 +++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/XivelyClient.cpp b/XivelyClient.cpp index da94b9e..09c3305 100644 --- a/XivelyClient.cpp +++ b/XivelyClient.cpp @@ -2,6 +2,11 @@ #include #include +// Initialize constants +const char* XivelyClient::kUserAgent = "Xively-Arduino-Lib/1.0"; +const char* XivelyClient::kApiHost = "api.xively.com"; +const char* XivelyClient::kApiKeyHeader = "X-ApiKey"; + XivelyClient::XivelyClient(Client& aClient) : _client(aClient) { @@ -13,11 +18,10 @@ int XivelyClient::put(XivelyFeed& aFeed, const char* aApiKey) char path[30]; buildPath(path, aFeed.id(), "json"); http.beginRequest(); - int ret = http.put("api.xively.com", path); + int ret = http.put(kApiHost, path, kUserAgent); if (ret == 0) { - http.sendHeader("X-ApiKey", aApiKey); - http.sendHeader("User-Agent", "Xively-Arduino-Lib/1.0"); + http.sendHeader(kApiKeyHeader, aApiKey); CountingStream countingStream; // Used to work out how long that data will be for (int i =kCalculateDataLength; i <= kSendData; i++) @@ -36,7 +40,7 @@ int XivelyClient::put(XivelyFeed& aFeed, const char* aApiKey) if (i == kCalculateDataLength) { // We now know how long the data will be... - http.sendHeader("Content-Length", len); + http.sendHeader(HTTP_HEADER_CONTENT_LENGTH, len); } } // Now we're done sending the request @@ -75,11 +79,10 @@ int XivelyClient::get(XivelyFeed& aFeed, const char* aApiKey) char path[30]; buildPath(path, aFeed.id(), "csv"); http.beginRequest(); - int ret = http.get("api.xively.com", path); + int ret = http.get(kApiHost, path, kUserAgent); if (ret == 0) { - http.sendHeader("X-ApiKey", aApiKey); - http.sendHeader("User-Agent", "Xively-Arduino-Lib/1.0"); + http.sendHeader(kApiKeyHeader, aApiKey); http.endRequest(); ret = http.responseStatusCode(); diff --git a/XivelyClient.h b/XivelyClient.h index e8924a6..f6c49e5 100644 --- a/XivelyClient.h +++ b/XivelyClient.h @@ -14,6 +14,9 @@ class XivelyClient int put(XivelyFeed& aFeed, const char* aApiKey); protected: + static const char* kUserAgent; + static const char* kApiHost; + static const char* kApiKeyHeader; static const int kCalculateDataLength =0; static const int kSendData =1; void buildPath(char* aDest, unsigned long aFeedId, const char* aFormat); From deea6dc1c5b4e3d6f683248f19407a68bf59b50f Mon Sep 17 00:00:00 2001 From: Adrian McEwen Date: Mon, 25 Nov 2013 10:18:14 +0000 Subject: [PATCH 3/3] Added examples using the GSM shield --- .../GSMDatastreamDownload.ino | 76 +++++++++++++++ .../GSMDatastreamUpload.ino | 75 +++++++++++++++ .../GSMMultipleDatastreamsUpload.ino | 95 +++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 examples/GSMDatastreamDownload/GSMDatastreamDownload.ino create mode 100644 examples/GSMDatastreamUpload/GSMDatastreamUpload.ino create mode 100644 examples/GSMMultipleDatastreamsUpload/GSMMultipleDatastreamsUpload.ino diff --git a/examples/GSMDatastreamDownload/GSMDatastreamDownload.ino b/examples/GSMDatastreamDownload/GSMDatastreamDownload.ino new file mode 100644 index 0000000..b6c19b5 --- /dev/null +++ b/examples/GSMDatastreamDownload/GSMDatastreamDownload.ino @@ -0,0 +1,76 @@ +#include +#include +#include +#include + +// Your phone SIM PIN Number +#define PINNUMBER "" + +// Your phone APN data +#define GPRS_APN "GPRS_APN" // replace your GPRS APN +#define GPRS_LOGIN "login" // replace with your GPRS login +#define GPRS_PASSWORD "password" // replace with your GPRS password + +// Your Xively key to let you upload data +char xivelyKey[] = "YOUR_XIVELY_API_KEY"; + +// Define the string for the datastream ID you want to retrieve +char temperatureId[] = "DATASTREAM_ID_TO_RETRIEVE"; + +XivelyDatastream datastreams[] = { + XivelyDatastream(temperatureId, strlen(temperatureId), DATASTREAM_FLOAT), +}; +// Finally, wrap the datastreams into a feed +XivelyFeed feed(FEED_ID_TO_RETRIEVE, datastreams, 1 /* number of datastreams */); + +// initialize the library instance +GSM gsmAccess; // include a 'true' parameter to enable debugging +GPRS gprs; +GSMClient client; +XivelyClient xivelyclient(client); + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("Reading from Xively example"); + Serial.println(); + + // connection state + boolean notConnected = true; + // After starting the modem with GSM.begin() + // attach the shield to the GPRS network with the APN, login and password + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } +} + +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); +} + diff --git a/examples/GSMDatastreamUpload/GSMDatastreamUpload.ino b/examples/GSMDatastreamUpload/GSMDatastreamUpload.ino new file mode 100644 index 0000000..c55c83d --- /dev/null +++ b/examples/GSMDatastreamUpload/GSMDatastreamUpload.ino @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +// Your phone SIM PIN Number +#define PINNUMBER "" + +// Your phone APN data +#define GPRS_APN "eseye.com" // replace your GPRS APN +#define GPRS_LOGIN "" // replace with your GPRS login +#define GPRS_PASSWORD "" // replace with your GPRS password + +// Your Xively key to let you upload data +char xivelyKey[] = "YOUR_XIVELY_API_KEY"; + +// Analog pin which we're monitoring +int sensorPin = 2; + +// Define the strings for our datastream IDs +char sensorId[] = "YOUR_DATASTREAM_ID"; +XivelyDatastream datastreams[] = { + XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT), +}; +// Finally, wrap the datastreams into a feed +XivelyFeed feed(YOUR_FEED_ID, datastreams, 1 /* number of datastreams */); + +// initialize the library instance +GSM gsmAccess; // include a 'true' parameter to enable debugging +GPRS gprs; +GSMClient client; +XivelyClient xivelyclient(client); + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("Starting single datastream upload to Xively..."); + Serial.println(); + + // connection state + boolean notConnected = true; + // After starting the modem with GSM.begin() + // attach the shield to the GPRS network with the APN, login and password + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } +} + +void loop() { + int sensorValue = analogRead(sensorPin); + datastreams[0].setFloat(sensorValue); + + Serial.print("Read sensor value "); + Serial.println(datastreams[0].getFloat()); + + Serial.println("Uploading it to Xively"); + int ret = xivelyclient.put(feed, xivelyKey); + Serial.print("xivelyclient.put returned "); + Serial.println(ret); + + Serial.println(); + delay(15000); +} diff --git a/examples/GSMMultipleDatastreamsUpload/GSMMultipleDatastreamsUpload.ino b/examples/GSMMultipleDatastreamsUpload/GSMMultipleDatastreamsUpload.ino new file mode 100644 index 0000000..f60c3a6 --- /dev/null +++ b/examples/GSMMultipleDatastreamsUpload/GSMMultipleDatastreamsUpload.ino @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +// Your phone SIM PIN Number +#define PINNUMBER "" + +// Your phone APN data +#define GPRS_APN "eseye.com" // replace your GPRS APN +#define GPRS_LOGIN "" // replace with your GPRS login +#define GPRS_PASSWORD "" // replace with your GPRS password + +// Your Xively key to let you upload data +char xivelyKey[] = "YOUR_XIVELY_API_KEY"; + +// Analog pin which we're monitoring +int sensorPin = 2; + +// Define the strings for our datastream IDs +// Replace these with strings that make sense for what you're recording +char sensorId[] = "sensor_reading"; +char bufferId[] = "info_message"; +String stringId("random_string"); +const int bufferSize = 140; +char bufferValue[bufferSize]; // enough space to store the string we're going to send +XivelyDatastream datastreams[] = { + XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT), + XivelyDatastream(bufferId, strlen(bufferId), DATASTREAM_BUFFER, bufferValue, bufferSize), + XivelyDatastream(stringId, DATASTREAM_STRING) +}; +// Finally, wrap the datastreams into a feed +XivelyFeed feed(YOUR_FEED_ID, datastreams, 3 /* number of datastreams */); + +// initialize the library instance +GSM gsmAccess; // include a 'true' parameter to enable debugging +GPRS gprs; +GSMClient client; +XivelyClient xivelyclient(client); + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("Starting multiple datastream upload to Xively..."); + Serial.println(); + + // connection state + boolean notConnected = true; + // After starting the modem with GSM.begin() + // attach the shield to the GPRS network with the APN, login and password + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } +} + +void loop() { + int sensorValue = analogRead(sensorPin); + datastreams[0].setFloat(sensorValue); + + Serial.print("Read sensor value "); + Serial.println(datastreams[0].getFloat()); + + datastreams[1].setBuffer("a message to upload"); + Serial.print("Setting buffer value to:\n "); + Serial.println(datastreams[1].getBuffer()); + + // Pick a random number to send up in a string + String stringValue(random(100)); + stringValue += " is a random number"; + datastreams[2].setString(stringValue); + Serial.print("Setting string value to:\n "); + Serial.println(datastreams[2].getString()); + + Serial.println("Uploading it to Xively"); + int ret = xivelyclient.put(feed, xivelyKey); + Serial.print("xivelyclient.put returned "); + Serial.println(ret); + + Serial.println(); + + delay(15000); +} +