Advertisement
mikecmills2

GroveStreams Arduino YUN Control Sketch

Feb 7th, 2015
2,763
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.99 KB | None | 0 0
  1. /*
  2.  
  3.  Arduino GroveStreams Stream Feed via Ethernet
  4.  
  5.  The GroveStreams client sketch is designed for the Arduino YUN.
  6.  A full "how to" guide for this sketh can be found at https://www.grovestreams.com/developers/getting_started_arduino_yun_control.html
  7.  This sketch updates several stream feeds with an analog input reading,
  8.  from a temperature probe, via the GroveStreams API: https://www.grovestreams.com/developers/api.html
  9.  It also checks for LED on/off commands, a sampleFrequency setting, and takes appropriate action(s).
  10.  Use the Serial Monitor on the Arduino IDE to see verbose network feedback
  11.  and the GroveStreams connectivity status.
  12.  
  13.  License:
  14.   Copyright 2015 GroveStreams LLC.
  15.   Licensed under the Apache License, Version 2.0 (the "License");
  16.   you may not use this file except in compliance with the License.
  17.   You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
  18.  
  19.   Unless required by applicable law or agreed to in writing, software
  20.   distributed under the License is distributed on an "AS IS" BASIS,
  21.   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22.   See the License for the specific language governing permissions and
  23.   limitations under the License.
  24.  
  25.  GroveStreams Setup:
  26.  
  27.  * Sign Up for Free User Account - https://www.grovestreams.com
  28.  * Create a GroveStreams organization while selecting the Arduino blueprint
  29.  * Enter a unique MAC Address for this network in this sketch under "Local Network Settings"
  30.  *    Navigate to http://arduino.local/ to find your YUN's MAC address
  31.  * Enter your GroveStreams secret api key under "GroveStreams Settings" in this sketch
  32.  *    (The api key can be retrieved from within a GroveStreams organization: click the Api Keys toolbar button,
  33.  *     select your Api Key, and click View Secret Key. Paste the Secret Key below)
  34.  
  35.  Arduino Requirements:
  36.  
  37.  * Arduino YUN
  38.  * Arduino 1.5.8 IDE
  39.  * ArduinoJson.h: https://github.com/bblanchon/ArduinoJson/wiki
  40. */
  41.  
  42. #include <Bridge.h>
  43. #include <Process.h>
  44. #include <ArduinoJson.h>
  45.  
  46.  
  47. // Local Network Settings
  48. char mac[] = "90:A2:DA:F5:01:C7"; // Change this!!! Must be unique on local network.
  49. // Browse to your YUN to find it: http://arduino.local/
  50.  
  51. // GroveStreams Settings
  52. char gsApiKey[] = "YOUR_SECRET_API_KEY_HERE";   //Change This!!!
  53. char gsComponentName[] = "Temperature";        //Optionally change. Set this to give your component a name when it initially registers.
  54.  
  55. char gsComponentTemplateId[] = "temp";  //Don't change. Tells GS what template to use when the feed initially arrives and a new component needs to be created.
  56. // The blueprint is expecting "temp".
  57.  
  58. //GroveStreams Stream IDs. Stream IDs tell GroveStreams which component streams the values will be assigned to.
  59. //Don't change these unless you edit your GroveStreams component definition and change the stream IDs to match these.
  60. char gsStreamId1[] = "s1";   //Don't change. Temp C.
  61. char gsStreamId2[] = "s2";   //Don't change. Temp F.
  62.  
  63. // Other Settings
  64. unsigned long updateFrequency = 10000UL;    // Update frequency in milliseconds (20000 = 20 seconds). Change this to change your sample frequency.
  65.  
  66. const int temperaturePin = 0;  // You might need to change depending on the Pin you are using. The Temperature pin number.
  67. const int ledPin = 13;                 // You might need to change depending on the Pin you are using. The LED pin number.
  68.  
  69. char samples[40];                   // Change this buffer size only if you increase or decrease the size of samples being uploaded.
  70.  
  71. unsigned long lastUploadTime = 0; //Don't change. Used to determine if samples need to be uploaded.
  72.  
  73.  
  74. void setup() {
  75.  
  76.   Bridge.begin();
  77.  
  78.   Serial.begin(9600);
  79.   while (!Serial);
  80.  
  81.   //Wait for the connection to finish stopping
  82.   delay(2500);
  83.  
  84.   //Set the mac and ip variables so that they can be used during sensor uploads later
  85.   Serial.print("MAC: ");
  86.   Serial.println(mac);
  87.   Serial.println();
  88.  
  89.   pinMode(ledPin, OUTPUT);
  90. }
  91.  
  92. void loop() {
  93.  
  94.   // Update sensor data to GroveStreams
  95.   if (millis() - lastUploadTime > updateFrequency)
  96.   {
  97.     updateGroveStreams();
  98.   }
  99.  
  100. }
  101.  
  102. void updateGroveStreams() {
  103.   Serial.println("updateGroveStreams...");
  104.  
  105.   //Assemble the url that is used to pass the temperature readings to GroveStreams; Include request stream IDs
  106.   lastUploadTime = millis();
  107.  
  108.   int urlBufSize = 210;
  109.   char urlBuf[urlBufSize];
  110.  
  111.   //Include the rsid (request stream ID) parameter for each stream's last_value to be returned. Below we are requesting the
  112.   // sample frequency and the led indicator stream last_values
  113.   sprintf(urlBuf, "http://grovestreams.com/api/feed?compTmplId=%s&compId=%s&compName=%s&rsid=freq&rsid=led&api_key=%s%s",
  114.           gsComponentTemplateId, mac, gsComponentName, gsApiKey, getSamples());
  115.  
  116.   char xHeadBuf[40];
  117.   sprintf(xHeadBuf, "X-Forwarded-For:%s", mac);
  118.  
  119.   //Uncomment the following lines to debug your strings and to ensure their buffers are large enough
  120.   //Serial.println(strlen(xHeadBuf));
  121.   //Serial.println(xHeadBuf);
  122.   //Serial.println(urlBuf);
  123.   //Serial.println(strlen(urlBuf));
  124.   //Serial.println(getSamples());
  125.   //Serial.println(strlen(getSamples()));
  126.  
  127.   if (strlen(urlBuf) > urlBufSize) {
  128.     Serial.println("urlBuf string buffer too small! Increase urlBufSize.");
  129.   }
  130.  
  131.   Process process;
  132.   process.begin("curl");
  133.   process.addParameter("-d");
  134.   process.addParameter("");
  135.   process.addParameter("-k");
  136.   process.addParameter("-X");
  137.   process.addParameter("PUT");
  138.  
  139.   //Headers
  140.   process.addParameter("-H");
  141.   process.addParameter(xHeadBuf);
  142.   process.addParameter("-H");
  143.   process.addParameter("Connection:close");
  144.   process.addParameter("-H");
  145.   process.addParameter("Content-Type:application/json");
  146.  
  147.   //URL
  148.   process.addParameter(urlBuf);
  149.  
  150.   //Make the request
  151.   unsigned int result = process.run();
  152.  
  153.   //Display whatever is returned (usually an error message or requested return streams)
  154.   char response[50] = {0}; //Initialize buffer to nulls;
  155.   int i = 0;
  156.   while (process.available() > 0) {
  157.     char c = process.read();
  158.     if (i < 50) {
  159.       response[i++] = c;
  160.     } else if (i == 50) {
  161.       Serial.println("response string buffer too small!");
  162.     }
  163.     Serial.print(c);
  164.   }
  165.   Serial.flush();
  166.  
  167.   Serial.print("\nFeed PUT Response Code: ");
  168.   Serial.println(result);
  169.   Serial.print("Feed PUT Response Body: ");
  170.   Serial.println(response);
  171.  
  172.   if (strlen(response) == 0) {
  173.     return;
  174.   }
  175.  
  176.   //Extract Return Stream last_values from the JSON returned
  177.   StaticJsonBuffer<200> jsonBuffer;
  178.  
  179.   JsonObject& root = jsonBuffer.parseObject(response);
  180.   if (!root.success()) {
  181.     Serial.println("parseObject() failed");
  182.     return;
  183.   }
  184.  
  185.   if (root.containsKey("freq") && root["freq"] >= 10000) {
  186.     //Set the update Frequency
  187.     updateFrequency = root["freq"];
  188.   }
  189.  
  190.   if (root.containsKey("led")) {
  191.     bool ledOn = (bool)root["led"];
  192.  
  193.     //Handle led command
  194.     if (ledOn && digitalRead(ledPin) == LOW) {
  195.       digitalWrite(ledPin, HIGH);
  196.     } else if (!ledOn && digitalRead(ledPin) == HIGH) {
  197.       digitalWrite(ledPin, LOW);
  198.     }
  199.  
  200.   }
  201.  
  202.   Serial.println("");
  203. }
  204.  
  205. char* getSamples() {
  206.   //Get the temperature analog reading and convert it to a string
  207.  
  208.   float voltage, degreesC, degreesF;
  209.  
  210.   voltage = (analogRead(temperaturePin) * 0.004882814);
  211.   degreesC = (voltage - 0.5) * 100.0;
  212.   degreesF = degreesC * (9.0 / 5.0) + 32.0;
  213.  
  214.   char tempC[15] = {0}; //Initialize buffer to nulls
  215.   dtostrf(degreesC, 12, 3, tempC); //Convert float to string
  216.  
  217.   char tempF[15] = {0}; //Initialize buffer to nulls
  218.   dtostrf(degreesF, 12, 3, tempF); //Convert float to string
  219.  
  220.   // Example: &s1=25.684&s2=78.231
  221.   sprintf(samples, "&%s=%s&%s=%s", gsStreamId1, trim(tempC), gsStreamId2, trim(tempF));
  222.  
  223.   return samples;
  224. }
  225.  
  226. char* trim(char* input) {
  227.   //Trim leading and ending spaces
  228.  
  229.   int i, j;
  230.   char *output = input;
  231.   for (i = 0, j = 0; i < strlen(input); i++, j++)
  232.   {
  233.     if (input[i] != ' ')
  234.       output[j] = input[i];
  235.     else
  236.       j--;
  237.   }
  238.   output[j] = 0;
  239.  
  240.   return output;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement