├── README.md ├── onboarding_kit_tutorial ├── onboarding_kit_lesson2B │ └── onboarding_kit_lesson2B.ino ├── onboarding_kit_lesson1 │ └── onboarding_kit_lesson1.ino ├── onboarding_kit_lesson2A │ └── onboarding_kit_lesson2A.ino ├── onboarding_kit_lesson3A │ └── onboarding_kit_lesson3A.ino ├── onboarding_kit_lesson3B │ └── onboarding_kit_lesson3B.ino └── onboarding_kit_lesson4 │ └── onboarding_kit_lesson4.ino ├── LICENSE ├── konekt_dash_helloworld ├── LICENSE └── konekt_dash_helloworld.ino ├── konekt_user_module_serial_gateway ├── LICENSE └── konekt_user_module_serial_gateway.ino ├── receive-sms └── receive-sms.ino ├── dash_repl └── dash_repl_basic.ino ├── magrelayshield └── magrelayshield.ino ├── rgbleds └── rgbleds.ino └── adafruit_gps_on_dash └── adafruitgpswithdash.ino /README.md: -------------------------------------------------------------------------------- 1 | # Hologram Dash Arduino Examples 2 | Example Arduino IDE sketches for use with Arduino IDE and the Hologram Dash and Hologram Dash Pro (and similar) boards 3 | -------------------------------------------------------------------------------- /onboarding_kit_tutorial/onboarding_kit_lesson2B/onboarding_kit_lesson2B.ino: -------------------------------------------------------------------------------- 1 | //Hologram Lesson 2B 2 | //This lesson uses a PIR sensor to turn on an LED 3 | 4 | int pirReading = 0; 5 | 6 | void setup() { 7 | 8 | // put your setup code here, to run once: 9 | 10 | // initialize digital pin LED_BUILTIN as an output. 11 | pinMode(D30, OUTPUT); 12 | pinMode(D09, INPUT); 13 | 14 | } 15 | 16 | void loop() { 17 | 18 | pirReading = digitalRead(D09); 19 | digitalWrite(D30, pirReading); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /onboarding_kit_tutorial/onboarding_kit_lesson1/onboarding_kit_lesson1.ino: -------------------------------------------------------------------------------- 1 | //Hologram Lesson 1 2 | //This lesson teaches how to blink an LED on the Dash 3 | 4 | void setup() { 5 | 6 | // put your setup code here, to run once: 7 | // initialize digital pin as an output. 8 | pinMode(D30, OUTPUT); 9 | 10 | } 11 | 12 | void loop() { 13 | 14 | // put your main code here, to run repeatedly: 15 | digitalWrite(D30, HIGH); // turn the LED on (HIGH is the voltage level) 16 | delay(1000); // wait for a second 17 | digitalWrite(D30, LOW); // turn the LED off by making the voltage LOW 18 | delay(1000); // wait for a second 19 | 20 | } 21 | -------------------------------------------------------------------------------- /onboarding_kit_tutorial/onboarding_kit_lesson2A/onboarding_kit_lesson2A.ino: -------------------------------------------------------------------------------- 1 | //Hologram Lesson 2A 2 | //This lesson teaches how to read a button output. 3 | 4 | int lastDebounceTime = 0; 5 | int debounceDelay = 50; 6 | int lastButtonState = 1; 7 | int ledState = LOW; 8 | int buttonReading = 0; 9 | int buttonState = HIGH; 10 | 11 | void setup() { 12 | 13 | // put your setup code here, to run once: 14 | 15 | // initialize digital pin LED_BUILTIN as an output. 16 | pinMode(D30, OUTPUT); 17 | pinMode(D19, INPUT); 18 | 19 | } 20 | 21 | void loop() { 22 | 23 | buttonReading = digitalRead(D19); 24 | 25 | if (buttonReading != lastButtonState) { 26 | lastDebounceTime = millis(); 27 | lastButtonState = buttonReading; 28 | } 29 | 30 | if ((millis() - lastDebounceTime) > debounceDelay) { 31 | if (buttonState != lastButtonState) { 32 | buttonState = lastButtonState; 33 | if (buttonState == LOW) { 34 | ledState = !ledState; 35 | digitalWrite(D30, ledState); 36 | } 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2015 Konekt, Inc. 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 | 23 | -------------------------------------------------------------------------------- /konekt_dash_helloworld/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2015 Konekt, Inc. 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 | 23 | -------------------------------------------------------------------------------- /konekt_user_module_serial_gateway/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2015 Konekt, Inc. 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 | 23 | -------------------------------------------------------------------------------- /onboarding_kit_tutorial/onboarding_kit_lesson3A/onboarding_kit_lesson3A.ino: -------------------------------------------------------------------------------- 1 | //Hologram Lesson 3A 2 | //This lesson turns the Lesson 2 system into a local motion detection security system 3 | 4 | #define ARMED 1 5 | #define UNARMED 2 6 | 7 | int lastDebounceTime = 0; 8 | int debounceDelay = 50; 9 | int lastButtonState = 1; 10 | int ledState = LOW; 11 | int buttonReading = 0; 12 | int pirReading = 0; 13 | int motionDetect = LOW; 14 | int alarmState = UNARMED; 15 | 16 | int buttonState = HIGH; 17 | 18 | void setup() { 19 | 20 | // put your setup code here, to run once: 21 | 22 | // initialize digital pin LED_BUILTIN as an output. 23 | pinMode(D30, OUTPUT); 24 | pinMode(D19, INPUT); 25 | pinMode(D09, INPUT); 26 | 27 | Serial.begin(9600); 28 | 29 | } 30 | 31 | void loop() { 32 | 33 | 34 | //blink LED if alarm is unarmed. arm alarm by pressing the button 35 | if (alarmState == UNARMED) { 36 | 37 | digitalWrite(D30, HIGH); // turn the LED on (HIGH is the voltage level) 38 | delay(100); // wait for a second 39 | digitalWrite(D30, LOW); // turn the LED off by making the voltage LOW 40 | delay(100); // wait for a second 41 | 42 | buttonReading = digitalRead(D19); 43 | 44 | if (buttonReading != lastButtonState) { 45 | lastDebounceTime = millis(); 46 | lastButtonState = buttonReading; 47 | } 48 | 49 | //the button toggles security system ARMED (1) or UNARMED (0) 50 | if ((millis() - lastDebounceTime) > debounceDelay) { 51 | if (buttonState != lastButtonState) { 52 | buttonState = lastButtonState; 53 | if (buttonState == LOW){ 54 | alarmState = ARMED; 55 | Serial.println("Button was pressed. System will be armed in 5 seconds."); 56 | delay(5000); 57 | } 58 | } 59 | } 60 | 61 | } 62 | 63 | if (alarmState == ARMED) { 64 | digitalWrite(D30, HIGH); 65 | pirReading = digitalRead(D09); 66 | if (pirReading == HIGH){ 67 | alarmState = UNARMED; 68 | Serial.println("Intruder detected! System unarmed."); 69 | } 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /receive-sms/receive-sms.ino: -------------------------------------------------------------------------------- 1 | /* 2 | receive-sms.ino - processes incoming Dash SMS in a Read-Eval-Print-Loop. 3 | 4 | http://hologram.io 5 | 6 | Copyright (c) 2016 Konekt, Inc. All rights reserved. 7 | 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library; if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #include 24 | 25 | //On received SMS, print the sender, timestamp and message 26 | //Send a message to the cloud that an SMS was received with the sender number 27 | //as the content and the tag SMSRX 28 | void cloud_sms(const String &sender, const rtc_datetime_t ×tamp, const String &message) { 29 | Serial.println("CLOUD SMS RECEIVED:"); 30 | Serial.print("SMS SENDER: "); 31 | Serial.println(sender); 32 | Serial.print("SMS TIMESTAMP: "); 33 | Serial.println(timestamp); 34 | Serial.println("SMS TEXT: "); 35 | Serial.println(message); 36 | 37 | if(HologramCloud.sendMessage(sender, "SMSRX")) { 38 | Serial.println("SMS received message sent to cloud."); 39 | } else { 40 | Serial.println("Notification send failed."); 41 | Serial.println("Check failure reason by typing:"); 42 | Serial.println("cloud status"); 43 | } 44 | } 45 | 46 | void setup() { 47 | Serial.begin(); //Start USB Serial 48 | DashReadEvalPrint.begin(); //Initialize ReadEvalPrint 49 | HologramCloud.attachHandlerSMS(cloud_sms); //Handle received SMS 50 | } 51 | 52 | void loop() { 53 | //open the Serial Monitor and type help for a list of commands 54 | DashReadEvalPrint.run(Serial); //Run the interpreter using USB Serial 55 | } 56 | -------------------------------------------------------------------------------- /onboarding_kit_tutorial/onboarding_kit_lesson3B/onboarding_kit_lesson3B.ino: -------------------------------------------------------------------------------- 1 | //Hologram Lesson 3B 2 | //This lesson turns on cloud messages from the Dash 3 | 4 | #define ARMED 1 5 | #define UNARMED 2 6 | 7 | int lastDebounceTime = 0; 8 | int debounceDelay = 50; 9 | int lastButtonState = 1; 10 | int ledState = LOW; 11 | int buttonReading = 0; 12 | int pirReading = 0; 13 | int motionDetect = LOW; 14 | int alarmState = UNARMED; 15 | int buttonState = HIGH; 16 | int messageSuccess = 0; 17 | int whileCounter = 5; 18 | 19 | void setup() { 20 | 21 | // put your setup code here, to run once: 22 | 23 | // initialize digital pin LED_BUILTIN as an output. 24 | pinMode(D30, OUTPUT); 25 | pinMode(D19, INPUT); 26 | pinMode(D09, INPUT); 27 | 28 | Serial.begin(9600); 29 | 30 | HologramCloud.begin(); 31 | 32 | } 33 | 34 | void loop() { 35 | 36 | 37 | //blink LED if alarm is unarmed. arm alarm by pressing the button 38 | if (alarmState == UNARMED) { 39 | 40 | digitalWrite(D30, HIGH); // turn the LED on (HIGH is the voltage level) 41 | delay(100); // wait for a second 42 | digitalWrite(D30, LOW); // turn the LED off by making the voltage LOW 43 | delay(100); // wait for a second 44 | 45 | buttonReading = digitalRead(D19); 46 | 47 | if (buttonReading != lastButtonState) { 48 | lastDebounceTime = millis(); 49 | lastButtonState = buttonReading; 50 | } 51 | 52 | //the button toggles security system ARMED (1) or UNARMED (0) 53 | if ((millis() - lastDebounceTime) > debounceDelay) { 54 | if (buttonState != lastButtonState) { 55 | buttonState = lastButtonState; 56 | if (buttonState == LOW){ 57 | alarmState = ARMED; 58 | Serial.println("Button was pressed. System will be armed in 5 seconds."); 59 | delay(5000); 60 | } 61 | } 62 | } 63 | 64 | } 65 | 66 | if (alarmState == ARMED) { 67 | digitalWrite(D30, HIGH); 68 | pirReading = digitalRead(D09); 69 | if (pirReading == HIGH){ 70 | alarmState = UNARMED; 71 | Serial.println("Intruder detected! System unarmed."); 72 | 73 | messageSuccess = HologramCloud.sendMessage("Intruder Detected!", "ALARM"); 74 | //retry if message doesn't succeed 75 | while(!messageSuccess && whileCounter--){ 76 | messageSuccess = HologramCloud.sendMessage("Intruder Detected!", "ALARM"); 77 | } 78 | } 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /konekt_dash_helloworld/konekt_dash_helloworld.ino: -------------------------------------------------------------------------------- 1 | /* Hologram Dash Hello World 2 | * 3 | * Author: Patrick F. Wilbur 4 | * 5 | * Purpose: This program demonstrates interactive serial mode, 6 | * a mechanism for performing cable replacement serial passthrough 7 | * over cellular to the cloud. This example works out-of-the-box 8 | * with zero configuration. 9 | * 10 | * License: Copyright (c) 2015 Konekt, Inc. All Rights Reserved. 11 | * 12 | * Released under the MIT License (MIT) 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in 22 | * all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | * SOFTWARE. 31 | * 32 | * 33 | */ 34 | 35 | void setup() { 36 | /* Serial Setup */ 37 | SerialUSB.begin(9600); /* USB UART */ 38 | Serial2.begin(9600); /* TTL UART */ 39 | SerialCloud.begin(115200); /* Konekt Cloud */ 40 | delay(4000); /* Delay 4 seconds to wait for Usb Serial to Init.*/ 41 | 42 | /* Setup Konekt Dash */ 43 | Dash.begin(); 44 | Dash.pulseLED(100,5000); /* Set the User Led to flash every 5 seconds */ 45 | 46 | /* Serial Print Info */ 47 | SerialUSB.println("Hologram Dash Hello World Example Started!"); 48 | SerialUSB.print("Using Boot Version: "); 49 | SerialUSB.println(Dash.bootVersion()); /* Print Dash Bootloader Version */ 50 | SerialCloud.println("Hello, World!"); /* one-time message */ 51 | } 52 | 53 | void loop() { 54 | char currChar; 55 | /* we don't loop sending data, since we don't want to eat up 56 | * a lot of data on our SIM! */ 57 | 58 | /* the code here will pass data between Cloud<-->UART */ 59 | 60 | while (SerialUSB.available()) { 61 | SerialCloud.write(SerialUSB.read()); 62 | } 63 | 64 | while (Serial2.available()) { 65 | SerialCloud.write(Serial2.read()); 66 | } 67 | 68 | while (SerialCloud.available()) { 69 | currChar = (char)SerialCloud.read(); 70 | SerialUSB.write(currChar); 71 | Serial2.write(currChar); 72 | } 73 | 74 | delay(5); 75 | } 76 | -------------------------------------------------------------------------------- /dash_repl/dash_repl_basic.ino: -------------------------------------------------------------------------------- 1 | /* 2 | dash_repl_basic.ino - processes Dash commands in a Read-Eval-Print-Loop. 3 | 4 | http://hologram.io 5 | 6 | Copyright (c) 2016 Konekt, Inc. All rights reserved. 7 | 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library; if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #include 24 | 25 | //send a notifcation message on RTC alarm 26 | //trigger the alarm to go off in 5 seconds with the command: 27 | //alarm seconds 5 28 | void alarm_handler(void) 29 | { 30 | rtc_datetime_t dt; 31 | if(HologramCloud.getNetworkTime(dt)) 32 | Clock.setDateTime(dt); 33 | HologramCloud.println("Alarm at "); 34 | HologramCloud.println(Clock.currentDateTime()); 35 | HologramCloud.attachTag("alarm"); 36 | if(HologramCloud.sendMessage()) 37 | Serial.println("Alarm notification sent"); 38 | else 39 | Serial.println("Alarm notification failed"); 40 | } 41 | 42 | //Toggle the LED on timer expiration 43 | //trigger the timer every 2 seconds with the command: 44 | //timer repeat 2000 45 | void timer_handler(void) 46 | { 47 | Dash.toggleLED(); 48 | } 49 | 50 | //On received SMS, print the sender, timestamp and message 51 | //Send a message to the cloud that an SMS was received with the sender number 52 | //as the content and the tag SMSRX 53 | void cloud_sms(const String &sender, const rtc_datetime_t ×tamp, const String &message) { 54 | Serial.println("CLOUD SMS RECEIVED:"); 55 | Serial.print("SMS SENDER: "); 56 | Serial.println(sender); 57 | Serial.print("SMS TIMESTAMP: "); 58 | Serial.println(timestamp); 59 | Serial.println("SMS TEXT: "); 60 | Serial.println(message); 61 | 62 | if(HologramCloud.sendMessage(sender, "SMSRX")) { 63 | Serial.println("SMS received message sent to cloud."); 64 | } else { 65 | Serial.println("Notification send failed."); 66 | Serial.println("Check failure reason by typing:"); 67 | Serial.println("cloud status"); 68 | } 69 | } 70 | 71 | void setup() { 72 | Serial.begin(); //Start USB Serial 73 | DashReadEvalPrint.begin(); //Initialize ReadEvalPrint 74 | Clock.attachAlarmInterrupt(alarm_handler); //Handle RTC alarm 75 | Dash.attachTimer(timer_handler); //Handle timer expiration 76 | HologramCloud.attachHandlerSMS(cloud_sms); //Handle received SMS 77 | } 78 | 79 | void loop() { 80 | //open the Serial Monitor and type help for a list of commands 81 | DashReadEvalPrint.run(Serial); //Run the interpreter using USB Serial 82 | } -------------------------------------------------------------------------------- /konekt_user_module_serial_gateway/konekt_user_module_serial_gateway.ino: -------------------------------------------------------------------------------- 1 | /* Hologram Dash User Module Cloud Serial Gateway Program 2 | * 3 | * Author: Hologram 4 | * 5 | * Purpose: This firmware sends all data that comes in on a serial port to the 6 | * Hologram Cloud. Data is sent once a newline is detected. 7 | * 8 | * License: Licensed under the MIT License. 9 | * 10 | * The MIT License (MIT) 11 | * 12 | * Copyright 2017 Hologram (Konekt, Inc.) 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in all 22 | * copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | * SOFTWARE. 31 | * 32 | */ 33 | 34 | #define LED_DATA_INDICATOR_DURATION 200 35 | 36 | /* globals */ 37 | unsigned ledStopMillis; 38 | bool isHandlingData; 39 | 40 | void setup() { 41 | Serial2.begin(9600); 42 | SerialUSB.begin(9600); 43 | ledStopMillis = 0; /* LED off by default */ 44 | isHandlingData = false; 45 | printToBoth("+++"); 46 | } 47 | 48 | void printToBoth(String msg) { 49 | // Write to USB and UART 50 | Serial2.println(msg); 51 | SerialUSB.println(msg); 52 | } 53 | 54 | void writeOrFlush(char cur) { 55 | // Write each character to HologramCloud buffer and then 56 | // send to cloud on a newline character 57 | isHandlingData = true; 58 | if(cur == '\n') { 59 | printToBoth("Sending message to cloud..."); 60 | int retriesLeft = 2; 61 | while(retriesLeft > 0) { 62 | bool res = HologramCloud.sendMessage(); 63 | if(!res) { 64 | String msg = "Failed. Trying "; 65 | msg += retriesLeft + " more times"; 66 | printToBoth(msg); 67 | } else { 68 | printToBoth("Data sent to cloud successfully"); 69 | break; 70 | } 71 | retriesLeft--; 72 | } 73 | } else { 74 | HologramCloud.write(cur); 75 | setLedState(); 76 | } 77 | } 78 | 79 | 80 | void loop() { 81 | char currChar; 82 | 83 | isHandlingData = false; 84 | 85 | while(Serial2.available()) { 86 | writeOrFlush(Serial2.available()); 87 | } 88 | 89 | while(SerialUSB.available()) { 90 | writeOrFlush(SerialUSB.read()); 91 | } 92 | 93 | while(SerialCloud.available()) { 94 | currChar = (char)SerialCloud.read(); 95 | SerialUSB.write(currChar); 96 | Serial2.write(currChar); 97 | isHandlingData = true; 98 | } 99 | 100 | setLedState(); 101 | 102 | delay(1); 103 | } 104 | 105 | void setLedState() { 106 | /* Blink LED while we're doing data operations and 200ms afterward */ 107 | 108 | if(ledStopMillis > 0 && ledStopMillis < millis()) { 109 | Dash.offLED(); 110 | ledStopMillis = 0; 111 | } 112 | 113 | if(isHandlingData && ledStopMillis == 0) { 114 | Dash.pulseLED(25, 50); 115 | ledStopMillis = millis() + LED_DATA_INDICATOR_DURATION; 116 | } 117 | } 118 | 119 | -------------------------------------------------------------------------------- /onboarding_kit_tutorial/onboarding_kit_lesson4/onboarding_kit_lesson4.ino: -------------------------------------------------------------------------------- 1 | //Hologram Lesson 4 2 | //ARM, DISARM via SMS and send status with STATUS 3 | 4 | #define ARMED 1 5 | #define UNARMED 2 6 | 7 | int lastDebounceTime = 0; 8 | int debounceDelay = 50; 9 | int lastButtonState = 1; 10 | int ledState = LOW; 11 | int buttonReading = 0; 12 | int alarmState = UNARMED; 13 | int buttonState = HIGH; 14 | 15 | void cloud_sms(const String &sender, const rtc_datetime_t ×tamp, const String &message) { 16 | Serial.println("CLOUD SMS RECEIVED:"); 17 | Serial.print("SMS SENDER: "); 18 | Serial.println(sender); 19 | Serial.print("SMS TIMESTAMP: "); 20 | Serial.println(timestamp); 21 | Serial.println("SMS TEXT: "); 22 | Serial.println(message); 23 | 24 | if (message == "ARM") { 25 | alarmState = ARMED; 26 | Serial.print("Alarm state is: "); 27 | Serial.println(alarmState); 28 | HologramCloud.sendMessage("System is currently armed", "ALARM"); 29 | } 30 | 31 | if (message == "DISARM") { 32 | alarmState = UNARMED; 33 | Serial.print("Alarm state is: "); 34 | Serial.println(alarmState); 35 | HologramCloud.sendMessage("System is currently unarmed", "ALARM"); 36 | } 37 | if (message == "STATUS") { 38 | Serial.println("Sending status..."); 39 | if (alarmState == ARMED) { 40 | HologramCloud.sendMessage("System is currently armed", "ALARM"); 41 | } 42 | else { 43 | HologramCloud.sendMessage("System is currently unarmed", "ALARM"); 44 | } 45 | } 46 | 47 | Serial.println("Leaving SMS handler..."); 48 | 49 | } 50 | 51 | void setup() { 52 | // put your setup code here, to run once: 53 | 54 | // initialize digital pin LED_BUILTIN as an output. 55 | pinMode(D30, OUTPUT); 56 | pinMode(D19, INPUT_PULLUP); 57 | pinMode(D09, INPUT_PULLDOWN); 58 | 59 | Serial.begin(); 60 | HologramCloud.attachHandlerSMS(cloud_sms); 61 | } 62 | 63 | void loop() { 64 | //blink LED if alarm is unarmed. arm alarm by pressing the button 65 | if (alarmState == UNARMED) { 66 | 67 | //blink the LED 68 | digitalWrite(D30, HIGH); // turn the LED on (HIGH is the voltage level) 69 | delay(100); // wait for a second 70 | digitalWrite(D30, LOW); // turn the LED off by making the voltage LOW 71 | delay(100); // wait for a second 72 | 73 | buttonReading = digitalRead(D19); 74 | 75 | if (buttonReading != lastButtonState) { 76 | lastDebounceTime = millis(); 77 | lastButtonState = buttonReading; 78 | } 79 | 80 | //the button toggles security system ARMED (1) or UNARMED (0) 81 | if ((millis() - lastDebounceTime) > debounceDelay) { 82 | if (buttonState != lastButtonState) { 83 | buttonState = lastButtonState; 84 | if (buttonState == LOW) { 85 | alarmState = ARMED; 86 | Serial.println("Button was pressed. System will be armed in 5 seconds."); 87 | delay(5000); 88 | } 89 | 90 | } 91 | } 92 | } 93 | 94 | if (alarmState == ARMED) { 95 | digitalWrite(D30, HIGH); 96 | int pirReading = digitalRead(D09); 97 | if (pirReading == HIGH) { 98 | int whileCounter = 5; 99 | alarmState = UNARMED; 100 | buttonReading = digitalRead(D19); 101 | 102 | Serial.println("Intruder detected! System unarmed."); 103 | bool messageSuccess = HologramCloud.sendMessage("Intruder Detected!", "ALARM"); 104 | 105 | while (!messageSuccess && whileCounter--) { 106 | Serial.println("Retrying message send..."); 107 | messageSuccess = HologramCloud.sendMessage(); 108 | } 109 | 110 | if(messageSuccess) 111 | Serial.println("Message transmitted successfully."); 112 | else 113 | Serial.println("Message transmission failed."); 114 | 115 | lastButtonState = 0; 116 | buttonReading = 0; //reset button inputs 117 | 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /magrelayshield/magrelayshield.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Note: This code is a demo for how to use the Hologram Dash and/or 3 | Dash Pro with the Hologram Magnetic Relay Shield. 4 | 5 | First, upload this user program to your Dash or Dash Pro. Then, 6 | at any point in time, enter one of the command characters in 7 | the serial monitor to open/close the corresponding relay 8 | circuit. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 13 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 14 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 15 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 16 | SOFTWARE. 17 | 18 | Character Command 19 | a Open all relay circuits 20 | 1 Open K1 relay circuit 21 | 2 Open K2 relay circuit 22 | 3 Open K3 relay circuit 23 | 4 Open K4 relay circuit 24 | 25 | z Close all relay circuits 26 | q close K1 relay circuit 27 | w close K2 relay circuit 28 | e Close K3 relay circuit 29 | r Close K4 relay circuit 30 | 31 | */ 32 | 33 | #include 34 | 35 | #define SPI_SELECT()(SPI.beginTransaction(L07)) 36 | #define SPI_DESELECT()(SPI.endTransaction()) 37 | #define SPI_WRITE(data) SPI_SELECT(); SPI.transfer(data); SPI_DESELECT() 38 | #define RELAYSHIELD_Close_ALL() SPI_WRITE(0b01010101) 39 | #define RELAYSHIELD_Open_ALL()SPI_WRITE(0b10101010) 40 | #define RELAYSHIELD_Close_K1()SPI_WRITE(0b00000001) 41 | #define RELAYSHIELD_Open_K1() SPI_WRITE(0b00000010) 42 | #define RELAYSHIELD_Close_K2()SPI_WRITE(0b00000100) 43 | #define RELAYSHIELD_Open_K2() SPI_WRITE(0b00001000) 44 | #define RELAYSHIELD_Close_K3()SPI_WRITE(0b00010000) 45 | #define RELAYSHIELD_Open_K3() SPI_WRITE(0b00100000) 46 | #define RELAYSHIELD_Close_K4()SPI_WRITE(0b01000000) 47 | #define RELAYSHIELD_Open_K4() SPI_WRITE(0b10000000) 48 | 49 | char currChar; 50 | 51 | void setup() { 52 | SerialUSB.begin(9600); /* USB UART */ 53 | Serial2.begin(9600); /* TTL UART */ 54 | SerialUSB.println("Hologram Dash Magnetic Relay Shield Example Started!"); 55 | SerialCloud.begin(115200); /* Hologram Cloud */ 56 | SPI.begin(); 57 | } 58 | 59 | void loop() 60 | { 61 | if (SerialUSB.available()) 62 | { 63 | switch(SerialUSB.read()) 64 | { 65 | case 'a': 66 | RELAYSHIELD_Open_ALL(); 67 | SerialUSB.println("Open ALL"); 68 | break; 69 | case '1': 70 | RELAYSHIELD_Open_K1(); 71 | SerialUSB.println("Open K1"); 72 | break; 73 | case '2': 74 | RELAYSHIELD_Open_K2(); 75 | SerialUSB.println("Open K2"); 76 | break; 77 | case '3': 78 | RELAYSHIELD_Open_K3(); 79 | SerialUSB.println("Open K3"); 80 | break; 81 | case '4': 82 | RELAYSHIELD_Open_K4(); 83 | SerialUSB.println("Open K4"); 84 | break; 85 | 86 | case 'z': 87 | RELAYSHIELD_Close_ALL(); 88 | SerialUSB.println("Close ALL"); 89 | break; 90 | case 'q': 91 | RELAYSHIELD_Close_K1(); 92 | SerialUSB.println("Close K1"); 93 | break; 94 | case 'w': 95 | RELAYSHIELD_Close_K2(); 96 | SerialUSB.println("Close K2"); 97 | break; 98 | case 'e': 99 | RELAYSHIELD_Close_K3(); 100 | SerialUSB.println("Close K3"); 101 | break; 102 | case 'r': 103 | RELAYSHIELD_Close_K4(); 104 | SerialUSB.println("Close K4"); 105 | break; 106 | } 107 | } 108 | 109 | while (Serial2.available()) { 110 | SerialCloud.write(Serial2.read()); 111 | } 112 | 113 | while (SerialCloud.available()) { 114 | currChar = (char)SerialCloud.read(); 115 | SerialUSB.write(currChar); 116 | Serial2.write(currChar); 117 | } 118 | 119 | delay(5); 120 | } 121 | -------------------------------------------------------------------------------- /rgbleds/rgbleds.ino: -------------------------------------------------------------------------------- 1 | /* rgbleds.ino 2 | * 3 | * This is a sketch for the Hologram dash that receives a color name 4 | * or list of names via SMS and then controls an RGB LED strip to 5 | * display that color. 6 | * 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 9 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 11 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 12 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 13 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 14 | * SOFTWARE. 15 | */ 16 | 17 | 18 | int pins[3] = {L09, L08, L07}; //R, G, B 19 | int curColVal[3] = {0,0,0}; 20 | int val; 21 | int colorStep = 4; 22 | int timeBetweenSteps = 100; 23 | int nextColorStep = 0; 24 | int curColors[10]; 25 | int curColorIdx = 0; 26 | String tempBuffer = ""; 27 | String payload = ""; 28 | bool foundSMS = false; 29 | 30 | #define NUMCOLORS 20 31 | String colors[] = 32 | {"BLACK", "RED", "GREEN", "BLUE", "WHITE", 33 | "PURPLE", "YELLOW", "CYAN", "PINK", "BT", 34 | "INDIGO", "NAVY", "TEAL", "TURQUOISE", 35 | "CHARTREUSE", "GOLD", "ORANGE", "BROWN", "MAROON", "GRAY"}; 36 | 37 | int colorVals[][3] = 38 | { { 0, 0, 0 }, //Black 39 | { 255, 0, 0 }, //Red 40 | { 0, 255, 0 }, //Green 41 | { 0, 0, 255 }, //Blue 42 | { 255, 255, 255}, //White 43 | { 255, 0, 255}, //Purple 44 | { 255, 255, 0 }, //Yellow 45 | { 0, 255, 255}, // Cyan 46 | { 255, 181, 197}, // Pink 47 | { 0, 255, 204}, //bright Turquoise 48 | { 75, 0, 130}, //indigo 49 | { 0, 0, 128}, //navy 50 | { 0, 128, 128}, //teal 51 | { 64, 224, 208}, //turquoise 52 | { 127, 255, 0}, //chartreuse 53 | { 238, 201, 0}, //gold 54 | { 255, 128, 0}, //orange 55 | { 165, 42, 42}, //brown 56 | { 128, 0, 0}, //maroon 57 | { 128, 128, 128} //gray 58 | }; 59 | 60 | void setup() 61 | { 62 | for(int i = 0; i < 3; ++i) { 63 | pinMode(pins[i], OUTPUT); 64 | } 65 | resetColorList(); 66 | SerialUSB.begin(9600); 67 | SerialCloud.begin(115200); 68 | delay(4000); 69 | 70 | Dash.begin(); 71 | Dash.pulseLED(100,5000); 72 | } 73 | 74 | int findColor(String color) 75 | { 76 | SerialUSB.println(color); 77 | 78 | int i; 79 | for (i = 0; i < NUMCOLORS; ++i) { 80 | if (color == colors[i]) { 81 | SerialUSB.println("Color found"); 82 | return i; 83 | } 84 | } 85 | return -1; 86 | } 87 | 88 | void resetColorList() 89 | { 90 | curColors[0] = 0; 91 | for(int i = 1; i < 10; ++i) { 92 | curColors[i] = -1; 93 | } 94 | curColorIdx = 0; 95 | colorStep = 4; 96 | timeBetweenSteps = 100; 97 | } 98 | 99 | void doPartyMode() 100 | { 101 | SerialUSB.println("PARTY!"); 102 | for(int i = 0; i < 10; ++i) { 103 | int randcolor = random(1, NUMCOLORS); 104 | curColors[i] = randcolor; 105 | } 106 | curColorIdx = 0; 107 | colorStep = 255; 108 | timeBetweenSteps = 150; 109 | } 110 | 111 | void parseColorString(String sms) 112 | { 113 | resetColorList(); 114 | sms.toUpperCase(); 115 | 116 | int numcolors = 0; 117 | int startidx = 0; 118 | while(startidx < sms.length() && numcolors < 10) { 119 | int endidx = sms.indexOf(' ', startidx); 120 | if(endidx == -1) { 121 | endidx = sms.length(); 122 | } 123 | String colorStr = sms.substring(startidx, endidx); 124 | SerialUSB.println(colorStr); 125 | if(colorStr == "PARTY") { 126 | doPartyMode(); 127 | return; 128 | } else if(colorStr == "BLINK") { 129 | colorStep = 255; 130 | timeBetweenSteps = 500; 131 | } else { 132 | int curColor = findColor(colorStr); 133 | if(curColor >= 0) { 134 | curColors[numcolors] = curColor; 135 | ++numcolors; 136 | } 137 | } 138 | startidx = endidx + 1; 139 | } 140 | } 141 | 142 | 143 | void loop() 144 | { 145 | char currChar; 146 | 147 | while (SerialCloud.available()) { 148 | 149 | currChar = (char)SerialCloud.read(); 150 | 151 | // check if the current buffer hits the SMSRCVD code. 152 | if (!foundSMS) { 153 | 154 | if (tempBuffer == "SMSRCVD") { 155 | foundSMS = true; 156 | } 157 | } 158 | // If it received the SMSRCVD code, the payload will get populated until 159 | // we get a \n. 160 | else if (currChar == '\n'){ 161 | 162 | SerialUSB.println("\nSMS received: "); 163 | 164 | payload = stripOffLengthNumber(payload); 165 | payload.trim(); 166 | 167 | SerialUSB.println(payload); 168 | 169 | parseColorString(payload); 170 | 171 | // reset foundSMS and the payload for the next iteration. 172 | foundSMS = false; 173 | payload = ""; 174 | } 175 | else { 176 | payload.concat(currChar); 177 | } 178 | 179 | // Only keep a sliding buffer length of size 7 180 | // (need to only check for SMSRCVD). 181 | if (tempBuffer.length() >= 7) { 182 | tempBuffer.remove(0, 1); 183 | } 184 | 185 | // add latest char to our buffer. 186 | if (currChar != '\0') { 187 | tempBuffer.concat(currChar); 188 | } 189 | 190 | SerialUSB.write(currChar); 191 | } 192 | 193 | if(nextColorStep < millis()) { 194 | nextColorStep = millis() + timeBetweenSteps; 195 | int curColor = curColors[curColorIdx]; 196 | if(curColor >= 0) { 197 | // Check if all colors are where they should be 198 | bool colorsSet = true; 199 | for(int i = 0; i < 3; ++i) { 200 | if(curColVal[i] != colorVals[curColor][i]) { 201 | colorsSet = false; 202 | break; 203 | } 204 | } 205 | 206 | if(colorsSet) { 207 | ++curColorIdx; 208 | if(curColorIdx >= 10 || curColors[curColorIdx] == -1) { 209 | curColorIdx = 0; 210 | } 211 | } else { 212 | for(int i = 0; i < 3; ++i) { 213 | if(curColVal[i] != colorVals[curColor][i]) { 214 | int remaining = colorVals[curColor][i] - curColVal[i]; 215 | if(remaining < 0) { 216 | curColVal[i] -= min((-1*remaining), colorStep); 217 | } else { 218 | curColVal[i] += min(remaining, colorStep); 219 | } 220 | analogWrite(pins[i], curColVal[i]); 221 | } 222 | } 223 | } 224 | } 225 | } 226 | 227 | delay(40); 228 | } 229 | 230 | String stripOffLengthNumber(String payload) 231 | { 232 | 233 | int index = 0; 234 | while (payload[index] == ',') { 235 | ++index; 236 | } 237 | while (payload[index] != ',') { 238 | ++index; 239 | } 240 | ++index; 241 | 242 | payload.remove(0, index); 243 | 244 | return payload; 245 | } 246 | -------------------------------------------------------------------------------- /adafruit_gps_on_dash/adafruitgpswithdash.ino: -------------------------------------------------------------------------------- 1 | /* Test code for Adafruit GPS modules using MTK3329/MTK3339 driver 2 | * Modified by Hologram for the Hologram Dash 3 | * This is based off of the Adafruit Arduino Due example at: 4 | * https://github.com/adafruit/Adafruit_GPS/blob/master/examples/due_parsing/due_parsing.ino 5 | * This modified Hologram version sends the latitude and longitude data back to the 6 | * Hologram cloud 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 9 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 11 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 12 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 13 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 14 | * SOFTWARE. 15 | * 16 | */ 17 | 18 | #include 19 | 20 | #define Serial SerialUSB 21 | #define mySerial Serial0 22 | 23 | //Change this to change how often the GPS data is printed and sent to the cloud 24 | #define GPS_SERIAL_SEND_TIME 30000 25 | #define GPS_CLOUD_SEND_TIME 900000 26 | 27 | #define LED_DATA_INDICATOR_DURATION 200 28 | #define LED_DATA_INDICATOR_FLICKER_OFF_DURATION 50 29 | #define LED_DATA_INDICATOR_FLICKER_ON_DURATION 5 30 | 31 | Adafruit_GPS GPS(&mySerial); 32 | 33 | // Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console 34 | // Set to 'true' if you want to debug and listen to the raw GPS sentences. 35 | #define GPSECHO false 36 | 37 | /* globals */ 38 | unsigned ledStartMillis; 39 | unsigned ledNextFlickerMillis; 40 | bool uplinkDataDetected; 41 | bool downlinkDataDetected; 42 | bool ledOn; 43 | uint32_t nextGPSSerialOutput; 44 | uint32_t nextGPSCloudOutput; 45 | unsigned lastMillis; 46 | 47 | void setup() 48 | { 49 | // connect at 115200 so we can read the GPS fast enough and echo without dropping chars 50 | // also spit it out 51 | Dash.begin(); 52 | Serial2.begin(9600); 53 | SerialUSB.begin(9600); 54 | SerialUSB.println("Hologram GPS Test!"); 55 | SerialCloud.begin(115200); 56 | 57 | ledStartMillis = 0; /* LED off by default */ 58 | ledNextFlickerMillis = 0; 59 | uplinkDataDetected = false; 60 | downlinkDataDetected = false; 61 | ledOn = false; 62 | ledIndicateData(); 63 | 64 | nextGPSSerialOutput = 0; 65 | nextGPSCloudOutput = 0; 66 | 67 | // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800 68 | GPS.begin(9600); 69 | mySerial.begin(9600); 70 | 71 | // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude 72 | GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); 73 | // uncomment this line to turn on only the "minimum recommended" data 74 | //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); 75 | // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since 76 | // the parser doesn't care about other sentences at this time 77 | 78 | // Set the update rate 79 | GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate 80 | // For the parsing code to work nicely and have time to sort thru the data, and 81 | // print it out we don't suggest using anything higher than 1 Hz 82 | 83 | // Request updates on antenna status, comment out to keep quiet 84 | GPS.sendCommand(PGCMD_ANTENNA); 85 | 86 | delay(1000); 87 | // Ask for firmware version 88 | mySerial.println(PMTK_Q_RELEASE); 89 | 90 | lastMillis = millis(); 91 | 92 | SerialCloud.println("Init"); 93 | } 94 | 95 | void loop() { 96 | char currChar; 97 | 98 | if(ledOn) { 99 | Dash.onLED(); 100 | } else { 101 | Dash.offLED(); 102 | } 103 | if (uplinkDataDetected) { 104 | /* for uplink data, we turn on LED for duration */ 105 | ledOn=true; 106 | if(millis() > (ledStartMillis + LED_DATA_INDICATOR_DURATION)) { 107 | uplinkDataDetected=false; 108 | ledOn=false; 109 | } 110 | } 111 | if (!uplinkDataDetected && downlinkDataDetected) { 112 | /* for downlink data, we flash LED for duration */ 113 | if(millis() > ledNextFlickerMillis) { 114 | if(ledOn) { 115 | ledOn=false; 116 | ledNextFlickerMillis = millis() + LED_DATA_INDICATOR_FLICKER_OFF_DURATION; 117 | } else { 118 | ledOn=true; 119 | ledNextFlickerMillis = millis() + LED_DATA_INDICATOR_FLICKER_ON_DURATION; 120 | } 121 | } 122 | if(millis() > (ledStartMillis + LED_DATA_INDICATOR_DURATION)) { 123 | downlinkDataDetected=false; 124 | ledOn=false; 125 | } 126 | } 127 | 128 | while(Serial2.available()) { 129 | SerialCloud.write(Serial2.read()); 130 | uplinkDataDetected=true; 131 | ledIndicateData(); 132 | } 133 | 134 | while(SerialUSB.available()) { 135 | SerialCloud.write(SerialUSB.read()); 136 | uplinkDataDetected=true; 137 | ledIndicateData(); 138 | } 139 | 140 | while(SerialCloud.available()) { 141 | currChar = (char)SerialCloud.read(); 142 | SerialUSB.write(currChar); 143 | Serial2.write(currChar); 144 | downlinkDataDetected=true; 145 | ledNextFlickerMillis = millis() + LED_DATA_INDICATOR_FLICKER_ON_DURATION; 146 | ledIndicateData(); 147 | } 148 | 149 | handleGPS(); 150 | 151 | // if millis() or timer wraps around, we'll just reset it 152 | if (lastMillis > millis()) { 153 | nextGPSSerialOutput = millis(); 154 | nextGPSCloudOutput = millis(); 155 | } 156 | lastMillis = millis(); 157 | } 158 | 159 | 160 | void handleGPS() { 161 | // read data from the GPS in the 'main loop' 162 | char c = GPS.read(); 163 | // if you want to debug, this is a good time to do it! 164 | if (GPSECHO) 165 | if (c) Serial.print(c); 166 | 167 | // if a sentence is received, we can check the checksum, parse it... 168 | if (GPS.newNMEAreceived()) { 169 | // a tricky thing here is if we print the NMEA sentence, or data 170 | // we end up not listening and catching other sentences! 171 | // so be very wary if using OUTPUT_ALLDATA and trytng to print out data 172 | //Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false 173 | 174 | if (!GPS.parse(GPS.lastNMEA())) { // this also sets the newNMEAreceived() flag to false 175 | return; // we can fail to parse a sentence in which case we should just wait for another 176 | } 177 | } 178 | 179 | // print out the current stats and send to cloud 180 | if (nextGPSSerialOutput < millis()) { 181 | nextGPSSerialOutput = millis() + GPS_SERIAL_SEND_TIME; // reset the timer 182 | 183 | Serial.print("\nTime: "); 184 | Serial.print(GPS.hour, DEC); Serial.print(':'); 185 | Serial.print(GPS.minute, DEC); Serial.print(':'); 186 | Serial.print(GPS.seconds, DEC); Serial.print('.'); 187 | Serial.println(GPS.milliseconds); 188 | Serial.print("Date: "); 189 | Serial.print(GPS.day, DEC); Serial.print('/'); 190 | Serial.print(GPS.month, DEC); Serial.print("/20"); 191 | Serial.println(GPS.year, DEC); 192 | Serial.print("Fix: "); Serial.print((int)GPS.fix); 193 | Serial.print(" quality: "); Serial.println((int)GPS.fixquality); 194 | if (GPS.fix) { 195 | Serial.print("Location: "); 196 | Serial.print(GPS.latitude, 4); Serial.print(GPS.lat); 197 | Serial.print(", "); 198 | Serial.print(GPS.longitude, 4); Serial.println(GPS.lon); 199 | 200 | Serial.print("Speed (knots): "); Serial.println(GPS.speed); 201 | Serial.print("Angle: "); Serial.println(GPS.angle); 202 | Serial.print("Altitude: "); Serial.println(GPS.altitude); 203 | Serial.print("Satellites: "); Serial.println((int)GPS.satellites); 204 | } 205 | } 206 | 207 | if(GPS.fix && nextGPSCloudOutput < millis()) { 208 | nextGPSCloudOutput = millis() + GPS_CLOUD_SEND_TIME; 209 | // Send latitude and longitude to cloud 210 | String loc; 211 | char coordbuf[16]; 212 | dtostrf(GPS.latitudeDegrees, 0, 4, coordbuf); 213 | loc.concat(coordbuf); 214 | loc.concat(" "); 215 | dtostrf(GPS.longitudeDegrees, 0, 4, coordbuf); 216 | loc.concat(coordbuf); 217 | SerialCloud.println(loc); 218 | } 219 | } 220 | 221 | void ledIndicateData() { 222 | ledStartMillis=millis(); 223 | ledOn=true; 224 | } 225 | --------------------------------------------------------------------------------