DRWI_Mayfly1_WiFi.ino example

Example for DRWI CitSci LTE sites.

Example for DRWI CitSci LTE sites.=========================================================================

This example shows proper settings for the following configuration:

Mayfly v1.x board EnviroDIY ESP32 Wifi Bee module Hydros21 CTD sensor


1/** =========================================================================
2 * @example{lineno} DRWI_Mayfly1_WiFi.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>
6 *
7 * @brief Example for DRWI CitSci LTE sites.
8 *
9 * This example shows proper settings for the following configuration:
10 *
11 * Mayfly v1.x board
12 * EnviroDIY ESP32 Wifi Bee module
13 * Hydros21 CTD sensor
14 *
15 * @m_examplenavigation{example_drwi_mayfly1_wifi,}
16 * ======================================================================= */
17
18// ==========================================================================
19// Defines for TinyGSM
20// ==========================================================================
21/** Start [defines] */
22#ifndef TINY_GSM_RX_BUFFER
23#define TINY_GSM_RX_BUFFER 256
24#endif
25#ifndef TINY_GSM_YIELD_MS
26#define TINY_GSM_YIELD_MS 2
27#endif
28/** End [defines] */
29
30// ==========================================================================
31// Include the libraries required for any data logger
32// ==========================================================================
33/** Start [includes] */
34// The Arduino library is needed for every Arduino program.
35#include <Arduino.h>
36
37// Include the main header for ModularSensors
38#include <ModularSensors.h>
39/** End [includes] */
40
41
42// ==========================================================================
43// Data Logging Options
44// ==========================================================================
45/** Start [logging_options] */
46// The name of this program file
47const char* sketchName = "DRWI_Mayfly1_WiFi.ino";
48// Logger ID, also becomes the prefix for the name of the data file on SD card
49const char* LoggerID = "XXXXX";
50// How frequently (in minutes) to log data
51const uint8_t loggingInterval = 15;
52// Your logger's timezone.
53const int8_t timeZone = -5; // Eastern Standard Time
54// NOTE: Daylight savings time will not be applied! Please use standard time!
55
56// Set the input and output pins for the logger
57// NOTE: Use -1 for pins that do not apply
58const int32_t serialBaud = 57600; // Baud rate for debugging
59const int8_t greenLED = 8; // Pin for the green LED
60const int8_t redLED = 9; // Pin for the red LED
61const int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin)
62const int8_t wakePin = 31; // MCU interrupt/alarm pin to wake from sleep
63// Mayfly 0.x, 1.x D31 = A7
64const int8_t sdCardPwrPin = -1; // MCU SD card power pin
65const int8_t sdCardSSPin = 12; // SD card chip select/slave select pin
66const int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power
67/** End [logging_options] */
68
69
70// ==========================================================================
71// Wifi/Cellular Modem Options
72// ==========================================================================
73/** Start [espressif_esp32] */
74#include <modems/EspressifESP32.h>
75
76// Create a reference to the serial port for the modem
77HardwareSerial& modemSerial = Serial1; // Use hardware serial if possible
78const int32_t modemBaud = 115200; // Communication speed of the modem
79// NOTE: This baud rate too fast for the Mayfly. We'll slow it down in the
80// setup.
81
82// Modem Pins - Describe the physical pin connection of your modem to your board
83// NOTE: Use -1 for pins that do not apply
84// Example pins here are for a EnviroDIY ESP32 Bluetooth/Wifi Bee with
85// Mayfly 1.1
86const int8_t modemVccPin = 18; // MCU pin controlling modem power
87const int8_t modemResetPin = -1; // MCU pin connected to modem reset pin
88const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
89 // status
90
91// Network connection information
92const char* wifiId = "xxxxx"; // WiFi access point name
93const char* wifiPwd = "xxxxx"; // WiFi password (WPA2)
94
95// Create the modem object
96EspressifESP32 modemESP(&modemSerial, modemVccPin, modemResetPin, wifiId,
97 wifiPwd);
98// Create an extra reference to the modem by a generic name
99EspressifESP32 modem = modemESP;
100/** End [espressif_esp32] */
101
102
103// ==========================================================================
104// Using the Processor as a Sensor
105// ==========================================================================
106/** Start [processor_sensor] */
107#include <sensors/ProcessorStats.h>
108
109// Create the main processor chip "sensor" - for general metadata
110const char* mcuBoardVersion = "v1.1";
111ProcessorStats mcuBoard(mcuBoardVersion);
112/** End [processor_sensor] */
113
114
115// ==========================================================================
116// Maxim DS3231 RTC (Real Time Clock)
117// Built in on all versions of the Mayfly
118// ==========================================================================
119/** Start [ds3231] */
120#include <sensors/MaximDS3231.h>
121
122// Create a DS3231 sensor object
123MaximDS3231 ds3231(1);
124/** End [ds3231] */
125
126
127// ==========================================================================
128// Sensirion SHT4X Digital Humidity and Temperature Sensor
129// Built in on Mayfly 1.x
130// ==========================================================================
131/** Start [sensirion_sht4x] */
132#include <sensors/SensirionSHT4x.h>
133
134// NOTE: Use -1 for any pins that don't apply or aren't being used.
135const int8_t SHT4xPower = sensorPowerPin; // Power pin
136const bool SHT4xUseHeater = true;
137
138// Create an Sensirion SHT4X sensor object
139SensirionSHT4x sht4x(SHT4xPower, SHT4xUseHeater);
140/** End [sensirion_sht4x] */
141
142
143// ==========================================================================
144// Meter Hydros 21 Conductivity, Temperature, and Depth Sensor
145// ==========================================================================
146/** Start [hydros21] */
147#include <sensors/MeterHydros21.h>
148
149const char* hydrosSDI12address = "1"; // The SDI-12 Address of the Hydros 21
150const uint8_t hydrosNumberReadings = 6; // The number of readings to average
151const int8_t SDI12Power = sensorPowerPin; // Power pin (-1 if unconnected)
152const int8_t SDI12Data = 7; // The SDI12 data pin
153
154// Create a Meter Hydros 21 sensor object
155MeterHydros21 hydros(*hydrosSDI12address, SDI12Power, SDI12Data,
156 hydrosNumberReadings);
157/** End [hydros21] */
158
159
160/* clang-format off */
161// ==========================================================================
162// Creating the Variable Array[s] and Filling with Variable Objects
163// ==========================================================================
164/** Start [variable_arrays] */
165Variable* variableList[] = {
166 new MeterHydros21_Cond(&hydros), // Specific conductance (Meter_Hydros21_Cond)
167 new MeterHydros21_Depth(&hydros), // Water depth (Meter_Hydros21_Depth)
168 new MeterHydros21_Temp(&hydros), // Temperature (Meter_Hydros21_Temp)
169 new SensirionSHT4x_Humidity(&sht4x), // Relative humidity (Sensirion_SHT40_Humidity)
170 new SensirionSHT4x_Temp(&sht4x), // Temperature (Sensirion_SHT40_Temperature)
171 new ProcessorStats_Battery(&mcuBoard), // Battery voltage (EnviroDIY_Mayfly_Batt)
172 new Modem_SignalPercent(&modem), // Percent full scale (EnviroDIY_LTEB_SignalPercent)
173};
174
175// All UUID's, device registration, and sampling feature information can be
176// pasted directly from Monitor My Watershed.
177// To get the list, click the "View token UUID list" button on the upper right
178// of the site page.
179
180// *** CAUTION --- CAUTION --- CAUTION --- CAUTION --- CAUTION ***
181// Check the order of your variables in the variable list!!!
182// Be VERY certain that they match the order of your UUID's!
183// Rearrange the variables in the variable list ABOVE if necessary to match!
184// Do not change the order of the variables in the section below.
185// *** CAUTION --- CAUTION --- CAUTION --- CAUTION --- CAUTION ***
186
187// Replace all of the text in the following section with the UUID array from
188// MonitorMyWatershed
189// --------------------- Beginning of Token UUID List ---------------------
190
191
192const char* UUIDs[] = // UUID array for device sensors
193 {
194 "12345678-abcd-1234-ef00-1234567890ab", // Specific conductance (Meter_Hydros21_Cond)
195 "12345678-abcd-1234-ef00-1234567890ab", // Water depth (Meter_Hydros21_Depth)
196 "12345678-abcd-1234-ef00-1234567890ab", // Temperature (Meter_Hydros21_Temp)
197 "12345678-abcd-1234-ef00-1234567890ab", // Relative humidity (Sensirion_SHT40_Humidity)
198 "12345678-abcd-1234-ef00-1234567890ab", // Temperature (Sensirion_SHT40_Temperature)
199 "12345678-abcd-1234-ef00-1234567890ab", // Battery voltage (EnviroDIY_Mayfly_Batt)
200 "12345678-abcd-1234-ef00-1234567890ab", // Percent full scale (EnviroDIY_LTEB_SignalPercent)
201};
202const char* registrationToken = "12345678-abcd-1234-ef00-1234567890ab"; // Device registration token
203const char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampling feature UUID
204
205
206// ----------------------- End of Token UUID List -----------------------
207/* clang-format on */
208
209// Count up the number of pointers in the array
210int variableCount = sizeof(variableList) / sizeof(variableList[0]);
211
212// Create the VariableArray object
213VariableArray varArray(variableCount, variableList, UUIDs);
214/** End [variable_arrays] */
215
216
217// ==========================================================================
218// The Logger Object[s]
219// ==========================================================================
220/** Start [loggers] */
221// Create a new logger instance
222Logger dataLogger(LoggerID, loggingInterval, &varArray);
223/** End [loggers] */
224
225
226// ==========================================================================
227// Creating Data Publisher[s]
228// ==========================================================================
229/** Start [publishers] */
230// Create a data publisher for the Monitor My Watershed/EnviroDIY POST endpoint
231#include <publishers/EnviroDIYPublisher.h>
232EnviroDIYPublisher EnviroDIYPOST(dataLogger, &modem.gsmClient,
233 registrationToken, samplingFeature);
234/** End [publishers] */
235
236
237// ==========================================================================
238// Working Functions
239// ==========================================================================
240/** Start [working_functions] */
241// Flashes the LED's on the primary board
242void greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) {
243 for (uint8_t i = 0; i < numFlash; i++) {
244 digitalWrite(greenLED, HIGH);
245 digitalWrite(redLED, LOW);
246 delay(rate);
247 digitalWrite(greenLED, LOW);
248 digitalWrite(redLED, HIGH);
249 delay(rate);
250 }
251 digitalWrite(redLED, LOW);
252}
253
254// Reads the battery voltage
255// NOTE: This will actually return the battery level from the previous update!
256float getBatteryVoltage() {
257 if (mcuBoard.sensorValues[0] == -9999) mcuBoard.update();
258 return mcuBoard.sensorValues[0];
259}
260
261
262// ==========================================================================
263// Arduino Setup Function
264// ==========================================================================
265/** Start [setup] */
266void setup() {
267 // Start the primary serial connection
268 Serial.begin(serialBaud);
269
270 // Print a start-up note to the first serial port
271 Serial.print(F("Now running "));
272 Serial.print(sketchName);
273 Serial.print(F(" on Logger "));
274 Serial.println(LoggerID);
275 Serial.println();
276
277 Serial.print(F("Using ModularSensors Library version "));
278 Serial.println(MODULAR_SENSORS_VERSION);
279 Serial.print(F("TinyGSM Library version "));
280 Serial.println(TINYGSM_VERSION);
281 Serial.println();
282
283 // Start the serial connection with the modem
284 modemSerial.begin(modemBaud);
285
286 // Set up pins for the LED's
287 pinMode(greenLED, OUTPUT);
288 digitalWrite(greenLED, LOW);
289 pinMode(redLED, OUTPUT);
290 digitalWrite(redLED, LOW);
291 // Blink the LEDs to show the board is on and starting up
292 greenredflash();
293
294 pinMode(20, OUTPUT); // for proper operation of the onboard flash memory
295 // chip's ChipSelect (Mayfly v1.0 and later)
296
297 // Set the timezones for the logger/data and the RTC
298 // Logging in the given time zone
299 Logger::setLoggerTimeZone(timeZone);
300 // It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)
301 Logger::setRTCTimeZone(0);
302
303 // Attach the modem and information pins to the logger
304 dataLogger.attachModem(modem);
305 modem.setModemLED(modemLEDPin);
306 dataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin,
307 greenLED);
308
309 // Begin the logger
310 dataLogger.begin();
311 EnviroDIYPOST.begin(dataLogger, &modem.gsmClient, registrationToken,
312 samplingFeature);
313
314 // Note: Please change these battery voltages to match your battery
315 // Set up the sensors, except at lowest battery level
316 if (getBatteryVoltage() > 3.4) {
317 Serial.println(F("Setting up sensors..."));
318 varArray.setupSensors();
319 }
320
321 /** Start [setup_esp] */
322 for (int8_t ntries = 5; ntries; ntries--) {
323 // This will also verify communication and set up the modem
324 if (modem.modemWake()) break;
325 // if that didn't work, try changing baud rate
326 modemSerial.begin(115200);
327 modem.gsmModem.sendAT(GF("+UART_DEF=9600,8,1,0,0"));
328 modem.gsmModem.waitResponse();
329 modemSerial.end();
330 modemSerial.begin(9600);
331 }
332 /** End [setup_esp] */
333
334
335 // Sync the clock if it isn't valid or we have battery to spare
336 if (getBatteryVoltage() > 3.55 || !dataLogger.isRTCSane()) {
337 // Synchronize the RTC with NIST
338 // This will also set up the modem
339 dataLogger.syncRTC();
340 }
341
342 // Create the log file, adding the default header to it
343 // Do this last so we have the best chance of getting the time correct
344 // and all sensor names correct Writing to the SD card can be power
345 // intensive, so if we're skipping the sensor setup we'll skip this too.
346 if (getBatteryVoltage() > 3.4) {
347 Serial.println(F("Setting up file on SD card"));
348 dataLogger.turnOnSDcard(
349 true); // true = wait for card to settle after power up
350 dataLogger.createLogFile(true); // true = write a new header
351 dataLogger.turnOffSDcard(
352 true); // true = wait for internal housekeeping after write
353 }
354
355 // Call the processor sleep
356 Serial.println(F("Putting processor to sleep\n"));
357 dataLogger.systemSleep();
358}
359/** End [setup] */
360
361
362// ==========================================================================
363// Arduino Loop Function
364// ==========================================================================
365/** Start [loop] */
366// Use this short loop for simple data logging and sending
367void loop() {
368 // Note: Please change these battery voltages to match your battery
369 // At very low battery, just go back to sleep
370 if (getBatteryVoltage() < 3.4) {
371 dataLogger.systemSleep();
372 }
373 // At moderate voltage, log data but don't send it over the modem
374 else if (getBatteryVoltage() < 3.55) {
375 dataLogger.logData();
376 }
377 // If the battery is good, send the data to the world
378 else {
379 dataLogger.logDataAndPublish();
380 }
381}
382/** End [loop] */