diff --git a/examples/Hypnos/Adalogger_Sleep/Adalogger_Sleep.ino b/examples/Hypnos/Adalogger_Sleep/Adalogger_Sleep.ino index 74ef366b..997d4683 100644 --- a/examples/Hypnos/Adalogger_Sleep/Adalogger_Sleep.ino +++ b/examples/Hypnos/Adalogger_Sleep/Adalogger_Sleep.ino @@ -36,6 +36,8 @@ void setup() { } void loop() { + // Set the RTC interrupt alarm to wake the device in 10 seconds, done at top so evenly spaced sample periods + hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 10)); // Measure and package data manager.measure(); @@ -47,8 +49,7 @@ void loop() { // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device in 10 seconds - hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 10)); + // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Hypnos/Hypnos_SD_Sleep/Hypnos_SD_Sleep.ino b/examples/Hypnos/Hypnos_SD_Sleep/Hypnos_SD_Sleep.ino index 589230d3..fa2b2838 100644 --- a/examples/Hypnos/Hypnos_SD_Sleep/Hypnos_SD_Sleep.ino +++ b/examples/Hypnos/Hypnos_SD_Sleep/Hypnos_SD_Sleep.ino @@ -38,6 +38,9 @@ void setup() { void loop() { + // Set the RTC interrupt alarm to wake the device in 10 seconds, at the top to schedule next interrupt asap + hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 10)); + // Measure and package data manager.measure(); manager.package(); @@ -48,8 +51,7 @@ void loop() { // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device in 10 seconds - hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 10)); + // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Hypnos/Hypnos_SD_Sleep_Interval_From_SD/Hypnos_SD_Sleep_Interval_From_SD.ino b/examples/Hypnos/Hypnos_SD_Sleep_Interval_From_SD/Hypnos_SD_Sleep_Interval_From_SD.ino index aa20f998..44230475 100644 --- a/examples/Hypnos/Hypnos_SD_Sleep_Interval_From_SD/Hypnos_SD_Sleep_Interval_From_SD.ino +++ b/examples/Hypnos/Hypnos_SD_Sleep_Interval_From_SD/Hypnos_SD_Sleep_Interval_From_SD.ino @@ -39,6 +39,9 @@ void setup() { } void loop() { + + // Set the RTC interrupt alarm to wake the device in 10 seconds + hypnos.setInterruptDuration(sleepInterval); // Print the current JSON packet manager.display_data(); @@ -46,9 +49,6 @@ void loop() { // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device in 10 seconds - hypnos.setInterruptDuration(sleepInterval); - // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Internet/Logging/LTEBatch/LTEBatch.ino b/examples/Internet/Logging/LTEBatch/LTEBatch.ino index aa296d6d..4362438e 100644 --- a/examples/Internet/Logging/LTEBatch/LTEBatch.ino +++ b/examples/Internet/Logging/LTEBatch/LTEBatch.ino @@ -46,6 +46,9 @@ void setup() { } void loop() { + // Set the RTC interrupt alarm to wake the device in 10 seconds + hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 10)); + // Package data manager.package(); @@ -58,8 +61,7 @@ void loop() { // Pass batch SD along to the MQTT module mqtt.publish(batchSD); - // Set the RTC interrupt alarm to wake the device in 10 seconds - hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 10)); + // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Lab Examples/Evaporometer/Evaporometer.ino b/examples/Lab Examples/Evaporometer/Evaporometer.ino index f1b57ba0..f746d7ad 100644 --- a/examples/Lab Examples/Evaporometer/Evaporometer.ino +++ b/examples/Lab Examples/Evaporometer/Evaporometer.ino @@ -36,6 +36,10 @@ void setup(){ } void loop(){ + + // Set the RTC interrupt alarm to wake the device in 30 seconds, at the top to schedule next interrupt asap + hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 30)); + // Measure and package the data from the sensors manager.measure(); manager.package(); @@ -46,9 +50,6 @@ void loop(){ // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device in 30 seconds - hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 30)); - // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Lab Examples/FloDar/FloDar.ino b/examples/Lab Examples/FloDar/FloDar.ino index 4d74130b..4eb4cff1 100644 --- a/examples/Lab Examples/FloDar/FloDar.ino +++ b/examples/Lab Examples/FloDar/FloDar.ino @@ -41,6 +41,9 @@ void setup() { void loop() { + // Set the RTC interrupt alarm to wake the device in 10 seconds, at the top to schedule next interrupt asap + hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); + // Measure and package data manager.measure(); manager.package(); @@ -51,9 +54,7 @@ void loop() { // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device in 10 seconds - hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); - + // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Lab Examples/MultipleInterrupts/MultipleInterrupts.ino b/examples/Lab Examples/MultipleInterrupts/MultipleInterrupts.ino index ec63d462..bcb8e1ce 100644 --- a/examples/Lab Examples/MultipleInterrupts/MultipleInterrupts.ino +++ b/examples/Lab Examples/MultipleInterrupts/MultipleInterrupts.ino @@ -30,20 +30,15 @@ void wakeTrigger(){ } void tipTrigger() { - tip_time = millis(); - - // Check if the time of the last tip is more than 250 ms to debounce the switch - if(tip_time - last_tip_time > 250){ - counter++; - tipFlag = true; - detachInterrupt(INT_PIN); - } + hypnos.shouldPowerUp = false; + tipFlag = true; + detachInterrupt(INT_PIN); } void setup() { - // Set the interrupt pin to pullup - pinMode(INT_PIN, INPUT_PULLUP); + // Set the interrupt pin to INPUT + pinMode(INT_PIN, INPUT); // Wait 20 seconds for the serial console to open manager.beginSerial(); @@ -62,12 +57,13 @@ void setup() { void loop() { - // If we are waking up normally then we should sample data - if(sampleFlag) { + if(sampleFlag){ + // Set the RTC interrupt alarm to wake the device in 15 min, this should be done as soon as the device enters sampling mode for consistant sleep cycles + hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); + // Measure and package the data manager.measure(); manager.package(); - manager.addData("Switch", "Status", counter); // Print the current JSON packet manager.display_data(); @@ -75,23 +71,23 @@ void loop() { // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device every 30 seconds - hypnos.setInterruptDuration(TimeSpan(0, 0, 0, 30)); - // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); - - sampleFlag = false; // Do not do this process unless ISR sets the flag + attachInterrupt(INT_PIN, tipTrigger, FALLING); + attachInterrupt(INT_PIN, tipTrigger, FALLING); + sampleFlag = false; } - // Check if Tipping Bucket event - if(tipFlag) { + if(tipFlag){ + digitalWrite(LED_BUILTIN, HIGH); + delay(20); + bucket.incrementCount(); tipFlag = false; - Serial.println(counter); attachInterrupt(INT_PIN, tipTrigger, FALLING); attachInterrupt(INT_PIN, tipTrigger, FALLING); + digitalWrite(LED_BUILTIN, LOW); } - // Put the device into a deep sleep + // Put the device into a deep sleep, operation HALTS here until the interrupt is triggered hypnos.sleep(); } \ No newline at end of file diff --git a/examples/Lab Examples/SmartRock/SmartRock/SmartRock.ino b/examples/Lab Examples/SmartRock/SmartRock/SmartRock.ino index edacba95..aeb9f4c9 100644 --- a/examples/Lab Examples/SmartRock/SmartRock/SmartRock.ino +++ b/examples/Lab Examples/SmartRock/SmartRock/SmartRock.ino @@ -43,6 +43,9 @@ void setup() { void loop() { + // Set the RTC interrupt alarm to wake the device in 10 seconds, at the top to schedule next interrupt asap + hypnos.setInterruptDuration(sleepInterval); + // Measure and package the data manager.measure(); manager.package(); @@ -58,9 +61,6 @@ void loop() { // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device in 10 seconds - hypnos.setInterruptDuration(sleepInterval); - // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Lab Examples/SmartRock/SmartRock2.5/SmartRock2.5.ino b/examples/Lab Examples/SmartRock/SmartRock2.5/SmartRock2.5.ino index a785ae8a..8e7e0d6b 100644 --- a/examples/Lab Examples/SmartRock/SmartRock2.5/SmartRock2.5.ino +++ b/examples/Lab Examples/SmartRock/SmartRock2.5/SmartRock2.5.ino @@ -44,6 +44,9 @@ void setup() { } void loop() { + + // Set the RTC interrupt alarm to wake the device in 10 seconds, at the top to schedule next interrupt asap + hypnos.setInterruptDuration(sleepInterval); // Measure and package the data manager.measure(); @@ -55,8 +58,6 @@ void loop() { // Log the data to the SD card hypnos.logToSD(); - // Set the RTC interrupt alarm to wake the device in 10 seconds - hypnos.setInterruptDuration(sleepInterval); // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Lab Examples/Wattson/Wattson.ino b/examples/Lab Examples/Wattson/Wattson.ino index a1f3cca7..70f3b970 100644 --- a/examples/Lab Examples/Wattson/Wattson.ino +++ b/examples/Lab Examples/Wattson/Wattson.ino @@ -17,13 +17,16 @@ Manager manager("Device", 1); //Loom_WIFI wifi(manager, CommunicationMode::AP); // For AP Loom_WIFI wifi(manager, CommunicationMode::CLIENT, SECRET_SSID, SECRET_PASS); // For Client + +// Create a new instance of max this takes in the WiFi object so we can communicate with the computer in addition to adding a controllable neopixel Loom_Max maxMsp(manager, wifi, new Loom_Neopixel()); Loom_MPU6050 mpu(manager); // Read the battery voltage and A0 and A1 Loom_Analog analog(manager, A0, A1); + // Reads the button on pin 10 -Loom_Digital digital(manager, 10); +Loom_Digital digital(manager, INPUT_PULLUP, 10); void setup() { diff --git a/examples/Lab Examples/Wattson/arduino_secrets.h b/examples/Lab Examples/Wattson/arduino_secrets.h new file mode 100644 index 00000000..a36e69b9 --- /dev/null +++ b/examples/Lab Examples/Wattson/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" \ No newline at end of file diff --git a/examples/Lab Examples/WeatherChimes/WeatherChimes4G/WeatherChimes4G.ino b/examples/Lab Examples/WeatherChimes/WeatherChimes4G/WeatherChimes4G.ino index aea8e7b7..2e0f74ea 100644 --- a/examples/Lab Examples/WeatherChimes/WeatherChimes4G/WeatherChimes4G.ino +++ b/examples/Lab Examples/WeatherChimes/WeatherChimes4G/WeatherChimes4G.ino @@ -79,6 +79,9 @@ void setup() { void loop() { + // Set the RTC interrupt alarm to wake the device in 15 min, at the top to schedule next interrupt asap + hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); + // Measure and package the data manager.measure(); manager.package(); @@ -95,9 +98,6 @@ void loop() { // Publish the collected data to MQTT mqtt.publish(); - // Set the RTC interrupt alarm to wake the device in 15 min - hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); - // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucket/WeatherChimesTippingBucket.ino b/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucket/WeatherChimesTippingBucket.ino index 3004b918..f525f2ef 100644 --- a/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucket/WeatherChimesTippingBucket.ino +++ b/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucket/WeatherChimesTippingBucket.ino @@ -75,7 +75,7 @@ void setup() { ENABLE_FUNC_SUMMARIES; // Set the interrupt pin to pullup - pinMode(INT_PIN, INPUT_PULLUP); + pinMode(INT_PIN, INPUT); // Wait 20 seconds for the serial console to open manager.beginSerial(); @@ -101,6 +101,9 @@ void setup() { void loop() { if(sampleFlag){ + // Set the RTC interrupt alarm to wake the device in 15 min, this should be done as soon as the device enters sampling mode for consistant sleep cycles + hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); + // Measure and package the data manager.measure(); manager.package(); @@ -117,9 +120,6 @@ void loop() { // Publish the collected data to MQTT mqtt.publish(); - // Set the RTC interrupt alarm to wake the device in 15 min - hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); - // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); attachInterrupt(INT_PIN, tipTrigger, FALLING); diff --git a/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucketI2C/WeatherChimesTippingBucketI2C.ino b/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucketI2C/WeatherChimesTippingBucketI2C.ino index f9916ae6..2ef7b64d 100644 --- a/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucketI2C/WeatherChimesTippingBucketI2C.ino +++ b/examples/Lab Examples/WeatherChimes/WeatherChimesTippingBucketI2C/WeatherChimesTippingBucketI2C.ino @@ -90,7 +90,7 @@ void loop() { // Publish the collected data to MQTT mqtt.publish(); - // Set the RTC interrupt alarm to wake the device in 15 min + // Set the RTC interrupt alarm to wake the device in 15 min, at the top to schedule next interrupt asap hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); // Reattach to the interrupt after we have set the alarm so we can have repeat triggers diff --git a/examples/Lab Examples/WeatherChimes/WeatherChimesWifi/WeatherChimesWiFi.ino b/examples/Lab Examples/WeatherChimes/WeatherChimesWifi/WeatherChimesWiFi.ino index bae0aab4..cb440570 100644 --- a/examples/Lab Examples/WeatherChimes/WeatherChimesWifi/WeatherChimesWiFi.ino +++ b/examples/Lab Examples/WeatherChimes/WeatherChimesWifi/WeatherChimesWiFi.ino @@ -79,6 +79,9 @@ void setup() { void loop() { + // Set the RTC interrupt alarm to wake the device in 15 min, at the top to schedule next interrupt asap + hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); + // Measure and package the data manager.measure(); manager.package(); @@ -95,9 +98,7 @@ void loop() { // Publish the collected data to MQTT mqtt.publish(); - // Set the RTC interrupt alarm to wake the device in 15 min - hypnos.setInterruptDuration(TimeSpan(0, 0, 15, 0)); - + // Reattach to the interrupt after we have set the alarm so we can have repeat triggers hypnos.reattachRTCInterrupt(); diff --git a/examples/Sensors/Digital/Digital.ino b/examples/Sensors/Digital/Digital.ino index b0439bb9..d45fc063 100644 --- a/examples/Sensors/Digital/Digital.ino +++ b/examples/Sensors/Digital/Digital.ino @@ -12,8 +12,8 @@ Manager manager("Device", 1); -// Reads the battery voltage -Loom_Digital digital(manager, 12, 11); +// Sets the pinMode of pin 12 and 11 to INPUT_PULLUP and then reads values from the pins +Loom_Digital digital(manager, INPUT_PULLUP, 12, 11); void setup() { @@ -25,7 +25,6 @@ void setup() { } void loop() { - // put your main code here, to run repeatedly: // Measure the data from the sensors manager.measure(); diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp index 6810e244..c052571a 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp @@ -351,7 +351,6 @@ void Loom_Hypnos::setInterruptDuration(const TimeSpan duration){ DateTime future(RTC_DS.now() + duration); RTC_DS.setAlarm(future); - // Print the time that the next interrupt is set to trigger snprintf(output, OUTPUT_SIZE, PSTR("Current Time: %s"), RTC_DS.now().text()); LOG(output); @@ -366,22 +365,27 @@ void Loom_Hypnos::setInterruptDuration(const TimeSpan duration){ ////////////////////////////////////////////////////////////////////////////////////////////////////// void Loom_Hypnos::sleep(bool waitForSerial){ - // Try to power down the active modules - if(shouldPowerUp){ - manInst->power_down(); - // 50ms delay allows this last message to be sent before the bus disconnects - LOG("Entering Standby Sleep..."); - delay(50); - } + // If the alarm set time is less than the current time we missed our next alarm so we need to set a new one + if(RTC_DS.getAlarm(1) > RTC_DS.now()){ - - - disable(); - pre_sleep(); // Pre-sleep cleanup - shouldPowerUp = true; - LowPower.sleep(); // Go to sleep and hang - post_sleep(waitForSerial); // Wake up + // Try to power down the active modules + if(shouldPowerUp){ + manInst->power_down(); + + // 50ms delay allows this last message to be sent before the bus disconnects + LOG("Entering Standby Sleep..."); + delay(50); + } + + disable(); + pre_sleep(); // Pre-sleep cleanup + shouldPowerUp = true; + LowPower.sleep(); // Go to sleep and hang + post_sleep(waitForSerial); // Wake up + }else{ + WARNING("Alarm triggered during sample, specified sample duration was too short! Setting new sample time..."); + } } ////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Internet/Logging/Loom_MQTT/Loom_MQTT.cpp b/src/Internet/Logging/Loom_MQTT/Loom_MQTT.cpp index 07f2e98a..23ced492 100644 --- a/src/Internet/Logging/Loom_MQTT/Loom_MQTT.cpp +++ b/src/Internet/Logging/Loom_MQTT/Loom_MQTT.cpp @@ -248,19 +248,36 @@ void Loom_MQTT::loadConfigFromJSON(char* json){ StaticJsonDocument<300> doc; DeserializationError deserialError = deserializeJson(doc, json); + /* + Initialize all to null bytes so they are treated as a 0 length string + Issue: https://github.com/OPEnSLab-OSU/Loom-V4/issues/57 + */ + memset(projectServer, '\0', 100); + memset(username, '\0', 100); + memset(password, '\0', 100); + // Check if an error occurred and if so print it if(deserialError != DeserializationError::Ok){ snprintf_P(output, OUTPUT_SIZE, PSTR("There was an error reading the MQTT credentials from SD: %s"), deserialError.c_str()); ERROR(output); } + // Only update values if not null if(!doc["broker"].isNull()){ strncpy(address, doc["broker"].as(), 100); strncpy(database_name, doc["database"].as(), 100); - strncpy(username, doc["username"].as(), 100); - strncpy(password, doc["password"].as(), 100); - strncpy(projectServer, doc["project"].as(), 100); + + // If we dont have a username don't try to update the variables + if(!doc["username"].isNull()){ + strncpy(username, doc["username"].as(), 100); + strncpy(password, doc["password"].as(), 100); + } + + // If there is no project parameter don't update the project + if(!doc["project"].isNull()) + strncpy(projectServer, doc["project"].as(), 100); + port = doc["port"].as(); } diff --git a/src/Sensors/Loom_Digital/Loom_Digital.h b/src/Sensors/Loom_Digital/Loom_Digital.h index 25a974c3..b959a84e 100644 --- a/src/Sensors/Loom_Digital/Loom_Digital.h +++ b/src/Sensors/Loom_Digital/Loom_Digital.h @@ -27,13 +27,13 @@ class Loom_Digital : public Module{ * @param additionalPins Variable length argument allowing you to supply multiple pins */ template - Loom_Digital(Manager& man, T firstPin , Args... additionalPins) : Module("Digital"){ + Loom_Digital(Manager& man, int pinState, T firstPin , Args... additionalPins) : Module("Digital"){ get_variadic_parameters(firstPin, additionalPins...); manInst = &man; // Set pin mode on digital pins for(int i = 0; i < digitalPins.size(); i++){ - pinMode(digitalPins[i], INPUT_PULLUP); + pinMode(digitalPins[i], pinState); } // Register the module with the manager @@ -46,12 +46,12 @@ class Loom_Digital : public Module{ * @param firstPin First digital pin we want to read from */ template - Loom_Digital(Manager& man, T firstPin) : Module("Digital"){ + Loom_Digital(Manager& man, int pinState, T firstPin) : Module("Digital"){ digitalPins.push_back(firstPin); manInst = &man; for(int i = 0; i < digitalPins.size(); i++){ - pinMode(digitalPins[i], INPUT_PULLUP); + pinMode(digitalPins[i], pinState); } // Register the module with the manager