OPEnSLab-OSU / Loom-V4

Open Source Internet Of Things Rapid Prototyping Framework For Environmental Sensing Applications
5 stars 1 forks source link

Resampling fails when Hypnos alarm is triggered before entering sleep #137

Closed Sarvesh-Thiruppathi closed 2 months ago

Sarvesh-Thiruppathi commented 4 months ago

Describe the bug Running WeatherChimesTippingBucket code w/ DO probe (ChimeDO.txt). The interrupt duration was set to one minute. During one of the cycles, the MQTT broker refused to connect and it continued trying to upload until the limit was exceeded after four attempts. By this point, the one-minute alarm interrupt got triggered before Hypnos went to sleep resulting in the following message being spammed onto the serial monitor: "Alarm triggered during sample, specified sample duration was too short! Resampling..."

Log file from the Hypnos Board: output_4.log (Scroll to the bottom)

Hardware in Use

To Reproduce Steps to reproduce the behavior:

  1. Flash a FeatherM0 with the following code: (ChimeDO.txt) with the interrupt duration set to 5 seconds (or something very low)
  2. Open serial monitor
  3. It is very likely that you will see the message "Alarm triggered during sample, specified sample duration was too short! Resampling..." as it would take longer than 5 seconds to log to SD and push the packet to MongoDB

(If possible, test it out on a WeatherChime board)

Expected behavior Resample data and log to SD/upload to MongoDB

Code

/**
 * In lab use case example for the WeatherChimes project
 * 
 * This project uses SDI12, TSL2591 and an SHT31 sensor to log environment data and logs it to both the SD card and also MQTT/MongoDB
 * 
 * MANAGER MUST BE INCLUDED FIRST IN ALL CODE
 */
#include <Loom_Manager.h>
#include <Logger.h>

#include <Hardware/Loom_Hypnos/Loom_Hypnos.h>

#include <Sensors/Loom_Analog/Loom_Analog.h>
#include <Sensors/I2C/Loom_SHT31/Loom_SHT31.h>
#include <Sensors/I2C/Loom_TSL2591/Loom_TSL2591.h>
#include <Sensors/I2C/Loom_MS5803/Loom_MS5803.h>
#include <Hardware/Loom_TippingBucket/Loom_TippingBucket.h>

#include <Internet/Logging/Loom_MongoDB/Loom_MongoDB.h>
#include <Internet/Connectivity/Loom_LTE/Loom_LTE.h>
#include <Sensors/I2C/Loom_EZODO/Loom_EZODO.h>

// Pin to have the secondary interrupt triggered from
#define INT_PIN A0

volatile bool sampleFlag = true;  // Sample flag set to 1 so we sample in the first cycle, set to 1 in the ISR, set ot 0 end of sample loop
volatile bool tipFlag = false;

// Used to track timing for debounce
unsigned long tip_time = 0;
unsigned long last_tip_time = 0;

Manager manager("KhutiChime", 5);

// Create a new Hypnos object
Loom_Hypnos hypnos(manager, HYPNOS_VERSION::V3_3, TIME_ZONE::PST, true);

// Analog for reading battery voltage
Loom_Analog analog(manager);

// Create sensor classes
Loom_SHT31 sht(manager);
Loom_TSL2591 tsl(manager);
Loom_MS5803 ms_water(manager, 119);  // 119(0x77) if CSB=LOW external, 118(0x76) if CSB=HIGH on WC PCB
Loom_MS5803 ms_air(manager, 118);    // 118(0x76) if CSB=HIGH on WC PCB
Loom_TippingBucket bucket(manager, COUNTER_TYPE::MANUAL, 0.01f);
Loom_EZODO ezoDO(manager, 0x61, false);

Loom_LTE lte(manager, "hologram", "", "");
Loom_MongoDB mqtt(manager, lte.getClient());

/* Calculate the water height based on the difference of pressures*/
float calculateWaterHeight() {
  // ((Water Pressure - Air Pressure) * 100 (conversion to pascals)) / (Water Density * Gravity)
  return (((ms_water.getPressure() - ms_air.getPressure()) * 100) / (997.77 * 9.81));
}

// Called when the interrupt is triggered
void isrTrigger() {
  sampleFlag = true;
  detachInterrupt(INT_PIN);
  hypnos.wakeup();
}

void tipTrigger() {
  hypnos.shouldPowerUp = false;
  tipFlag = true;
  detachInterrupt(INT_PIN);
}

void setup() {

  // Enable debug SD logging and function summaires
  ENABLE_SD_LOGGING;
  ENABLE_FUNC_SUMMARIES;

  // Set the interrupt pin to pullup
  pinMode(INT_PIN, INPUT);

  // Wait 20 seconds for the serial console to open
  manager.beginSerial();

  // Enable the hypnos rails
  hypnos.enable();

  // Give the bucket an instance of the hypnos
  bucket.setHypnosInstance(hypnos);

  // Read the MQTT creds file to supply the device with MQTT credentials
  mqtt.loadConfigFromJSON(hypnos.readFile("mqtt_creds.json"));

  // Initialize all in-use modules
  manager.initialize();

  // Register the ISR and attach to the interrupt
  hypnos.registerInterrupt(isrTrigger);

  attachInterrupt(INT_PIN, tipTrigger, FALLING);
}

void loop() {

  if (sampleFlag) {
    // Set the RTC interrupt alarm to wake the device in 1 min, this should be done as soon as the device enters sampling mode for consistant sleep cycles
    hypnos.setInterruptDuration(TimeSpan(0, 0, 1, 0));

    // Measure and package the data
    manager.measure();
    manager.package();

    // Add the water height calculation to the data
    manager.addData("Water", "Height_(m)", calculateWaterHeight());

    // Print the current JSON packet
    manager.display_data();

    // Log the data to the SD card
    hypnos.logToSD();

    // Publish the collected data to MQTT
    mqtt.publish();

    // Reattach to the interrupt after we have set the alarm so we can have repeat triggers
    hypnos.reattachRTCInterrupt();
    attachInterrupt(INT_PIN, tipTrigger, FALLING);
    attachInterrupt(INT_PIN, tipTrigger, FALLING);
    sampleFlag = false;
  }

  if (tipFlag) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(20);
    bucket.incrementCount();
    tipFlag = false;
    attachInterrupt(INT_PIN, tipTrigger, FALLING);
    attachInterrupt(INT_PIN, tipTrigger, FALLING);
    digitalWrite(LED_BUILTIN, LOW);
  }

  // Put the device into a deep sleep, operation HALTS here until the interrupt is triggered
  hypnos.sleep();
}

Output

[2024.02.23 15:57:51] [DEBUG] [:log:159] Successfully logged data to KhutiChime4.csv
[2024.02.23 15:57:53] [DEBUG] [:connectToBroker:46] Attempting to connect to broker: cas-mosquitto.biossys.oregonstate.edu:1883
[2024.02.23 15:57:56] [ERROR] [:connectToBroker:51] Failed to connect to broker: CONNECTION_REFUSED
[2024.02.23 15:58:03] [DEBUG] [:connectToBroker:46] Attempting to connect to broker: cas-mosquitto.biossys.oregonstate.edu:1883
[2024.02.23 15:58:06] [ERROR] [:connectToBroker:51] Failed to connect to broker: CONNECTION_REFUSED
[2024.02.23 15:58:13] [DEBUG] [:connectToBroker:46] Attempting to connect to broker: cas-mosquitto.biossys.oregonstate.edu:1883
[2024.02.23 15:58:16] [ERROR] [:connectToBroker:51] Failed to connect to broker: CONNECTION_REFUSED
[2024.02.23 15:58:23] [DEBUG] [:connectToBroker:46] Attempting to connect to broker: cas-mosquitto.biossys.oregonstate.edu:1883
[2024.02.23 15:58:27] [ERROR] [:connectToBroker:51] Failed to connect to broker: CONNECTION_REFUSED
[2024.02.23 15:58:34] [ERROR] [:connectToBroker:39] MQTT Retry limit exceeded!
[2024.02.23 15:58:34] [DEBUG] [:reattachRTCInterrupt:161] Interrupt successfully reattached!
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...
[2024.02.23 15:58:34] [WARNING] [:sleep:424] Alarm triggered during sample, specified sample duration was too short! Resampling...

Additional context N/A

WL-Richards commented 3 months ago

This occurs because of the way the alarm detection works, if our alarm is already triggered it just doesn't go to sleep but because the sampleFlag is no longer true, and as such it just gets stuck in sleep. We could just push the interrupt time x amount from when we realized the alarm has been already triggered

WL-Richards commented 2 months ago

This was fixed by simply reattaching to the RTC interrupt and sampling again