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 example calls on two of the sensors available in this library. The example may be run exactly as written.
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 Learn EnviroDIY Example Only logs data to an SD card. Uses a few more sensors than the other simple logging example 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_LearnEnviroDIY 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_ LearnEnviroDIY.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: 1 // Logger ID, also becomes the prefix for the name of the data file on SD card
2 const char * LoggerID = "XXXX" ;
Upload! Test everything at home before deploying out in the wild! PlatformIO Configuration 1 ; PlatformIO Project Configuration File
3 ; Build options: build flags, source filter
4 ; Upload options: custom upload port, speed and extra flags
5 ; Library options: dependencies, extra library storages
6 ; Advanced options: extra scripting
8 ; Please visit documentation for the other options and examples
9 ; http://docs.platformio.org/page/projectconf.html
12 description = ModularSensors example logging data to an SD card from external sensors
30 -DSDI12_EXTERNAL_PCINT
31 -DNEOSWSERIAL_EXTERNAL_PCINT
32 -DMQTT_MAX_PACKET_SIZE = 240
33 -DTINY_GSM_RX_BUFFER = 64
36 envirodiy/EnviroDIY_ModularSensors
37 ; ^^ Use this when working from an official release of the library
38 ; https://github.com/EnviroDIY/ModularSensors.git#develop
39 ; ^^ Use this when if you want to pull from the develop branch
40 https : //github.com/PaulStoffregen/AltSoftSerial.git
41 https : //github.com/SRGDamia1/NeoSWSerial.git
42 https : //github.com/EnviroDIY/SoftwareSerial_ExternalInts.git
43 ; ^^ These are software serial port emulator libraries, you may not need them
The Complete Code 1 /** =========================================================================
2 * @example{lineno} simple_logging_LearnEnviroDIY.ino
3 * @copyright Stroud Water Research Center
4 * @license This example is published under the BSD-3 license.
5 * @author Sara Geleskie Damiano <sdamiano@stroudcenter.org>
7 * @brief A data logging example for the Learn EnviroDIY tutorial.
9 * See [the walkthrough page](@ref example_learn_envirodiy) for detailed
12 * @m_examplenavigation{example_learn_envirodiy,}
13 * ======================================================================= */
15 // ==========================================================================
16 // Include the libraries required for any data logger
17 // ==========================================================================
18 /** Start [includes] */
19 // The Arduino library is needed for every Arduino program.
22 // Include the main header for ModularSensors
23 #include <ModularSensors.h>
27 // ==========================================================================
28 // Data Logging Options
29 // ==========================================================================
30 /** Start [logging_options] */
31 // The name of this program file
32 const char * sketchName = "simple_logging.ino" ;
33 // Logger ID, also becomes the prefix for the name of the data file on SD card
34 const char * LoggerID = "XXXXX" ;
35 // How frequently (in minutes) to log data
36 const uint8_t loggingInterval = 15 ;
37 // Your logger's timezone.
38 const int8_t timeZone = -5 ; // Eastern Standard Time
39 // NOTE: Daylight savings time will not be applied! Please use standard time!
41 // Set the input and output pins for the logger
42 // NOTE: Use -1 for pins that do not apply
43 const int32_t serialBaud = 115200 ; // Baud rate for debugging
44 const int8_t greenLED = 8 ; // Pin for the green LED
45 const int8_t redLED = 9 ; // Pin for the red LED
46 const int8_t buttonPin = 21 ; // Pin for debugging mode (ie, button pin)
47 const int8_t wakePin = 31 ; // MCU interrupt/alarm pin to wake from sleep
49 // Set the wake pin to -1 if you do not want the main processor to sleep.
50 // In a SAMD system where you are using the built-in rtc, set wakePin to 1
51 const int8_t sdCardPwrPin = -1 ; // MCU SD card power pin
52 const int8_t sdCardSSPin = 12 ; // SD card chip select/slave select pin
53 const int8_t sensorPowerPin = 22 ; // MCU pin controlling main sensor power
54 /** End [logging_options] */
57 // ==========================================================================
58 // Using the Processor as a Sensor
59 // ==========================================================================
60 /** Start [processor_sensor] */
61 #include <sensors/ProcessorStats.h>
63 // Create the main processor chip "sensor" - for general metadata
64 const char * mcuBoardVersion = "v1.1" ;
65 ProcessorStats mcuBoard ( mcuBoardVersion );
66 /** End [processor_sensor] */
69 // ==========================================================================
70 // Maxim DS3231 RTC (Real Time Clock)
71 // ==========================================================================
73 #include <sensors/MaximDS3231.h> // Includes wrapper functions for Maxim DS3231 RTC
75 // Create a DS3231 sensor object, using this constructor function:
80 // ==========================================================================
81 // Settings for Additional Sensors
82 // ==========================================================================
83 // Additional sensors can setup here, similar to the RTC, but only if
84 // they have been supported with ModularSensors wrapper functions. See:
85 // https://github.com/EnviroDIY/ModularSensors/wiki#just-getting-started
86 // Syntax for the include statement and constructor function for each sensor is
88 // https://github.com/EnviroDIY/ModularSensors/wiki#these-sensors-are-currently-supported
89 // or can be copied from the `menu_a_la_carte.ino` example
92 // ==========================================================================
93 // Bosch BME280 Environmental Sensor
94 // ==========================================================================
96 #include <sensors/BoschBME280.h>
98 const int8_t I2CPower = sensorPowerPin ; // Power pin (-1 if unconnected)
99 uint8_t BMEi2c_addr = 0x76 ;
100 // The BME280 can be addressed either as 0x77 (Adafruit default) or 0x76 (Grove
101 // default) Either can be physically mofidied for the other address
103 // Create a Bosch BME280 sensor object
104 BoschBME280 bme280 ( I2CPower , BMEi2c_addr );
108 // ==========================================================================
109 // Maxim DS18 One Wire Temperature Sensor
110 // ==========================================================================
112 #include <sensors/MaximDS18.h>
114 // OneWire Address [array of 8 hex characters]
115 // If only using a single sensor on the OneWire bus, you may omit the address
116 // DeviceAddress OneWireAddress1 = {0x28, 0xFF, 0xBD, 0xBA, 0x81, 0x16, 0x03,
118 const int8_t OneWirePower = sensorPowerPin ; // Power pin (-1 if unconnected)
119 const int8_t OneWireBus = 6 ; // OneWire Bus Pin (-1 if unconnected)
121 // Create a Maxim DS18 sensor objects (use this form for a known address)
122 // MaximDS18 ds18(OneWireAddress1, OneWirePower, OneWireBus);
124 // Create a Maxim DS18 sensor object (use this form for a single sensor on bus
125 // with an unknown address)
126 MaximDS18 ds18 ( OneWirePower , OneWireBus );
130 // ==========================================================================
131 // Creating the Variable Array[s] and Filling with Variable Objects
132 // ==========================================================================
133 /** Start [variable_arrays] */
134 Variable * variableList [] = {
135 new ProcessorStats_SampleNumber ( & mcuBoard ),
136 new ProcessorStats_FreeRam ( & mcuBoard ),
137 new ProcessorStats_Battery ( & mcuBoard ),
138 new MaximDS3231_Temp ( & ds3231 ),
139 new BoschBME280_Temp ( & bme280 ),
140 new BoschBME280_Humidity ( & bme280 ),
141 new BoschBME280_Pressure ( & bme280 ),
142 new BoschBME280_Altitude ( & bme280 ),
143 new MaximDS18_Temp ( & ds18 )
144 // Additional sensor variables can be added here, by copying the syntax
145 // for creating the variable pointer (FORM1) from the
146 // `menu_a_la_carte.ino` example
147 // The example code snippets in the wiki are primarily FORM2.
149 // Count up the number of pointers in the array
150 int variableCount = sizeof ( variableList ) / sizeof ( variableList [ 0 ]);
152 // Create the VariableArray object
153 VariableArray varArray ;
154 /** End [variable_arrays] */
157 // ==========================================================================
158 // The Logger Object[s]
159 // ==========================================================================
160 /** Start [loggers] */
161 // Create a logger instance
166 // ==========================================================================
168 // ==========================================================================
169 /** Start [working_functions] */
170 // Flashes the LED's on the primary board
171 void greenredflash ( uint8_t numFlash = 4 , uint8_t rate = 75 ) {
172 for ( uint8_t i = 0 ; i < numFlash ; i ++ ) {
173 digitalWrite ( greenLED , HIGH );
174 digitalWrite ( redLED , LOW );
176 digitalWrite ( greenLED , LOW );
177 digitalWrite ( redLED , HIGH );
180 digitalWrite ( redLED , LOW );
182 /** End [working_functions] */
185 // ==========================================================================
186 // Arduino Setup Function
187 // ==========================================================================
190 // Start the primary serial connection
191 Serial . begin ( serialBaud );
193 // Print a start-up note to the first serial port
194 Serial . print ( F ( "Now running " ));
195 Serial . print ( sketchName );
196 Serial . print ( F ( " on Logger " ));
197 Serial . println ( LoggerID );
200 Serial . print ( F ( "Using ModularSensors Library version " ));
201 Serial . println ( MODULAR_SENSORS_VERSION );
203 // Set up pins for the LED's
204 pinMode ( greenLED , OUTPUT );
205 digitalWrite ( greenLED , LOW );
206 pinMode ( redLED , OUTPUT );
207 digitalWrite ( redLED , LOW );
208 // Blink the LEDs to show the board is on and starting up
211 // Set the timezones for the logger/data and the RTC
212 // Logging in the given time zone
213 Logger :: setLoggerTimeZone ( timeZone );
214 // It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)
215 Logger :: setRTCTimeZone ( 0 );
217 // Set information pins
218 dataLogger . setLoggerPins ( wakePin , sdCardSSPin , sdCardPwrPin , buttonPin ,
221 // Begin the variable array[s], logger[s], and publisher[s]
222 varArray . begin ( variableCount , variableList );
223 dataLogger . begin ( LoggerID , loggingInterval , & varArray );
225 // Set up the sensors
226 Serial . println ( F ( "Setting up sensors..." ));
227 varArray . setupSensors ();
229 // Create the log file, adding the default header to it
230 // Do this last so we have the best chance of getting the time correct and
231 // all sensor names correct
232 dataLogger . createLogFile ( true ); // true = write a new header
234 // Call the processor sleep
235 dataLogger . systemSleep ();
240 // ==========================================================================
241 // Arduino Loop Function
242 // ==========================================================================
245 dataLogger . logData ();