Components and supplies
Jumper wires (generic)
NeoPixel strip
Resistor 10k ohm
Arduino MKR1000
Pushbutton switch 12mm
Apps and platforms
Arduino IDE
Firebase
Maker service
Google Maps
Project description
Code
FlashStorage
The FlashStorage library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory of microcontrollers.
RTCZero
The RTC library enables an Arduino Zero or MKR1000 board to take control of the internal RTC.
WifiLocation
This is a library that sends Google Maps Geolocaion API a request with a list of all WiFi AP's BSSID that your microcontroller listens to. Google, then answer with location and accuracy in JSON format.
WiFi101 modified
Modification of the WiFi101 library to access the MACs of neighboring routers.
Tracking web
html
Is the web page to show de map.
1<!DOCTYPE html> 2<html> 3<head> 4 <title>Dash Button Tracking Santa Claus</title> 5 <style type="text/css"> 6 html, body { height: 100%; margin: 0; padding: 0; } 7 #map { height: 100%; } 8 </style> 9 <meta name="robots" content="noindex"> 10</head> 11<body> 12 <!--<ul id="costumers" class="list-group"> 13 </ul>--> 14 15 <div id="map"></div> 16 17 18 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> 19 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> 20 <!-- Latest compiled and minified Bootstrap --> 21 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> 22 <!-- Include Firebase Library --> 23 <script src='https://cdn.firebase.com/js/client/2.2.1/firebase.js'></script> 24 <!-- Tracking Store JavaScript --> 25 <script src="script.js"></script> 26 <!-- API Google Maps --> 27 <script async defer 28 src="https://maps.googleapis.com/maps/api/js?key=AIzaSyABRsKsE4ISjkikM96Hn7RIv9nW-oice8Q&callback=initMap"> 29 </script> 30</body> 31</html>
Main Sketch
arduino
1/* 2 DashButtonSanta 3 4 Send information to Santa Claus about the status of the gift request. It uses the geolocation through the WiFi, 5 of the Google API, and it is sent to Firebase, along with the state and with the MAC (key value) of the Arduino MKR1000. 6 7 It also sends the information to Twitter @ dashbuttonsanta and to the email dashbuttonsanta@gmail.com through IFTTT. 8 9 On the web https://programarfacil.com/proyectos/dashbuttonsanta/tracking-santa.html you can follow the status of all requests. 10 11 When at the end Santa leaves the gifts on the site sent to Twitter and the email, press the button and gives the delivery finished. 12 13 States: 14 0 => Device OFF (LED color red) 15 1 => I have behaved well, I have made the bed, I have cleaned the dishes, I have helped an old lady, I pray every night, etc ... 16 and I have sent the letter :) (LED color blue) 17 2 => Is Christmas Day (LED blink color blue) 18 3 => Santa claus left the presents and pressed the button (LED blink color green) 19 20 Errors: 21 Wifi shield not present => LED blink Color(233, 149, 16) 22 NTP unreachable => LED blink Color(150, 0, 0) 23 24 The circuit: 25 Arduino MKR1000 26 Pushbutton to pin 6 27 pull-down resistor to pushbutton 28 3 addressable LEDs 29 Created 2017 30 By https://programarfacil.com 31 Luis del Valle @ldelvalleh 32 Germn Martn @gmag12 33 34*/ 35#include <Adafruit_NeoPixel.h> 36#include <WiFi101.h> 37#include <WiFiUdp.h> 38#include <RTCZero.h> 39#include <FlashStorage.h> 40#include "WifiLocation.h" 41 42// Fill these fields with your data 43#define GOOGLE_API_KEY "YOURGOOGLEAPIKEY" 44#define IFTTTKEY "YOURIFTTKEY" 45 46#define SSID "WIFISSID" 47#define PASS "WIFIPASS" 48 49 50// Constants 51#define DASHBUTTON 6 // Button 52#define PINNEO 7 // Pin Neopixel 53#define NUMPIXELS 3 // Num pixels 54#define HOST "dash-button-arduino.firebaseio.com" // Host Firebase 55#define HOSTIFTTT "maker.ifttt.com" // Host IFTTT to send tweet and email 56#define TWITTEREVENT "tweet_santa" // Event name IFTTT Twitter 57#define EMAILEVENT "email_santa" // Event name IFTTT email 58#define SANTAEVENT "santa_santa" // Event name IFTTT Twitter Santa Claus 59 60#define D_DAY 25 // Christmas Day 61#define M_MONTH 12 // Christmas Month 62#define LOC_PRECISSION 4 // Accuracy of location data to control privacy 63 64 65// Neopixel 66Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PINNEO, NEO_GRB + NEO_KHZ800); 67 68// Dash Button States 69int dashButtonState = 0; 70volatile bool makeUpdate = false; 71 72// Reserve a portion of flash memory to store an "int" variable 73// and call it "state_dashbutton". 74FlashStorage(state_dashbutton, int); 75 76// RTC with WiFi 77RTCZero rtc; 78const int GMT = 1; 79 80int status = WL_IDLE_STATUS; 81WiFiClient client; 82 83// Info person 84byte mac[6]; 85location_t location; 86 87void setup() { 88 // Init Neopixel 89 pixels.begin(); 90 91 // Read the content of state_dashbutton 92 dashButtonState = state_dashbutton.read(); 93 94 pixels.setPixelColor(0, pixels.Color(150, 0, 0)); 95 pixels.show(); 96 97 pixels.setPixelColor(1, pixels.Color(0, 0, 150)); 98 pixels.show(); 99 100 pixels.setPixelColor(2, pixels.Color(0, 150, 0)); 101 pixels.show(); 102 103 104 // WiFi configuration 105 configWiFi(); 106 107 // Get location using WiFi networks around 108 getLocation(); 109 110 // Update Dash Button state 111 putRequest(dashButtonState); 112 113 // Init Dash Button 114 pinMode(DASHBUTTON, INPUT); 115 116 // Init interrupt 117 attachInterrupt(digitalPinToInterrupt(DASHBUTTON), dashbuttonAction, RISING); 118 119 // RTC configuration 120 configRTC(); 121 122 // Random seed 123 randomSeed(analogRead(A0)); 124 125} 126 127void loop() { 128 129 // Off 130 if (dashButtonState == 0) 131 { 132 for (int i = 0; i < NUMPIXELS; i++) { 133 134 // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255 135 pixels.setPixelColor(i, pixels.Color(150, 0, 0)); 136 pixels.show(); 137 } 138 } 139 // Location sended but not Christmas day 140 else if (dashButtonState == 1 && rtc.getDay() != D_DAY && rtc.getMonth() != M_MONTH) 141 { 142 for (int i = 0; i < NUMPIXELS; i++) { 143 144 pixels.setPixelColor(i, pixels.Color(0, 0, 150)); 145 pixels.show(); 146 } 147 } 148 // Location sended and Christmas day 149 else if (dashButtonState == 1 && rtc.getDay() == D_DAY && rtc.getMonth() == M_MONTH) 150 { 151 blinkNeopixel(pixels.Color(0, 0, 150)); 152 } 153 // Shipping 154 else if (dashButtonState == 2) 155 { 156 for (int i = 0; i < NUMPIXELS; i++) { 157 158 pixels.setPixelColor(i, pixels.Color(0, 150, 0)); 159 pixels.show(); 160 } 161 } 162 163 // If need update 164 if (makeUpdate) 165 { 166 // Change Dash Button State 167 if (dashButtonState == 0) 168 { 169 pixels.setPixelColor(0, pixels.Color(150, 0, 0)); 170 pixels.show(); 171 172 pixels.setPixelColor(1, pixels.Color(0, 0, 150)); 173 pixels.show(); 174 175 pixels.setPixelColor(2, pixels.Color(0, 0, 150)); 176 pixels.show(); 177 178 if (putRequest(1)) 179 { 180 // Send Email 181 sendEmail(); 182 delay(2000); 183 // Send Twitter 184 sendToTwitterPerson(); 185 186 dashButtonState = 1; 187 } 188 } 189 // Only Christmas Day 190 else if (dashButtonState == 1 && rtc.getDay() == D_DAY && rtc.getMonth() == M_MONTH) 191 { 192 pixels.setPixelColor(0, pixels.Color(0, 0, 150)); 193 pixels.show(); 194 195 pixels.setPixelColor(1, pixels.Color(0, 150, 0)); 196 pixels.show(); 197 198 pixels.setPixelColor(2, pixels.Color(0, 150, 0)); 199 pixels.show(); 200 201 if (putRequest(2)) 202 { 203 sendToTwitterSanta(); 204 dashButtonState = 2; 205 } 206 } 207 208 // Change state in FlashStorage 209 state_dashbutton.write(dashButtonState); 210 } 211 212 makeUpdate = false; 213} 214 215// Callback interruption 216void dashbuttonAction() 217{ 218 noInterrupts(); 219 if (!makeUpdate) 220 makeUpdate = true; 221 interrupts(); 222} 223 224void blinkNeopixel(uint32_t c) 225{ 226 for (int i = 0; i < NUMPIXELS; i++) { 227 228 pixels.setPixelColor(i, pixels.Color(0, 0, 0)); 229 pixels.show(); 230 } 231 delay(500); 232 233 for (int i = 0; i < NUMPIXELS; i++) { 234 235 pixels.setPixelColor(i, c); 236 pixels.show(); 237 } 238 delay(500); 239} 240 241/**************** WiFi Connection ****************/ 242void configWiFi() 243{ 244 // check for the presence of the shield: 245 if (WiFi.status() == WL_NO_SHIELD) { 246 // don't continue: 247 while (true) 248 { 249 // Show error shield not present 250 blinkNeopixel(pixels.Color(233, 149, 16)); 251 } 252 } 253 254 // attempt to connect to Wifi network: 255 while (status != WL_CONNECTED) { 256 // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 257 status = WiFi.begin(SSID, PASS); 258 259 // wait 10 seconds for connection: 260 delay(10000); 261 } 262 263 // Get mac 264 WiFi.macAddress(mac); 265} 266 267/**************** RTCZero ****************/ 268void configRTC() 269{ 270 // Init RTC 271 rtc.begin(); 272 273 unsigned long epoch; 274 int numberOfTries = 0, maxTries = 6; 275 do { 276 epoch = WiFi.getTime(); 277 numberOfTries++; 278 } 279 while ((epoch == 0) || (numberOfTries > maxTries)); 280 281 if (numberOfTries > maxTries) { 282 while (1) 283 { 284 { 285 // Show error RTC 286 blinkNeopixel(pixels.Color(150, 0, 0)); 287 } 288 } 289 } 290 else { 291 rtc.setEpoch(epoch); 292 293 } 294 295} 296 297/**************** HTTP PUT Request to Firebase ****************/ 298bool putRequest(int newDashButtonState) 299{ 300 String keyMac = ""; 301 302 for (int i = 0; i < 6; i++) 303 { 304 String pos = String((uint8_t)mac[i], HEX); 305 if (mac[i] <= 0xF) 306 pos = "0" + pos; 307 pos.toUpperCase(); 308 keyMac += pos; 309 if (i < 5) 310 keyMac += ":"; 311 } 312 313 // close any connection before send a new request. 314 client.stop(); 315 client.flush(); 316 317 // send SSL request 318 if (client.connectSSL(HOST, 443)) { 319 320 // PUT request 321 String toSend = "PUT /persons/"; 322 toSend += keyMac; 323 toSend += ".json HTTP/1.1\ \ 324"; 325 toSend += "Host:"; 326 toSend += HOST; 327 toSend += "\ \ 328" ; 329 toSend += "Content-Type: application/json\ \ 330"; 331 String payload = "{\\"lat\\":"; 332 payload += String(location.lat, LOC_PRECISSION); 333 payload += ","; 334 payload += "\\"lon\\":"; 335 payload += String(location.lon, LOC_PRECISSION); 336 payload += ","; 337 payload += "\\"prec\\":"; 338 payload += String(location.accuracy); 339 payload += ","; 340 payload += "\\"status\\": \\""; 341 payload += newDashButtonState; 342 payload += "\\"}"; 343 payload += "\ \ 344"; 345 toSend += "Content-Length: " + String(payload.length()) + "\ \ 346"; 347 toSend += "\ \ 348"; 349 toSend += payload; 350 351 client.println(toSend); 352 client.println(); 353 354 client.flush(); 355 client.stop(); 356 357 return true; 358 } else { 359 // if you couldn't make a connection: 360 client.flush(); 361 client.stop(); 362 return false; 363 } 364 365} 366 367/**************** Send to Twitter IFTTT ****************/ 368void sendToTwitterPerson() 369{ 370 requestIFTTT(TWITTEREVENT); 371} 372 373void sendToTwitterSanta() 374{ 375 requestIFTTT(SANTAEVENT); 376} 377 378/**************** Send email IFTTT ****************/ 379void sendEmail() 380{ 381 requestIFTTT(EMAILEVENT); 382} 383 384/**************** Request IFTTT ****************/ 385void requestIFTTT(String eventName) 386{ 387 for (int i = 0; i < 3; i++) 388 { 389 // close any connection before send a new request. 390 if (client.connected()) 391 { 392 client.stop(); 393 } 394 395 client.flush(); 396 397 // Random request: from IFTTT Twitter publish Cannot send duplicate tweet. 398 long randomRequest = random(1, 10000); 399 400 // send SSL request 401 if (client.connectSSL(HOSTIFTTT, 443)) { 402 // Make a HTTP request: 403 String toSend = "GET /trigger/"; 404 toSend += eventName; 405 toSend += "/with/key/"; 406 toSend += IFTTTKEY; 407 toSend += "?value1="; 408 toSend += String(location.lat, LOC_PRECISSION); 409 toSend += "&value2="; 410 toSend += String(location.lon, LOC_PRECISSION); 411 toSend += "&value3="; 412 toSend += randomRequest; 413 toSend += " HTTP/1.1\ \ 414"; 415 toSend += "Host: maker.ifttt.com\ \ 416"; 417 toSend += "Connection: close\ \ 418\ \ 419"; 420 client.print(toSend); 421 break; 422 } else { 423 // if you couldn't make a connection: 424 } 425 } 426 client.flush(); 427 client.stop(); 428} 429 430/**************** Get Location info ****************/ 431bool getLocation() { 432 433 WifiLocation gLocation(GOOGLE_API_KEY); 434 435 location = gLocation.getGeoFromWiFi(); 436 437 return (location.accuracy < 100); 438 439} 440 441
RTCZero
The RTC library enables an Arduino Zero or MKR1000 board to take control of the internal RTC.
Main Sketch
arduino
1/* 2 DashButtonSanta 3 4 Send information to Santa Claus about the status of the gift request. It uses the geolocation through the WiFi, 5 of the Google API, and it is sent to Firebase, along with the state and with the MAC (key value) of the Arduino MKR1000. 6 7 It also sends the information to Twitter @ dashbuttonsanta and to the email dashbuttonsanta@gmail.com through IFTTT. 8 9 On the web https://programarfacil.com/proyectos/dashbuttonsanta/tracking-santa.html you can follow the status of all requests. 10 11 When at the end Santa leaves the gifts on the site sent to Twitter and the email, press the button and gives the delivery finished. 12 13 States: 14 0 => Device OFF (LED color red) 15 1 => I have behaved well, I have made the bed, I have cleaned the dishes, I have helped an old lady, I pray every night, etc ... 16 and I have sent the letter :) (LED color blue) 17 2 => Is Christmas Day (LED blink color blue) 18 3 => Santa claus left the presents and pressed the button (LED blink color green) 19 20 Errors: 21 Wifi shield not present => LED blink Color(233, 149, 16) 22 NTP unreachable => LED blink Color(150, 0, 0) 23 24 The circuit: 25 Arduino MKR1000 26 Pushbutton to pin 6 27 pull-down resistor to pushbutton 28 3 addressable LEDs 29 Created 2017 30 By https://programarfacil.com 31 Luis del Valle @ldelvalleh 32 Germn Martn @gmag12 33 34*/ 35#include <Adafruit_NeoPixel.h> 36#include <WiFi101.h> 37#include <WiFiUdp.h> 38#include <RTCZero.h> 39#include <FlashStorage.h> 40#include "WifiLocation.h" 41 42// Fill these fields with your data 43#define GOOGLE_API_KEY "YOURGOOGLEAPIKEY" 44#define IFTTTKEY "YOURIFTTKEY" 45 46#define SSID "WIFISSID" 47#define PASS "WIFIPASS" 48 49 50// Constants 51#define DASHBUTTON 6 // Button 52#define PINNEO 7 // Pin Neopixel 53#define NUMPIXELS 3 // Num pixels 54#define HOST "dash-button-arduino.firebaseio.com" // Host Firebase 55#define HOSTIFTTT "maker.ifttt.com" // Host IFTTT to send tweet and email 56#define TWITTEREVENT "tweet_santa" // Event name IFTTT Twitter 57#define EMAILEVENT "email_santa" // Event name IFTTT email 58#define SANTAEVENT "santa_santa" // Event name IFTTT Twitter Santa Claus 59 60#define D_DAY 25 // Christmas Day 61#define M_MONTH 12 // Christmas Month 62#define LOC_PRECISSION 4 // Accuracy of location data to control privacy 63 64 65// Neopixel 66Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PINNEO, NEO_GRB + NEO_KHZ800); 67 68// Dash Button States 69int dashButtonState = 0; 70volatile bool makeUpdate = false; 71 72// Reserve a portion of flash memory to store an "int" variable 73// and call it "state_dashbutton". 74FlashStorage(state_dashbutton, int); 75 76// RTC with WiFi 77RTCZero rtc; 78const int GMT = 1; 79 80int status = WL_IDLE_STATUS; 81WiFiClient client; 82 83// Info person 84byte mac[6]; 85location_t location; 86 87void setup() { 88 // Init Neopixel 89 pixels.begin(); 90 91 // Read the content of state_dashbutton 92 dashButtonState = state_dashbutton.read(); 93 94 pixels.setPixelColor(0, pixels.Color(150, 0, 0)); 95 pixels.show(); 96 97 pixels.setPixelColor(1, pixels.Color(0, 0, 150)); 98 pixels.show(); 99 100 pixels.setPixelColor(2, pixels.Color(0, 150, 0)); 101 pixels.show(); 102 103 104 // WiFi configuration 105 configWiFi(); 106 107 // Get location using WiFi networks around 108 getLocation(); 109 110 // Update Dash Button state 111 putRequest(dashButtonState); 112 113 // Init Dash Button 114 pinMode(DASHBUTTON, INPUT); 115 116 // Init interrupt 117 attachInterrupt(digitalPinToInterrupt(DASHBUTTON), dashbuttonAction, RISING); 118 119 // RTC configuration 120 configRTC(); 121 122 // Random seed 123 randomSeed(analogRead(A0)); 124 125} 126 127void loop() { 128 129 // Off 130 if (dashButtonState == 0) 131 { 132 for (int i = 0; i < NUMPIXELS; i++) { 133 134 // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255 135 pixels.setPixelColor(i, pixels.Color(150, 0, 0)); 136 pixels.show(); 137 } 138 } 139 // Location sended but not Christmas day 140 else if (dashButtonState == 1 && rtc.getDay() != D_DAY && rtc.getMonth() != M_MONTH) 141 { 142 for (int i = 0; i < NUMPIXELS; i++) { 143 144 pixels.setPixelColor(i, pixels.Color(0, 0, 150)); 145 pixels.show(); 146 } 147 } 148 // Location sended and Christmas day 149 else if (dashButtonState == 1 && rtc.getDay() == D_DAY && rtc.getMonth() == M_MONTH) 150 { 151 blinkNeopixel(pixels.Color(0, 0, 150)); 152 } 153 // Shipping 154 else if (dashButtonState == 2) 155 { 156 for (int i = 0; i < NUMPIXELS; i++) { 157 158 pixels.setPixelColor(i, pixels.Color(0, 150, 0)); 159 pixels.show(); 160 } 161 } 162 163 // If need update 164 if (makeUpdate) 165 { 166 // Change Dash Button State 167 if (dashButtonState == 0) 168 { 169 pixels.setPixelColor(0, pixels.Color(150, 0, 0)); 170 pixels.show(); 171 172 pixels.setPixelColor(1, pixels.Color(0, 0, 150)); 173 pixels.show(); 174 175 pixels.setPixelColor(2, pixels.Color(0, 0, 150)); 176 pixels.show(); 177 178 if (putRequest(1)) 179 { 180 // Send Email 181 sendEmail(); 182 delay(2000); 183 // Send Twitter 184 sendToTwitterPerson(); 185 186 dashButtonState = 1; 187 } 188 } 189 // Only Christmas Day 190 else if (dashButtonState == 1 && rtc.getDay() == D_DAY && rtc.getMonth() == M_MONTH) 191 { 192 pixels.setPixelColor(0, pixels.Color(0, 0, 150)); 193 pixels.show(); 194 195 pixels.setPixelColor(1, pixels.Color(0, 150, 0)); 196 pixels.show(); 197 198 pixels.setPixelColor(2, pixels.Color(0, 150, 0)); 199 pixels.show(); 200 201 if (putRequest(2)) 202 { 203 sendToTwitterSanta(); 204 dashButtonState = 2; 205 } 206 } 207 208 // Change state in FlashStorage 209 state_dashbutton.write(dashButtonState); 210 } 211 212 makeUpdate = false; 213} 214 215// Callback interruption 216void dashbuttonAction() 217{ 218 noInterrupts(); 219 if (!makeUpdate) 220 makeUpdate = true; 221 interrupts(); 222} 223 224void blinkNeopixel(uint32_t c) 225{ 226 for (int i = 0; i < NUMPIXELS; i++) { 227 228 pixels.setPixelColor(i, pixels.Color(0, 0, 0)); 229 pixels.show(); 230 } 231 delay(500); 232 233 for (int i = 0; i < NUMPIXELS; i++) { 234 235 pixels.setPixelColor(i, c); 236 pixels.show(); 237 } 238 delay(500); 239} 240 241/**************** WiFi Connection ****************/ 242void configWiFi() 243{ 244 // check for the presence of the shield: 245 if (WiFi.status() == WL_NO_SHIELD) { 246 // don't continue: 247 while (true) 248 { 249 // Show error shield not present 250 blinkNeopixel(pixels.Color(233, 149, 16)); 251 } 252 } 253 254 // attempt to connect to Wifi network: 255 while (status != WL_CONNECTED) { 256 // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 257 status = WiFi.begin(SSID, PASS); 258 259 // wait 10 seconds for connection: 260 delay(10000); 261 } 262 263 // Get mac 264 WiFi.macAddress(mac); 265} 266 267/**************** RTCZero ****************/ 268void configRTC() 269{ 270 // Init RTC 271 rtc.begin(); 272 273 unsigned long epoch; 274 int numberOfTries = 0, maxTries = 6; 275 do { 276 epoch = WiFi.getTime(); 277 numberOfTries++; 278 } 279 while ((epoch == 0) || (numberOfTries > maxTries)); 280 281 if (numberOfTries > maxTries) { 282 while (1) 283 { 284 { 285 // Show error RTC 286 blinkNeopixel(pixels.Color(150, 0, 0)); 287 } 288 } 289 } 290 else { 291 rtc.setEpoch(epoch); 292 293 } 294 295} 296 297/**************** HTTP PUT Request to Firebase ****************/ 298bool putRequest(int newDashButtonState) 299{ 300 String keyMac = ""; 301 302 for (int i = 0; i < 6; i++) 303 { 304 String pos = String((uint8_t)mac[i], HEX); 305 if (mac[i] <= 0xF) 306 pos = "0" + pos; 307 pos.toUpperCase(); 308 keyMac += pos; 309 if (i < 5) 310 keyMac += ":"; 311 } 312 313 // close any connection before send a new request. 314 client.stop(); 315 client.flush(); 316 317 // send SSL request 318 if (client.connectSSL(HOST, 443)) { 319 320 // PUT request 321 String toSend = "PUT /persons/"; 322 toSend += keyMac; 323 toSend += ".json HTTP/1.1\ \ 324"; 325 toSend += "Host:"; 326 toSend += HOST; 327 toSend += "\ \ 328" ; 329 toSend += "Content-Type: application/json\ \ 330"; 331 String payload = "{\\"lat\\":"; 332 payload += String(location.lat, LOC_PRECISSION); 333 payload += ","; 334 payload += "\\"lon\\":"; 335 payload += String(location.lon, LOC_PRECISSION); 336 payload += ","; 337 payload += "\\"prec\\":"; 338 payload += String(location.accuracy); 339 payload += ","; 340 payload += "\\"status\\": \\""; 341 payload += newDashButtonState; 342 payload += "\\"}"; 343 payload += "\ \ 344"; 345 toSend += "Content-Length: " + String(payload.length()) + "\ \ 346"; 347 toSend += "\ \ 348"; 349 toSend += payload; 350 351 client.println(toSend); 352 client.println(); 353 354 client.flush(); 355 client.stop(); 356 357 return true; 358 } else { 359 // if you couldn't make a connection: 360 client.flush(); 361 client.stop(); 362 return false; 363 } 364 365} 366 367/**************** Send to Twitter IFTTT ****************/ 368void sendToTwitterPerson() 369{ 370 requestIFTTT(TWITTEREVENT); 371} 372 373void sendToTwitterSanta() 374{ 375 requestIFTTT(SANTAEVENT); 376} 377 378/**************** Send email IFTTT ****************/ 379void sendEmail() 380{ 381 requestIFTTT(EMAILEVENT); 382} 383 384/**************** Request IFTTT ****************/ 385void requestIFTTT(String eventName) 386{ 387 for (int i = 0; i < 3; i++) 388 { 389 // close any connection before send a new request. 390 if (client.connected()) 391 { 392 client.stop(); 393 } 394 395 client.flush(); 396 397 // Random request: from IFTTT Twitter publish Cannot send duplicate tweet. 398 long randomRequest = random(1, 10000); 399 400 // send SSL request 401 if (client.connectSSL(HOSTIFTTT, 443)) { 402 // Make a HTTP request: 403 String toSend = "GET /trigger/"; 404 toSend += eventName; 405 toSend += "/with/key/"; 406 toSend += IFTTTKEY; 407 toSend += "?value1="; 408 toSend += String(location.lat, LOC_PRECISSION); 409 toSend += "&value2="; 410 toSend += String(location.lon, LOC_PRECISSION); 411 toSend += "&value3="; 412 toSend += randomRequest; 413 toSend += " HTTP/1.1\ \ 414"; 415 toSend += "Host: maker.ifttt.com\ \ 416"; 417 toSend += "Connection: close\ \ 418\ \ 419"; 420 client.print(toSend); 421 break; 422 } else { 423 // if you couldn't make a connection: 424 } 425 } 426 client.flush(); 427 client.stop(); 428} 429 430/**************** Get Location info ****************/ 431bool getLocation() { 432 433 WifiLocation gLocation(GOOGLE_API_KEY); 434 435 location = gLocation.getGeoFromWiFi(); 436 437 return (location.accuracy < 100); 438 439} 440 441
FlashStorage
The FlashStorage library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory of microcontrollers.
Tracking web
html
Is the web page to show de map.
1<!DOCTYPE html> 2<html> 3<head> 4 <title>Dash Button Tracking Santa Claus</title> 5 <style type="text/css"> 6 html, body { height: 100%; margin: 0; padding: 0; } 7 #map { height: 100%; } 8 </style> 9 <meta name="robots" content="noindex"> 10</head> 11<body> 12 <!--<ul id="costumers" class="list-group"> 13 </ul>--> 14 15 <div id="map"></div> 16 17 18 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> 19 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> 20 <!-- Latest compiled and minified Bootstrap --> 21 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> 22 <!-- Include Firebase Library --> 23 <script src='https://cdn.firebase.com/js/client/2.2.1/firebase.js'></script> 24 <!-- Tracking Store JavaScript --> 25 <script src="script.js"></script> 26 <!-- API Google Maps --> 27 <script async defer 28 src="https://maps.googleapis.com/maps/api/js?key=AIzaSyABRsKsE4ISjkikM96Hn7RIv9nW-oice8Q&callback=initMap"> 29 </script> 30</body> 31</html>
JavaScript
javascript
JavaScript to connect Firebase and show the map
1// Create a firebase reference 2var dbRef = new Firebase('https://dash-button-arduino.firebaseio.com/'); 3var costumersRef = dbRef.child('persons'); 4var markers = {} 5 6//load persons 7costumersRef.on("child_added", function(snap) { 8 9 // Print to map 10 addNewPerson(snap.val().lat,snap.val().lon,snap.val().status, snap.key()); 11}); 12 13//change persons 14costumersRef.on("child_changed", function (snap) { 15 changePerson(snap.val().lat, snap.val().lon, snap.val().status); 16}); 17 18/******** GOOGLE MAPS *********/ 19var map; 20function initMap() { 21 // Center map 22 var myLatLng = {lat: 38.392101, lng: -0.525467}; 23 24 map = new google.maps.Map(document.getElementById('map'), { 25 center: myLatLng, 26 zoom: 3 27 }); 28} 29 30function addNewPerson(lat, lon,status, key){ 31 console.log("status",status); 32 var image 33 if(status==0) 34 { 35 image='images/santa-icon-1.png'; 36 } 37 else if(status==1) 38 { 39 image='images/santa-icon-2.png'; 40 } 41 else if(status==2) 42 { 43 image='images/santa-icon-3.png'; 44 } 45 var marker = new google.maps.Marker({ 46 position: new google.maps.LatLng(lat,lon), 47 icon: image, 48 map: map, 49 title: key // Tooltip = MAC address 50 }); 51 markers[key] = marker; 52} 53 54function changePerson(lat, lon, status, key) { 55 console.log("status", status); 56 var image; 57 if (status == 0) { 58 image = 'images/santa-icon-1.png'; 59 } 60 else if (status == 1) { 61 image = 'images/santa-icon-2.png'; 62 } 63 else if (status == 2) { 64 image = 'images/santa-icon-3.png'; 65 } 66 marker = markers[key]; 67 marker = new google.maps.Marker({ 68 position: new google.maps.LatLng(lat, lon), 69 icon: image, 70 map: map, 71 title: key // Tooltip = MAC address 72 }); 73 markers[key] = marker; 74}
WiFi101 modified
Modification of the WiFi101 library to access the MACs of neighboring routers.
WifiLocation
This is a library that sends Google Maps Geolocaion API a request with a list of all WiFi AP's BSSID that your microcontroller listens to. Google, then answer with location and accuracy in JSON format.
Downloadable files
Dash Button Santa - Schematics
It looks great if you use a button on the nose of a Rudolf or Santa Claus doll
Dash Button Santa - Schematics
Dash Button Santa - Schematics
It looks great if you use a button on the nose of a Rudolf or Santa Claus doll
Dash Button Santa - Schematics
Comments
Only logged in users can leave comments
ldelvalle
0 Followers
•0 Projects
+1
Work attribution
Table of contents
Intro
1
0