Forum Replies Created
-
AuthorPosts
-
@srgdamiano Sorry to bother you on this, but I still need help understanding the issues I’ve had with the Teros library.
@srgdamiano were you able to look at the cpp code?
No worries! I also just wanted to let you know that I have run into similar issues using the Teros 11 files where it won’t record all of the measurements.
For anyone who would be interested in using these radio modules with modular sensors, I was able to transfer modular sensor readings from a Mayfly through the XBee Pro S3B to another XBee Pro S3B in transparent mode using the following lines of code in my void loop() function:
12345digitalWrite(xbeeSleepPin, LOW);delay(100);dataLogger.printSensorDataCSV(&Serial1);delay(100);digitalWrite(xbeeSleepPin, HIGH);Here, dataLogger is just the Logger object. The xbeeSleepPin is 23. I also used the following lines of code in my setup() function:
1234567// Setup XBeepinMode(xbeeRegulatorPin, OUTPUT);pinMode(xbeeSleepPin, OUTPUT);digitalWrite(xbeeRegulatorPin, HIGH); // Supply power to the XBee regulatorSerial1.begin(xbeeBaud); // Begin UART-1 communicationWire.begin();digitalWrite(xbeeSleepPin, HIGH); // Put XBee in sleep modeThe xbeeRegulatorPin is 18, and the xbeeBaud is 9600.
@srgdamiano could I get your help with these h/cpp files I created for the Teros 12 sensors? I am having some issues with my sensors not getting values other than -9999 when I have multiple Teros 12 sensors connected. When I use the Teros 11 modules, they all record together, which leads me to believe I set up my h/cpp files wrong. Could I get your help on this? Here is my cpp file to start:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166/*** @file MeterTeros12.cpp* @copyright 2017-2022 Stroud Water Research Center* Part of the EnviroDIY ModularSensors library for Arduino* @author Written By: Anthony Aufdenkampe <aaufdenkampe@limno.com>* Edited by Sara Geleskie Damiano <sdamiano@stroudcenter.org>** @brief Implements the MeterTeros12 class.*/#include "MeterTeros12.h"bool MeterTeros12::getResults(void) {// Set up the float variables for receiving datafloat raw = -9999;float temp = -9999;float ec = -9999;// Check if this the currently active SDI-12 Objectbool wasActive = _SDI12Internal.isActive();// If it wasn't active, activate it now.// Use begin() instead of just setActive() to ensure timer is set// correctly.if (!wasActive) _SDI12Internal.begin();// Empty the buffer_SDI12Internal.clearBuffer();MS_DBG(getSensorNameAndLocation(), F("is reporting:"));String getDataCommand = "";getDataCommand += _SDI12address;// SDI-12 command to get data [address][D][dataOption][!]getDataCommand += "D0!";_SDI12Internal.sendCommand(getDataCommand, _extraWakeTime);delay(30); // It just needs this little delayMS_DEEP_DBG(F(" >>>"), getDataCommand);// Wait for the first few charaters to arrive. The response from a data// request should always have more than three charactersuint32_t start = millis();while (_SDI12Internal.available() < 3 && (millis() - start) < 1500) {// wait}// read the returned address to remove it from the bufferauto returnedAddress = static_cast<char>(_SDI12Internal.read());// print out a warning if the address doesn't match upif (returnedAddress != _SDI12address) {MS_DBG(F("Warning, expecting data from"), _SDI12address,F("but got data from"), returnedAddress);}// Start printing out the returned dataMS_DEEP_DBG(F(" <<<"), returnedAddress);// read the '+' out of the buffer, and print it if we're debugging#ifdef MS_SDI12SENSORS_DEBUG_DEEPMS_DEEP_DBG(F(" <<<"), static_cast<char>(_SDI12Internal.read()));#else_SDI12Internal.read();#endif// Read the raw VWC countsraw = _SDI12Internal.parseFloat(SKIP_NONE);MS_DEEP_DBG(F(" <<<"), String(raw, 10));// read the next '+' out of the buffer#ifdef MS_SDI12SENSORS_DEBUG_DEEPMS_DEEP_DBG(F(" <<<"), static_cast<char>(_SDI12Internal.read()));#else_SDI12Internal.read();#endif// Now read the temperaturetemp = _SDI12Internal.parseFloat(SKIP_NONE);MS_DEEP_DBG(F(" <<<"), String(temp, 10));// read the next '+' out of the buffer#ifdef MS_SDI12SENSORS_DEBUG_DEEPMS_DEEP_DBG(F(" <<<"), static_cast<char>(_SDI12Internal.read()));#else_SDI12Internal.read();#endif// Now read the electrical conductivityec = _SDI12Internal.parseFloat(SKIP_NONE);MS_DEEP_DBG(F(" <<<"), String(ec, 10));// read and dump anything elsewhile (_SDI12Internal.available()) {#ifdef MS_SDI12SENSORS_DEBUG_DEEPMS_DEEP_DBG(F(" <<<"), static_cast<char>(_SDI12Internal.read()));#else_SDI12Internal.read();#endif}// Empty the buffer again_SDI12Internal.clearBuffer();// De-activate the SDI-12 Object// Use end() instead of just forceHold to un-set the timersif (!wasActive) _SDI12Internal.end();MS_DBG(F("Raw VWC Counts:"), raw);MS_DBG(F("Raw Temperature Value:"), temp);MS_DBG(F("Raw Electrical Conductivity Value:"), ec);// Set up the float variables for calculated variablefloat ea = -9999;float VWC = -9999;// Calculate the dielectric EA from the raw count value.// Equation 8 from the Teros 12 user manual:// http://publications.metergroup.com/Manuals/20587_TEROS11-12_Manual_Web.pdfif (raw < 0 || raw > 5000) {MS_DBG(F("WARNING: raw results out of range (0-5000)! Cannot calculate ""Ea or VWC"));raw = -9999;}if (raw != -9999) {ea = ((2.887e-9 * (raw * raw * raw)) - (2.08e-5 * (raw * raw)) +(5.276e-2 * raw) - 43.39) *((2.887e-9 * (raw * raw * raw)) - (2.08e-5 * (raw * raw)) +(5.276e-2 * raw) - 43.39);MS_DBG(F("Calculated Ea:"), ea);}// Calculate the VWC from EA using the Topp equation// range checkif (ea < 0 || ea > 350) {MS_DBG(F("WARNING: Ea results out of range (0-350)! Cannot calculate ""VWC"));ea = -9999;}// calculateif (ea != -9999) {VWC = (4.3e-6 * (ea * ea * ea)) - (5.5e-4 * (ea * ea)) +(2.92e-2 * ea) - 5.3e-2;VWC *= 100; // Convert to actual percentMS_DBG(F("Calculated VWC:"), ea);if (VWC < 0) {VWC = 0;MS_DBG(F("Setting negative VWC to 0"));}if (VWC > 100) {VWC = 100;MS_DBG(F("Setting VWC >100 to 100"));}}// VWC = 3.879e-4*raw-0.6956; // equation for mineral soils// range check on temp; range is - 40°C to + 50°Cif (temp < -50 || temp > 60) {temp = -9999;MS_DBG(F("WARNING: temperature results out of range (-50-60)!"));}verifyAndAddMeasurementResult(TEROS12_COUNT_VAR_NUM, raw);verifyAndAddMeasurementResult(TEROS12_TEMP_VAR_NUM, temp);verifyAndAddMeasurementResult(TEROS12_EA_VAR_NUM, ea);verifyAndAddMeasurementResult(TEROS12_VWC_VAR_NUM, VWC);verifyAndAddMeasurementResult(TEROS12_EC_VAR_NUM, ec);return temp != -9999;}Yes, these two modules can be set up like a wire. I got a Mayfly to send information over the Pro S3B module to another module connected to a computer. I set them up on the XCTU in transparent mode, set the network IDs to be the same, and told the sender XBee what the serial address is of the receiver XBee. In transparent mode, anytime data is printed to the UART it is automatically sent out of the radio, which is all I really need for the time being. My main question is how to bridge the gap between 900 MHz radio modules and the modular sensors library.
Okay, so what do you think would be the best way to pull out the data generated from the logger object’s logData()? If it is easy to access it, then I feel it shouldn’t be too hard to just jump to a Serial1.print() statement once the logData() method is complete to send the data. Am I thinking this through correctly?
@srgdamiano would you know if the XBee Pro S3B modules can be used with the ModularSensors library? I know how to send data over them using Serial1.print(), but I would like to use these 900 MHz modules with ModularSensors if that is possible. Thanks!
Can a 900 MHz XBee radio be used with the ModularSensors library? I noticed that there is are DigiXBee.cpp and DigiXBee.h files in the modems folder. Can modem objects created with that class be used with the logAndPublishData() function found in most ModularSensor examples that use XBees, or is there a different way of integrating 900 MHz XBee radios with ModularSensors?
@srgdamiano I made a header and cpp file for the Teros 12 by copying the 11 files and adjusting them. When I try to use it, the outputs recorded to my SD card are all -9999 values, and the column headers for the variables are never added (but it will add the headers for the other variables besides the Teros). I get the same problem when I use the MeterTeros11 file, which I figured should still give me some results as it looks like it will just dump whatever is leftover in the data retrieval past the VWC counts and the temperature in the MeterTeros11.cpp file. Maybe I am using these objects incorrectly? Here is what I have for using the Teros11 class (the Teros sensors are at the bottom of my sensor objects):
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574/** =========================================================================* @file simple_logging.ino* @brief A simple data logging example.** @author Sara Geleskie Damiano <sdamiano@stroudcenter.org>* @copyright (c) 2017-2022 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>// Include the main header for ModularSensors#include <ModularSensors.h>/** End [includes] */#include <AltSoftSerial.h>AltSoftSerial sonarSerial(6, -1);// ==========================================================================// Defines for the Arduino IDE// NOTE: These are ONLY needed to compile with the Arduino IDE.// If you use PlatformIO, you should set these build flags in your// platformio.ini// ==========================================================================/** Start [defines] *///#ifndef TINY_GSM_RX_BUFFER//#define TINY_GSM_RX_BUFFER 64//#endif//#ifndef TINY_GSM_YIELD_MS//#define TINY_GSM_YIELD_MS 2//#endif//#ifndef MQTT_MAX_PACKET_SIZE//#define MQTT_MAX_PACKET_SIZE 240//#endif/** End [defines] */// ==========================================================================// Data Logging Options// ==========================================================================/** Start [logging_options] */// The name of this program fileconst char* sketchName = "simple_logging_MaxBotix.ino";// Logger ID, also becomes the prefix for the name of the data file on SD cardconst char* LoggerID = "22376";// How frequently (in minutes) to log dataconst uint8_t loggingInterval = 1;// Your logger's timezone.const int8_t timeZone = -6; // 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 applyconst int32_t serialBaud = 115200; // Baud rate for debuggingconst int8_t greenLED = 8; // Pin for the green LEDconst int8_t redLED = 9; // Pin for the red LEDconst int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin)const int8_t wakePin = 31; // MCU interrupt/alarm pin to wake from sleep// Mayfly 0.x D31 = A7// 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 1const int8_t sdCardPwrPin = -1; // MCU SD card power pinconst int8_t sdCardSSPin = 12; // SD card chip select/slave select pinconst 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 metadataconst char* mcuBoardVersion = "v1.1";ProcessorStats mcuBoard(mcuBoardVersion);/** End [processor_sensor] */// ==========================================================================// Maxim DS3231 RTC (Real Time Clock)// ==========================================================================/** Start [ds3231] */#include <sensors/MaximDS3231.h> // Includes wrapper functions for Maxim DS3231 RTC// Create a DS3231 sensor object, using this constructor function:MaximDS3231 ds3231(1);/** End [ds3231] */// ==========================================================================// MaxBotix sonar sensor for snow depth// ==========================================================================#include <sensors/MaxBotixSonar.h>const int32_t sonarHeight;const int8_t sonarPower = sensorPowerPin;const int8_t sonarTrigger = -1;const uint8_t sonarNumReadings = 3;MaxBotixSonar sonar(sonarSerial, sonarPower, sonarTrigger, sonarNumReadings);Variable* sonarRange =new MaxBotixSonar_Range(&sonar, "12345678-abcd-1234-ef00-1234567890ab");float calculateSnowDepth(void) {float calculatedResult = -9999; // Always safest to start with a bad valuefloat inputVar1 = sonarHeight;float inputVar2 = sonarRange->getValue();// make sure both inputs are goodif (inputVar1 != -9999 && inputVar2 != -9999) {calculatedResult = inputVar1 - inputVar2;}return calculatedResult;}// Properties of the calculated snow depth// The number of digits after the decimal placeconst uint8_t calculatedSnowDepthResolution = 0;// This must be a value from http://vocabulary.odm2.org/variablename/const char* calculatedSnowDepthName = "Snow Depth";// This must be a value from http://vocabulary.odm2.org/units/const char* calculatedSnowDepthUnit = "mm";// A short code for the variableconst char* calculatedSnowDepthCode = "SNWD";// The (optional) universallly unique identifierconst char* calculatedSnowDepthUUID = "12345678-abcd-1234-ef00-1234567890ab";Variable* calculatedSnowDepth = new Variable(calculateSnowDepth, calculatedSnowDepthResolution, calculatedSnowDepthName,calculatedSnowDepthUnit, calculatedSnowDepthCode, calculatedSnowDepthUUID);// ==========================================================================// Apogee sensors// ==========================================================================// Adafruit ADC voltage header file#include <sensors/TIADS1x15.h>#define boardADSi2cAddress 0x48#define extraADSi2cAddress 0x49const uint8_t apogeeNumReadings = 50; // How many readings to average for the apogee pyranometers and pyrgeometersfloat adsGain = 1;// ==========================================================================// Apogee SP-510-SS for incoming shortwave radiation// ==========================================================================const int8_t sp510Power = sensorPowerPin;const uint8_t sp510adsChannel = 2;TIADS1x15 sp510(sp510Power, sp510adsChannel, adsGain, boardADSi2cAddress, apogeeNumReadings);Variable* sp510Voltage =new TIADS1x15_Voltage(&sp510, "12345678-abcd-1234-ef00-1234567890ab");const float sp510Calibration = 22;float calculateInShortRad(void) {float calculatedResult = -9999; // Always safest to start with a bad valuefloat inputVar1 = sp510Voltage->getValue();// make sure both input is goodif (inputVar1 != -9999) {calculatedResult = inputVar1 * 1000 * sp510Calibration;}return calculatedResult;}// Properties of the calculated incoming shortwave radiation// The number of digits after the decimal placeconst uint8_t calculatedInShortRadResolution = 2;// This must be a value from http://vocabulary.odm2.org/variablename/const char* calculatedInShortRadName = "Radiation, incoming shortwave";// This must be a value from http://vocabulary.odm2.org/units/const char* calculatedInShortRadUnit = "W/m^2";// A short code for the variableconst char* calculatedInShortRadCode = "ISWR";// The (optional) universallly unique identifierconst char* calculatedInShortRadUUID = "12345678-abcd-1234-ef00-1234567890ab";Variable* radiationIncomingShortwave = new Variable(calculateInShortRad, calculatedInShortRadResolution, calculatedInShortRadName,calculatedInShortRadUnit, calculatedInShortRadCode, calculatedInShortRadUUID);// ==========================================================================// Apogee SP-610-SS for outgoing shortwave radiation// ==========================================================================const int8_t sp610Power = sensorPowerPin;const uint8_t sp610adsChannel = 3;TIADS1x15 sp610(sp610Power, sp610adsChannel, adsGain, boardADSi2cAddress, apogeeNumReadings);Variable* sp610Voltage =new TIADS1x15_Voltage(&sp610, "12345678-abcd-1234-ef00-1234567890ab");const float sp610Calibration = 28.5;float calculateOutShortRad(void) {float calculatedResult = -9999; // Always safest to start with a bad valuefloat inputVar1 = sp610Voltage->getValue();// make sure both input is goodif (inputVar1 != -9999) {calculatedResult = inputVar1 * 1000 * sp610Calibration;}return calculatedResult;}// Properties of the calculated outgoing shortwave radiation// The number of digits after the decimal placeconst uint8_t calculatedOutShortRadResolution = 2;// This must be a value from http://vocabulary.odm2.org/variablename/const char* calculatedOutShortRadName = "Radiation, outgoing shortwave";// This must be a value from http://vocabulary.odm2.org/units/const char* calculatedOutShortRadUnit = "W/m^2";// A short code for the variableconst char* calculatedOutShortRadCode = "OSWR";// The (optional) universallly unique identifierconst char* calculatedOutShortRadUUID = "12345678-abcd-1234-ef00-1234567890ab";Variable* radiationOutgoingShortwave = new Variable(calculateOutShortRad, calculatedOutShortRadResolution, calculatedOutShortRadName,calculatedOutShortRadUnit, calculatedOutShortRadCode, calculatedOutShortRadUUID);// ==========================================================================// Constants for longwave calculations// ==========================================================================// Steinhart-Hart equation constants for thermistor with 30 kOhm resistance at 25 deg C// Found on page 14 of SL-510-610 manualconst float A_less = 0.000932960; // Temperatures less than 0 deg Cconst float B_less = 0.000221424; // Temperatures less than 0 deg Cconst float C_less = 0.000000126329; // Temperatures less than 0 deg Cconst float A_more = 0.000932794; // Temperatures more than 0 deg Cconst float B_more = 0.000221451; // Temperatures more than 0 deg Cconst float C_more = 0.000000126233; // Temperatures more than 0 deg C// Stefan-Boltzmann constantconst float sb_const = 0.000000056704;// Volt power supply to the pyrgeometer thermistorconst float powerPyrg = 3300;// ==========================================================================// Apogee SL-510-SS for incoming longwave radiation// ==========================================================================const int8_t sl510Power = sensorPowerPin;const uint8_t sl510ThermADSChannel = 0;const uint8_t sl510PyrgADSChannel = 1;TIADS1x15 sl510Therm(sl510Power, sl510ThermADSChannel, adsGain, boardADSi2cAddress, apogeeNumReadings);TIADS1x15 sl510Pyrg(sl510Power, sl510PyrgADSChannel, adsGain, boardADSi2cAddress, apogeeNumReadings);Variable* sl510ThermVoltage =new TIADS1x15_Voltage(&sl510Therm, "12345678-abcd-1234-ef00-1234567890ab");Variable* sl510PyrgVoltage =new TIADS1x15_Voltage(&sl510Pyrg, "12345678-abcd-1234-ef00-1234567890ab");const float K1in = 9.509; // calibration coefficient (K1) from apogee certificateconst float K2in = 1.020; // calibration coefficient (K2) from apogee certificatefloat RtIn; // Thermistor resistance using half-bridge measurementfloat pyrgInTemp;float calculateInLongRad(void) {float calculatedResult = -9999; // Always safest to start with a bad valuefloat inputVar1 = sl510ThermVoltage->getValue();float inputVar2 = sl510PyrgVoltage->getValue();// make sure both inputs are goodif (inputVar1 != -9999 && inputVar2 != -9999) {RtIn = 24900 * (inputVar1 * 1000 / (powerPyrg - inputVar1 * 1000));if (RtIn > 94980) {pyrgInTemp = 1 / (A_less + B_less * log(RtIn) + C_less * pow(log(RtIn), 3)); // for temperatures below 0 degC} else {pyrgInTemp = 1 / (A_more + B_more * log(RtIn) + C_more * pow(log(RtIn), 3)); // for temperatures above 0 degC}calculatedResult = K1in * inputVar2 + K2in * sb_const * pow(pyrgInTemp, 4); // Equation retrieved from product manual}return calculatedResult;}// Properties of the calculated incoming longwave radiation// The number of digits after the decimal placeconst uint8_t calculatedInLongRadResolution = 2;// This must be a value from http://vocabulary.odm2.org/variablename/const char* calculatedInLongRadName = "Radiation, incoming longwave";// This must be a value from http://vocabulary.odm2.org/units/const char* calculatedInLongRadUnit = "W/m^2";// A short code for the variableconst char* calculatedInLongRadCode = "ILWR";// The (optional) universallly unique identifierconst char* calculatedInLongRadUUID = "12345678-abcd-1234-ef00-1234567890ab";Variable* radiationIncomingLongwave = new Variable(calculateInLongRad, calculatedInLongRadResolution, calculatedInLongRadName,calculatedInLongRadUnit, calculatedInLongRadCode, calculatedInLongRadUUID);// ==========================================================================// Apogee SL-610-SS for outgoing longwave radiation// ==========================================================================const int8_t sl610Power = sensorPowerPin;const uint8_t sl610ThermADSChannel = 0;const uint8_t sl610PyrgADSChannel = 1;TIADS1x15 sl610Therm(sl610Power, sl610ThermADSChannel, adsGain, extraADSi2cAddress, apogeeNumReadings);TIADS1x15 sl610Pyrg(sl610Power, sl610PyrgADSChannel, adsGain, extraADSi2cAddress, apogeeNumReadings);Variable* sl610ThermVoltage =new TIADS1x15_Voltage(&sl610Therm, "12345678-abcd-1234-ef00-1234567890ab");Variable* sl610PyrgVoltage =new TIADS1x15_Voltage(&sl610Pyrg, "12345678-abcd-1234-ef00-1234567890ab");const float K1out; // calibration coefficient (K1) from apogee certificateconst float K2out; // calibration coefficient (K2) from apogee certificatefloat RtOut; // Thermistor resistance using half-bridge measurementfloat pyrgOutTemp;float calculateOutLongRad(void) {float calculatedResult = -9999; // Always safest to start with a bad valuefloat inputVar1 = sl610ThermVoltage->getValue();float inputVar2 = sl610PyrgVoltage->getValue();// make sure both input is goodif (inputVar1 != -9999 && inputVar2 != -9999) {RtOut = 24900 * (inputVar1 / (powerPyrg - inputVar1));if (RtOut > 94980) {pyrgOutTemp = 1 / (A_less + B_less * log(RtOut) + C_less * pow(log(RtOut), 3)); // for temperatures below 0 degC} else {pyrgOutTemp = 1 / (A_more + B_more * log(RtOut) + C_more * pow(log(RtOut), 3)); // for temperatures above 0 degC}calculatedResult = K1out * inputVar2 + K2out * sb_const * pow(pyrgOutTemp, 4); // Equation retrieved from product manual}return calculatedResult;}// Properties of the calculated incoming longwave radiation// The number of digits after the decimal placeconst uint8_t calculatedOutLongRadResolution = 2;// This must be a value from http://vocabulary.odm2.org/variablename/const char* calculatedOutLongRadName = "Radiation, outgoing longwave";// This must be a value from http://vocabulary.odm2.org/units/const char* calculatedOutLongRadUnit = "W/m^2";// A short code for the variableconst char* calculatedOutLongRadCode = "OLWR";// The (optional) universallly unique identifierconst char* calculatedOutLongRadUUID = "12345678-abcd-1234-ef00-1234567890ab";Variable* radiationOutgoingLongwave = new Variable(calculateOutLongRad, calculatedOutLongRadResolution, calculatedOutLongRadName,calculatedOutLongRadUnit, calculatedOutLongRadCode, calculatedOutLongRadUUID);// ==========================================================================// METER Teros 12 Soil Moisture Sensors// ==========================================================================#include <sensors/MeterTeros11.h>char add1 = "a"; // Address 1 at depth XXXXchar add2 = "b"; // Address 2 at depth XXXXchar add3 = "c"; // Address 3 at depth XXXXint8_t sdiPowerPin = sensorPowerPin;int8_t sdiDataPin = 7;MeterTeros11 probe1(add1, sdiPowerPin, sdiDataPin);MeterTeros11 probe2(add2, sdiPowerPin, sdiDataPin);MeterTeros11 probe3(add3, sdiPowerPin, sdiDataPin);Variable* rawVWCCounts1 =new MeterTeros11_Count(&probe1, "12345678-abcd-1234-ef00-1234567890ab");Variable* soilTemp1 =new MeterTeros11_Temp(&probe1, "12345678-abcd-1234-ef00-1234567890ab");Variable* soilEa1 =new MeterTeros11_Ea(&probe1, "12345678-abcd-1234-ef00-1234567890ab");Variable* vwc1 =new MeterTeros11_VWC(&probe1, "12345678-abcd-1234-ef00-1234567890ab");Variable* rawVWCCounts2 =new MeterTeros11_Count(&probe2, "12345678-abcd-1234-ef00-1234567890ab");Variable* soilTemp2 =new MeterTeros11_Temp(&probe2, "12345678-abcd-1234-ef00-1234567890ab");Variable* soilEa2 =new MeterTeros11_Ea(&probe2, "12345678-abcd-1234-ef00-1234567890ab");Variable* vwc2 =new MeterTeros11_VWC(&probe2, "12345678-abcd-1234-ef00-1234567890ab");Variable* rawVWCCounts3 =new MeterTeros11_Count(&probe3, "12345678-abcd-1234-ef00-1234567890ab");Variable* soilTemp3 =new MeterTeros11_Temp(&probe3, "12345678-abcd-1234-ef00-1234567890ab");Variable* soilEa3 =new MeterTeros11_Ea(&probe3, "12345678-abcd-1234-ef00-1234567890ab");Variable* vwc3 =new MeterTeros11_VWC(&probe3, "12345678-abcd-1234-ef00-1234567890ab");// ==========================================================================// Creating the Variable Array[s] and Filling with Variable Objects// ==========================================================================/** Start [variable_arrays] */Variable* variableList[] = {new ProcessorStats_SampleNumber(&mcuBoard),new ProcessorStats_FreeRam(&mcuBoard),new ProcessorStats_Battery(&mcuBoard),new MaximDS3231_Temp(&ds3231),sonarRange,calculatedSnowDepth,sp510Voltage,radiationIncomingShortwave,sp610Voltage,radiationOutgoingShortwave,sl510ThermVoltage,sl510PyrgVoltage,radiationIncomingLongwave,sl610ThermVoltage,sl610PyrgVoltage,radiationOutgoingLongwave,rawVWCCounts1,soilTemp1,soilEa1,vwc1,rawVWCCounts2,soilTemp2,soilEa2,vwc2,rawVWCCounts3,soilTemp3,soilEa3,vwc3// Additional sensor variables can be added here, by copying the syntax// for creating the variable pointer (FORM1) from the// <code>menu_a_la_carte.ino</code> example// The example code snippets in the wiki are primarily FORM2.};const char* UUIDs[] = {"12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab","12345678-abcd-1234-ef00-1234567890ab",// ... The number of UUID's must match the number of variables!"12345678-abcd-1234-ef00-1234567890ab",};// Count up the number of pointers in the arrayint variableCount = sizeof(variableList) / sizeof(variableList[0]);// Create the VariableArray objectVariableArray varArray;/** End [variable_arrays] */// ==========================================================================// The Logger Object[s]// ==========================================================================/** Start [loggers] */// Create a logger instanceLogger dataLogger;/** End [loggers] */// ==========================================================================// Working Functions// ==========================================================================/** Start [working_functions] */// Flashes the LED's on the primary boardvoid 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);}/** End [working_functions] */// ==========================================================================// Arduino Setup Function// ==========================================================================/** Start [setup] */void setup() {// Start the primary serial connectionSerial.begin(serialBaud);// Print a start-up note to the first serial portSerial.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'spinMode(greenLED, OUTPUT);digitalWrite(greenLED, LOW);pinMode(redLED, OUTPUT);digitalWrite(redLED, LOW);// Blink the LEDs to show the board is on and starting upgreenredflash();// Set the timezones for the logger/data and the RTC// Logging in the given time zoneLogger::setLoggerTimeZone(timeZone);// It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)Logger::setRTCTimeZone(0);// Set information pinsdataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin,greenLED);// Begin the variable array[s], logger[s], and publisher[s]varArray.begin(variableCount, variableList);dataLogger.begin(LoggerID, loggingInterval, &varArray);// Set up the sensorsSerial.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 correctdataLogger.createLogFile(true); // true = write a new header// Call the processor sleepdataLogger.systemSleep();sonarSerial.begin(9600);}/** End [setup] */// ==========================================================================// Arduino Loop Function// ==========================================================================/** Start [loop] */void loop() {dataLogger.logData();}/** End [loop] */ -
AuthorPosts