OPEnSLab-OSU / Loom-V4

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

WiFi stuck in connect loop #154

Open WL-Richards opened 3 months ago

WL-Richards commented 3 months ago

Describe the bug The WiFi module appears to get stuck in an infinite connection loop, sometimes it sleeps and then only trys to connect to WiFi and then immediately goes back to sleep. Other times it just infinitely retrties to connect as shown in screenshots below

image image

Hardware in Use A list of all hardware currently in use

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior A clear and concise description of what you expected to happen.

Code In the Arduino IDE while editing the main.ino, goto 'Edit' -> 'Copy for HTML' and paste the output of that here

Output Copy and paste the serial output here if possible wrapped in ``` ```

Additional context Add any other context about the problem here.

CaseyJ37 commented 2 months ago

Hardware in use: Full WeatherChimes devices, both the 9-18-2023 and the Whisp v0.4 pcb versions have this issue.

To reproduce: Run a WeatherChimes device with the current code sample on the mqtt-network-component branch of loom. There is no guarantee that this bug will occur, as it has not happened with every WeatherChime running this code, and the lengths of time that the devices that had this bug ran properly before the bug appeared vary widely.

Expected behavior: The WeatherChimes should continue to run (sample data and log the data to the SD card) once every 15 minutes. The output should look like the first image without the highlighted text.

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 <Sensors/Analog/Loom_Teros10/Loom_Teros10.h>

#include <Internet/Logging/Loom_MongoDB/Loom_MongoDB.h>
#include <Internet/Connectivity/Loom_LTE/Loom_LTE.h>
#include <Internet/Connectivity/Loom_Wifi/Loom_Wifi.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("WhalefestChime", 1);

// 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_Teros10 teros(manager, A1);

//Loom_LTE lte(manager, "hologram");
Loom_WIFI wifi(manager, CommunicationMode::CLIENT);
Loom_MongoDB mqtt(manager, wifi);

/* 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 summaries
  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();

  hypnos.setNetworkInterface(&wifi);

  // 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"));
  wifi.loadConfigFromJSON(hypnos.readFile("wifi_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){
    detachInterrupt(INT_PIN);
    //hypnos.networkTimeUpdate();
    // 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();

    // 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: The output of the bug is shown in the two images.

udellc commented 2 months ago

May have something to do with mismanaging how wifi gets disabled or enabled going to sleep/wakeup.

CaseyJ37 commented 1 month ago

I think the issue might be that connecting to WiFi is the first thing it tries to do when it wakes up, and maybe it needs to do the other initialization steps first.