Logger class

The "Logger" Class handles low power sleep for the main processor, interfacing with the real-time clock and modem, writing to the SD card, and passing data on to the data publishers.

A logger is a device that can control all functions of the modem sensors and that are attached to it and save the values of all variables measured by those sensors to an attached SD card. It must also work with a real-time clock to give timestamps to values. It may also work with a loggerModem for internet connection and send out data over the internet through one or more data publishers.

In this library, all loggers are Arduino-style small processor circuit boards.

Constructors, destructors, conversion operators

Logger(const char* loggerID, uint16_t loggingIntervalMinutes, int8_t SDCardSSPin, int8_t mcuWakePin, VariableArray* inputArray)
Construct a new Logger object.
Logger(const char* loggerID, uint16_t loggingIntervalMinutes, VariableArray* inputArray)
Construct a new Logger object.
Logger()
Construct a new Logger object.
~Logger() virtual
Destroy the Logger object - takes no action.

Basic Logging Parameters

Public functions to get and set basic logging paramters

const char* _loggerID protected
The logger id.
uint16_t _loggingIntervalMinutes protected
The logging interval in minutes.
uint8_t _initialShortIntervals protected
The initial number of samples to log at an interval of 1 minute for fast field verification.
int8_t _SDCardSSPin protected
Digital pin number on the mcu controlling the SD card slave select.
int8_t _SDCardPowerPin protected
Digital pin number on the mcu controlling SD card power.
int8_t _mcuWakePin protected
Digital pin number on the mcu receiving interrupts to wake from deep-sleep.
uint8_t _wakePinMode protected
The pin mode used for wake up on the clock alert pin.
int8_t _ledPin protected
Digital pin number on the mcu used to output an alert that the logger is measuring.
int8_t _buttonPin protected
Digital pin number on the mcu receiving interrupts to enter testing mode.
const char* _samplingFeatureUUID protected
The sampling feature UUID.
void setLoggerID(const char* loggerID)
Set the Logger ID.
const char* getLoggerID() -> const char*
Get the Logger ID.
void setLoggingInterval(uint16_t loggingIntervalMinutes)
Set the logging interval in minutes.
uint16_t getLoggingInterval() -> uint16_t
Get the Logging Interval.
void setSamplingFeatureUUID(const char* samplingFeatureUUID)
Set the universally unique identifier (UUID or GUID) of the sampling feature.
const char* getSamplingFeatureUUID() -> const char*
Get the Sampling Feature UUID.
void setSDCardPwr(int8_t SDCardPowerPin)
Set a digital pin number (on the mcu) to use to control power to the SD card and activate it as an output pin.
void turnOnSDcard(bool waitToSettle = true)
Send power to the SD card by setting the SDCardPowerPin HIGH.
void turnOffSDcard(bool waitForHousekeeping = true)
Cut power to the SD card by setting the SDCardPowerPin LOW.
void setSDCardSS(int8_t SDCardSSPin)
Set a digital pin number for the slave select (chip select) of the SD card and activate it as an output pin.
void setSDCardPins(int8_t SDCardSSPin, int8_t SDCardPowerPin)
Set both pin numbers related to the SD card and activate them as output pins.
void setRTCWakePin(int8_t mcuWakePin, uint8_t wakePinMode = INPUT_PULLUP)
Set digital pin number for the wake up pin used as an RTC interrupt and activate it in the given pin mode.
void setAlertPin(int8_t ledPin)
Set the digital pin number to put out an alert that a measurement is being logged and activate it as an output pin.
void alertOn()
Set the alert pin high.
void alertOff()
Set the alert pin low.
void setTestingModePin(int8_t buttonPin, uint8_t buttonPinMode = INPUT)
Set the digital pin number for an interrupt pin used to enter testing mode, activate that pin as the given input type, and attach the testing interrupt to it.
void setLoggerPins(int8_t mcuWakePin, int8_t SDCardSSPin, int8_t SDCardPowerPin, int8_t buttonPin, int8_t ledPin, uint8_t wakePinMode = INPUT_PULLUP, uint8_t buttonPinMode = INPUT)
Set the digital pin numbers and activate pin modes for the five pins of interest for the logger.

Attached Variable Array Functions

Public functions to get information about the attached variable array

VariableArray* _internalArray protected
A pointer to the internal variable array instance.
void setVariableArray(VariableArray* inputArray)
Set the variable array object.
uint8_t getArrayVarCount() -> uint8_t
Get the number of variables in the internal variable array object.
String getParentSensorNameAtI(uint8_t position_i) -> String
Get the name of the parent sensor of the variable at the given position in the internal variable array object.
String getParentSensorNameAndLocationAtI(uint8_t position_i) -> String
Get the name and pin location of the parent sensor of the variable at the given position in the internal variable array object.
String getVarNameAtI(uint8_t position_i) -> String
Get the name of the variable at the given position in the internal variable array object.
String getVarUnitAtI(uint8_t position_i) -> String
Get the unit of the variable at the given position in the internal variable array object.
String getVarCodeAtI(uint8_t position_i) -> String
Get the customized code of the variable at the given position in the internal variable array object.
String getVarUUIDAtI(uint8_t position_i) -> String
Get the UUID of the variable at the given position in the internal variable array object.
float getValueAtI(uint8_t position_i) -> float
Get the most recent value of the variable at the given position in the internal variable array object.
String getValueStringAtI(uint8_t position_i) -> String
Get the most recent value of the variable at the given position in the internal variable array object.
String formatValueStringAtI(uint8_t position_i, float value) -> String
Get the string representing a particular value of the variable at the given position in the internal variable array object.

Internet and Publisher Functions

Public functions for internet and dataPublishers

loggerModem* _logModem protected
The internal modem instance.
dataPublisher* dataPublishers protected
An array of all of the attached data publishers.
void attachModem(loggerModem& modem)
Attach a loggerModem to the logger to provide internet access.
bool syncRTC() -> bool
Use the attahed loggerModem to synchronize the real-time clock with NIST time servers.
void registerDataPublisher(dataPublisher* publisher)
Register a data publisher object to receive data from the logger.
void publishDataToRemotes(void)
Publish data to all registered data publishers.
void sendDataToRemotes(void) deprecated in v0.22.5
Retained for backwards compatibility, use publishDataToRemotes() in new code.

SD Cards and Saving Data

Public functions for logging data to an SD card

SdFat sd protected
An internal reference to SdFat for SD card control.
File logFile protected
An internal reference to an SdFat file instance.
String _fileName protected
An internal reference to the current filename.
void setFileName(const char* fileName)
Set the file name, if you want to decide on it in advance.
void setFileName(String& fileName)
Set the file name, if you want to decide on it in advance.
String getFileName(void) -> String
Get the current filename.
void printFileHeader(Stream* stream) virtual
Print a header out to a stream.
void printSensorDataCSV(Stream* stream)
Print a comma separated list of volues of sensor data - including the time in the logging timezone - out over an Arduino stream.
bool createLogFile(String& filename, bool writeDefaultHeader = false) -> bool
Create a file on the SD card and set the created, modified, and accessed timestamps in that file.
bool createLogFile(bool writeDefaultHeader = false) -> bool
Create a file on the SD card and set the created, modified, and accessed timestamps in that file.
bool logToSD(String& filename, String& rec) -> bool
Open a file with the given name on the SD card and append the given line to the bottom of it.
bool logToSD(String& rec) -> bool
Open a file named with the current internal filename value and append the given line to the bottom of it.
bool logToSD(void) -> bool
Open a file named with the current internal filename value and append a line to the bottom of it with the most recent values of all variables in the variable array as a comma separated list.
bool initializeSDCard(void) -> bool protected
Check if the SD card is available and ready to write to.
void generateAutoFileName(void) protected
Generate a file name from the logger id and the current date.
void setFileTimestamp(File& fileToStamp, uint8_t stampFlag) protected
Set a timestamp on a file.
bool openFile(String& filename, bool createFile, bool writeDefaultHeader) -> bool protected
Open or creates a file, converting a string file name to a character file name.

Clock and Timezones

Public Functions for sleeping the logger

AVR Sleep modes

In the avr/sleep.h file, the call names of these 5 sleep modes are: SLEEP_MODE_IDLE - the least power savings SLEEP_MODE_ADC SLEEP_MODE_PWR_SAVE SLEEP_MODE_STANDBY SLEEP_MODE_PWR_DOWN - the most power savings

SAMD21 Sleep Modes

The SAM D21/DA1 have two software-selectable sleep modes, Idle and Stand-by. In Idle mode, the CPU is stopped while all other functions can be kept running. In Stand-by mode, all clocks and functions are stopped, expect those selected to continue running. The device supports SleepWalking. This feature allows the peripheral to wake up from sleep based on predefined conditions, and thus allows the CPU to wake up only when needed, e.g., when a threshold is crossed or a result is ready. The Event System supports synchronous and asynchronous events, allowing peripherals to receive, react to and send events even in Stand-by mode.

SAMD51 Sleep Modes

The device can be set in a sleep mode. In sleep mode, the CPU is stopped and the peripherals are either active or idle, according to the sleep mode depth:

  • Idle sleep mode:
    • The CPU is stopped.
    • Synchronous clocks are stopped except when requested.
    • The logic is retained.
  • Standby sleep mode:
    • The CPU is stopped as well as the peripherals.
    • The logic is retained, and power domain gating can be used to fully or partially turn off the PDSYSRAM power domain.
  • Hibernate sleep mode:
    • PDCORESW power domain is turned OFF.
    • The backup power domain is kept powered to allow few features to run (RTC, 32KHz clock sources, and wake-up from external pins).
    • The PDSYSRAM power domain can be retained according to software configuration.
  • Backup sleep mode:
    • Only the backup domain is kept powered to allow few features to run (RTC, 32KHz clock sources, and wake-up from external pins).
    • The PDBKUPRAM power domain can be retained according to software configuration.
  • Off sleep mode:
    • The entire device is powered off.
Bit Settings
ValueNameDefinition
0x0Reserved-
0x1Reserved-
0x2IDLECPU, AHBx, and APBx clocks are OFF
0x3ReservedReserved
0x4STANDBYAll Clocks are OFF
0x5HIBERNATEBackup domain is ON as well as some PDRAMs
0x6BACKUPOnly Backup domain is powered ON
0x7OFFAll power domains are powered OFF
static int8_t _loggerTimeZone protected
The static timezone data is being logged in.
static int8_t _loggerRTCOffset protected
The static difference between the timezone of the RTC and the timezone data is being logged in.
extendedWatchDogAVR watchDogTimer
A watch-dog implementation to use to reboot the system in case of lock-ups.
bool setRTClock(uint32_t UTCEpochSeconds) -> bool
Veify that the input value is sane and if so sets the real time clock to the given time.
bool checkInterval(void) -> bool
Check if the CURRENT time is an even interval of the logging rate.
bool checkMarkedInterval(void) -> bool
Check if the MARKED time is an even interval of the logging rate - That is the value saved in the static variable markedLocalEpochTime.
void systemSleep(void)
Put the mcu to sleep to conserve battery life and handle post-interrupt wake actions.
static void setLoggerTimeZone(int8_t timeZone)
Set the static timezone that the data will be logged in.
static int8_t getLoggerTimeZone(void) -> int8_t
Get the Logger Time Zone.
static void setTimeZone(int8_t timeZone) deprecated in v0.22.4
Retained for backwards compatibility; use setLoggerTimeZone(int8_t timeZone) in new code.
static int8_t getTimeZone(void) -> int8_t deprecated in v0.22.4
Retained for backwards compatibility; use getLoggerTimeZone() in new code.
static void setRTCTimeZone(int8_t timeZone)
Set the static timezone that the RTC is programmed in.
static int8_t getRTCTimeZone(void) -> int8_t
Get the timezone of the real-time clock (RTC).
static void setTZOffset(int8_t offset)
Set the offset between the built-in clock and the time zone where the data is being recorded.
static int8_t getTZOffset(void) -> int8_t
Get the offset between the built-in clock and the time zone where the data is being recorded.
static uint32_t getNowEpoch(void) -> uint32_t deprecated in v0.33.0
Get the current epoch time from the RTC (unix time, ie, the number of seconds from January 1, 1970 00:00:00) and correct it to the logging time zone.
static uint32_t getNowLocalEpoch(void) -> uint32_t
Get the current epoch time from the RTC (unix time, ie, the number of seconds from January 1, 1970 00:00:00) and correct it to the logging time zone.
static uint32_t getNowUTCEpoch(void) -> uint32_t
Get the current Universal Coordinated Time (UTC) epoch time from the RTC (unix time, ie, the number of seconds from January 1, 1970 00:00:00 UTC)
static void setNowUTCEpoch(uint32_t ts)
Set the real time clock to the given number of seconds from January 1, 1970.
static DateTime dtFromEpoch(uint32_t epochTime) -> DateTime
Convert the number of seconds from January 1, 1970 to a DateTime object instance.
static String formatDateTime_ISO8601(DateTime& dt) -> String
Convert a date-time object into a ISO8601 formatted string.
static String formatDateTime_ISO8601(uint32_t epochTime) -> String
Convert an epoch time (unix time) into a ISO8601 formatted string.
static bool isRTCSane(void) -> bool
Check that the current time on the RTC is within a "sane" range.
static bool isRTCSane(uint32_t epochTime) -> bool
Check that a given epoch time (seconds since 1970) is within a "sane" range.
static void markTime(void)
Set static variables for the date/time.
static void wakeISR(void)
Set up the Interrupt Service Request for waking.

Do-It-All Convience Functions

Convience functions to call several of the above functions

static uint32_t markedLocalEpochTime
The static "marked" epoch time for the local timezone.
static uint32_t markedUTCEpochTime
The static "marked" epoch time for UTC.
static volatile bool isLoggingNow
Internal flag set to true when logger is currently updating sensors or writing to the SD card.
static volatile bool isTestingNow
Internal flag set to true when the logger is going through the "testing mode" routine.
static volatile bool startTesting
Internal flag set to true with then logger should begin the "testing mode" routine when it finishes other operations.
void begin(const char* loggerID, uint16_t loggingIntervalMinutes, VariableArray* inputArray) virtual
Set all pin levels and does initial communication with the real-time clock and SD card to prepare the logger for full functionality.
void begin(VariableArray* inputArray) virtual
Set all pin levels and does initial communication with the real-time clock and SD card to prepare the logger for full functionality.
void begin() virtual
Set all pin levels and does initial communication with the real-time clock and SD card to prepare the logger for full functionality.
void logData(bool sleepBeforeReturning = true) virtual
This is a one-and-done to log data.
void logDataAndPublish(bool sleepBeforeReturning = true)
This is a one-and-done to log data and publish the results to any associated publishers.

Sensor Testing Mode

Public functions for a "sensor testing" mode

void testingMode(bool sleepBeforeReturning = true) virtual
Execute testing mode.
static void testingISR(void)
The interrupt sevice routine called when an iterrupt is detected on the pin assigned for "testing" mode.

Function documentation

Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, int8_t SDCardSSPin, int8_t mcuWakePin, VariableArray* inputArray)

Construct a new Logger object.

Parameters
loggerID A name for the logger - unless otherwise specified, files saved to the SD card will be named with the logger id and the date the file was started.
loggingIntervalMinutes The frequency in minutes at which data should be logged
SDCardSSPin The pin of the chip select/slave select for the SPI connection to the SD card
mcuWakePin The pin used to wake the logger from deep sleep - expected to be attached to an alarm pin of the real-time clock. Use a value of -1 to prevent the board from sleeping.
inputArray A pointer to a variableArray object instance providing data to be logged. This is NOT an array of variables, but an object of the variable array class.

Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, VariableArray* inputArray)

Construct a new Logger object.

Parameters
loggerID A name for the logger - unless otherwise specified, files saved to the SD card will be named with the logger id and the date the file was started.
loggingIntervalMinutes The frequency in minutes at which data should be logged
inputArray A variableArray object instance providing data to be logged. This is NOT an array of variables, but an object of the variable array class.

Logger::Logger()

Construct a new Logger object.


void Logger::setLoggerID(const char* loggerID)

Set the Logger ID.

Parameters
loggerID A pointer to the logger ID

Unless otherwise specified, files saved to the SD card will be named with the logger id and the date the file was started.


const char* Logger::getLoggerID()

Get the Logger ID.

Returns const char* A pointer to the logger ID

void Logger::setLoggingInterval(uint16_t loggingIntervalMinutes)

Set the logging interval in minutes.

Parameters
loggingIntervalMinutes The frequency with which to update sensor values and write data to the SD card.

uint16_t Logger::getLoggingInterval()

Get the Logging Interval.

Returns uint16_t The logging interval in minutes

void Logger::setSamplingFeatureUUID(const char* samplingFeatureUUID)

Set the universally unique identifier (UUID or GUID) of the sampling feature.

Parameters
samplingFeatureUUID A pointer to the sampling feature UUID

const char* Logger::getSamplingFeatureUUID()

Get the Sampling Feature UUID.

Returns const char* The sampling feature UUID

void Logger::setSDCardPwr(int8_t SDCardPowerPin)

Set a digital pin number (on the mcu) to use to control power to the SD card and activate it as an output pin.

Parameters
SDCardPowerPin A digital pin number on the mcu controlling power to the SD card.

Because this sets the pin mode, this function should only be called during the setup() or loop() portion of an Arduino program.


void Logger::turnOnSDcard(bool waitToSettle = true)

Send power to the SD card by setting the SDCardPowerPin HIGH.

Parameters
waitToSettle True to add a short (6ms) delay between powering on the card and beginning initialization. Defaults to true.

Optionally waits for the card to "settle." Has no effect if a pin has not been set to control power to the SD card.


void Logger::turnOffSDcard(bool waitForHousekeeping = true)

Cut power to the SD card by setting the SDCardPowerPin LOW.

Parameters
waitForHousekeeping True to add a 1 second delay between to allow any on-chip writing to complete before cutting power. Defaults to true.

Optionally waits for the card to do "housekeeping" before cutting the power. Has o effect if a pin has not been set to control power to the SD card.


void Logger::setSDCardSS(int8_t SDCardSSPin)

Set a digital pin number for the slave select (chip select) of the SD card and activate it as an output pin.

Parameters
SDCardSSPin The pin on the mcu connected to the slave select of the SD card.

This over-writes the value (if any) given in the constructor. The pin mode of this pin will be set as OUTPUT.

Because this sets the pin mode, this function should only be called during the setup() or loop() portion of an Arduino program.


void Logger::setSDCardPins(int8_t SDCardSSPin, int8_t SDCardPowerPin)

Set both pin numbers related to the SD card and activate them as output pins.

Parameters
SDCardSSPin The pin on the mcu connected to the slave select of the SD card.
SDCardPowerPin A digital pin number on the mcu controlling power to the SD card.

These over-write the values (if any) given in the constructor. The pin mode of these pins will be set as OUTPUT.

Because this sets the pin mode, this function should only be called during the setup() or loop() portion of an Arduino program.


void Logger::setRTCWakePin(int8_t mcuWakePin, uint8_t wakePinMode = INPUT_PULLUP)

Set digital pin number for the wake up pin used as an RTC interrupt and activate it in the given pin mode.

Parameters
mcuWakePin The pin on the mcu to be used to wake the mcu from deep sleep.
wakePinMode The pin mode to be used for wake up on the clock alert pin. Must be either INPUT OR INPUT_PULLUP. Optional with a default value of INPUT_PULLUP. The DS3231 has an active low interrupt, so the pull-up resistors should be enabled.

This over-writes the value (if any) given in the constructor. Use a value of -1 to prevent the board from attempting to sleep. If using a SAMD board with the internal RTC, the value of the pin is irrelevant as long as it is positive.

Because this sets the pin mode, this function should only be called during the setup() or loop() portion of an Arduino program.


void Logger::setAlertPin(int8_t ledPin)

Set the digital pin number to put out an alert that a measurement is being logged and activate it as an output pin.

Parameters
ledPin The pin on the mcu to be held HIGH while sensor data is being collected and logged.

The pin mode of this pin will be set as OUTPUT. This is intended to be a pin with a LED on it so you can see the light come on when a measurement is being taken.

Because this sets the pin mode, this function should only be called during the setup() or loop() portion of an Arduino program.


void Logger::setTestingModePin(int8_t buttonPin, uint8_t buttonPinMode = INPUT)

Set the digital pin number for an interrupt pin used to enter testing mode, activate that pin as the given input type, and attach the testing interrupt to it.

Parameters
buttonPin The pin on the mcu to listen to for a value-change interrupt.
buttonPinMode The pin mode to be used for the button pin. Must be either INPUT OR INPUT_PULLUP. Optional with a default value of INPUT. Using INPUT_PULLUP will enable processor input resistors, while using INPUT will explicitly disable them. If your pin is externally pulled down or the button is a normally open (NO) switch with common (COM) connected to Vcc, like the EnviroDIY Mayfly), you should use the INPUT pin mode. Coversely, if your button connect to ground when activated, you should enable the processor pull-up resistors using INPUT_PULLUP.

Intended to be used for a pin attached to a button or other manual interrupt source.

Because this sets the pin mode, this function should only be called during the setup() or loop() portion of an Arduino program.

Once in testing mode, the logger will attempt to connect the the internet and take 25 measurements spaced at 5 second intervals writing the results to the main output destination (ie, Serial). Testing mode cannot be entered while the logger is taking a scheduled measureemnt. No data is written to the SD card in testing mode.


void Logger::setLoggerPins(int8_t mcuWakePin, int8_t SDCardSSPin, int8_t SDCardPowerPin, int8_t buttonPin, int8_t ledPin, uint8_t wakePinMode = INPUT_PULLUP, uint8_t buttonPinMode = INPUT)

Set the digital pin numbers and activate pin modes for the five pins of interest for the logger.

Parameters
mcuWakePin The pin on the mcu to listen to for a value-change interrupt to wake from deep sleep. The mode of this pin will be set to wakePinMode.
SDCardSSPin The pin on the mcu connected to the slave select of the SD card. The pin mode of this pin will be set as OUTPUT.
SDCardPowerPin A digital pin number on the mcu controlling power to the SD card. The pin mode of this pin will be set as OUTPUT.
buttonPin The pin on the mcu to listen to for a value-change interrupt to enter testing mode. The mode of this pin will be set to buttonPinMode.
ledPin The pin on the mcu to be held HIGH while sensor data is being collected and logged. The pin mode of this pin will be set as OUTPUT.
wakePinMode The pin mode to be used for wake up on the mcuWakePin (clock alert) pin. Must be either INPUT OR INPUT_PULLUP. Optional with a default value of INPUT_PULLUP. The DS3231 has an active low interrupt, so the pull-up resistors should be enabled.
buttonPinMode The pin mode to be used for the button pin. Must be either INPUT OR INPUT_PULLUP. Optional with a default value of INPUT. Using INPUT_PULLUP will enable processor input resistors, while using INPUT will explicitly disable them. If your pin is externally pulled down or the button is a normally open (NO) switch with common (COM) connected to Vcc, like the EnviroDIY Mayfly), you should use the INPUT pin mode. Coversely, if your button is active when connected to ground, you should enable the processor pull-up resistors using INPUT_PULLUP.

Because this sets the pin mode, this function should only be called during the setup() or loop() portion of an Arduino program.


void Logger::setVariableArray(VariableArray* inputArray)

Set the variable array object.

Parameters
inputArray A pointer to a variable array object instance. This is NOT an array of variables, but an object of the variable array class.

uint8_t Logger::getArrayVarCount()

Get the number of variables in the internal variable array object.

Returns uint8_t The number of variables in the internal variable array object

String Logger::getParentSensorNameAtI(uint8_t position_i)

Get the name of the parent sensor of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns String The name of the parent sensor of that variable, if applicable.

String Logger::getParentSensorNameAndLocationAtI(uint8_t position_i)

Get the name and pin location of the parent sensor of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns String The concatenated name and pin location of the parent sensor of that variable, if applicable.

String Logger::getVarNameAtI(uint8_t position_i)

Get the name of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns String The variable name

Variable names must follow the controlled vocabulary documented here: http://vocabulary.odm2.org/variablename/


String Logger::getVarUnitAtI(uint8_t position_i)

Get the unit of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns String The variable unit

Variable units must follow the controlled vocabulary documented here: http://vocabulary.odm2.org/units/


String Logger::getVarCodeAtI(uint8_t position_i)

Get the customized code of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns String The variable code

String Logger::getVarUUIDAtI(uint8_t position_i)

Get the UUID of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns String The variable UUID

float Logger::getValueAtI(uint8_t position_i)

Get the most recent value of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns float The value of the variable as a float.

String Logger::getValueStringAtI(uint8_t position_i)

Get the most recent value of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
Returns String The value of the variable as a string with the correct number of significant figures.

String Logger::formatValueStringAtI(uint8_t position_i, float value)

Get the string representing a particular value of the variable at the given position in the internal variable array object.

Parameters
position_i The position of the variable in the array.
value The value to format.
Returns String The given value as a string with the correct number of significant figures.

void Logger::attachModem(loggerModem& modem)

Attach a loggerModem to the logger to provide internet access.

Parameters
modem An instance of the loggerModem class

See Modem and Internet Functions for more information on how the modem must be set up before it is attached to the logger. You must include an ampersand to tie in the already created modem! If you do not attach a modem, no action will be taken to publish data.


bool Logger::syncRTC()

Use the attahed loggerModem to synchronize the real-time clock with NIST time servers.

Returns bool True if clock synchronization was successful

void Logger::registerDataPublisher(dataPublisher* publisher)

Register a data publisher object to receive data from the logger.

Parameters
publisher A dataPublisher object

void Logger::sendDataToRemotes(void) deprecated in v0.22.5

Retained for backwards compatibility, use publishDataToRemotes() in new code.


void Logger::setFileName(const char* fileName)

Set the file name, if you want to decide on it in advance.

Parameters
fileName The file name

If the file name is set using this function, the same file name will be used for every single file created by the logger.


void Logger::setFileName(String& fileName)

Set the file name, if you want to decide on it in advance.

Parameters
fileName The file name

If the file name is set using this function, the same file name will be used for every single file created by the logger.


String Logger::getFileName(void)

Get the current filename.

Returns String The name of the file data is currently being saved to.

This may be a single filename set using the setFileName(name) function or an auto-generated filename which is a concatenation of the logger id and the date when the file was started.


void Logger::printFileHeader(Stream* stream) virtual

Print a header out to a stream.

Parameters
stream An Arduino stream instance - expected to be an SdFat file - but could also be the "main" Serial port for debugging.

This removes need to pass around very long string objects which can crash the logger


void Logger::printSensorDataCSV(Stream* stream)

Print a comma separated list of volues of sensor data - including the time in the logging timezone - out over an Arduino stream.

Parameters
stream An Arduino stream instance - expected to be an SdFat file - but could also be the "main" Serial port for debugging.

bool Logger::createLogFile(String& filename, bool writeDefaultHeader = false)

Create a file on the SD card and set the created, modified, and accessed timestamps in that file.

Parameters
filename The name of the file to create
writeDefaultHeader True to write a header to the file, default is false
Returns bool True if the file was successfully created.

The filename will be the value specified in the function. If desired, a header will also be written to the file based on the variable information from the variable array. This can be used to force a logger to create a file with a secondary file name.


bool Logger::createLogFile(bool writeDefaultHeader = false)

Create a file on the SD card and set the created, modified, and accessed timestamps in that file.

Parameters
writeDefaultHeader True to write a header to the file, default is false
Returns bool True if the file was successfully created.

The filename will be the one set by setFileName(String) or generated using the logger id and the date. If desired, a header will also be written to the file based on the variable information from the variable array.


bool Logger::logToSD(String& filename, String& rec)

Open a file with the given name on the SD card and append the given line to the bottom of it.

Parameters
filename The name of the file to write to
rec The line to be written to the file
Returns bool True if the file was successfully accessed or created and data appended to it.

If a file with the specified name does not already exist, attempt to create the file and add a header to it. Set the modified and accessed timestamps of the file to the current time.


bool Logger::logToSD(String& rec)

Open a file named with the current internal filename value and append the given line to the bottom of it.

Parameters
rec The line to be written to the file
Returns bool True if the file was successfully accessed or created and data appended to it.

If a file with the with the intenal filename does not already exist, attempt to create a file with that name and add a header to it. Set the modified and accessed timestamps of the file to the current time.


bool Logger::logToSD(void)

Open a file named with the current internal filename value and append a line to the bottom of it with the most recent values of all variables in the variable array as a comma separated list.

Returns bool True if the file was successfully accessed or created and data appended to it.

If a file with the with the intenal filename does not already exist, attempt to create the file and add a header to it. Set the modified and accessed timestamps of the file to the current time.


bool Logger::initializeSDCard(void) protected

Check if the SD card is available and ready to write to.

Returns bool True if the SD card is ready

We run this check before every communication with the SD card to prevent hanging.


void Logger::generateAutoFileName(void) protected

Generate a file name from the logger id and the current date.


void Logger::setFileTimestamp(File& fileToStamp, uint8_t stampFlag) protected

Set a timestamp on a file.

Parameters
fileToStamp The filename to change the timestamp of
stampFlag The "flag" of the timestamp to change - should be T_CREATE, T_WRITE, or T_ACCESS

bool Logger::openFile(String& filename, bool createFile, bool writeDefaultHeader) protected

Open or creates a file, converting a string file name to a character file name.

Parameters
filename The name of the file to open
createFile True to create the file if it did not already exist
writeDefaultHeader True to add a header to the file if it is created
Returns bool True if a file was successfully opened or created.

bool Logger::setRTClock(uint32_t UTCEpochSeconds)

Veify that the input value is sane and if so sets the real time clock to the given time.

Parameters
UTCEpochSeconds The number of seconds since 1970 in UTC.
Returns bool True if the input timestamp passes sanity checks and the clock has been successfully set.

bool Logger::checkInterval(void)

Check if the CURRENT time is an even interval of the logging rate.

Returns bool True if the current time on the RTC is an even interval of the logging rate.

bool Logger::checkMarkedInterval(void)

Check if the MARKED time is an even interval of the logging rate - That is the value saved in the static variable markedLocalEpochTime.

Returns bool True if the marked time is an even interval of the logging rate.

This should be used in conjunction with markTime() to ensure that all data outputs from a single data update session (SD, EnviroDIY, serial printing, etc) have the same timestamp even though the update routine may take several (or many) seconds.


void Logger::systemSleep(void)

Put the mcu to sleep to conserve battery life and handle post-interrupt wake actions.


static void Logger::setLoggerTimeZone(int8_t timeZone)

Set the static timezone that the data will be logged in.

Parameters
timeZone The timezone data shold be saved to the SD card in. This need not be the same as the timezone of the real time clock.

static int8_t Logger::getLoggerTimeZone(void)

Get the Logger Time Zone.

Returns int8_t The timezone data is be saved to the SD card in. This is not be the same as the timezone of the real time clock.

static void Logger::setTimeZone(int8_t timeZone) deprecated in v0.22.4

Retained for backwards compatibility; use setLoggerTimeZone(int8_t timeZone) in new code.

Parameters
timeZone The timezone data shold be saved to the SD card in. This need not be the same as the timezone of the real time clock.

static int8_t Logger::getTimeZone(void) deprecated in v0.22.4

Retained for backwards compatibility; use getLoggerTimeZone() in new code.

Returns int8_t The timezone data is be saved to the SD card in. This is not be the same as the timezone of the real time clock.

static void Logger::setRTCTimeZone(int8_t timeZone)

Set the static timezone that the RTC is programmed in.

Parameters
timeZone The timezone of the real-time clock (RTC)

static int8_t Logger::getRTCTimeZone(void)

Get the timezone of the real-time clock (RTC).

Returns int8_t The timezone of the real-time clock (RTC)

static void Logger::setTZOffset(int8_t offset)

Set the offset between the built-in clock and the time zone where the data is being recorded.

Parameters
offset The difference between the timezone of the RTC and the saved data

If your RTC is set in UTC and your logging timezone is EST, this should be -5. If your RTC is set in EST and your timezone is EST this does not need to be called.


static int8_t Logger::getTZOffset(void)

Get the offset between the built-in clock and the time zone where the data is being recorded.

Returns int8_t The offset between the built-in clock and the time zone where the data is being recorded.

static uint32_t Logger::getNowEpoch(void) deprecated in v0.33.0

Get the current epoch time from the RTC (unix time, ie, the number of seconds from January 1, 1970 00:00:00) and correct it to the logging time zone.

Returns uint32_t The number of seconds from January 1, 1970 in the logging time zone.

static uint32_t Logger::getNowLocalEpoch(void)

Get the current epoch time from the RTC (unix time, ie, the number of seconds from January 1, 1970 00:00:00) and correct it to the logging time zone.

Returns uint32_t The number of seconds from January 1, 1970 in the logging time zone.

static uint32_t Logger::getNowUTCEpoch(void)

Get the current Universal Coordinated Time (UTC) epoch time from the RTC (unix time, ie, the number of seconds from January 1, 1970 00:00:00 UTC)

Returns uint32_t The number of seconds from 1970-01-01T00:00:00Z0000

static void Logger::setNowUTCEpoch(uint32_t ts)

Set the real time clock to the given number of seconds from January 1, 1970.

Parameters
ts The number of seconds since 1970.

The validity of the timestamp is not checked in any way! In practice, setRTClock(ts) should be used to avoid setting the clock to an obviously invalid value. The input value should be in the timezone of the RTC.


static DateTime Logger::dtFromEpoch(uint32_t epochTime)

Convert the number of seconds from January 1, 1970 to a DateTime object instance.

Parameters
epochTime The number of seconds since 1970.
Returns DateTime The equivalent DateTime

static String Logger::formatDateTime_ISO8601(DateTime& dt)

Convert a date-time object into a ISO8601 formatted string.

Parameters
dt A DateTime object to convert
Returns String An ISO8601 formatted String.

This assumes the supplied date/time is in the LOGGER's timezone and adds the LOGGER's offset as the time zone offset in the string.


static String Logger::formatDateTime_ISO8601(uint32_t epochTime)

Convert an epoch time (unix time) into a ISO8601 formatted string.

Parameters
epochTime The number of seconds since 1970.
Returns String An ISO8601 formatted String.

This assumes the supplied date/time is in the LOGGER's timezone and adds the LOGGER's offset as the time zone offset in the string.


static bool Logger::isRTCSane(void)

Check that the current time on the RTC is within a "sane" range.

Returns bool True if the current time on the RTC passes sanity range checking

To be sane the clock must be between 2020 and 2030.


static bool Logger::isRTCSane(uint32_t epochTime)

Check that a given epoch time (seconds since 1970) is within a "sane" range.

Parameters
epochTime The epoch time to be checked.
Returns bool True if the given time passes sanity range checking.

To be sane the clock must be between 2020 and 2025.


static void Logger::markTime(void)

Set static variables for the date/time.

This is needed so that all data outputs (SD, EnviroDIY, serial printing, etc) print the same time for updating the sensors - even though the routines to update the sensors and to output the data may take several seconds. It is not currently possible to output the instantaneous time an individual sensor was updated, just a single marked time. By custom, this should be called before updating the sensors, not after.


static void Logger::wakeISR(void)

Set up the Interrupt Service Request for waking.

In this case, we're doing nothing, we just want the processor to wake. This must be a static function (which means it can only call other static functions.)


void Logger::begin(const char* loggerID, uint16_t loggingIntervalMinutes, VariableArray* inputArray) virtual

Set all pin levels and does initial communication with the real-time clock and SD card to prepare the logger for full functionality.

Parameters
loggerID An ID for the logger - will be used to auto-generate file names. Supplying a logger ID here will override any value given in the constructor.
loggingIntervalMinutes The interval in minutes at which to log data. Supplying an interval here will override any value given in the constructor.
inputArray A variableArray object instance providing data to be logged. This is NOT an array of variables, but an object of the variable array class. Supplying a variableArray object here will override any value given in the constructor.

This is used for operations that cannot happen in the logger constructor

  • they must happen at run time, not at compile time.

void Logger::begin(VariableArray* inputArray) virtual

Set all pin levels and does initial communication with the real-time clock and SD card to prepare the logger for full functionality.

Parameters
inputArray A variableArray object instance providing data to be logged. This is NOT an array of variables, but an object of the variable array class. Supplying a variableArray object here will override any value given in the constructor.

This is used for operations that cannot happen in the logger constructor

  • they must happen at run time, not at compile time.

void Logger::begin() virtual

Set all pin levels and does initial communication with the real-time clock and SD card to prepare the logger for full functionality.

This is used for operations that cannot happen in the logger constructor

  • they must happen at run time, not at compile time.

void Logger::logData(bool sleepBeforeReturning = true) virtual

This is a one-and-done to log data.

Parameters
sleepBeforeReturning True to put the logger to sleep before returning from the function; optional with a default value of true.

void Logger::logDataAndPublish(bool sleepBeforeReturning = true)

This is a one-and-done to log data and publish the results to any associated publishers.

Parameters
sleepBeforeReturning True to put the logger to sleep before returning from the function; optional with a default value of true.

void Logger::testingMode(bool sleepBeforeReturning = true) virtual

Execute testing mode.

Parameters
sleepBeforeReturning True to put the logger to sleep before returning from the function; optional with a default value of true.

In testing mode, the logger uses the loggerModem, if attached, to connect to the internet. It then powers up all sensors tied to variable in the internal variable array. The logger then updates readings from all sensors 25 times with a 5 second wait in between. All results are output to the "main" output - ie Serial - and NOT to the SD card. After 25 measurements, the sensors are put to sleep, the modem is disconnected from the internet, and the logger goes back to sleep.



Variable documentation

uint8_t Logger::_wakePinMode protected

The pin mode used for wake up on the clock alert pin.

Must be either INPUT OR INPUT_PULLUP with an AVR board. On a SAM/D board INPUT_PULLDOWN is also an option. Optional with a default value of INPUT_PULLUP. The DS3231 has an active low interrupt, so the pull-up resistors should be enabled.


int8_t Logger::_ledPin protected

Digital pin number on the mcu used to output an alert that the logger is measuring.

Expected to be connected to a LED.


int8_t Logger::_buttonPin protected

Digital pin number on the mcu receiving interrupts to enter testing mode.

Expected to be connected to a user button.


loggerModem* Logger::_logModem protected

The internal modem instance.


static int8_t Logger::_loggerTimeZone protected

The static timezone data is being logged in.


static int8_t Logger::_loggerRTCOffset protected

The static difference between the timezone of the RTC and the timezone data is being logged in.