Welcome to EnviroDIY, a community for do-it-yourself environmental science and monitoring. EnviroDIY is part of WikiWatershed, an initiative of Stroud Water Research Center designed to help people advance knowledge and stewardship of fresh water.
New to EnviroDIY? Start here

FreakyZ

Forum Replies Created

Viewing 1 post (of 1 total)
  • Author
    Posts
  • in reply to: XBee Networks of Mayfly Loggers – 900Mhz #15569
    FreakyZ
    Participant

      Hi there! I’m hoping to do something similar to what David is doing. I’m using a couple Xbee Pro 900HP modules and couple Mayfly’s. I’m setting up the network using PlatformIO and the Monitoring Station Manual, and I came across a roadblock when I updated the code with some of the Xbee lines. The code runs, printing data to the Mayfly’s SD card until I add the the Xbee code to the loop(). Once I added the Xbee code, the SD card printing prompts don’t pop up in the Serial Monitor (only the “Wake up the Xbee” and “Putting the Xbee to sleep” prompts).

      I feel like it’s an ordering issue in the loop() from when I updated the code, but I’m not sure. Any help is greatly appreciated! Thanks!

      Also, while I’m here, I also have been struggling on how to take the sensor measurements that are printed to the SD card and communicate them to the Xbee (with the Serial1.println() line in the loop() command). I’m pretty new to Arduino programming, so I feel like I’m probably overcomplicating it.

      /** =========================================================================
      * @file DRWI_NoCellular.ino
      * @brief Example for DRWI CitSci without cellular service.
      *
      * @author Sara Geleskie Damiano <sdamiano@stroudcenter.org>
      * @copyright (c) 2017-2020 Stroud Water Research Center (SWRC)
      * and the EnviroDIY Development Team
      * This example is published under the BSD-3 license.
      *
      * Build Environment: Visual Studios Code with PlatformIO
      * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger
      *
      * DISCLAIMER:
      * THIS CODE IS PROVIDED “AS IS” – NO WARRANTY IS GIVEN.
      * ======================================================================= */

      // ==========================================================================
      // Include the libraries required for any data logger
      // ==========================================================================
      /** Start [includes] */
      // The Arduino library is needed for every Arduino program.
      #include <Arduino.h>

      // EnableInterrupt is used by ModularSensors for external and pin change
      // interrupts and must be explicitly included in the main program.
      #include <EnableInterrupt.h>

      // To get all of the base classes for ModularSensors, include LoggerBase.
      // NOTE: Individual sensor definitions must be included separately.
      #include <LoggerBase.h>
      /** End [includes] */

      //Defines the XBEE Sleep pin
      #define XBEE_SleepPin 23

      // ==========================================================================
      // Data Logging Options
      // ==========================================================================
      /** Start [logging_options] */
      // The name of this program file
      const char* sketchName = “sensor_test.ino”;
      // Logger ID, also becomes the prefix for the name of the data file on SD card
      const char* LoggerID = “XXXXX”;
      // How frequently (in minutes) to log data
      const uint8_t loggingInterval = 1;
      // Your logger’s timezone.
      const int8_t timeZone = -5; // Eastern Standard Time
      // NOTE: Daylight savings time will not be applied! Please use standard time!

      // Set the input and output pins for the logger
      // NOTE: Use -1 for pins that do not apply
      const int32_t serialBaud = 115200; // Baud rate for debugging
      const int8_t greenLED = 8; // Pin for the green LED
      const int8_t redLED = 9; // Pin for the red LED
      const int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin)
      const int8_t wakePin = A7; // MCU interrupt/alarm pin to wake from sleep
      // Set the wake pin to -1 if you do not want the main processor to sleep.
      // In a SAMD system where you are using the built-in rtc, set wakePin to 1
      const int8_t sdCardPwrPin = -1; // MCU SD card power pin
      const int8_t sdCardSSPin = 12; // SD card chip select/slave select pin
      const int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power
      /** End [logging_options] */

      // ==========================================================================
      // Using the Processor as a Sensor
      // ==========================================================================
      /** Start [processor_sensor] */
      #include <sensors/ProcessorStats.h>

      // Create the main processor chip “sensor” – for general metadata
      const char* mcuBoardVersion = “v0.5b”;
      ProcessorStats mcuBoard(mcuBoardVersion);
      /** End [processor_sensor] */

      // ==========================================================================
      // Maxim DS3231 RTC (Real Time Clock)
      // ==========================================================================
      /** Start [ds3231] */
      #include <sensors/MaximDS3231.h>

      // Create a DS3231 sensor object
      MaximDS3231 ds3231(1);
      /** End [ds3231] */

      // ==========================================================================
      // Campbell OBS 3 / OBS 3+ Analog Turbidity Sensor
      // ==========================================================================
      /** Start [obs3] */
      #include <sensors/CampbellOBS3.h>

      const int8_t OBS3Power = sensorPowerPin; // Power pin (-1 if unconnected)
      const uint8_t OBS3NumberReadings = 10;
      const uint8_t ADSi2c_addr = 0x48; // The I2C address of the ADS1115 ADC
      // Campbell OBS 3+ *Low* Range Calibration in Volts
      const int8_t OBSLowADSChannel = 0; // ADS channel for *low* range output
      const float OBSLow_A = 0.000E+00; // “A” value (X^2) [*low* range]
      const float OBSLow_B = 1.000E+00; // “B” value (X) [*low* range]
      const float OBSLow_C = 0.000E+00; // “C” value [*low* range]

      // Create a Campbell OBS3+ *low* range sensor object
      CampbellOBS3 osb3low(OBS3Power, OBSLowADSChannel, OBSLow_A, OBSLow_B, OBSLow_C,
      ADSi2c_addr, OBS3NumberReadings);

      // Campbell OBS 3+ *High* Range Calibration in Volts
      const int8_t OBSHighADSChannel = 1; // ADS channel for *high* range output
      const float OBSHigh_A = 0.000E+00; // “A” value (X^2) [*high* range]
      const float OBSHigh_B = 1.000E+00; // “B” value (X) [*high* range]
      const float OBSHigh_C = 0.000E+00; // “C” value [*high* range]

      // Create a Campbell OBS3+ *high* range sensor object
      CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B,
      OBSHigh_C, ADSi2c_addr, OBS3NumberReadings);
      /** End [obs3] */

      // ==========================================================================
      // Meter Hydros 21 Conductivity, Temperature, and Depth Sensor
      // ==========================================================================
      /** Start [decagon_ctd] */
      #include <sensors/DecagonCTD.h>

      const char* CTDSDI12address = “1”; // The SDI-12 Address of the CTD
      const uint8_t CTDNumberReadings = 6; // The number of readings to average
      const int8_t SDI12Power = sensorPowerPin; // Power pin (-1 if unconnected)
      const int8_t SDI12Data = 7; // The SDI12 data pin

      // Create a Decagon CTD sensor object
      DecagonCTD ctd(*CTDSDI12address, SDI12Power, SDI12Data, CTDNumberReadings);
      /** End [decagon_ctd] */

      // ==========================================================================
      // Creating the Variable Array[s] and Filling with Variable Objects
      // ==========================================================================
      /** Start [variable_arrays] */
      Variable* variableList[] = {
      new DecagonCTD_Cond(&ctd),
      new DecagonCTD_Temp(&ctd),
      new DecagonCTD_Depth(&ctd),
      new CampbellOBS3_Turbidity(&osb3low, “”, “TurbLow”),
      new CampbellOBS3_Turbidity(&osb3high, “”, “TurbHigh”),
      new ProcessorStats_Battery(&mcuBoard),
      new MaximDS3231_Temp(&ds3231),
      };

      // All UUID’s, device registration, and sampling feature information can be
      // pasted directly from Monitor My Watershed. To get the list, click the “View
      // token UUID list” button on the upper right of the site page.
      // Even if not publishing live data, this is needed so the logger file will be
      // “drag-and-drop” ready for manual upload to the portal.

      // *** CAUTION — CAUTION — CAUTION — CAUTION — CAUTION ***
      // Check the order of your variables in the variable list!!!
      // Be VERY certain that they match the order of your UUID’s!
      // Rearrange the variables in the variable list if necessary to match!
      // *** CAUTION — CAUTION — CAUTION — CAUTION — CAUTION ***
      const char* UUIDs[] = {
      “12345678-abcd-1234-ef00-1234567890ab”, // Electrical conductivity
      // (Decagon_CTD-10_Cond)
      “12345678-abcd-1234-ef00-1234567890ab”, // Temperature
      // (Decagon_CTD-10_Temp)
      “12345678-abcd-1234-ef00-1234567890ab”, // Water depth
      // (Decagon_CTD-10_Depth)
      “12345678-abcd-1234-ef00-1234567890ab”, // Turbidity (Campbell_OBS3_Turb)
      “12345678-abcd-1234-ef00-1234567890ab”, // Turbidity (Campbell_OBS3_Turb)
      “12345678-abcd-1234-ef00-1234567890ab”, // Battery voltage
      // (EnviroDIY_Mayfly_Batt)
      “12345678-abcd-1234-ef00-1234567890ab” // Temperature
      // (EnviroDIY_Mayfly_Temp)
      };
      const char* registrationToken =
      “12345678-abcd-1234-ef00-1234567890ab”; // Device registration token
      const char* samplingFeature =
      “12345678-abcd-1234-ef00-1234567890ab”; // Sampling feature UUID

      // Count up the number of pointers in the array
      int variableCount = sizeof(variableList) / sizeof(variableList[0]);

      // Create the VariableArray object
      VariableArray varArray(variableCount, variableList, UUIDs);
      /** End [variable_arrays] */

      // ==========================================================================
      // The Logger Object[s]
      // ==========================================================================
      /** Start [loggers] */
      // Create a new logger instance
      Logger dataLogger(LoggerID, loggingInterval, &varArray);
      /** End [loggers] */

      // ==========================================================================
      // Working Functions
      // ==========================================================================
      /** Start [working_functions] */
      // Flashes the LED’s on the primary board
      void greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) {
      for (uint8_t i = 0; i < numFlash; i++) {
      digitalWrite(greenLED, HIGH);
      digitalWrite(redLED, LOW);
      delay(rate);
      digitalWrite(greenLED, LOW);
      digitalWrite(redLED, HIGH);
      delay(rate);
      }
      digitalWrite(redLED, LOW);
      }

      // Reads the battery voltage
      // NOTE: This will actually return the battery level from the previous update!
      float getBatteryVoltage() {
      if (mcuBoard.sensorValues[0] == -9999) mcuBoard.update();
      return mcuBoard.sensorValues[0];
      }
      /** End [working_functions] */

      // ==========================================================================
      // Arduino Setup Function
      // ==========================================================================
      /** Start [setup] */
      void setup() {
      // Start the primary serial connection
      Serial.begin(serialBaud);

      //Sets up the baud rate for the XBEE
      Serial1.begin(9600);

      // Print a start-up note to the first serial port
      Serial.print(F(“Now running “));
      Serial.print(sketchName);
      Serial.print(F(” on Logger “));
      Serial.println(LoggerID);
      Serial.println();

      Serial.print(F(“Using ModularSensors Library version “));
      Serial.println(MODULAR_SENSORS_VERSION);

      // Set up pins for the LED’s
      pinMode(greenLED, OUTPUT);
      digitalWrite(greenLED, LOW);
      pinMode(redLED, OUTPUT);
      digitalWrite(redLED, LOW);

      //Sets up pins for the XBEE
      pinMode(XBEE_SleepPin,OUTPUT); //Setting XBEE sleep pin as an output
      digitalWrite(XBEE_SleepPin, LOW); //Start with XBEE awake
      Serial.println(“Xbee is now set up”);
      delay(2000);

      // Blink the LEDs to show the board is on and starting up
      greenredflash();

      // Set the timezones for the logger/data and the RTC
      // Logging in the given time zone
      Logger::setLoggerTimeZone(timeZone);
      // It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)
      Logger::setRTCTimeZone(0);

      // Attach information pins to the logger
      dataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin,
      greenLED);
      dataLogger.setSamplingFeatureUUID(samplingFeature);

      // Begin the logger
      dataLogger.begin();

      // Note: Please change these battery voltages to match your battery
      // Set up the sensors, except at lowest battery level
      if (getBatteryVoltage() > 3.4) {
      Serial.println(F(“Setting up sensors…”));
      varArray.setupSensors();
      }

      // Create the log file, adding the default header to it
      // Do this last so we have the best chance of getting the time correct and
      // all sensor names correct
      // Writing to the SD card can be power intensive, so if we’re skipping
      // the sensor setup we’ll skip this too.
      if (getBatteryVoltage() > 3.4) {
      Serial.println(F(“Setting up file on SD card”));
      dataLogger.turnOnSDcard(
      true); // true = wait for card to settle after power up
      dataLogger.createLogFile(true); // true = write a new header
      dataLogger.turnOffSDcard(
      true); // true = wait for internal housekeeping after write
      }

      // Call the processor sleep
      Serial.println(F(“Putting processor to sleep\n”));
      dataLogger.systemSleep();
      }
      /** End [setup] */

      // ==========================================================================
      // Arduino Loop Function
      // ==========================================================================
      /** Start [loop] */
      // Use this short loop for simple data logging and sending
      void loop() {
      // Note: Please change these battery voltages to match your battery
      // At very low battery, just go back to sleep
      if (getBatteryVoltage() < 3.4) {
      dataLogger.systemSleep();
      }
      // If the battery is OK, log data
      else {
      wakeXbee(); //Wakes up XBEE
      delay(3000); //Gives XBEE time to be seen by the network
      Serial1.println(); //Text being sent by XBEE module
      delay(3000); //Gives XBEE a bit before sending it back to sleep
      sleepXbee(); //Puts Xbee to sleep

      delay(10000); //wait 10 seconds, then repeat loop
      dataLogger.logData();

      }
      }

      void sleepXbee() {
      Serial.println(“Putting the Xbee to sleep”);
      delay(100);
      pinMode(XBEE_SleepPin,INPUT_PULLUP); // Set the “wake-up pin” to input and enable the internal pullup
      digitalWrite(XBEE_SleepPin,HIGH); //put the Xbee to sleep
      digitalWrite(9, LOW); //turn off the RED LED when the Xbee is asleep
      }

      void wakeXbee() {
      Serial.println(“Wake up the Xbee”);
      delay(100);
      pinMode(XBEE_SleepPin,OUTPUT); // Set the “wake-up pin” to output
      digitalWrite(XBEE_SleepPin,LOW); // wake-up XBee
      digitalWrite(9, HIGH); // turn on the RED LED when the Xbee is awake
      }
      /** End [loop] */

    Viewing 1 post (of 1 total)