Simple Logging
This shows the simplest use of a "logger" object. That is, creating an array of variable objects and then creating a logger object that utilizes those variables to update all of the variable results together and save the data to a SD card. The processor then goes to sleep between readings.
This is the example you should use to deploy a logger somewhere where you don't want or have access to a way of streaming live data and you won't want to upload data to the Monitor My Watershed data portal.
Unique Features of the Simple Logging Example
- Only logs data to an SD card.
To Use this Example
Prepare and set up PlatformIO
- Create a new PlatformIO project
- Replace the contents of the platformio.ini for your new project with the platformio.ini file in the examples/simple_logging folder on GitHub.
- It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example.
- Without this, the program won't compile.
- Open simple_
logging.ino and save it to your computer. Put it into the src directory of your project. - Delete main.cpp in that folder.
Set the logger ID
- Change the "XXXX" in this section of code to the loggerID assigned by Stroud:
// Logger ID, also becomes the prefix for the name of the data file on SD card const char *LoggerID = "XXXX";
Upload!
- Test everything at home before deploying out in the wild!
PlatformIO Configuration
; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [platformio] description = ModularSensors example logging data to an SD card [env:mayfly] monitor_speed = 115200 board = mayfly platform = atmelavr framework = arduino lib_ldf_mode = deep+ lib_ignore = RTCZero Adafruit NeoPixel Adafruit GFX Library Adafruit SSD1306 Adafruit ADXL343 Adafruit STMPE610 Adafruit TouchScreen Adafruit ILI9341 build_flags = -DSDI12_EXTERNAL_PCINT -DNEOSWSERIAL_EXTERNAL_PCINT -DMQTT_MAX_PACKET_SIZE=240 -DTINY_GSM_RX_BUFFER=64 -DTINY_GSM_YIELD_MS=2 lib_deps = envirodiy/EnviroDIY_ModularSensors ; ^^ Use this when working from an official release of the library ; https://github.com/EnviroDIY/ModularSensors.git#develop ; ^^ Use this when if you want to pull from the develop branch https://github.com/PaulStoffregen/AltSoftSerial.git https://github.com/SRGDamia1/NeoSWSerial.git https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git ; ^^ These are software serial port emulator libraries, you may not need them
The Complete Code
/** ========================================================================= * @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] */ // ========================================================================== // Data Logging Options // ========================================================================== /** Start [logging_options] */ // The name of this program file const char* sketchName = "simple_logging.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 = 15; // 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 = 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 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 = "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] */ // ========================================================================== // Settings for Additional Sensors // ========================================================================== // Additional sensors can setup here, similar to the RTC, but only if // they have been supported with ModularSensors wrapper functions. See: // https://github.com/EnviroDIY/ModularSensors/wiki#just-getting-started // Syntax for the include statement and constructor function for each sensor is // at // https://github.com/EnviroDIY/ModularSensors/wiki#these-sensors-are-currently-supported // or can be copied from the `menu_a_la_carte.ino` example // ========================================================================== // 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) // Additional sensor variables can be added here, by copying the syntax // for creating the variable pointer (FORM1) from the // `menu_a_la_carte.ino` example // The example code snippets in the wiki are primarily FORM2. }; // Count up the number of pointers in the array int variableCount = sizeof(variableList) / sizeof(variableList[0]); // Create the VariableArray object VariableArray varArray; /** End [variable_arrays] */ // ========================================================================== // The Logger Object[s] // ========================================================================== /** Start [loggers] */ // Create a logger instance Logger dataLogger; /** 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); } /** End [working_functions] */ // ========================================================================== // Arduino Setup Function // ========================================================================== /** Start [setup] */ void setup() { // Start the primary serial connection Serial.begin(serialBaud); // 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); // 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); // Set information pins dataLogger.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 sensors 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 dataLogger.createLogFile(true); // true = write a new header // Call the processor sleep dataLogger.systemSleep(); } /** End [setup] */ // ========================================================================== // Arduino Loop Function // ========================================================================== /** Start [loop] */ void loop() { dataLogger.logData(); } /** End [loop] */