├── LICENSE.txt ├── README.md ├── arduino-ethernet-example.ino ├── arduinoESP8266wifishieldstream-AT.ino ├── arduinoESP8266wifishieldstream.ino ├── arduinociaoexample.ino ├── arduinoethernetshieldstream.ino └── arduinoyunstream.ino /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Initial State 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Streaming with Arduino 2 | 3 | 4 | ![arduinolaptop](https://user-images.githubusercontent.com/10930201/27447855-3ed7820c-5748-11e7-8616-0c757e2724da.png) 5 | 6 | 7 | arduinoyunstream.ino (cURL) 8 | -------------------- 9 | 10 | Arduino Yun Sketch implementation of the Initial State events api to easily send data using the Process class. 11 | 12 | You are required to provide your accessKey, bucketKey, bucketName, number of signals to be streamed, and signal names. 13 | 14 | The sketch will not currently return the cURL output, so be sure to check your Initial State account to ensure that your data is actually sending. 15 | 16 | arduinoESP8266wifishieldstream.ino / arduinoESP8266wifishieldstream-AT.ino (HTTP POST) 17 | --------------------------- 18 | 19 | Arduino Sketch implementation of the Initial State events api to easily send data using an ESP8266 WiFi shield. 20 | 21 | The first sketch handles ESP8266 boards that do not require AT commands. The second sketch uses the ESP8266 connected to the Cactus Micro board, which requires AT commands. Both should be easily adaptable to whatever Arduino/Shield combo you are using. 22 | 23 | You are required to provide your accessKey, bucketKey, bucketName, number of signals to be streamed, signal names, WiFi SSID and password. 24 | 25 | You may need to wait a minute or so for the module to connect to the groker.initialstate.com service. 26 | 27 | NOTE: This uses the "insecure" Initial State API endpoint since many Arduinos can't handle https. For more secure streaming, route through a device capable of encryption (like a node.js hub). 28 | 29 | arduino-ethernet-example.ino (HTTP GET) 30 | --------------------------- 31 | 32 | Arduino Sketch implementation of the Initial State events api to easily send data using an Ethernet shield. 33 | 34 | You are required to provide your accessKey, bucketKey, bucketName, number of signals to be streamed, signal names. 35 | 36 | NOTE: This uses the "insecure" Initial State API endpoint since many Arduinos can't handle https. For more secure streaming, route through a device capable of encryption (like a node.js hub). 37 | 38 | arduinociaostream.ino (URL Parameters) 39 | --------------------------- 40 | 41 | Arduino Sketch implementation of the Initial State events api to easily send data using the [Ciao library](http://www.arduino.org/learning/tutorials/advanced-guides/ciao). 42 | 43 | Current Ciao compatible boards include: Arduino Yun, Arduino Yun Mini, Linino One, Arduino Tian, Arduino Industrial 101 44 | 45 | You are required to provide your accessKey, bucketKey, signal names. 46 | 47 | NOTE: This uses the "insecure" Initial State API endpoint since many Arduinos can't handle https. For more secure streaming, route through a device capable of encryption (like a node.js hub). 48 | 49 | -------------------------------------------------------------------------------- /arduino-ethernet-example.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Web client 3 | This sketch sends an event to Initial State (http://insecure-groker.initialstate.com) 4 | using an Arduino Wiznet Ethernet shield. 5 | Circuit: 6 | * Ethernet shield attached to pins 10, 11, 12, 13 7 | created 18 Dec 2009 8 | by David A. Mellis 9 | modified 9 Apr 2012 10 | by Tom Igoe, based on work by Adrian McEwen 11 | modified 25 Aug 2016 12 | by David Sulpy, based on work by authors above to change from google.com to initialstate.com 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | // Enter a MAC address for your controller below. 19 | // Newer Ethernet shields have a MAC address printed on a sticker on the shield 20 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 21 | // if you don't want to use DNS (and reduce your sketch size) 22 | // use the numeric IP instead of the name for the server: 23 | //IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) 24 | char server[] = "insecure-groker.initialstate.com"; // name address for Google (using DNS) 25 | 26 | // Set the static IP address to use if the DHCP fails to assign 27 | IPAddress ip(192, 168, 0, 177); 28 | 29 | // Initialize the Ethernet client library 30 | // with the IP address and port of the server 31 | // that you want to connect to (port 80 is default for HTTP): 32 | EthernetClient client; 33 | 34 | void setup() { 35 | // Open serial communications and wait for port to open: 36 | Serial.begin(9600); 37 | while (!Serial) { 38 | ; // wait for serial port to connect. Needed for native USB port only 39 | } 40 | 41 | // start the Ethernet connection: 42 | if (Ethernet.begin(mac) == 0) { 43 | Serial.println("Failed to configure Ethernet using DHCP"); 44 | // try to congifure using IP address instead of DHCP: 45 | Ethernet.begin(mac, ip); 46 | } 47 | // give the Ethernet shield a second to initialize: 48 | delay(1000); 49 | Serial.println("connecting..."); 50 | 51 | // if you get a connection, report back via serial: 52 | if (client.connect(server, 80) > 0) { 53 | Serial.println("connected"); 54 | // Make a HTTP request: 55 | client.println("GET /api/events?accessKey=YOUR_ACCESS_KEY&bucketKey=SOME_BUCKET_KEY&streamKey=1 HTTP/1.1"); 56 | client.println("Host: insecure-groker.initialstate.com"); 57 | client.println("Connection: close"); 58 | client.println(); 59 | } else { 60 | // if you didn't get a connection to the server: 61 | Serial.println("connection failed"); 62 | } 63 | } 64 | 65 | void loop() { 66 | // if there are incoming bytes available 67 | // from the server, read them and print them: 68 | if (client.available()) { 69 | char c = client.read(); 70 | Serial.print(c); 71 | } 72 | 73 | // if the server's disconnected, stop the client: 74 | if (!client.connected()) { 75 | Serial.println(); 76 | Serial.println("disconnecting."); 77 | client.stop(); 78 | 79 | // do nothing forevermore: 80 | while (true); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /arduinoESP8266wifishieldstream-AT.ino: -------------------------------------------------------------------------------- 1 | // Will work only with ESP8266 firmware 0.9.2.2 or higher 2 | // Some particulars of this sketch are for the Cactus Micro board, 3 | // but it can be adapted for any Arduino 4 | // Special thanks to David Reeves for his help 5 | 6 | // This sketch uses Software Serial, which is the current default for the Cactus Micro board 7 | // If you are using Hardware Serial, you will need to change this line and any with "myserial" 8 | #include 9 | 10 | 11 | //////////////////////////// 12 | // Initial State Streamer // 13 | //////////////////////////// 14 | 15 | // Data destination 16 | // https can't be handled by the ESP8266, thus "insecure" 17 | #define ISDestURL "insecure-groker.initialstate.com" 18 | // Bucket key (hidden reference to your bucket that allows appending): 19 | #define bucketKey "arduino" 20 | // Bucket name (name your data will be associated with in Initial State): 21 | #define bucketName "Arduino Stream" 22 | // Access key (the one you find in your account settings): 23 | #define accessKey "Your_Access_Key_Here" 24 | // How many signals are in your stream? You can have as few or as many as you want 25 | const int NUM_SIGNALS = 3; 26 | // What are the names of your signals (i.e. "Temperature", "Humidity", etc.) 27 | String signalName[NUM_SIGNALS] = {"Signal 1", "Signal 2", "Signal 3"}; 28 | // This array is to store our signal data later 29 | String signalData[NUM_SIGNALS]; 30 | 31 | 32 | // WiFi SSID 33 | #define SSID "SSID" 34 | // WiFi password 35 | #define PASS "password" 36 | 37 | 38 | // CH_PD pin - Used by Cactus Micro to enable ESP8266 39 | #define RESET 13 40 | // RST pin - ESP8266 reset pin 41 | #define RST 5 42 | 43 | // Timeout in milliseconds 44 | #define TIMEOUT 5000 45 | #define CONTINUE false 46 | #define HALT true 47 | 48 | // TCP can only send a payload size of 290 when using Software Serial 49 | // This is not an issue when using Hardware Serial 50 | // 30 is how many characters are free for bucketKey, signalName, and signalData 51 | const int TCPLengthCap = 30; 52 | 53 | // The Cactus Micro's TX and RX 54 | SoftwareSerial mySerial(11, 12); 55 | 56 | 57 | // This only runs once at the very beginning 58 | void setup() { 59 | 60 | Serial.begin(9600); 61 | // Communication with ESP8266 62 | mySerial.begin(9600); 63 | 64 | // Enable RST pin 65 | digitalWrite(RST, 1); 66 | // Enable CH_PD pin 67 | digitalWrite(RESET, 1); 68 | // Wait for chip enable 69 | delay(2000); 70 | 71 | Serial.println("ESP8266 A0 Monitor"); 72 | reset(); 73 | // Wait for reset to complete 74 | delay(5000); 75 | 76 | // Reset & test if the module is ready 77 | echoCommand("AT+RST", "Ready", HALT); 78 | delay(5000); 79 | echoCommand("AT+CSYSWDTENABLE", "WDT Enabled", HALT); 80 | delay(500); 81 | Serial.println("Module is ready."); 82 | 83 | // Set up connection modes 84 | // Retrieves the firmware ID (version number) of the module. 85 | echoCommand("AT+GMR", "OK", CONTINUE); 86 | // Station mode 87 | echoCommand("AT+CWMODE=3", "", HALT); 88 | // Allow one connection 89 | echoCommand("AT+CIPMUX=0", "", HALT); 90 | 91 | // Connect to the wifi 92 | boolean connection_established = false; 93 | for(int i=0;i<5;i++) 94 | { 95 | if(connectWiFi()) 96 | { 97 | connection_established = true; 98 | delay(5000); 99 | break; 100 | } 101 | } 102 | if (!connection_established) errorHalt("Connection failed"); 103 | delay(5000); 104 | 105 | // Echo IP address. 106 | echoCommand("AT+CIFSR", "", HALT); 107 | 108 | // Initialize random number generation for our example signals 109 | randomSeed (millis()); 110 | 111 | // The postBucket() function creates a bucket 112 | // (unnecessary if the bucket already exists) 113 | while (!postBucket()) {}; 114 | } 115 | 116 | // This repeats 117 | void loop() 118 | { 119 | // Reset ESP8266 each time around 120 | reset(); 121 | delay(5000); 122 | 123 | // Gather Data 124 | // Read from a port for input or output or generate your own values/messages 125 | // These signals are random numbers for the sake of example 126 | signalData[0] = String(random(18,25)); 127 | signalData[1] = String(random(1, 100)); 128 | signalData[2] = String("Alert"); 129 | 130 | // The postData() function streams our events 131 | while(!postData()); 132 | 133 | // Wait for 5 seconds before collecting and sending the next batch 134 | delay(5000); 135 | } 136 | 137 | 138 | 139 | // Here are the data bucket creation, event data posting, error handling, 140 | // and WiFi connection functions 141 | // They do not need to be edited - everything you would need to change for 142 | // your project can be found above 143 | 144 | boolean postBucket () 145 | { 146 | // Must be connected to your destination URL 147 | while(!connectService(ISDestURL,80)) {}; 148 | 149 | // Get connection status 150 | if (!echoCommand("AT+CIPSTATUS", "OK", CONTINUE)) return false; 151 | 152 | // Build HTTP request. 153 | String toSend = "POST /api/buckets HTTP/1.1\r\n"; 154 | toSend += "Host: "ISDestURL"\r\n" ; 155 | toSend += "User-Agent:Arduino\r\n"; 156 | toSend += "Accept-Version: ~0\r\n"; 157 | toSend += "X-IS-AccessKey: " accessKey "\r\n"; 158 | toSend += "Content-Type: application/json\r\n"; 159 | String payload = "{\"bucketKey\": \"" bucketKey "\","; 160 | payload += "\"bucketName\": \"" bucketName "\"}"; 161 | payload += "\r\n"; 162 | toSend += "Content-Length: "+String(payload.length())+"\r\n"; 163 | toSend += "\r\n"; 164 | toSend += payload; 165 | 166 | Serial.println(toSend); 167 | 168 | // Ready the module to receive raw data 169 | if (!echoCommand("AT+CIPSEND="+String(toSend.length()), ">", CONTINUE)) 170 | { 171 | echoCommand("AT+CIPCLOSE", "", CONTINUE); 172 | Serial.println("Connection timeout."); 173 | return false; 174 | } 175 | 176 | // Send the raw HTTP request 177 | // POST 178 | if(!echoCommand(toSend,"20", CONTINUE)) return false; 179 | Serial.println("Bucket Created or Exists"); 180 | 181 | return true; 182 | } 183 | 184 | boolean postData() 185 | { 186 | // Must be connected to your destination URL 187 | if (!connectService(ISDestURL,80)) return false; 188 | 189 | // Get connection status 190 | if (!echoCommand("AT+CIPSTATUS", "OK", CONTINUE)) return false; 191 | 192 | // Build HTTP request. 193 | for (int i=0; i", CONTINUE)) 217 | { 218 | echoCommand("AT+CIPCLOSE", "", CONTINUE); 219 | Serial.println("Connection timeout."); 220 | return false; 221 | } 222 | 223 | // Send the raw HTTP request 224 | // POST 225 | if(!echoCommand(toSend,"204", CONTINUE)) return false; 226 | String toPrint = "Data batch "; 227 | toPrint += i; 228 | toPrint += " posted!"; 229 | Serial.println(toPrint); 230 | } 231 | 232 | return true; 233 | } 234 | 235 | // This function can be deleted if using Hardware Serial 236 | void truncateString(int sigNum) 237 | { 238 | int variableLength = (sizeof(bucketKey) + signalName[sigNum].length() + signalData[sigNum].length()); 239 | int eventValueLength = (30 - sizeof(bucketKey)); 240 | 241 | if (variableLength > TCPLengthCap) 242 | { 243 | int halfEventValueLength; 244 | 245 | if ((eventValueLength & 1) == 0) 246 | halfEventValueLength = (eventValueLength/2); 247 | else 248 | halfEventValueLength = ((eventValueLength-1)/2); 249 | 250 | signalName[sigNum] = signalName[sigNum].substring(0,halfEventValueLength); 251 | signalData[sigNum] = signalData[sigNum].substring(0,halfEventValueLength); 252 | } 253 | } 254 | 255 | // Print error message and loop stop. 256 | void errorHalt(String msg) 257 | { 258 | Serial.println(msg); 259 | Serial.println("HALT"); 260 | while(true){}; 261 | } 262 | 263 | // Read characters from WiFi module and echo to serial until keyword occurs or timeout. 264 | boolean echoFind(String keyword) 265 | { 266 | byte current_char = 0; 267 | byte keyword_length = keyword.length(); 268 | 269 | // Fail if the target string has not been sent by deadline. 270 | unsigned long deadline = millis() + TIMEOUT; 271 | while(millis() < deadline) 272 | { 273 | if (mySerial.available()) 274 | { 275 | char ch = mySerial.read(); 276 | Serial.write(ch); 277 | 278 | if (ch == keyword[current_char]) 279 | if (++current_char == keyword_length) 280 | { 281 | Serial.println(); 282 | return true; 283 | } 284 | } 285 | } 286 | // Timed out 287 | return false; 288 | } 289 | 290 | // Read and echo all available module output. 291 | // (Used when we're indifferent to "OK" vs. "no change" responses or to get around firmware bugs.) 292 | void echoFlush() 293 | {while(mySerial.available()) Serial.write(mySerial.read());} 294 | 295 | // Echo module output until 3 newlines encountered. 296 | // (Used when we're indifferent to "OK" vs. "no change" responses.) 297 | void echoSkip() 298 | { 299 | echoFind("\n"); // Search for nl at end of command echo 300 | echoFind("\n"); // Search for 2nd nl at end of response. 301 | echoFind("\n"); // Search for 3rd nl at end of blank line. 302 | } 303 | 304 | // Send a command to the module and wait for acknowledgement string 305 | // (or flush module output if no ack specified). 306 | // Echoes all data received to the serial monitor. 307 | boolean echoCommand(String cmd, String ack, boolean halt_on_fail) 308 | { 309 | mySerial.println(cmd); 310 | #ifdef ECHO_COMMANDS 311 | Serial.print("--"); Serial.println(cmd); 312 | #endif 313 | 314 | // If no ack response specified, skip all available module output. 315 | if (ack == "") 316 | echoSkip(); 317 | else 318 | // Otherwise wait for ack. 319 | // Timed out waiting for ack string 320 | if (!echoFind(ack)) 321 | if (halt_on_fail) 322 | // Critical failure halt. 323 | errorHalt(cmd+" failed"); 324 | else 325 | // Let the caller handle it. 326 | return false; 327 | // Ack blank or ack found 328 | return true; 329 | } 330 | 331 | // Connect to the specified wireless network. 332 | boolean connectWiFi() 333 | { 334 | String cmd = "AT+CWJAP=\"" SSID "\",\"" PASS "\""; 335 | // Join Access Point 336 | if (echoCommand(cmd, "OK", CONTINUE)) 337 | { 338 | Serial.println("Connected to WiFi."); 339 | return true; 340 | } 341 | else 342 | { 343 | Serial.println("Connection to WiFi failed."); 344 | return false; 345 | } 346 | } 347 | 348 | boolean connectService(String service, int port) 349 | { 350 | String serviceConnect = "AT+CIPSTART=\"TCP\",\"" + service + "\"," + port; 351 | // Handle connection errors 352 | if (!echoCommand(serviceConnect, "Linked", CONTINUE)) { 353 | if (echoCommand(serviceConnect, "ALREADY CONNECT", CONTINUE)){ 354 | return true; 355 | } 356 | if (echoCommand(serviceConnect, "busy p...", CONTINUE)) { 357 | reset(); 358 | delay(5000); 359 | } 360 | if (echoCommand(serviceConnect, "ERROR", CONTINUE)) { 361 | reset(); 362 | delay(5000); 363 | } 364 | delay(2000); 365 | return false; 366 | } 367 | delay(2000); 368 | return true; 369 | } 370 | 371 | void reset() 372 | { 373 | digitalWrite(RESET,LOW); 374 | delay(1000); 375 | digitalWrite(RESET,HIGH); 376 | delay(1000); 377 | } 378 | -------------------------------------------------------------------------------- /arduinoESP8266wifishieldstream.ino: -------------------------------------------------------------------------------- 1 | // Should work with most ESP8266 boards. 2 | // Special thanks to Kurt Lanes for providing the example 3 | 4 | #include 5 | 6 | #include 7 | 8 | //////////////////////////// 9 | // Initial State Streamer // 10 | //////////////////////////// 11 | // Data destination 12 | #define ISDestURL "insecure-groker.initialstate.com" // https can't be handled by the ESP8266, thus "insecure" 13 | #define bucketKey "arduino" // Bucket key (hidden reference to your bucket that allows appending): 14 | #define bucketName "Arduino Stream" // Bucket name (name your data will be associated with in Initial State): 15 | #define accessKey "Your_IS_Access_Key" // Access key (the one you find in your account settings): 16 | 17 | const int NUM_SIGNALS = 2; // How many signals are in your stream? You can have as few or as many as you want 18 | String signalName[NUM_SIGNALS] = {"Signal 1", "Signal 2"}; // What are the names of your signals (i.e. "Temperature", "Humidity", etc.) 19 | 20 | String signalData[NUM_SIGNALS]; // This array is to store our signal data later 21 | 22 | ///////////// 23 | // Signals // 24 | //////////// 25 | 26 | //Signal number 1 27 | int i = 0; 28 | //Signal number 2 29 | bool increase = true; 30 | 31 | ////////////////////// 32 | // Network Settings // 33 | ///////////////////// 34 | 35 | char ssid[] = "WiFi_SSID"; // your network SSID (name) 36 | char password[] = "WiFi_PW"; // your network password 37 | 38 | WiFiClient client; // initialize the library instance: 39 | 40 | void setup() { 41 | Serial.begin(115200); 42 | delay(10); 43 | 44 | // We start by connecting to a WiFi network 45 | 46 | Serial.println(); 47 | Serial.println(); 48 | Serial.print("Connecting to "); 49 | Serial.println(ssid); 50 | 51 | WiFi.begin(ssid, password); 52 | 53 | while (WiFi.status() != WL_CONNECTED) { 54 | delay(500); 55 | Serial.print("."); 56 | } 57 | 58 | Serial.println(""); 59 | Serial.println("WiFi connected"); 60 | Serial.println("IP address: "); 61 | Serial.println(WiFi.localIP()); 62 | 63 | // The postBucket() function creates a bucket 64 | // (unnecessary if the bucket already exists) 65 | while (!postBucket()) {}; 66 | } 67 | 68 | void loop() { 69 | 70 | // if there's incoming data from the net connection. 71 | // send it out the serial port. This is for debugging 72 | // purposes only: 73 | if (client.available()) { 74 | char c = client.read(); 75 | Serial.write(c); 76 | } 77 | 78 | // these lines generate a random signal that can be easily understood on the dashboard 79 | if (increase) 80 | { 81 | i = i + 1; 82 | if (i == 10) 83 | { 84 | increase = false; 85 | } 86 | } 87 | else 88 | { 89 | i = i - 1; 90 | if (i == 0) 91 | { 92 | increase = true; 93 | } 94 | } 95 | 96 | // Gather Data 97 | // Read from a port for input or output or generate your own values/messages 98 | signalData[0] = String(i); 99 | signalData[1] = String(increase); 100 | 101 | // The postData() function streams our events 102 | while(!postData()); 103 | 104 | // Wait for 1 seconds before collecting and sending the next batch 105 | delay(1000); 106 | 107 | } 108 | 109 | 110 | 111 | // this method makes a HTTP connection to the server and creates a bucket is it does not exist: 112 | bool postBucket() { 113 | // close any connection before send a new request. 114 | // This will free the socket on the WiFi shield 115 | client.stop(); 116 | 117 | // if there's a successful connection: 118 | if (client.connect(ISDestURL, 80) > 0) { 119 | Serial.println("connecting..."); 120 | // send the HTTP PUT request: 121 | // Build HTTP request. 122 | String toSend = "POST /api/buckets HTTP/1.1\r\n"; 123 | toSend += "Host:"; 124 | toSend += ISDestURL; 125 | toSend += "\r\n" ; 126 | toSend += "User-Agent:Arduino\r\n"; 127 | toSend += "Accept-Version: ~0\r\n"; 128 | toSend += "X-IS-AccessKey: " accessKey "\r\n"; 129 | toSend += "Content-Type: application/json\r\n"; 130 | String payload = "{\"bucketKey\": \"" bucketKey "\","; 131 | payload += "\"bucketName\": \"" bucketName "\"}"; 132 | payload += "\r\n"; 133 | toSend += "Content-Length: "+String(payload.length())+"\r\n"; 134 | toSend += "\r\n"; 135 | toSend += payload; 136 | 137 | client.println(toSend); 138 | Serial.println(toSend); 139 | 140 | return true; 141 | } else { 142 | // if you couldn't make a connection: 143 | Serial.println("connection failed"); 144 | return false; 145 | } 146 | } 147 | 148 | 149 | // this method makes a HTTP connection to the server and sends the signals measured: 150 | bool postData() { 151 | // close any connection before send a new request. 152 | // This will free the socket on the WiFi shield 153 | client.stop(); 154 | 155 | // if there's a successful connection: 156 | if (client.connect(ISDestURL, 80) > 0) { 157 | Serial.println("connecting..."); 158 | // send the HTTP PUT request: 159 | 160 | // Build HTTP request. 161 | for (int i=0; i 2 | #include 3 | 4 | //////////////////////////// 5 | // Initial State Streamer // 6 | //////////////////////////// 7 | 8 | // Data destination 9 | // https can't be handled by most Arduinos, thus "insecure" 10 | #define CONNECTOR "rest" 11 | #define SERVER_ADDR "insecure-groker.initialstate.com" 12 | 13 | // Access key (the one you find in your account settings): 14 | #define ACCESSKEY "Your_IS_Access_Key" 15 | // Bucket key (hidden reference to your bucket that allows appending): 16 | #define BUCKETKEY "ciao_stream" 17 | 18 | void setup() { 19 | // CIAO init 20 | Ciao.begin(); 21 | } 22 | 23 | void loop() { 24 | 25 | // read temperature, pressure, altitude, humidity 26 | int number = random(18,25); 27 | String alert = "Alert"; 28 | 29 | // Build HTTP request. 30 | String uri = "/api/events?accessKey="; 31 | uri += ACCESSKEY; 32 | uri += "&bucketKey="; 33 | uri += BUCKETKEY; 34 | uri += "&number="; 35 | uri += String(number); 36 | uri += "&alert="; 37 | uri += String(alert); 38 | 39 | 40 | Ciao.println("Send data to Initial State"); 41 | 42 | // Send the raw HTTP request 43 | CiaoData data = Ciao.write(CONNECTOR, SERVER_ADDR, uri); 44 | 45 | if (!data.isEmpty()){ 46 | Ciao.println( "State: " + String (data.get(1)) ); 47 | Ciao.println( "Response: " + String (data.get(2)) ); 48 | } 49 | else{ 50 | Ciao.println("Write Error"); 51 | } 52 | 53 | delay(300000); // wait 5 minutes between reads 54 | 55 | } 56 | -------------------------------------------------------------------------------- /arduinoethernetshieldstream.ino: -------------------------------------------------------------------------------- 1 | /* 2 | // Will work with Ethernet Shield 3 | // Thanks to Gaetano Carlucci 4 | */ 5 | 6 | ///////////////////// 7 | // Ethernet Shield // 8 | ///////////////////// 9 | #include 10 | #include 11 | 12 | //////////////////////////// 13 | // Initial State Streamer // 14 | //////////////////////////// 15 | 16 | // Data destination 17 | // https can't be handled by the ESP8266, thus "insecure" 18 | #define ISDestURL "insecure-groker.initialstate.com" 19 | // Bucket key (hidden reference to your bucket that allows appending): 20 | #define bucketKey "arduino" 21 | // Bucket name (name your data will be associated with in Initial State): 22 | #define bucketName "Arduino Stream" 23 | // Access key (the one you find in your account settings): 24 | #define accessKey "enter your key" 25 | // How many signals are in your stream? You can have as few or as many as you want 26 | const int NUM_SIGNALS = 2; 27 | // What are the names of your signals (i.e. "Temperature", "Humidity", etc.) 28 | String signalName[NUM_SIGNALS] = {"Signal 1", "Signal 2"}; 29 | // This array is to store our signal data later 30 | String signalData[NUM_SIGNALS]; 31 | 32 | ///////////// 33 | // Signals // 34 | //////////// 35 | 36 | //Signal number 1 37 | int i = 0; 38 | //Signal number 2 39 | bool increase = true; 40 | 41 | ////////////////////// 42 | // Network Settings // 43 | ///////////////////// 44 | 45 | // assign a MAC address for the ethernet controller. 46 | // fill in your address here: 47 | byte mac[] = { 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 49 | 50 | // fill in an available IP address on your network here, 51 | // for manual configuration: 52 | IPAddress ip(192, 168, 0, 177); 53 | 54 | // fill in your Domain Name Server address here: 55 | IPAddress myDns(8, 8, 8, 8); 56 | 57 | // initialize the library instance: 58 | EthernetClient client; 59 | 60 | void setup() { 61 | // start serial port: 62 | Serial.begin(9600); 63 | while (!Serial) { 64 | ; // wait for serial port to connect. Needed for native USB port only 65 | } 66 | 67 | // give the ethernet module time to boot up: 68 | delay(1000); 69 | // start the Ethernet connection using a fixed IP address and DNS server: 70 | Ethernet.begin(mac, ip, myDns); 71 | // print the Ethernet board/shield's IP address: 72 | Serial.print("My IP address: "); 73 | Serial.println(Ethernet.localIP()); 74 | 75 | // The postBucket() function creates a bucket 76 | // (unnecessary if the bucket already exists) 77 | while (!postBucket()) {}; 78 | } 79 | 80 | void loop() { 81 | 82 | // if there's incoming data from the net connection. 83 | // send it out the serial port. This is for debugging 84 | // purposes only: 85 | if (client.available()) { 86 | char c = client.read(); 87 | Serial.write(c); 88 | } 89 | 90 | // these lines gererate a random signal that can be easily understood on the dashboard 91 | if (increase) 92 | { 93 | i = i + 1; 94 | if (i == 10) 95 | { 96 | increase = false; 97 | } 98 | } 99 | else 100 | { 101 | i = i - 1; 102 | if (i == 0) 103 | { 104 | increase = true; 105 | } 106 | } 107 | // Gather Data 108 | // Read from a port for input or output or generate your own values/messages 109 | signalData[0] = String(i); 110 | signalData[1] = String(increase); 111 | 112 | // The postData() function streams our events 113 | while(!postData()); 114 | 115 | // Wait for 1 seconds before collecting and sending the next batch 116 | delay(1000); 117 | 118 | } 119 | 120 | // this method makes a HTTP connection to the server and creates a bucket is it does not exist: 121 | bool postBucket() { 122 | // close any connection before send a new request. 123 | // This will free the socket on the WiFi shield 124 | client.stop(); 125 | 126 | // if there's a successful connection: 127 | if (client.connect(ISDestURL, 80) > 0) { 128 | Serial.println("connecting..."); 129 | // send the HTTP PUT request: 130 | // Build HTTP request. 131 | String toSend = "POST /api/buckets HTTP/1.1\r\n"; 132 | toSend += "Host:"; 133 | toSend += ISDestURL; 134 | toSend += "\r\n" ; 135 | toSend += "User-Agent:Arduino\r\n"; 136 | toSend += "Accept-Version: ~0\r\n"; 137 | toSend += "X-IS-AccessKey: " accessKey "\r\n"; 138 | toSend += "Content-Type: application/json\r\n"; 139 | String payload = "{\"bucketKey\": \"" bucketKey "\","; 140 | payload += "\"bucketName\": \"" bucketName "\"}"; 141 | payload += "\r\n"; 142 | toSend += "Content-Length: "+String(payload.length())+"\r\n"; 143 | toSend += "\r\n"; 144 | toSend += payload; 145 | 146 | client.println(toSend); 147 | Serial.println(toSend); 148 | 149 | return true; 150 | } else { 151 | // if you couldn't make a connection: 152 | Serial.println("connection failed"); 153 | return false; 154 | } 155 | } 156 | 157 | 158 | 159 | // this method makes a HTTP connection to the server and sends the signals measured: 160 | bool postData() { 161 | // close any connection before send a new request. 162 | // This will free the socket on the WiFi shield 163 | client.stop(); 164 | 165 | // if there's a successful connection: 166 | if (client.connect(ISDestURL, 80) > 0) { 167 | Serial.println("connecting..."); 168 | // send the HTTP PUT request: 169 | // Build HTTP request. 170 | // Build HTTP request. 171 | 172 | for (int i=0; i 4 | #include 5 | 6 | //////////////////////////// 7 | // Initial State Streamer // 8 | //////////////////////////// 9 | // URL to IS Bucket API 10 | String ISBucketURL = "https://groker.initialstate.com/api/buckets"; 11 | // URL to IS Event API 12 | String ISEventURL = "https://groker.initialstate.com/api/events"; 13 | // Access key (the one you find in your account settings): 14 | String accessKey = "Your_Access_Key"; 15 | // Bucket key (hidden reference to your bucket that allows appending): 16 | String bucketKey = "arduino_stream"; 17 | // Bucket name (name your data will be associated with in Initial State): 18 | String bucketName = "Arduino Stream"; 19 | // How many signals are in your stream? You can have as few or as many as you want 20 | const int NUM_SIGNALS = 3; 21 | // What are the names of your signals (i.e. "Temperature", "Humidity", etc.) 22 | String signalName[NUM_SIGNALS] = {"Signal 1", "Signal 2", "Signal 3"}; 23 | // This array is to store our signal data later 24 | String signalData[NUM_SIGNALS]; 25 | 26 | 27 | // This only runs once at the very beginning 28 | void setup() 29 | { 30 | Bridge.begin(); 31 | Serial.begin(9600); 32 | 33 | // Initialize random number generation for our example signals 34 | randomSeed (millis()); 35 | 36 | while (!Serial); 37 | // Post Bucket 38 | Serial.println("Posting Bucket!"); 39 | // The postBucket() function creates a bucket 40 | // (unnecessary if the bucket already exists) 41 | postBucket(); 42 | } 43 | 44 | // This repeats 45 | void loop() 46 | { 47 | // Gather Data 48 | // Read from a port for input or output or generate your own values/messages 49 | // These signals are random numbers for the sake of example 50 | signalData[0] = String(random(18,25)); 51 | signalData[1] = String(random(1,100)); 52 | signalData[2] = String("Alert"); 53 | 54 | // Post Data 55 | Serial.println("Posting Data!"); 56 | // The postData() function streams our events 57 | postData(); 58 | // Wait for 5 seconds before collecting and sending the next batch 59 | delay(5000); 60 | } 61 | 62 | 63 | 64 | // Here are the data bucket creation and posting functions 65 | // They do not need to be edited - everything you would need to change for 66 | // your situation can be found above 67 | 68 | void postBucket() 69 | { 70 | // Initialize the process 71 | Process isbucket; 72 | 73 | isbucket.begin("curl"); 74 | isbucket.addParameter("-k"); 75 | isbucket.addParameter("-v"); 76 | isbucket.addParameter("-X"); 77 | isbucket.addParameter("POST"); 78 | isbucket.addParameter("-H"); 79 | isbucket.addParameter("Content-Type:application/json"); 80 | isbucket.addParameter("-H"); 81 | isbucket.addParameter("Accept-Version:0.0.1"); 82 | 83 | // IS Access Key Header 84 | isbucket.addParameter("-H"); 85 | isbucket.addParameter("X-IS-AccessKey:" + accessKey); 86 | 87 | // IS Bucket Key Header 88 | isbucket.addParameter("-d"); 89 | isbucket.addParameter("{\"bucketKey\": \"" + bucketKey + "\", \"bucketName\": \"" + bucketName + "\"}"); 90 | 91 | isbucket.addParameter("https://groker.initialstate.com/api/buckets"); 92 | 93 | // Run the process 94 | isbucket.run(); 95 | 96 | Serial.flush(); 97 | } 98 | 99 | void postData() 100 | { 101 | // Initialize the process 102 | Process isstreamer; 103 | 104 | isstreamer.begin("curl"); 105 | isstreamer.addParameter("-k"); 106 | isstreamer.addParameter("-v"); 107 | isstreamer.addParameter("-X"); 108 | isstreamer.addParameter("POST"); 109 | isstreamer.addParameter("-H"); 110 | isstreamer.addParameter("Content-Type:application/json"); 111 | isstreamer.addParameter("-H"); 112 | isstreamer.addParameter("Accept-Version:0.0.1"); 113 | 114 | // IS Access Key Header 115 | isstreamer.addParameter("-H"); 116 | isstreamer.addParameter("X-IS-AccessKey:" + accessKey); 117 | 118 | // IS Bucket Key Header 119 | // Note that bucketName is not needed here 120 | isstreamer.addParameter("-H"); 121 | isstreamer.addParameter("X-IS-BucketKey:" + bucketKey); 122 | 123 | isstreamer.addParameter("-d"); 124 | 125 | // Initialize a string to hold our signal data 126 | String jsonData; 127 | 128 | jsonData = "["; 129 | 130 | for (int i=0; i