From d994777633de4f32c7fc20ee69b4d612075f0c77 Mon Sep 17 00:00:00 2001 From: Will Richards Date: Sat, 30 Sep 2023 11:50:48 -0700 Subject: [PATCH 1/7] Integrated SEN55 and moved Sensor examples into sub-folders based on their protocol --- .../Sensors/Analog/{ => Analog}/Analog.ino | 0 .../Sensors/{ => Analog}/Teros10/Teros10.ino | 0 .../Sensors/{ => I2C}/ADS1115/ADS1115.ino | 0 examples/Sensors/{ => I2C}/AS7262/AS7262.ino | 0 examples/Sensors/{ => I2C}/AS7263/AS7263.ino | 0 .../Sensors/{ => I2C}/AS7265X/AS7265X.ino | 0 .../Sensors/{ => I2C}/EZO/EZO-CO2/EZO-CO2.ino | 0 .../EZO/EZO-DisOxygen/EZO-DisOxygen.ino | 0 .../Sensors/{ => I2C}/EZO/EZO-ORP/EZO-ORP.ino | 0 .../Sensors/{ => I2C}/EZO/EZO-PH/EZO-PH.ino | 0 .../Sensors/{ => I2C}/EZO/EZO-RGB/EZO-RGB.ino | 0 examples/Sensors/{ => I2C}/K30/K30.ino | 0 examples/Sensors/{ => I2C}/MB1232/MB1232.ino | 0 .../Sensors/{ => I2C}/MMA8451/MMA8451.ino | 0 examples/Sensors/{ => I2C}/MS5803/MS5803.ino | 0 .../MS5803_2_Sensors/MS5803_2_Sensors.ino | 0 .../{ => I2C}/Multiplexer/Multiplexer.ino | 0 examples/Sensors/I2C/SEN55/SEN55.ino | 35 ++++ examples/Sensors/{ => I2C}/SHT31/SHT31.ino | 0 examples/Sensors/{ => I2C}/STEMMA/STEMMA.ino | 0 .../Sensors/{ => I2C}/TSL2591/TSL2591.ino | 0 .../Sensors/{ => I2C}/ZXGesture/ZXGesture.ino | 0 .../{ => SPI}/MAX/MAX31856/MAX31856.ino | 0 .../{ => SPI}/MAX/MAX31865/MAX31865.ino | 0 .../Sensors/{ => Serial}/NOVASDS/NOVASDS.ino | 0 src/Hardware/Loom_Hypnos/Loom_Hypnos.h | 2 +- src/Module.h | 2 +- src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp | 169 +++++++++++++++ src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h | 194 ++++++++++++++++++ src/Sensors/I2C/Loom_SHT31/Loom_SHT31.h | 2 +- 30 files changed, 401 insertions(+), 3 deletions(-) rename examples/Sensors/Analog/{ => Analog}/Analog.ino (100%) rename examples/Sensors/{ => Analog}/Teros10/Teros10.ino (100%) rename examples/Sensors/{ => I2C}/ADS1115/ADS1115.ino (100%) rename examples/Sensors/{ => I2C}/AS7262/AS7262.ino (100%) rename examples/Sensors/{ => I2C}/AS7263/AS7263.ino (100%) rename examples/Sensors/{ => I2C}/AS7265X/AS7265X.ino (100%) rename examples/Sensors/{ => I2C}/EZO/EZO-CO2/EZO-CO2.ino (100%) rename examples/Sensors/{ => I2C}/EZO/EZO-DisOxygen/EZO-DisOxygen.ino (100%) rename examples/Sensors/{ => I2C}/EZO/EZO-ORP/EZO-ORP.ino (100%) rename examples/Sensors/{ => I2C}/EZO/EZO-PH/EZO-PH.ino (100%) rename examples/Sensors/{ => I2C}/EZO/EZO-RGB/EZO-RGB.ino (100%) rename examples/Sensors/{ => I2C}/K30/K30.ino (100%) rename examples/Sensors/{ => I2C}/MB1232/MB1232.ino (100%) rename examples/Sensors/{ => I2C}/MMA8451/MMA8451.ino (100%) rename examples/Sensors/{ => I2C}/MS5803/MS5803.ino (100%) rename examples/Sensors/{ => I2C}/MS5803_2_Sensors/MS5803_2_Sensors.ino (100%) rename examples/Sensors/{ => I2C}/Multiplexer/Multiplexer.ino (100%) create mode 100644 examples/Sensors/I2C/SEN55/SEN55.ino rename examples/Sensors/{ => I2C}/SHT31/SHT31.ino (100%) rename examples/Sensors/{ => I2C}/STEMMA/STEMMA.ino (100%) rename examples/Sensors/{ => I2C}/TSL2591/TSL2591.ino (100%) rename examples/Sensors/{ => I2C}/ZXGesture/ZXGesture.ino (100%) rename examples/Sensors/{ => SPI}/MAX/MAX31856/MAX31856.ino (100%) rename examples/Sensors/{ => SPI}/MAX/MAX31865/MAX31865.ino (100%) rename examples/Sensors/{ => Serial}/NOVASDS/NOVASDS.ino (100%) create mode 100644 src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp create mode 100644 src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h diff --git a/examples/Sensors/Analog/Analog.ino b/examples/Sensors/Analog/Analog/Analog.ino similarity index 100% rename from examples/Sensors/Analog/Analog.ino rename to examples/Sensors/Analog/Analog/Analog.ino diff --git a/examples/Sensors/Teros10/Teros10.ino b/examples/Sensors/Analog/Teros10/Teros10.ino similarity index 100% rename from examples/Sensors/Teros10/Teros10.ino rename to examples/Sensors/Analog/Teros10/Teros10.ino diff --git a/examples/Sensors/ADS1115/ADS1115.ino b/examples/Sensors/I2C/ADS1115/ADS1115.ino similarity index 100% rename from examples/Sensors/ADS1115/ADS1115.ino rename to examples/Sensors/I2C/ADS1115/ADS1115.ino diff --git a/examples/Sensors/AS7262/AS7262.ino b/examples/Sensors/I2C/AS7262/AS7262.ino similarity index 100% rename from examples/Sensors/AS7262/AS7262.ino rename to examples/Sensors/I2C/AS7262/AS7262.ino diff --git a/examples/Sensors/AS7263/AS7263.ino b/examples/Sensors/I2C/AS7263/AS7263.ino similarity index 100% rename from examples/Sensors/AS7263/AS7263.ino rename to examples/Sensors/I2C/AS7263/AS7263.ino diff --git a/examples/Sensors/AS7265X/AS7265X.ino b/examples/Sensors/I2C/AS7265X/AS7265X.ino similarity index 100% rename from examples/Sensors/AS7265X/AS7265X.ino rename to examples/Sensors/I2C/AS7265X/AS7265X.ino diff --git a/examples/Sensors/EZO/EZO-CO2/EZO-CO2.ino b/examples/Sensors/I2C/EZO/EZO-CO2/EZO-CO2.ino similarity index 100% rename from examples/Sensors/EZO/EZO-CO2/EZO-CO2.ino rename to examples/Sensors/I2C/EZO/EZO-CO2/EZO-CO2.ino diff --git a/examples/Sensors/EZO/EZO-DisOxygen/EZO-DisOxygen.ino b/examples/Sensors/I2C/EZO/EZO-DisOxygen/EZO-DisOxygen.ino similarity index 100% rename from examples/Sensors/EZO/EZO-DisOxygen/EZO-DisOxygen.ino rename to examples/Sensors/I2C/EZO/EZO-DisOxygen/EZO-DisOxygen.ino diff --git a/examples/Sensors/EZO/EZO-ORP/EZO-ORP.ino b/examples/Sensors/I2C/EZO/EZO-ORP/EZO-ORP.ino similarity index 100% rename from examples/Sensors/EZO/EZO-ORP/EZO-ORP.ino rename to examples/Sensors/I2C/EZO/EZO-ORP/EZO-ORP.ino diff --git a/examples/Sensors/EZO/EZO-PH/EZO-PH.ino b/examples/Sensors/I2C/EZO/EZO-PH/EZO-PH.ino similarity index 100% rename from examples/Sensors/EZO/EZO-PH/EZO-PH.ino rename to examples/Sensors/I2C/EZO/EZO-PH/EZO-PH.ino diff --git a/examples/Sensors/EZO/EZO-RGB/EZO-RGB.ino b/examples/Sensors/I2C/EZO/EZO-RGB/EZO-RGB.ino similarity index 100% rename from examples/Sensors/EZO/EZO-RGB/EZO-RGB.ino rename to examples/Sensors/I2C/EZO/EZO-RGB/EZO-RGB.ino diff --git a/examples/Sensors/K30/K30.ino b/examples/Sensors/I2C/K30/K30.ino similarity index 100% rename from examples/Sensors/K30/K30.ino rename to examples/Sensors/I2C/K30/K30.ino diff --git a/examples/Sensors/MB1232/MB1232.ino b/examples/Sensors/I2C/MB1232/MB1232.ino similarity index 100% rename from examples/Sensors/MB1232/MB1232.ino rename to examples/Sensors/I2C/MB1232/MB1232.ino diff --git a/examples/Sensors/MMA8451/MMA8451.ino b/examples/Sensors/I2C/MMA8451/MMA8451.ino similarity index 100% rename from examples/Sensors/MMA8451/MMA8451.ino rename to examples/Sensors/I2C/MMA8451/MMA8451.ino diff --git a/examples/Sensors/MS5803/MS5803.ino b/examples/Sensors/I2C/MS5803/MS5803.ino similarity index 100% rename from examples/Sensors/MS5803/MS5803.ino rename to examples/Sensors/I2C/MS5803/MS5803.ino diff --git a/examples/Sensors/MS5803_2_Sensors/MS5803_2_Sensors.ino b/examples/Sensors/I2C/MS5803_2_Sensors/MS5803_2_Sensors.ino similarity index 100% rename from examples/Sensors/MS5803_2_Sensors/MS5803_2_Sensors.ino rename to examples/Sensors/I2C/MS5803_2_Sensors/MS5803_2_Sensors.ino diff --git a/examples/Sensors/Multiplexer/Multiplexer.ino b/examples/Sensors/I2C/Multiplexer/Multiplexer.ino similarity index 100% rename from examples/Sensors/Multiplexer/Multiplexer.ino rename to examples/Sensors/I2C/Multiplexer/Multiplexer.ino diff --git a/examples/Sensors/I2C/SEN55/SEN55.ino b/examples/Sensors/I2C/SEN55/SEN55.ino new file mode 100644 index 00000000..c7b2c902 --- /dev/null +++ b/examples/Sensors/I2C/SEN55/SEN55.ino @@ -0,0 +1,35 @@ +/** + * This is an example use case for using the SEN55 Sensor + * + * MANAGER MUST BE INCLUDED FIRST IN ALL CODE + */ +#include + +#include + +Manager manager("Device", 1); +// Manager Reference, Whether or not we should measure particulate matter or nor +Loom_SEN55 sen55(manager, true); + +void setup() { + + // Start the serial interface + manager.beginSerial(); + + // Initialize the manager + manager.initialize(); +} + +void loop() { + // Measure the data from the sensors + manager.measure(); + + // Package the data into JSON + manager.package(); + + // Print the JSON document to the Serial monitor + manager.display_data(); + + // Wait for 5 seconds + manager.pause(5000); +} diff --git a/examples/Sensors/SHT31/SHT31.ino b/examples/Sensors/I2C/SHT31/SHT31.ino similarity index 100% rename from examples/Sensors/SHT31/SHT31.ino rename to examples/Sensors/I2C/SHT31/SHT31.ino diff --git a/examples/Sensors/STEMMA/STEMMA.ino b/examples/Sensors/I2C/STEMMA/STEMMA.ino similarity index 100% rename from examples/Sensors/STEMMA/STEMMA.ino rename to examples/Sensors/I2C/STEMMA/STEMMA.ino diff --git a/examples/Sensors/TSL2591/TSL2591.ino b/examples/Sensors/I2C/TSL2591/TSL2591.ino similarity index 100% rename from examples/Sensors/TSL2591/TSL2591.ino rename to examples/Sensors/I2C/TSL2591/TSL2591.ino diff --git a/examples/Sensors/ZXGesture/ZXGesture.ino b/examples/Sensors/I2C/ZXGesture/ZXGesture.ino similarity index 100% rename from examples/Sensors/ZXGesture/ZXGesture.ino rename to examples/Sensors/I2C/ZXGesture/ZXGesture.ino diff --git a/examples/Sensors/MAX/MAX31856/MAX31856.ino b/examples/Sensors/SPI/MAX/MAX31856/MAX31856.ino similarity index 100% rename from examples/Sensors/MAX/MAX31856/MAX31856.ino rename to examples/Sensors/SPI/MAX/MAX31856/MAX31856.ino diff --git a/examples/Sensors/MAX/MAX31865/MAX31865.ino b/examples/Sensors/SPI/MAX/MAX31865/MAX31865.ino similarity index 100% rename from examples/Sensors/MAX/MAX31865/MAX31865.ino rename to examples/Sensors/SPI/MAX/MAX31865/MAX31865.ino diff --git a/examples/Sensors/NOVASDS/NOVASDS.ino b/examples/Sensors/Serial/NOVASDS/NOVASDS.ino similarity index 100% rename from examples/Sensors/NOVASDS/NOVASDS.ino rename to examples/Sensors/Serial/NOVASDS/NOVASDS.ino diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.h b/src/Hardware/Loom_Hypnos/Loom_Hypnos.h index 9962131f..87efa823 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.h +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.h @@ -92,7 +92,7 @@ class Loom_Hypnos : public Module{ * @param use_custom_time Use a specific time set by the user that is different than the compile time * @param useSD Whether or not SD card functionality should be enabled */ - Loom_Hypnos(Manager& man, HYPNOS_VERSION version, TIME_ZONE zone, bool use_custom_time = false, bool useSD = true); + Loom_Hypnos(Manager& man, HYPNOS_VERSION version, TIME_ZONE zone, bool use_custom_time = true, bool useSD = true); /** * Cleanup any dynamically allocated pointers diff --git a/src/Module.h b/src/Module.h index 4b3c1c00..12165b9a 100644 --- a/src/Module.h +++ b/src/Module.h @@ -20,7 +20,7 @@ #define TIMER_RESET #endif -#define OUTPUT_SIZE 200 +#define OUTPUT_SIZE 256 /** * General overarching interface to provide basic unified functionality diff --git a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp new file mode 100644 index 00000000..e03355b2 --- /dev/null +++ b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp @@ -0,0 +1,169 @@ +#include "Loom_SEN55.h" +#include "Logger.h" + +////////////////////////////////////////////////////////////////////////////////////////////////////// +Loom_SEN55::Loom_SEN55( + Manager& man, + bool measurePM, + bool useMux + ) : I2CDevice("SEN55"), manInst(&man), measurePM(measurePM){ + + // Register the module with the manager + if(!useMux) + manInst->registerModule(this); + } +////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////// +void Loom_SEN55::initialize() { + FUNCTION_START; + char output[OUTPUT_SIZE]; + char errorMessage[OUTPUT_SIZE]; + + /* Initialize wire and start the sensor using the standard I2C interface */ + Wire.begin(); + sen5x.begin(Wire); + + // Attempt to reset the device + uint16_t error = sen5x.deviceReset(); + if(error){ + /* Stringify the errro and log the error */ + errorToString(error, errorMessage, OUTPUT_SIZE); + snprintf(output, OUTPUT_SIZE, "Error occurred while attempting to reset device: %s, module will not be initialized!", errorMessage); + ERROR(output); + moduleInitialized = false; + } + else{ + LOG("Sensor successfully initialized!"); + } + FUNCTION_END; +} +////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////// +void Loom_SEN55::measure() { + FUNCTION_START; + char output[OUTPUT_SIZE]; + char sensorError[OUTPUT_SIZE]; + + /* TODO: Implement this once we know the raw integration works. + // Get the current connection status + bool connectionStatus = checkDeviceConnection(); + + // If we are connected and we need to reinit + if(connectionStatus && needsReinit){ + initialize(); + needsReinit = false; + } + + // If we are not connected + else if(!connectionStatus){ + ERROR(F("No acknowledge received from the device")); + FUNCTION_END; + return; + }*/ + + /* Attempt to initiate a measurement with the sensor */ + + uint16_t error = 0; + + /* Determine if we want to measure with the particulate matter readings or not */ + if(measurePM) + error = sen5x.startMeasurement(); + else + error = sen5x.startMeasurementWithoutPm(); + + if(error){ + errorToString(error, sensorError, OUTPUT_SIZE); + snprintf(output, OUTPUT_SIZE, "Error occurred when attempting to collect measurement: %s", sensorError); + ERROR(output); + FUNCTION_END; + return; + } + + // Wait for required one second as described in the readMeasuredValues() documentation + delay(1000); + + // Give the sensor time to prepare for measuring + bool dataReady = false; + uint16_t startTime = millis(); + LOG("Waiting for data to be ready... If not ready in 10 seconds we will stop trying"); + while(!dataReady && millis() < startTime + 10000){ + error = sen5x.readDataReady(dataReady); + if(error){ + errorToString(error, sensorError, OUTPUT_SIZE); + snprintf(output, OUTPUT_SIZE, "Failed to check if data was ready to be read: %s", sensorError); + ERROR(output); + } + } + + // If the data was not ready we don't want to update the sensor values + if(dataReady){ + // Request the measured values form the sensor + error = sen5x.readMeasuredValues( + massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, + massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, + noxIndex + ); + + // Check if we had an error reading the sensor values + if(error){ + errorToString(error, sensorError, OUTPUT_SIZE); + snprintf(output, OUTPUT_SIZE, "Error occurred when reading measurement: %s", sensorError); + ERROR(output); + FUNCTION_END; + return; + } + }else{ + ERROR("No new data was ready within the given time period."); + } + + // Stop measuring and return the sensor to its idle state + error = sen5x.stopMeasurement(); + if(error){ + errorToString(error, sensorError, OUTPUT_SIZE); + snprintf(output, OUTPUT_SIZE, "Error occurred when attempting to stop measuring: %s", sensorError); + ERROR(output); + } + + FUNCTION_END; +} +////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////// +void Loom_SEN55::package() { + FUNCTION_START; + JsonObject json = manInst->get_data_object(getModuleName()); + + // Only include the PM measurements if we are actually measuring PM + if(measurePM){ + json["PM1.0"] = massConcentrationPm10p0; + json["PM2.5"] = massConcentrationPm2p5; + json["PM4.0"] = massConcentrationPm4p0; + json["PM10.0"] = massConcentrationPm10p0; + } + json["AmbientHumidity"] = (isnan(ambientHumidity) ? -1 : ambientHumidity); + json["AmbientTemperature"] = (isnan(ambientTemperature) ? -1 : ambientTemperature); + json["VocIndex"] = (isnan(vocIndex) ? -1 : vocIndex); + json["NoxIndex"] = (isnan(noxIndex) ? -1 : noxIndex); + FUNCTION_END; +} +////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////// +void Loom_SEN55::adjustTempOffset(float offset) { + FUNCTION_START; + char output[OUTPUT_SIZE]; + char sensorError[OUTPUT_SIZE]; + + if(moduleInitialized){ + uint16_t error = sen5x.setTemperatureOffsetSimple(offset); + if(error){ + errorToString(error, sensorError, OUTPUT_SIZE); + snprintf(output, OUTPUT_SIZE, "Failed to adjust sensor offset: %s", sensorError); + ERROR(output); + } + } + FUNCTION_END; +} +////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h new file mode 100644 index 00000000..d682227b --- /dev/null +++ b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h @@ -0,0 +1,194 @@ +#pragma once + +#include +#include + +#include "../I2CDevice.h" +#include "Loom_Manager.h" + +/** + * SHT31 Temperature and Humidity Sensor + * + * @author Will Richards + */ +class Loom_SEN55 : public I2CDevice{ + protected: + + // Manager controlled functions + void measure() override; + void initialize() override; + void power_up() override {}; + void power_down() override {}; + void package() override; + + public: + /** + * Constructs a new SEN55 sensor + * + * @param man Reference to the manager that is used to universally package all data + * @param measurePM This sets whether or not we should conduct measurements without PM readings (uses less power) + * @param useMux Whether or not we are using the multiplexer class + */ + Loom_SEN55( + Manager& man, + bool measurePM = true, + bool useMux = false + ); + + /** + * Adjust the temperature reading offset in celsius. By default it accounts for the internal heating of the sensor. + * Adjustments should be made based off this datasheet: https://cdn.sos.sk/productdata/a8/47/608a6927/sen54-sdn-t.pdf + * + * @param offset The additional temperature offset in degrees celsius + */ + void adjustTempOffset(float offset); + + /** + * Copied directly from the SEN55 library + * setVocAlgorithmTuningParameters() - Sets the tuning parameters of the VOC + * algorithm. + * + * Supported sensors: SEN54, SEN55 + * + * @note This command is available only in idle mode. In measure mode, this + * command has no effect. In addition, it has no effect if at least one + * parameter is outside the specified range. + * + * @param indexOffset VOC index representing typical (average) conditions. + * Allowed values are in range 1..250. The default value is 100. + * + * @param learningTimeOffsetHours Time constant to estimate the VOC + * algorithm offset from the history in hours. Past events will be forgotten + * after about twice the learning time. Allowed values are in range 1..1000. + * The default value is 12 hours. + * + * @param learningTimeGainHours Time constant to estimate the VOC algorithm + * gain from the history in hours. Past events will be forgotten after about + * twice the learning time. Allowed values are in range 1..1000. The default + * value is 12 hours. + * + * @param gatingMaxDurationMinutes Maximum duration of gating in minutes + * (freeze of estimator during high VOC index signal). Set to zero to + * disable the gating. Allowed values are in range 0..3000. The default + * value is 180 minutes. + * + * @param stdInitial Initial estimate for standard deviation. Lower value + * boosts events during initial learning period, but may result in larger + * device-to-device variations. Allowed values are in range 10..5000. The + * default value is 50. + * + * @param gainFactor Gain factor to amplify or to attenuate the VOC index + * output. Allowed values are in range 1..1000. The default value is 230. + * + * @return 0 on success, an error code otherwise + */ + uint16_t setVocAlgorithmTuningParameters(int16_t indexOffset, + int16_t learningTimeOffsetHours, + int16_t learningTimeGainHours, + int16_t gatingMaxDurationMinutes, + int16_t stdInitial, + int16_t gainFactor) { return sen5x.setVocAlgorithmTuningParameters(indexOffset, learningTimeOffsetHours, learningTimeGainHours, gatingMaxDurationMinutes, stdInitial, gainFactor);}; + + + /** + * setNoxAlgorithmTuningParameters() - Sets the tuning parameters of the NOx + * algorithm. + * + * Supported sensors: SEN55 + * + * @note This command is available only in idle mode. In measure mode, this + * command has no effect. In addition, it has no effect if at least one + * parameter is outside the specified range. + * + * @param indexOffset NOx index representing typical (average) conditions. + * Allowed values are in range 1..250. The default value is 1. + * + * @param learningTimeOffsetHours Time constant to estimate the NOx + * algorithm offset from the history in hours. Past events will be forgotten + * after about twice the learning time. Allowed values are in range 1..1000. + * The default value is 12 hours. + * + * @param learningTimeGainHours The time constant to estimate the NOx + * algorithm gain from the history has no impact for NOx. This parameter is + * still in place for consistency reasons with the VOC tuning parameters + * command. This parameter must always be set to 12 hours. + * + * @param gatingMaxDurationMinutes Maximum duration of gating in minutes + * (freeze of estimator during high NOx index signal). Set to zero to + * disable the gating. Allowed values are in range 0..3000. The default + * value is 720 minutes. + * + * @param stdInitial The initial estimate for standard deviation parameter + * has no impact for NOx. This parameter is still in place for consistency + * reasons with the VOC tuning parameters command. This parameter must + * always be set to 50. + * + * @param gainFactor Gain factor to amplify or to attenuate the NOx index + * output. Allowed values are in range 1..1000. The default value is 230. + * + * @return 0 on success, an error code otherwise + */ + uint16_t setNoxAlgorithmTuningParameters(int16_t indexOffset, + int16_t learningTimeOffsetHours, + int16_t learningTimeGainHours, + int16_t gatingMaxDurationMinutes, + int16_t stdInitial, + int16_t gainFactor) { return sen5x.setNoxAlgorithmTuningParameters(indexOffset, learningTimeOffsetHours, learningTimeGainHours, gatingMaxDurationMinutes, stdInitial, gainFactor); }; + /** + * Get the PM 1.0 reading + */ + float getPM1() { return massConcentrationPm1p0; }; + + /** + * Get the PM2.5 reading + */ + float getPM25() { return massConcentrationPm2p5; }; + + /** + * Get the PM4.0 reading + */ + float getPM4() { return massConcentrationPm4p0; }; + + /** + * Get the PM 10 reading + */ + float getPM10() { return massConcentrationPm10p0; }; + + /** + * Get the PM2.5 reading + */ + float getHumidity() { return ambientHumidity; }; + + /** + * Get the temperature reading + */ + float getTemperature() { return ambientTemperature; }; + + /** + * Get the VOX Index reading + */ + float getVOCIndex() { return vocIndex; }; + + /** + * Get NOX Index + */ + float getNOXIndex() { return noxIndex; }; + + private: + Manager* manInst; // Instance of the manager + SensirionI2CSen5x sen5x; // Instance of the SEN55 object + + bool measurePM; // Are we measuring particulate matter or not + + /* Sensor readings */ + float massConcentrationPm1p0; + float massConcentrationPm2p5; + float massConcentrationPm4p0; + float massConcentrationPm10p0; + float ambientHumidity; + float ambientTemperature; + float vocIndex; + float noxIndex; + + +}; \ No newline at end of file diff --git a/src/Sensors/I2C/Loom_SHT31/Loom_SHT31.h b/src/Sensors/I2C/Loom_SHT31/Loom_SHT31.h index 22320357..6b031c4b 100644 --- a/src/Sensors/I2C/Loom_SHT31/Loom_SHT31.h +++ b/src/Sensors/I2C/Loom_SHT31/Loom_SHT31.h @@ -22,7 +22,7 @@ class Loom_SHT31 : public I2CDevice{ public: /** - * Constructs a new TSL2591 sensor + * Constructs a new SHT31 sensor * @param man Reference to the manager that is used to universally package all data * @param address I2C address that is assigned to the sensor */ From 244558b87c94dab75d9c01fbd71fa9161aaae46e Mon Sep 17 00:00:00 2001 From: Will Richards Date: Mon, 16 Oct 2023 14:49:20 -0700 Subject: [PATCH 2/7] SEN55 sensor code works, however SEN55 must remain powered on --- src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp | 47 +++++++++++------------ src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h | 6 ++- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp index e03355b2..18a9c141 100644 --- a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp +++ b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp @@ -32,10 +32,31 @@ void Loom_SEN55::initialize() { snprintf(output, OUTPUT_SIZE, "Error occurred while attempting to reset device: %s, module will not be initialized!", errorMessage); ERROR(output); moduleInitialized = false; + return; } else{ LOG("Sensor successfully initialized!"); } + + /* Determine if we want to measure with the particulate matter readings or not */ + if(measurePM){ + error = sen5x.startMeasurement(); + } + else{ + error = sen5x.startMeasurementWithoutPm(); + } + + if(error){ + errorToString(error, errorMessage, OUTPUT_SIZE); + snprintf(output, OUTPUT_SIZE, "Error occurred when attempting to collect measurement: %s", errorMessage); + ERROR(output); + FUNCTION_END; + return; + } + + // Wait for required one second as described in the readMeasuredValues() documentation + LOG("Waiting 10 seconds seconds so that we can warm the sensor up"); + delay(10000); FUNCTION_END; } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -67,23 +88,6 @@ void Loom_SEN55::measure() { uint16_t error = 0; - /* Determine if we want to measure with the particulate matter readings or not */ - if(measurePM) - error = sen5x.startMeasurement(); - else - error = sen5x.startMeasurementWithoutPm(); - - if(error){ - errorToString(error, sensorError, OUTPUT_SIZE); - snprintf(output, OUTPUT_SIZE, "Error occurred when attempting to collect measurement: %s", sensorError); - ERROR(output); - FUNCTION_END; - return; - } - - // Wait for required one second as described in the readMeasuredValues() documentation - delay(1000); - // Give the sensor time to prepare for measuring bool dataReady = false; uint16_t startTime = millis(); @@ -99,6 +103,7 @@ void Loom_SEN55::measure() { // If the data was not ready we don't want to update the sensor values if(dataReady){ + LOG("Device was ready to read a new sample!"); // Request the measured values form the sensor error = sen5x.readMeasuredValues( massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, @@ -118,14 +123,6 @@ void Loom_SEN55::measure() { ERROR("No new data was ready within the given time period."); } - // Stop measuring and return the sensor to its idle state - error = sen5x.stopMeasurement(); - if(error){ - errorToString(error, sensorError, OUTPUT_SIZE); - snprintf(output, OUTPUT_SIZE, "Error occurred when attempting to stop measuring: %s", sensorError); - ERROR(output); - } - FUNCTION_END; } ////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h index d682227b..7294d467 100644 --- a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h +++ b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.h @@ -7,7 +7,11 @@ #include "Loom_Manager.h" /** - * SHT31 Temperature and Humidity Sensor + * SEN55 Air Quality sensors, supports pm 1.0, 2.5, 4.0, 10 as well as Temp/Humidity and Nox and Voc index + * + * NOTE: To get accurate results using the SE555 it should be powered on and remain on as according to the data sheet, + * the switch-on behavior for the VOC Index is ~ 1 hr and the NOx is ~ 6 hours. + * Data sheet: https://cdn.sparkfun.com/assets/5/b/f/2/8/Sensirion_Datasheet_SEN5x.pdf (Page 8) * * @author Will Richards */ From 111056359c76917effe35397d5abf79022f6e71c Mon Sep 17 00:00:00 2001 From: Douglas Crocker Jr <105105069+drcrockerjr@users.noreply.github.com> Date: Sun, 3 Dec 2023 18:29:09 -0800 Subject: [PATCH 3/7] adding functionality to disable certain rails to SEN55 branch --- src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp | 8 ++++---- src/Hardware/Loom_Hypnos/Loom_Hypnos.h | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp index 6810e244..176b3c09 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp @@ -365,7 +365,7 @@ void Loom_Hypnos::setInterruptDuration(const TimeSpan duration){ /* Sleep Functionality */ ////////////////////////////////////////////////////////////////////////////////////////////////////// -void Loom_Hypnos::sleep(bool waitForSerial){ +void Loom_Hypnos::sleep(bool waitForSerial, bool disable33 = true, bool disable5 = true){ // Try to power down the active modules if(shouldPowerUp){ manInst->power_down(); @@ -377,7 +377,7 @@ void Loom_Hypnos::sleep(bool waitForSerial){ - disable(); + disable(disable33, disable5); pre_sleep(); // Pre-sleep cleanup shouldPowerUp = true; LowPower.sleep(); // Go to sleep and hang @@ -395,7 +395,7 @@ void Loom_Hypnos::pre_sleep(){ attachInterrupt(digitalPinToInterrupt(pinToInterrupt.begin()->first), std::get<0>(pinToInterrupt.begin()->second), std::get<1>(pinToInterrupt.begin()->second)); // Disable the power rails - disable(); + //disable(); commented out as rails are already disabled in the sleep() function } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -516,4 +516,4 @@ bool Loom_Hypnos::logToSD() { sdMan->log(getCurrentTime()); FUNCTION_END; } -////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file +////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.h b/src/Hardware/Loom_Hypnos/Loom_Hypnos.h index 87efa823..d66d0d92 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.h +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.h @@ -155,8 +155,10 @@ class Loom_Hypnos : public Module{ /** * Drops the Feather M0 and Hypnos board into a low power sleep waiting for an interrupt to wake it up and pull it out of sleep * @param waitForSerial Whether or not we should wait for the user to open the serial monitor before continuing execution + * @param disable33 Whether or not to disable 3.3V rails + * @param disable5 Whether or not to disable 5V and 12V rails */ - void sleep(bool waitForSerial = false); + void sleep(bool waitForSerial = false, bool disable33 = true, bool disable5 = true); /** * Get the current time from the RTC @@ -250,4 +252,4 @@ class Loom_Hypnos : public Module{ -}; \ No newline at end of file +}; From fbdb9160e854358db02225615c429931d24b4eba Mon Sep 17 00:00:00 2001 From: Douglas Crocker Jr <105105069+drcrockerjr@users.noreply.github.com> Date: Mon, 18 Dec 2023 17:34:23 -0500 Subject: [PATCH 4/7] changes to fix disable and enable for power rails in hypnos sleep functionality --- src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp | 15 ++++++++------- src/Hardware/Loom_Hypnos/Loom_Hypnos.h | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp index 176b3c09..aa1c8eac 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp @@ -57,6 +57,7 @@ void Loom_Hypnos::enable(bool enable33, bool enable5){ // Enable the 3.3v and 5v rails on the Hypnos digitalWrite(5, (enable33) ? LOW : HIGH); digitalWrite(6, (enable5) ? HIGH : LOW); + //digitalWrite(6, (enable5) ? LOW : HIGH); digitalWrite(LED_BUILTIN, HIGH); if(enableSD){ @@ -77,10 +78,10 @@ void Loom_Hypnos::enable(bool enable33, bool enable5){ ////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////// -void Loom_Hypnos::disable(){ +void Loom_Hypnos::disable(bool disable33, bool disable5){ // Disable the 3.3v and 5v rails on the Hypnos - digitalWrite(5, HIGH); - digitalWrite(6, LOW); + digitalWrite(5, (disable33) ? HIGH : LOW); + digitalWrite(6, (disable5) ? LOW : HIGH); digitalWrite(LED_BUILTIN, LOW); if(enableSD){ @@ -365,7 +366,7 @@ void Loom_Hypnos::setInterruptDuration(const TimeSpan duration){ /* Sleep Functionality */ ////////////////////////////////////////////////////////////////////////////////////////////////////// -void Loom_Hypnos::sleep(bool waitForSerial, bool disable33 = true, bool disable5 = true){ +void Loom_Hypnos::sleep(bool waitForSerial, bool disable33, bool disable5){ // Try to power down the active modules if(shouldPowerUp){ manInst->power_down(); @@ -377,8 +378,9 @@ void Loom_Hypnos::sleep(bool waitForSerial, bool disable33 = true, bool disable5 - disable(disable33, disable5); + //disable(disable33, disable5); pre_sleep(); // Pre-sleep cleanup + disable(disable33, disable5); // Disable the power rails shouldPowerUp = true; LowPower.sleep(); // Go to sleep and hang post_sleep(waitForSerial); // Wake up @@ -395,8 +397,7 @@ void Loom_Hypnos::pre_sleep(){ attachInterrupt(digitalPinToInterrupt(pinToInterrupt.begin()->first), std::get<0>(pinToInterrupt.begin()->second), std::get<1>(pinToInterrupt.begin()->second)); // Disable the power rails - //disable(); commented out as rails are already disabled in the sleep() function - + //disable(); } ////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.h b/src/Hardware/Loom_Hypnos/Loom_Hypnos.h index d66d0d92..1e2d114e 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.h +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.h @@ -108,13 +108,13 @@ class Loom_Hypnos : public Module{ * @param enable33 whether or not to enable the 3.3v rails * @param enable5 whether or not to enable the 5v and 12v rails */ - void enable(bool enable33 = true, bool emable5 = true); + void enable(bool enable33 = true, bool enable5 = true); /** * Disables the Hypnos Board * Disables the Power Rails and sets the SPI pins to INPUT which effectively disables them */ - void disable(); + void disable(bool disable33 = true, bool disable5 = true); /* SD Functionality */ From b0ae5212c37bbb85fcbb9e873e65b4292f5028e5 Mon Sep 17 00:00:00 2001 From: Douglas Crocker Jr <105105069+drcrockerjr@users.noreply.github.com> Date: Tue, 19 Dec 2023 20:25:51 -0500 Subject: [PATCH 5/7] temporary change that turns on the 5V rail and doesnt disable from flags --- src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp index aa1c8eac..c5204289 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp @@ -56,8 +56,8 @@ void Loom_Hypnos::enable(bool enable33, bool enable5){ // Enable the 3.3v and 5v rails on the Hypnos digitalWrite(5, (enable33) ? LOW : HIGH); - digitalWrite(6, (enable5) ? HIGH : LOW); - //digitalWrite(6, (enable5) ? LOW : HIGH); + //digitalWrite(6, (enable5) ? HIGH : LOW); + digitalWrite(6, HIGH); digitalWrite(LED_BUILTIN, HIGH); if(enableSD){ @@ -81,7 +81,7 @@ void Loom_Hypnos::enable(bool enable33, bool enable5){ void Loom_Hypnos::disable(bool disable33, bool disable5){ // Disable the 3.3v and 5v rails on the Hypnos digitalWrite(5, (disable33) ? HIGH : LOW); - digitalWrite(6, (disable5) ? LOW : HIGH); + //digitalWrite(6, (disable5) ? LOW : HIGH); digitalWrite(LED_BUILTIN, LOW); if(enableSD){ @@ -397,7 +397,7 @@ void Loom_Hypnos::pre_sleep(){ attachInterrupt(digitalPinToInterrupt(pinToInterrupt.begin()->first), std::get<0>(pinToInterrupt.begin()->second), std::get<1>(pinToInterrupt.begin()->second)); // Disable the power rails - //disable(); + disable(); } ////////////////////////////////////////////////////////////////////////////////////////////////////// From ba845976e5e30d9aa829f7e5925580105b1fd8e8 Mon Sep 17 00:00:00 2001 From: ZakaryW Date: Tue, 9 Jan 2024 11:24:54 -0800 Subject: [PATCH 6/7] Removed the dot in package to fix invalid formatting --- src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp index 18a9c141..5b2c6644 100644 --- a/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp +++ b/src/Sensors/I2C/Loom_SEN55/Loom_SEN55.cpp @@ -4,10 +4,10 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////// Loom_SEN55::Loom_SEN55( Manager& man, - bool measurePM, + bool measurePM, bool useMux ) : I2CDevice("SEN55"), manInst(&man), measurePM(measurePM){ - + // Register the module with the manager if(!useMux) manInst->registerModule(this); @@ -24,7 +24,7 @@ void Loom_SEN55::initialize() { Wire.begin(); sen5x.begin(Wire); - // Attempt to reset the device + // Attempt to reset the device uint16_t error = sen5x.deviceReset(); if(error){ /* Stringify the errro and log the error */ @@ -66,7 +66,7 @@ void Loom_SEN55::measure() { FUNCTION_START; char output[OUTPUT_SIZE]; char sensorError[OUTPUT_SIZE]; - + /* TODO: Implement this once we know the raw integration works. // Get the current connection status bool connectionStatus = checkDeviceConnection(); @@ -83,7 +83,7 @@ void Loom_SEN55::measure() { FUNCTION_END; return; }*/ - + /* Attempt to initiate a measurement with the sensor */ uint16_t error = 0; @@ -105,12 +105,12 @@ void Loom_SEN55::measure() { if(dataReady){ LOG("Device was ready to read a new sample!"); // Request the measured values form the sensor - error = sen5x.readMeasuredValues( + error = sen5x.readMeasuredValues( massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex ); - + // Check if we had an error reading the sensor values if(error){ errorToString(error, sensorError, OUTPUT_SIZE); @@ -134,10 +134,10 @@ void Loom_SEN55::package() { // Only include the PM measurements if we are actually measuring PM if(measurePM){ - json["PM1.0"] = massConcentrationPm10p0; - json["PM2.5"] = massConcentrationPm2p5; - json["PM4.0"] = massConcentrationPm4p0; - json["PM10.0"] = massConcentrationPm10p0; + json["PM1_0"] = massConcentrationPm10p0; + json["PM2_5"] = massConcentrationPm2p5; + json["PM4_0"] = massConcentrationPm4p0; + json["PM10_0"] = massConcentrationPm10p0; } json["AmbientHumidity"] = (isnan(ambientHumidity) ? -1 : ambientHumidity); json["AmbientTemperature"] = (isnan(ambientTemperature) ? -1 : ambientTemperature); From aa06046aa89587d875aad693d4f0f2420a7d18ad Mon Sep 17 00:00:00 2001 From: ZakaryW Date: Wed, 10 Jan 2024 11:34:12 -0800 Subject: [PATCH 7/7] Small adjustments to power rail disabling in hypnos sleep --- src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp | 67 ++++++++++++------------ 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp index c5204289..40e678fb 100644 --- a/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp +++ b/src/Hardware/Loom_Hypnos/Loom_Hypnos.cpp @@ -9,7 +9,7 @@ Loom_Hypnos::Loom_Hypnos(Manager& man, HYPNOS_VERSION version, TIME_ZONE zone, b pinMode(5, OUTPUT); // 3.3v power rail pinMode(6, OUTPUT); // 5v power rail pinMode(LED_BUILTIN, OUTPUT); // Status LED - + // Create the SD Manager if we want to use SD if(useSD){ sdMan = new SDManager(manInst, sd_chip_select); @@ -26,7 +26,7 @@ Loom_Hypnos::Loom_Hypnos(Manager& man, HYPNOS_VERSION version, TIME_ZONE zone, b ////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////// -Loom_Hypnos::~Loom_Hypnos(){ +Loom_Hypnos::~Loom_Hypnos(){ if(sdMan != nullptr) delete sdMan; } @@ -56,8 +56,7 @@ void Loom_Hypnos::enable(bool enable33, bool enable5){ // Enable the 3.3v and 5v rails on the Hypnos digitalWrite(5, (enable33) ? LOW : HIGH); - //digitalWrite(6, (enable5) ? HIGH : LOW); - digitalWrite(6, HIGH); + digitalWrite(6, (enable5) ? HIGH : LOW); digitalWrite(LED_BUILTIN, HIGH); if(enableSD){ @@ -81,8 +80,8 @@ void Loom_Hypnos::enable(bool enable33, bool enable5){ void Loom_Hypnos::disable(bool disable33, bool disable5){ // Disable the 3.3v and 5v rails on the Hypnos digitalWrite(5, (disable33) ? HIGH : LOW); - //digitalWrite(6, (disable5) ? LOW : HIGH); - digitalWrite(LED_BUILTIN, LOW); + digitalWrite(6, (disable5) ? LOW : HIGH); + digitalWrite(LED_BUILTIN, LOW); if(enableSD){ // Disable SPI pins/SD chip select to save power @@ -116,7 +115,7 @@ bool Loom_Hypnos::registerInterrupt(InterruptCallbackFunction isrFunc, int inter LOG(F("Interrupt successfully attached!")); } else{ - + attachInterrupt(digitalPinToInterrupt(interruptPin), isrFunc, triggerState); attachInterrupt(digitalPinToInterrupt(interruptPin), isrFunc, triggerState); LOG(F("Interrupt successfully attached!")); @@ -125,7 +124,7 @@ bool Loom_Hypnos::registerInterrupt(InterruptCallbackFunction isrFunc, int inter pinToInterrupt.insert(std::make_pair(interruptPin, std::make_tuple(isrFunc, triggerState, interruptType))); FUNCTION_END; return true; - } + } else{ detachInterrupt(digitalPinToInterrupt(interruptPin)); ERROR(F("Failed to attach interrupt! Interrupt callback evaluated to a null pointer, it is possible you forgot to supply a callback function")); @@ -135,8 +134,8 @@ bool Loom_Hypnos::registerInterrupt(InterruptCallbackFunction isrFunc, int inter FUNCTION_END; return false; - - + + } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -154,7 +153,7 @@ bool Loom_Hypnos::reattachRTCInterrupt(int interruptPin){ attachInterrupt(digitalPinToInterrupt(interruptPin), std::get<0>(pinToInterrupt[interruptPin]), std::get<1>(pinToInterrupt[interruptPin])); attachInterrupt(digitalPinToInterrupt(interruptPin), std::get<0>(pinToInterrupt[interruptPin]), std::get<1>(pinToInterrupt[interruptPin])); - + } else{ LowPower.attachInterruptWakeup(interruptPin, std::get<0>(pinToInterrupt[interruptPin]), std::get<1>(pinToInterrupt[interruptPin])); @@ -168,7 +167,7 @@ bool Loom_Hypnos::reattachRTCInterrupt(int interruptPin){ ////////////////////////////////////////////////////////////////////////////////////////////////////// void Loom_Hypnos::wakeup(){ - detachInterrupt(pinToInterrupt.begin()->first); // Detach the interrupt so it doesn't trigger again + detachInterrupt(pinToInterrupt.begin()->first); // Detach the interrupt so it doesn't trigger again } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -182,7 +181,7 @@ void Loom_Hypnos::initializeRTC(){ ERROR(F("Couldn't start RTC! Check your connections... Execution will now hang as this is likely a fatal error")); return; } - + // This may end up causing a problem in practice - what if RTC loses power in field? Shouldn't happen with coin cell batt backup if (RTC_DS.lostPower()) { WARNING(F("RTC lost power, let's set the time!")); @@ -202,12 +201,12 @@ void Loom_Hypnos::initializeRTC(){ RTC_DS.writeSqwPinMode(DS3231_OFF); - // We successfully started the RTC + // We successfully started the RTC LOG(F("DS3231 Real-Time Clock Initialized Successfully!")); RTC_initialized = true; FUNCTION_END; - - + + } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -223,20 +222,20 @@ DateTime Loom_Hypnos::get_utc_time(){ else if(timezone == AST || timezone == EST || timezone == CST || timezone == MST || timezone == AST || timezone == PST || timezone == AKST){ // If we are in the months where daylight savings is not in affect if(now.month() >= 3 && now.month() <= 10){ - + return now + TimeSpan(0, (timezone)-1, 0, 0); // If in the months when it changes check if the days are correct if( (now.month() == 3 && now.day() >= 13) || (now.month() == 10 && now.day() < 6)){ return now + TimeSpan(0, (timezone)-1, 0, 0); } - + } else{ return now + TimeSpan(0, (timezone), 0, 0); } } - + else{ return now + TimeSpan(0, timezone, 0, 0); } @@ -246,7 +245,7 @@ DateTime Loom_Hypnos::get_utc_time(){ ////////////////////////////////////////////////////////////////////////////////////////////////////// DateTime Loom_Hypnos::getCurrentTime(){ if(RTC_initialized) - return RTC_DS.now(); + return RTC_DS.now(); else{ LOG(F("Attempted to pull time when RTC was not previously initialized! Returned default datetime")); return DateTime(); @@ -256,7 +255,7 @@ DateTime Loom_Hypnos::getCurrentTime(){ ////////////////////////////////////////////////////////////////////////////////////////////////////// void Loom_Hypnos::dateTime_toString(DateTime time, char array[21]){ - + // Formatted as: YYYY-MM-DDTHH:MM:SSZ snprintf_P(array, 21, PSTR("%u-%02u-%02uT%u:%u:%uZ"), time.year(), time.month(), time.day(), time.hour(), time.minute(), time.second()); } @@ -280,7 +279,7 @@ void Loom_Hypnos::set_custom_time(){ // Entering the year LOG(F("Enter the Year (Four digits, e.g. 2020)")); - + while(computer_year == ""){ computer_year = Serial.readStringUntil('\n'); } @@ -305,7 +304,7 @@ void Loom_Hypnos::set_custom_time(){ } snprintf(output, OUTPUT_SIZE, "Day Entered: %s", computer_day.c_str()); LOG(output); - + // Entering the hour LOG(F("Enter the Hour (0 ~ 23)")); @@ -344,7 +343,7 @@ void Loom_Hypnos::set_custom_time(){ ////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////// -void Loom_Hypnos::setInterruptDuration(const TimeSpan duration){ +void Loom_Hypnos::setInterruptDuration(const TimeSpan duration){ FUNCTION_START; char output[OUTPUT_SIZE]; @@ -376,11 +375,11 @@ void Loom_Hypnos::sleep(bool waitForSerial, bool disable33, bool disable5){ } - - + + //disable(disable33, disable5); pre_sleep(); // Pre-sleep cleanup - disable(disable33, disable5); // Disable the power rails + disable(disable33, disable5); // Disable the power rails shouldPowerUp = true; LowPower.sleep(); // Go to sleep and hang post_sleep(waitForSerial); // Wake up @@ -397,7 +396,7 @@ void Loom_Hypnos::pre_sleep(){ attachInterrupt(digitalPinToInterrupt(pinToInterrupt.begin()->first), std::get<0>(pinToInterrupt.begin()->second), std::get<1>(pinToInterrupt.begin()->second)); // Disable the power rails - disable(); + // disable(); <------------ TODO: test with this commented out } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -408,12 +407,12 @@ void Loom_Hypnos::post_sleep(bool waitForSerial){ if(shouldPowerUp){ USBDevice.attach(); Serial.begin(115200); - + enable(); // Re-init the modules that need it - manInst->power_up(); - + manInst->power_up(); + // Clear any pending RTC alarms RTC_DS.clearAlarm(); @@ -475,7 +474,7 @@ void Loom_Hypnos::getTimeZoneFromSD(const char* fileName){ if(!json["timezone"].isNull()) timezone = timezoneMap[json["timezone"].as()]; LOG(F("Timezone successfully loaded!")); - + } FUNCTION_END; } @@ -513,8 +512,8 @@ void Loom_Hypnos::createTimezoneMap(){ ////////////////////////////////////////////////////////////////////////////////////////////////////// bool Loom_Hypnos::logToSD() { - FUNCTION_START; - sdMan->log(getCurrentTime()); + FUNCTION_START; + sdMan->log(getCurrentTime()); FUNCTION_END; } //////////////////////////////////////////////////////////////////////////////////////////////////////