Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Arduino GroveStreams Stream Feed via Ethernet
- The GroveStreams client sketch is designed for the Arduino and Ethernet.
- A full "how to" guide for this sketh can be found at https://www.grovestreams.com/developers/getting_started_arduino_temp.html
- This sketch updates several stream feeds with an analog input reading,
- from a temperature probe, via the GroveStreams API: https://www.grovestreams.com/developers/api.html
- The Arduino uses DHCP and DNS for a simpler network setup.
- The sketch also includes Internet Connection Reset logic to ensure the
- Arduino stays connected and can regain connectivity after a network outage.
- Use the Serial Monitor on the Arduino IDE to see verbose network feedback
- and the GroveStreams connectivity status.
- License:
- Copyright 2014 GroveStreams LLC.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- GroveStreams Setup:
- * Sign Up for Free User Account - https://www.grovestreams.com
- * Create a GroveStreams organization while selecting the Arduino blueprint
- * Enter a unique MAC Address for this network in this sketch under "Local Network Settings"
- * (Newer shields have the mac address on a sticker on the shield. Use that.)
- * (A MAC address can also be generated within a GroveStreams organization: Tools toolbar button - Generate MAC Address)
- * (The MAC address is used to identify this device within GroveStreams. It must be unique within your GS organization)
- * Enter your GroveStreams secret api key under "GroveStreams Settings" in this sketch
- * (The api key can be retrieved from within a GroveStreams organization: click the Api Keys toolbar button,
- * select your Api Key, and click View Secret Key. Paste the Secret Key below)
- Arduino Requirements:
- * Arduino with Ethernet Shield or Arduino Ethernet
- * Arduino 1.0 IDE
- Network Requirements:
- * Ethernet port on Router
- * DHCP enabled on Router
- * Unique MAC Address for Arduino
- Additional Credits:
- Example sketches from Arduino team, Ethernet by David A. Mellis
- Sketch review and advice from Arduino enthusiast and expert David Thompson, http://www.desert-home.com/
- */
- #include <SPI.h>
- #include <Ethernet.h>
- // Local Network Settings
- byte mac[] = {
- 0x90, 0xA2, 0xDA, 0x0E, 0x60, 0xA3 }; // Change this!!! Must be unique on local network.
- // Look for a sticker on the back of your Ethernet shield.
- // GroveStreams Settings
- char gsApiKey[] = "YOUR_SECRET_API_KEY_HERE"; //Change This!!!
- char gsComponentName[] = "Temperature"; //Optionally change. Set this to give your component a name when it initially registers.
- char gsDomain[] = "grovestreams.com"; //Don't change. The GroveStreams domain.
- 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.
- // The blueprint is expecting "temp".
- //GroveStreams Stream IDs. Stream IDs tell GroveStreams which component streams the values will be assigned to.
- //Don't change these unless you edit your GroveStreams component definition and change the stream IDs to match these.
- char gsStreamId1[] = "s1"; //Don't change. Temp C.
- char gsStreamId2[] = "s2"; //Don't change. Temp F.
- // Other Settings
- const unsigned long updateFrequency = 20000UL; // Update frequency in milliseconds (20000 = 20 seconds). Change this to change your sample frequency.
- const int temperaturePin = 0; // You might need to change depending on the Pin you are using. The Temperature pin number.
- char samples[35]; // Change this buffer size only if you increase or decrease the size of samples being uploaded.
- char myIPAddress[20]; //Don't Change. Set below from DHCP. Needed by GroveStreams to verify that a device is not uploading more than once every 10s.
- char myMac[20]; //Don't Change. Set below from the above mac variable. The readable Mac is used by GS to determine which component the
- // feeds are uploading into. It must match an existing GroveStreams component's ID
- unsigned long lastSuccessfulUploadTime = 0; //Don't change. Used to determine if samples need to be uploaded.
- int failedCounter = 0; //Don't change. Used for Internet Connection Reset logic
- // Initialize Arduino Ethernet Client
- EthernetClient client;
- void setup()
- {
- // Start Serial for debugging on the Serial Monitor
- Serial.begin(9600);
- // Start Ethernet on Arduino
- startEthernet();
- }
- void loop()
- {
- // Update sensor data to GroveStreams
- if(millis() - lastSuccessfulUploadTime > updateFrequency)
- {
- updateGroveStreams();
- }
- }
- void updateGroveStreams()
- {
- //Assemble the url that is used to pass the temperature readings to GroveStreams and call it
- unsigned long connectAttemptTime = millis();
- if (client.connect(gsDomain, 80))
- {
- //You may need to increase the size of urlBuf if any other char array sizes have increased
- char urlBuf[175];
- sprintf(urlBuf, "PUT /api/feed?compTmplId=%s&compId=%s&compName=%s&api_key=%s%s HTTP/1.1",
- gsComponentTemplateId, myMac, gsComponentName, gsApiKey, getSamples());
- //Uncomment the next three lines for debugging purposes
- Serial.println(urlBuf);
- //Serial.print(F("urlBuf length = "));
- //Serial.println(strlen(urlBuf));
- client.println(urlBuf); //Send the url with temp readings in one println(..) to decrease the chance of dropped packets
- client.print(F("Host: "));
- client.println();
- client.println(F("Connection: close"));
- client.print(F("X-Forwarded-For: ")); //Include this line and the next line if you have more than one device uploading behind
- client.println(myIPAddress); // your outward facing router (avoids the GS 10 second upload rule)
- client.println(F("Content-Type: application/json"));
- client.println();
- if (client.connected())
- {
- //Begin Report Response
- while(!client.available())
- {
- delay(1);
- }
- while(client.available())
- {
- char c = client.read();
- Serial.print(c);
- }
- //End Report Response
- //Client is now disconnected; stop it to cleannup.
- client.stop();
- lastSuccessfulUploadTime = connectAttemptTime;
- failedCounter = 0;
- }
- else
- {
- handleConnectionFailure();
- }
- }
- else
- {
- handleConnectionFailure();
- }
- }
- void handleConnectionFailure() {
- //Connection failed. Increase failed counter
- failedCounter++;
- Serial.print(F("Connection to GroveStreams Failed "));
- Serial.print(failedCounter);
- Serial.println(F(" times"));
- delay(1000);
- // Check if Arduino Ethernet needs to be restarted
- if (failedCounter > 3 )
- {
- //Too many failures. Restart Ethernet.
- startEthernet();
- }
- }
- void startEthernet()
- {
- //Start or restart the Ethernet connection.
- client.stop();
- Serial.println(F("Connecting Arduino to network..."));
- Serial.println();
- //Wait for the connection to finish stopping
- delay(2000);
- //Connect to the network and obtain an IP address using DHCP
- if (Ethernet.begin(mac) == 0)
- {
- Serial.println(F("DHCP Failed, reset your Arduino and try again"));
- Serial.println();
- }
- else
- {
- Serial.println(F("Arduino connected to network using DHCP"));
- //Set the mac and ip variables so that they can be used during sensor uploads later
- Serial.print(F(" MAC: "));
- Serial.println(getMacReadable());
- Serial.print(F(" IP address: "));
- Serial.println(getIpReadable(Ethernet.localIP()));
- Serial.println();
- }
- }
- char* getMacReadable()
- {
- //Convert the mac address to a readable string
- sprintf(myMac, "%02x:%02x:%02x:%02x:%02x:%02x\0", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- return myMac;
- }
- char* getIpReadable(IPAddress ipAddress)
- {
- //Convert the ip address to a readable string
- unsigned char octet[4] = {0,0,0,0};
- for (int i=0; i<4; i++)
- {
- octet[i] = ( ipAddress >> (i*8) ) & 0xFF;
- }
- sprintf(myIPAddress, "%d.%d.%d.%d\0",octet[0],octet[1],octet[2],octet[3]);
- return myIPAddress;
- }
- char* getSamples()
- {
- //Get the temperature analog reading and convert it to a string
- float voltage, degreesC, degreesF;
- voltage = (analogRead(temperaturePin) * 0.004882814);
- degreesC = (voltage - 0.5) * 100.0;
- degreesF = degreesC * (9.0/5.0) + 32.0;
- char tempC[15] = {0}; //Initialize buffer to nulls
- dtostrf(degreesC, 12, 3, tempC); //Convert float to string
- char tempF[15] = {0}; //Initialize buffer to nulls
- dtostrf(degreesF, 12, 3, tempF); //Convert float to string
- //Assemble the samples into URL parameters which are seperated with the "&" character
- //
- // Example: &s1=25.684&s2=78.231
- sprintf(samples, "&%s=%s&%s=%s", gsStreamId1, trim(tempC), gsStreamId2, trim(tempF));
- return samples;
- }
- char* trim(char* input)
- {
- //Trim leading and ending spaces
- int i,j;
- char *output=input;
- for (i = 0, j = 0; i<strlen(input); i++,j++)
- {
- if (input[i]!=' ')
- output[j]=input[i];
- else
- j--;
- }
- output[j]=0;
- return output;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement