Example showing all possible functionality

This shows most of the functionality of the library at once. It has code in it for every possible sensor and modem and for both AVR and SAMD boards. This example should never be used directly; it is intended to document all possibilities and to verify compilating.

To create your own code, I recommend starting from a much simpler targeted example, like the Logging to MMW example, and then adding to it based on only the parts of this menu example that apply to you.


Walking Through the Code

PlatformIO Configuration

1; PlatformIO Project Configuration File
2;
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
7;
8; Please visit documentation for the other options and examples
9; http://docs.platformio.org/page/projectconf.html
10
11[platformio]
12description = ModularSensors example menu_a_la_carte
13
14[env:mayfly]
15monitor_speed = 115200
16board = mayfly
17platform = atmelavr
18framework = arduino
19lib_ldf_mode = deep+
20lib_ignore =
21 RTCZero
22 Adafruit NeoPixel
23 Adafruit GFX Library
24 Adafruit SSD1306
25 Adafruit ADXL343
26 Adafruit STMPE610
27 Adafruit TouchScreen
28 Adafruit ILI9341
29build_flags =
30 -DSDI12_EXTERNAL_PCINT
31 -DNEOSWSERIAL_EXTERNAL_PCINT
32 -DMQTT_MAX_PACKET_SIZE=240
33 -DTINY_GSM_RX_BUFFER=64
34 -DTINY_GSM_YIELD_MS=2
35 -DENABLE_SERIAL2
36 -DENABLE_SERIAL3
37 ; -D BUILD_MODEM_DIGI_XBEE_CELLULAR_TRANSPARENT ; Turn on first time w/ a Digi LTE-M module
38 ; -D MS_LOGGERBASE_DEBUG
39 ; -D MS_DATAPUBLISHERBASE_DEBUG
40 ; -D MS_ENVIRODIYPUBLISHER_DEBUG
41lib_deps =
42 envirodiy/EnviroDIY_ModularSensors
43; ^^ Use this when working from a tagged release of the library
44; See tags at https://platformio.org/lib/show/1648/EnviroDIY_ModularSensors
45
46; https://github.com/EnviroDIY/ModularSensors.git#develop
47; ^^ Use this when if you want to pull from the develop branch
48
49 https://github.com/PaulStoffregen/AltSoftSerial.git
50 https://github.com/SRGDamia1/NeoSWSerial.git
51 https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git
52; ^^ These are software serial port emulator libraries, you may not need them

The Complete Code

1/** =========================================================================
2 * @example{lineno} menu_a_la_carte.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 with all possible functionality.
8 *
9 * See [the walkthrough page](@ref example_menu) for detailed instructions.
10 *
11 * @m_examplenavigation{example_menu,}
12 * ======================================================================= */
13
14// ==========================================================================
15// Defines for TinyGSM
16// ==========================================================================
17/** Start [defines] */
18#ifndef TINY_GSM_RX_BUFFER
19#define TINY_GSM_RX_BUFFER 64
20#endif
21#ifndef TINY_GSM_YIELD_MS
22#define TINY_GSM_YIELD_MS 2
23#endif
24#ifndef MQTT_MAX_PACKET_SIZE
25#define MQTT_MAX_PACKET_SIZE 240
26#endif
27/** End [defines] */
28
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// Creating Additional Serial Ports
44// ==========================================================================
45// The modem and a number of sensors communicate over UART/TTL - often called
46// "serial". "Hardware" serial ports (automatically controlled by the MCU) are
47// generally the most accurate and should be configured and used for as many
48// peripherals as possible. In some cases (ie, modbus communication) many
49// sensors can share the same serial port.
50
51#if defined(__AVR__) || defined(ARDUINO_ARCH_AVR) // For AVR boards
52// Unfortunately, most AVR boards have only one or two hardware serial ports,
53// so we'll set up three types of extra software serial ports to use
54
55#ifdef BUILD_TEST_ALTSOFTSERIAL
56// AltSoftSerial by Paul Stoffregen
57// (https://github.com/PaulStoffregen/AltSoftSerial) is the most accurate
58// software serial port for AVR boards. AltSoftSerial can only be used on one
59// set of pins on each board so only one AltSoftSerial port can be used. Not all
60// AVR boards are supported by AltSoftSerial.
61/** Start [altsoftserial] */
62#include <AltSoftSerial.h>
63AltSoftSerial altSoftSerial;
64/** End [altsoftserial] */
65#endif // #ifdef BUILD_TEST_ALTSOFTSERIAL
66
67#ifdef BUILD_TEST_NEOSWSERIAL
68// NeoSWSerial (https://github.com/SRGDamia1/NeoSWSerial) is the best software
69// serial that can be used on any pin supporting interrupts.
70// You can use as many instances of NeoSWSerial as you need.
71// Not all AVR boards are supported by NeoSWSerial.
72/** Start [neoswserial] */
73#include <NeoSWSerial.h> // for the stream communication
74const int8_t neoSSerial1Rx = 11; // data in pin
75const int8_t neoSSerial1Tx = -1; // data out pin
76NeoSWSerial neoSSerial1(neoSSerial1Rx, neoSSerial1Tx);
77// To use NeoSWSerial in this library, we define a function to receive data
78// This is just a short-cut for later
79void neoSSerial1ISR() {
80 NeoSWSerial::rxISR(*portInputRegister(digitalPinToPort(neoSSerial1Rx)));
81}
82/** End [neoswserial] */
83#endif // #ifdef BUILD_TEST_NEOSWSERIAL
84
85#ifdef BUILD_TEST_SOFTSERIAL
86// The "standard" software serial library uses interrupts that conflict
87// with several other libraries used within this program. I've created a
88// [version of software serial that has been stripped of
89// interrupts](https://github.com/EnviroDIY/SoftwareSerial_ExtInts) but it is
90// still far from ideal.
91// NOTE: Only use if necessary. This is not a very accurate serial port!
92// You can use as many instances of SoftwareSerial as you need.
93/** Start [softwareserial] */
94const int8_t softSerialRx = A3; // data in pin
95const int8_t softSerialTx = A4; // data out pin
96
97#include <SoftwareSerial_ExtInts.h> // for the stream communication
98SoftwareSerial_ExtInts softSerial1(softSerialRx, softSerialTx);
99/** End [softwareserial] */
100#endif // #ifdef BUILD_TEST_SOFTSERIAL
101
102
103#if defined(MS_PALEOTERRA_SOFTWAREWIRE) || defined(MS_RAIN_SOFTWAREWIRE)
104/** Start [softwarewire] */
105// A software I2C (Wire) instance using Testato's SoftwareWire
106// To use SoftwareWire, you must also set a define for the sensor you want to
107// use Software I2C for, ie:
108// `#define MS_RAIN_SOFTWAREWIRE`
109// `#define MS_PALEOTERRA_SOFTWAREWIRE`
110// or set the build flag(s):
111// `-D MS_RAIN_SOFTWAREWIRE`
112// `-D MS_PALEOTERRA_SOFTWAREWIRE`
113#include <SoftwareWire.h> // Testato's Software I2C
114const int8_t softwareSDA = 5;
115const int8_t softwareSCL = 4;
116SoftwareWire softI2C(softwareSDA, softwareSCL);
117/** End [softwarewire] */
118#endif // #if defined(MS_PALEOTERRA_SOFTWAREWIRE) ...
119
120#endif // End software serial for avr boards
121
122#if defined(ARDUINO_ARCH_SAMD)
123/** Start [serial_ports_SAMD] */
124// The SAMD21 has 6 "SERCOM" ports, any of which can be used for UART
125// communication. The "core" code for most boards defines one or more UART
126// (Serial) ports with the SERCOMs and uses others for I2C and SPI. We can
127// create new UART ports on any available SERCOM. The table below shows
128// definitions for select boards.
129
130// Board => Arduino Zero Adafruit Feather Sodaq Boards
131// ------- --------------- ---------------- ----------------
132// SERCOM0 Serial1 (D0/D1) Serial1 (D0/D1) Serial (D0/D1)
133// SERCOM1 Available Available Serial3 (D12/D13)
134// SERCOM2 Available Available I2C (A4/A5)
135// SERCOM3 I2C (D20/D21) I2C (D20/D21) SPI (D11/12/13)
136// SERCOM4 SPI (D21/22/23) SPI (D21/22/23) SPI1/Serial2
137// SERCOM5 EDBG/Serial Available Serial1
138
139// If using a Sodaq board, do not define the new sercoms, instead:
140// #define ENABLE_SERIAL2
141// #define ENABLE_SERIAL3
142
143#include <wiring_private.h> // Needed for SAMD pinPeripheral() function
144
145#ifndef ENABLE_SERIAL2
146// Set up a 'new' UART using SERCOM1
147// The Rx will be on digital pin 11, which is SERCOM1's Pad #0
148// The Tx will be on digital pin 10, which is SERCOM1's Pad #2
149// NOTE: SERCOM1 is undefinied on a "standard" Arduino Zero and many clones,
150// but not all! Please check the variant.cpp file for you individual
151// board! Sodaq Autonomo's and Sodaq One's do NOT follow the 'standard'
152// SERCOM definitions!
153Uart Serial2(&sercom1, 11, 10, SERCOM_RX_PAD_0, UART_TX_PAD_2);
154// Hand over the interrupts to the sercom port
155void SERCOM1_Handler() {
156 Serial2.IrqHandler();
157}
158#endif
159
160#ifndef ENABLE_SERIAL3
161// Set up a 'new' UART using SERCOM2
162// The Rx will be on digital pin 5, which is SERCOM2's Pad #3
163// The Tx will be on digital pin 2, which is SERCOM2's Pad #2
164// NOTE: SERCOM2 is undefinied on a "standard" Arduino Zero and many clones,
165// but not all! Please check the variant.cpp file for you individual
166// board! Sodaq Autonomo's and Sodaq One's do NOT follow the 'standard'
167// SERCOM definitions!
168Uart Serial3(&sercom2, 5, 2, SERCOM_RX_PAD_3, UART_TX_PAD_2);
169// Hand over the interrupts to the sercom port
170void SERCOM2_Handler() {
171 Serial3.IrqHandler();
172}
173#endif
174
175/** End [serial_ports_SAMD] */
176#endif // End hardware serial on SAMD21 boards
177
178
179// ==========================================================================
180// Assigning Serial Port Functionality
181// ==========================================================================
182#if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAMD_ZERO) || \
183 defined(ATMEGA2560) || defined(ARDUINO_AVR_MEGA2560)
184/** Start [assign_ports_hw] */
185// If there are additional hardware Serial ports possible - use them!
186
187// We give the modem first priority and assign it to hardware serial
188// All of the supported processors have a hardware port available named Serial1
189#define modemSerial Serial1
190
191// Define the serial port for modbus
192// Modbus (at 9600 8N1) is used by the Keller level loggers and Yosemitech
193// sensors
194#define modbusSerial Serial2
195
196// The Maxbotix sonar is the only sensor that communicates over a serial port
197// but does not use modbus
198#define sonarSerial Serial3
199
200/** End [assign_ports_hw] */
201#else
202/** Start [assign_ports_sw] */
203
204// We give the modem first priority and assign it to hardware serial
205// All of the supported processors have a hardware port available named Serial1
206#define modemSerial Serial1
207
208// Define the serial port for modbus
209// Modbus (at 9600 8N1) is used by the Keller level loggers and Yosemitech
210// sensors
211// Since AltSoftSerial is the best software option, we use it for modbus
212// If AltSoftSerial (or its pins) aren't avaiable, use NeoSWSerial
213// SoftwareSerial **WILL NOT** work for modbus!
214#ifdef BUILD_TEST_ALTSOFTSERIAL
215#define modbusSerial altSoftSerial // For AltSoftSerial
216#elif defined(BUILD_TEST_NEOSWSERIAL)
217#define modbusSerial neoSSerial1 // For Neo software serial
218#elif defined(BUILD_TEST_SOFTSERIAL)
219#define modbusSerial softSerial1 // For software serial
220#else
221#define modbusSerial Serial1 // Hardware serial
222#endif
223
224// The Maxbotix sonar is the only sensor that communicates over a serial port
225// but does not use modbus
226// Since the Maxbotix only needs one-way communication and sends a simple text
227// string repeatedly, almost any software serial port will do for it.
228#ifdef BUILD_TEST_ALTSOFTSERIAL
229#define sonarSerial altSoftSerial // For AltSoftSerial
230#elif defined(BUILD_TEST_NEOSWSERIAL)
231#define sonarSerial neoSSerial1 // For Neo software serial
232#elif defined(BUILD_TEST_SOFTSERIAL)
233#define sonarSerial softSerial1 // For software serial
234#else
235#define sonarSerial Serial1 // Hardware serial
236#endif
237
238/** End [assign_ports_sw] */
239#endif
240
241
242// ==========================================================================
243// Data Logging Options
244// ==========================================================================
245/** Start [logging_options] */
246// The name of this program file
247const char* sketchName = "menu_a_la_carte.ino";
248// Logger ID, also becomes the prefix for the name of the data file on SD card
249const char* LoggerID = "XXXXX";
250// How frequently (in minutes) to log data
251const uint8_t loggingInterval = 15;
252// Your logger's timezone.
253const int8_t timeZone = -5; // Eastern Standard Time
254// NOTE: Daylight savings time will not be applied! Please use standard time!
255
256// Set the input and output pins for the logger
257// NOTE: Use -1 for pins that do not apply
258const int32_t serialBaud = 115200; // Baud rate for debugging
259const int8_t greenLED = 8; // Pin for the green LED
260const int8_t redLED = 9; // Pin for the red LED
261const int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin)
262const int8_t wakePin = 31; // MCU interrupt/alarm pin to wake from sleep
263// Mayfly 0.x, 1.x D31 = A7
264// Set the wake pin to -1 if you do not want the main processor to sleep.
265// In a SAMD system where you are using the built-in rtc, set wakePin to 1
266const int8_t sdCardPwrPin = -1; // MCU SD card power pin
267const int8_t sdCardSSPin = 12; // SD card chip select/slave select pin
268const int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power
269/** End [logging_options] */
270
271
272// ==========================================================================
273// Wifi/Cellular Modem Options
274// NOTE: DON'T USE MORE THAN ONE MODEM OBJECT!
275// Delete the sections you are not using!
276// ==========================================================================
277
278#if defined(BUILD_MODEM_DIGI_XBEE_CELLULAR_TRANSPARENT)
279/** Start [digi_xbee_cellular_transparent] */
280// For any Digi Cellular XBee's
281// NOTE: The u-blox based Digi XBee's (3G global and LTE-M global) can be used
282// in either bypass or transparent mode, each with pros and cons
283// The Telit based Digi XBees (LTE Cat1) can only use this mode.
284#include <modems/DigiXBeeCellularTransparent.h>
285
286// NOTE: Extra hardware and software serial ports are created in the "Settings
287// for Additional Serial Ports" section
288const int32_t modemBaud = 9600; // All XBee's use 9600 by default
289
290// Modem Pins - Describe the physical pin connection of your modem to your board
291// NOTE: Use -1 for pins that do not apply
292// The pin numbers here are for a Digi XBee with a Mayfly 0.x and LTE adapter
293// For options https://github.com/EnviroDIY/LTEbee-Adapter/edit/master/README.md
294const int8_t modemVccPin = -1; // MCU pin controlling modem power
295 // Option: modemVccPin = A5, if Mayfly SJ7 is
296 // connected to the ASSOC pin
297const int8_t modemStatusPin = 19; // MCU pin used to read modem status
298// NOTE: If possible, use the `STATUS/SLEEP_not` (XBee pin 13) for status, but
299// the CTS pin can also be used if necessary
300const bool useCTSforStatus = false; // Flag to use the CTS pin for status
301const int8_t modemResetPin = 20; // MCU pin connected to modem reset pin
302const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
303const int8_t modemLEDPin =
304 redLED; // MCU pin connected an LED to show modem status
305
306// Network connection information
307const char* apn = "xxxxx"; // APN for GPRS connection
308
309// Create the modem object
310DigiXBeeCellularTransparent modemXBCT(&modemSerial, modemVccPin, modemStatusPin,
311 useCTSforStatus, modemResetPin,
312 modemSleepRqPin, apn);
313// Create an extra reference to the modem by a generic name
314DigiXBeeCellularTransparent modem = modemXBCT;
315/** End [digi_xbee_cellular_transparent] */
316// ==========================================================================
317
318
319#elif defined(BUILD_MODEM_DIGI_XBEE_LTE_BYPASS)
320/** Start [digi_xbee_lte_bypass] */
321// For the u-blox SARA R410M based Digi LTE-M XBee3
322// NOTE: According to the manual, this should be less stable than transparent
323// mode, but my experience is the complete reverse.
324#include <modems/DigiXBeeLTEBypass.h>
325
326// NOTE: Extra hardware and software serial ports are created in the "Settings
327// for Additional Serial Ports" section
328const int32_t modemBaud = 9600; // All XBee's use 9600 by default
329
330// Modem Pins - Describe the physical pin connection of your modem to your board
331// NOTE: Use -1 for pins that do not apply
332// The pin numbers here are for a Digi XBee with a Mayfly 0.x and LTE adapter
333const int8_t modemVccPin = A5; // MCU pin controlling modem power
334const int8_t modemStatusPin = 19; // MCU pin used to read modem status
335// NOTE: If possible, use the `STATUS/SLEEP_not` (XBee pin 13) for status, but
336// the CTS pin can also be used if necessary
337const bool useCTSforStatus = false; // Flag to use the CTS pin for status
338const int8_t modemResetPin = 20; // MCU pin connected to modem reset pin
339const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
340const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
341 // status
342
343// Network connection information
344const char* apn = "xxxxx"; // APN for GPRS connection
345
346// Create the modem object
347DigiXBeeLTEBypass modemXBLTEB(&modemSerial, modemVccPin, modemStatusPin,
348 useCTSforStatus, modemResetPin, modemSleepRqPin,
349 apn);
350// Create an extra reference to the modem by a generic name
351DigiXBeeLTEBypass modem = modemXBLTEB;
352/** End [digi_xbee_lte_bypass] */
353// ==========================================================================
354
355
356#elif defined(BUILD_MODEM_DIGI_XBEE_3G_BYPASS)
357/** Start [digi_xbee_3g_bypass] */
358// For the u-blox SARA U201 based Digi 3G XBee with 2G fallback
359// NOTE: According to the manual, this should be less stable than transparent
360// mode, but my experience is the complete reverse.
361#include <modems/DigiXBee3GBypass.h>
362
363// NOTE: Extra hardware and software serial ports are created in the "Settings
364// for Additional Serial Ports" section
365const int32_t modemBaud = 9600; // All XBee's use 9600 by default
366
367// Modem Pins - Describe the physical pin connection of your modem to your board
368// NOTE: Use -1 for pins that do not apply
369// The pin numbers here are for a Digi XBee with a Mayfly and LTE adapter
370const int8_t modemVccPin = A5; // MCU pin controlling modem power
371const int8_t modemStatusPin = 19; // MCU pin used to read modem status
372// NOTE: If possible, use the `STATUS/SLEEP_not` (XBee pin 13) for status, but
373// the CTS pin can also be used if necessary
374const bool useCTSforStatus = false; // Flag to use the CTS pin for status
375const int8_t modemResetPin = 20; // MCU pin connected to modem reset pin
376const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
377const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
378 // status
379
380// Network connection information
381const char* apn = "xxxxx"; // APN for GPRS connection
382
383// Create the modem object
384DigiXBee3GBypass modemXB3GB(&modemSerial, modemVccPin, modemStatusPin,
385 useCTSforStatus, modemResetPin, modemSleepRqPin,
386 apn);
387// Create an extra reference to the modem by a generic name
388DigiXBee3GBypass modem = modemXB3GB;
389/** End [digi_xbee_3g_bypass] */
390// ==========================================================================
391
392
393#elif defined(BUILD_MODEM_DIGI_XBEE_WIFI)
394/** Start [digi_xbee_wifi] */
395// For the Digi Wifi XBee (S6B)
396#include <modems/DigiXBeeWifi.h>
397
398// NOTE: Extra hardware and software serial ports are created in the "Settings
399// for Additional Serial Ports" section
400const int32_t modemBaud = 9600; // All XBee's use 9600 by default
401
402// Modem Pins - Describe the physical pin connection of your modem to your board
403// NOTE: Use -1 for pins that do not apply
404// The pin numbers here are for a Digi XBee direcly connected to a Mayfly 1.x
405const int8_t modemVccPin = 18; // MCU pin controlling modem power
406const int8_t modemStatusPin = 19; // MCU pin used to read modem status
407// NOTE: If possible, use the `STATUS/SLEEP_not` (XBee pin 13) for status, but
408// the CTS pin can also be used if necessary
409const bool useCTSforStatus = true; // Flag to use the CTS pin for status
410const int8_t modemResetPin = A5; // MCU pin connected to modem reset pin
411const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
412const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
413 // status
414
415// Network connection information
416const char* wifiId = "xxxxx"; // WiFi access point name
417const char* wifiPwd = "xxxxx"; // WiFi password (WPA2)
418
419// Create the modem object
420DigiXBeeWifi modemXBWF(&modemSerial, modemVccPin, modemStatusPin,
421 useCTSforStatus, modemResetPin, modemSleepRqPin, wifiId,
422 wifiPwd);
423// Create an extra reference to the modem by a generic name
424DigiXBeeWifi modem = modemXBWF;
425/** End [digi_xbee_wifi] */
426// ==========================================================================
427
428
429#elif defined(BUILD_MODEM_ESPRESSIF_ESP8266)
430/** Start [espressif_esp8266] */
431// For almost anything based on the Espressif ESP8266 using the
432// AT command firmware
433#include <modems/EspressifESP8266.h>
434
435// NOTE: Extra hardware and software serial ports are created in the "Settings
436// for Additional Serial Ports" section
437const int32_t modemBaud = 115200; // Communication speed of the modem
438// NOTE: This baud rate too fast for an 8MHz board, like the Mayfly! The
439// module should be programmed to a slower baud rate or set to auto-baud using
440// the AT+UART_CUR or AT+UART_DEF command.
441
442// Modem Pins - Describe the physical pin connection of your modem to your board
443// NOTE: Use -1 for pins that do not apply
444// Example pins here are for a EnviroDIY ESP32 Bluetooth/Wifi Bee with
445// Mayfly 1.1
446const int8_t modemVccPin = 18; // MCU pin controlling modem power
447const int8_t modemResetPin = A5; // MCU pin connected to modem reset pin
448const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
449 // status
450
451// Network connection information
452const char* wifiId = "xxxxx"; // WiFi access point name
453const char* wifiPwd = "xxxxx"; // WiFi password (WPA2)
454
455// Create the modem object
456EspressifESP8266 modemESP(&modemSerial, modemVccPin, modemResetPin, wifiId,
457 wifiPwd);
458// Create an extra reference to the modem by a generic name
459EspressifESP8266 modem = modemESP;
460/** End [espressif_esp8266] */
461// ==========================================================================
462
463
464#elif defined(BUILD_MODEM_ESPRESSIF_ESP32)
465/** Start [espressif_esp32] */
466// For almost anything based on the Espressif ESP8266 using the
467// AT command firmware
468#include <modems/EspressifESP32.h>
469
470// NOTE: Extra hardware and software serial ports are created in the "Settings
471// for Additional Serial Ports" section
472const int32_t modemBaud = 57600; // Communication speed of the modem
473// NOTE: This baud rate too fast for an 8MHz board, like the Mayfly! The
474// module should be programmed to a slower baud rate or set to auto-baud using
475// the AT+UART_CUR or AT+UART_DEF command.
476
477// Modem Pins - Describe the physical pin connection of your modem to your board
478// NOTE: Use -1 for pins that do not apply
479// Example pins here are for a EnviroDIY ESP32 Bluetooth/Wifi Bee with
480// Mayfly 1.1
481const int8_t modemVccPin = 18; // MCU pin controlling modem power
482const int8_t modemResetPin = -1; // MCU pin connected to modem reset pin
483const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
484 // status
485
486// Network connection information
487const char* wifiId = "xxxxx"; // WiFi access point name
488const char* wifiPwd = "xxxxx"; // WiFi password (WPA2)
489
490// Create the modem object
491EspressifESP32 modemESP(&modemSerial, modemVccPin, modemResetPin, wifiId,
492 wifiPwd);
493// Create an extra reference to the modem by a generic name
494EspressifESP32 modem = modemESP;
495/** End [espressif_esp32] */
496// ==========================================================================
497
498
499#elif defined(BUILD_MODEM_QUECTEL_BG96)
500/** Start [quectel_bg96] */
501// For the Dragino, Nimbelink or other boards based on the Quectel BG96
502#include <modems/QuectelBG96.h>
503
504// NOTE: Extra hardware and software serial ports are created in the "Settings
505// for Additional Serial Ports" section
506const int32_t modemBaud = 115200; // Communication speed of the modem
507// NOTE: This baud rate too fast for an 8MHz board, like the Mayfly! The
508// module should be programmed to a slower baud rate or set to auto-baud using
509// the AT+IPR=9600 command.
510
511// Modem Pins - Describe the physical pin connection of your modem to your board
512// NOTE: Use -1 for pins that do not apply
513// Example pins here are for a Mayfly 1.x and a Dragino IoT Bee
514const int8_t modemVccPin = 18; // MCU pin controlling modem power
515const int8_t modemStatusPin = -1; // MCU pin used to read modem status
516const int8_t modemResetPin = A5; // MCU pin connected to modem reset pin
517const int8_t modemSleepRqPin = -1; // MCU pin for modem sleep/wake request
518const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
519 // status
520
521// Network connection information
522const char* apn = "xxxxx"; // APN for GPRS connection
523
524// Create the modem object
525QuectelBG96 modemBG96(&modemSerial, modemVccPin, modemStatusPin, modemResetPin,
526 modemSleepRqPin, apn);
527// Create an extra reference to the modem by a generic name
528QuectelBG96 modem = modemBG96;
529/** End [quectel_bg96] */
530// ==========================================================================
531
532
533#elif defined(BUILD_MODEM_SEQUANS_MONARCH)
534/** Start [sequans_monarch] */
535// For the Nimbelink LTE-M Verizon/Sequans or other boards based on the Sequans
536// Monarch series
537#include <modems/SequansMonarch.h>
538
539// NOTE: Extra hardware and software serial ports are created in the "Settings
540// for Additional Serial Ports" section
541const int32_t modemBaud = 921600; // Default baud rate of SVZM20 is 921600
542// NOTE: This baud rate is much too fast for many Arduinos! The module should
543// be programmed to a slower baud rate or set to auto-baud using the AT+IPR
544// command.
545
546// Modem Pins - Describe the physical pin connection of your modem to your board
547// NOTE: Use -1 for pins that do not apply
548// Nimbelink Skywire (NOT directly connectable to a Mayfly!)
549const int8_t modemVccPin = 18; // MCU pin controlling modem power
550const int8_t modemStatusPin = 19; // MCU pin used to read modem status
551const int8_t modemResetPin = 20; // MCU pin connected to modem reset pin
552const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
553const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
554 // status
555
556// Network connection information
557const char* apn = "xxxxx"; // APN for GPRS connection
558
559// Create the modem object
560SequansMonarch modemSVZM(&modemSerial, modemVccPin, modemStatusPin,
561 modemResetPin, modemSleepRqPin, apn);
562// Create an extra reference to the modem by a generic name
563SequansMonarch modem = modemSVZM;
564/** End [sequans_monarch] */
565// ==========================================================================
566
567
568#elif defined(BUILD_MODEM_SIM_COM_SIM800)
569/** Start [sim_com_sim800] */
570// For almost anything based on the SIMCom SIM800 EXCEPT the Sodaq 2GBee R6 and
571// higher
572#include <modems/SIMComSIM800.h>
573
574// NOTE: Extra hardware and software serial ports are created in the "Settings
575// for Additional Serial Ports" section
576const int32_t modemBaud = 9600; // SIM800 does auto-bauding by default
577
578// Modem Pins - Describe the physical pin connection of your modem to your board
579// NOTE: Use -1 for pins that do not apply
580// Example pins are for a Sodaq GPRSBee R4 with a Mayfly 0.x
581const int8_t modemVccPin = -1; // MCU pin controlling modem power
582const int8_t modemStatusPin = 19; // MCU pin used to read modem status
583const int8_t modemResetPin = -1; // MCU pin connected to modem reset pin
584const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
585const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
586 // status
587
588// Network connection information
589const char* apn = "xxxxx"; // APN for GPRS connection
590
591// Create the modem object
592SIMComSIM800 modemS800(&modemSerial, modemVccPin, modemStatusPin, modemResetPin,
593 modemSleepRqPin, apn);
594// Create an extra reference to the modem by a generic name
595SIMComSIM800 modem = modemS800;
596/** End [sim_com_sim800] */
597// ==========================================================================
598
599
600#elif defined(BUILD_MODEM_SIM_COM_SIM7000)
601/** Start [sim_com_sim7000] */
602// For almost anything based on the SIMCom SIM7000
603#include <modems/SIMComSIM7000.h>
604
605// NOTE: Extra hardware and software serial ports are created in the "Settings
606// for Additional Serial Ports" section
607const int32_t modemBaud = 9600; // SIM7000 does auto-bauding by default
608
609// Modem Pins - Describe the physical pin connection of your modem to your board
610// NOTE: Use -1 for pins that do not apply
611const int8_t modemVccPin = 18; // MCU pin controlling modem power
612const int8_t modemStatusPin = 19; // MCU pin used to read modem status
613const int8_t modemResetPin = A5; // MCU pin connected to modem reset pin
614const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
615const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
616 // status
617
618// Network connection information
619const char* apn = "xxxxx"; // APN for GPRS connection
620
621// Create the modem object
622SIMComSIM7000 modem7000(&modemSerial, modemVccPin, modemStatusPin,
623 modemResetPin, modemSleepRqPin, apn);
624// Create an extra reference to the modem by a generic name
625SIMComSIM7000 modem = modem7000;
626/** End [sim_com_sim7000] */
627// ==========================================================================
628
629
630#elif defined(BUILD_MODEM_SIM_COM_SIM7080)
631/** Start [sim_com_sim7080] */
632// For almost anything based on the SIMCom SIM7080G
633#include <modems/SIMComSIM7080.h>
634
635// NOTE: Extra hardware and software serial ports are created in the "Settings
636// for Additional Serial Ports" section
637const int32_t modemBaud =
638 9600; // SIM7080 does auto-bauding by default, but I set mine to 9600
639
640// Modem Pins - Describe the physical pin connection of your modem to your board
641// NOTE: Use -1 for pins that do not apply
642// and-global breakout bk-7080a
643const int8_t modemVccPin = 18; // MCU pin controlling modem power
644const int8_t modemStatusPin = 19; // MCU pin used to read modem status
645const int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake request
646const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
647 // status
648
649// Network connection information
650const char* apn = "xxxxx"; // APN for GPRS connection
651
652// Create the modem object
653SIMComSIM7080 modem7080(&modemSerial, modemVccPin, modemStatusPin,
654 modemSleepRqPin, apn);
655// Create an extra reference to the modem by a generic name
656SIMComSIM7080 modem = modem7080;
657/** End [sim_com_sim7080] */
658// ==========================================================================
659
660
661#elif defined(BUILD_MODEM_SODAQ_2G_BEE_R6)
662/** Start [sodaq_2g_bee_r6] */
663// For the Sodaq 2GBee R6 and R7 based on the SIMCom SIM800
664// NOTE: The Sodaq GPRSBee doesn't expose the SIM800's reset pin
665#include <modems/Sodaq2GBeeR6.h>
666
667// NOTE: Extra hardware and software serial ports are created in the "Settings
668// for Additional Serial Ports" section
669const int32_t modemBaud = 9600; // SIM800 does auto-bauding by default
670
671// Modem Pins - Describe the physical pin connection of your modem to your board
672// NOTE: Use -1 for pins that do not apply
673// Example pins are for a Sodaq GPRSBee R6 or R7 with a Mayfly 0.x
674const int8_t modemVccPin = 23; // MCU pin controlling modem power
675const int8_t modemStatusPin = 19; // MCU pin used to read modem status
676const int8_t modemResetPin = -1; // MCU pin connected to modem reset pin
677const int8_t modemSleepRqPin = -1; // MCU pin for modem sleep/wake request
678const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
679 // status
680
681// Network connection information
682const char* apn = "xxxxx"; // APN for GPRS connection
683
684// Create the modem object
685Sodaq2GBeeR6 modem2GB(&modemSerial, modemVccPin, modemStatusPin, apn);
686// Create an extra reference to the modem by a generic name
687Sodaq2GBeeR6 modem = modem2GB;
688/** End [sodaq_2g_bee_r6] */
689// ==========================================================================
690
691
692#elif defined(BUILD_MODEM_SODAQ_UBEE_R410M)
693/** Start [sodaq_ubee_r410m] */
694// For the Sodaq UBee based on the 4G LTE-M u-blox SARA R410M
695#include <modems/SodaqUBeeR410M.h>
696
697// NOTE: Extra hardware and software serial ports are created in the "Settings
698// for Additional Serial Ports" section
699const int32_t modemBaud =
700 115200; // Default baud rate of the SARA R410M is 115200
701// NOTE: The SARA R410N DOES NOT save baud rate to non-volatile memory. After
702// every power loss, the module will return to the default baud rate of 115200.
703// NOTE: 115200 is TOO FAST for an 8MHz Arduino. This library attempts to
704// compensate by sending a baud rate change command in the wake function when
705// compiled for a 8MHz board. Because of this, 8MHz boards, LIKE THE MAYFLY,
706// *MUST* use a HardwareSerial instance as modemSerial.
707
708// Modem Pins - Describe the physical pin connection of your modem to your board
709// NOTE: Use -1 for pins that do not apply
710// Example pins are for a Sodaq uBee R410M with a Mayfly 0.x
711const int8_t modemVccPin = 23; // MCU pin controlling modem power
712const int8_t modemStatusPin = 19; // MCU pin used to read modem status
713const int8_t modemResetPin = -1; // MCU pin connected to modem reset pin
714const int8_t modemSleepRqPin = 20; // MCU pin for modem sleep/wake request
715const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
716 // status
717
718// Network connection information
719const char* apn = "xxxxx"; // APN for GPRS connection
720
721// Create the modem object
722SodaqUBeeR410M modemR410(&modemSerial, modemVccPin, modemStatusPin,
723 modemResetPin, modemSleepRqPin, apn);
724// Create an extra reference to the modem by a generic name
725SodaqUBeeR410M modem = modemR410;
726/** End [sodaq_ubee_r410m] */
727// ==========================================================================
728
729
730#elif defined(BUILD_MODEM_SODAQ_UBEE_U201)
731/** Start [sodaq_ubee_u201] */
732// For the Sodaq UBee based on the 3G u-blox SARA U201
733#include <modems/SodaqUBeeU201.h>
734
735// NOTE: Extra hardware and software serial ports are created in the "Settings
736// for Additional Serial Ports" section
737const int32_t modemBaud =
738 9600; // SARA U2xx module does auto-bauding by default
739
740// Modem Pins - Describe the physical pin connection of your modem to your board
741// NOTE: Use -1 for pins that do not apply
742// Example pins are for a Sodaq uBee U201 with a Mayfly 0.x
743const int8_t modemVccPin = 23; // MCU pin controlling modem power
744const int8_t modemStatusPin = 19; // MCU pin used to read modem status
745const int8_t modemResetPin = -1; // MCU pin connected to modem reset pin
746const int8_t modemSleepRqPin = 20; // MCU pin for modem sleep/wake request
747const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem
748 // status
749
750// Network connection information
751const char* apn = "xxxxx"; // APN for GPRS connection
752
753// Create the modem object
754SodaqUBeeU201 modemU201(&modemSerial, modemVccPin, modemStatusPin,
755 modemResetPin, modemSleepRqPin, apn);
756// Create an extra reference to the modem by a generic name
757SodaqUBeeU201 modem = modemU201;
758/** End [sodaq_ubee_u201] */
759// ==========================================================================
760#endif
761
762
763/** Start [modem_variables] */
764// Create RSSI and signal strength variable pointers for the modem
765Variable* modemRSSI =
766 new Modem_RSSI(&modem, "12345678-abcd-1234-ef00-1234567890ab", "RSSI");
767Variable* modemSignalPct = new Modem_SignalPercent(
768 &modem, "12345678-abcd-1234-ef00-1234567890ab", "signalPercent");
769Variable* modemBatteryState = new Modem_BatteryState(
770 &modem, "12345678-abcd-1234-ef00-1234567890ab", "modemBatteryCS");
771Variable* modemBatteryPct = new Modem_BatteryPercent(
772 &modem, "12345678-abcd-1234-ef00-1234567890ab", "modemBatteryPct");
773Variable* modemBatteryVoltage = new Modem_BatteryVoltage(
774 &modem, "12345678-abcd-1234-ef00-1234567890ab", "modemBatterymV");
775Variable* modemTemperature =
776 new Modem_Temp(&modem, "12345678-abcd-1234-ef00-1234567890ab", "modemTemp");
777/** End [modem_variables] */
778
779
780// ==========================================================================
781// Using the Processor as a Sensor
782// ==========================================================================
783/** Start [processor_stats] */
784#include <sensors/ProcessorStats.h>
785
786// Create the main processor chip "sensor" - for general metadata
787const char* mcuBoardVersion = "v1.1";
788ProcessorStats mcuBoard(mcuBoardVersion);
789
790// Create sample number, battery voltage, and free RAM variable pointers for the
791// processor
792Variable* mcuBoardBatt = new ProcessorStats_Battery(
793 &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab");
794Variable* mcuBoardAvailableRAM = new ProcessorStats_FreeRam(
795 &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab");
796Variable* mcuBoardSampNo = new ProcessorStats_SampleNumber(
797 &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab");
798/** End [processor_stats] */
799
800
801#if defined(ARDUINO_ARCH_AVR) || defined(MS_SAMD_DS3231)
802// ==========================================================================
803// Maxim DS3231 RTC (Real Time Clock)
804// ==========================================================================
805/** Start [maxim_ds3231] */
806#include <sensors/MaximDS3231.h>
807
808// Create a DS3231 sensor object
809MaximDS3231 ds3231(1);
810
811// Create a temperature variable pointer for the DS3231
812Variable* ds3231Temp =
813 new MaximDS3231_Temp(&ds3231, "12345678-abcd-1234-ef00-1234567890ab");
814/** End [maxim_ds3231] */
815#endif
816
817
818#if defined(BUILD_SENSOR_ALPHASENSE_CO2)
819// ==========================================================================
820// Alphasense CO2 Sensor
821// ==========================================================================
822/** Start [alphasense_co2] */
823#include <sensors/AlphasenseCO2.h>
824
825// NOTE: Use -1 for any pins that don't apply or aren't being used.
826const int8_t AlphasenseCO2Power = sensorPowerPin; // Power pin
827aco2_adsDiffMux_t AlphasenseDiffMux = DIFF_MUX_2_3; // Differential voltage config
828const uint8_t AlphasenseCO2ADSi2c_addr =
829 0x48; // The I2C address of the ADS1115 ADC
830
831// Create an Alphasense CO2 sensor object
832AlphasenseCO2 alphasenseCO2(AlphasenseCO2Power, AlphasenseDiffMux,AlphasenseCO2ADSi2c_addr);
833
834// Create PAR and raw voltage variable pointers for the CO2
835Variable* asCO2 = new AlphasenseCO2_CO2(&alphasenseCO2,
836 "12345678-abcd-1234-ef00-1234567890ab");
837Variable* asco2voltage = new AlphasenseCO2_Voltage(
838 &alphasenseCO2, "12345678-abcd-1234-ef00-1234567890ab");
839/** End [alphasense_co2] */
840#endif
841
842
843#if defined(BUILD_SENSOR_AO_SONG_AM2315)
844// ==========================================================================
845// AOSong AM2315 Digital Humidity and Temperature Sensor
846// ==========================================================================
847/** Start [ao_song_am2315] */
848#include <sensors/AOSongAM2315.h>
849
850// NOTE: Use -1 for any pins that don't apply or aren't being used.
851const int8_t AM2315Power = sensorPowerPin; // Power pin
852
853// Create an AOSong AM2315 sensor object
854AOSongAM2315 am2315(AM2315Power);
855
856// Create humidity and temperature variable pointers for the AM2315
857Variable* am2315Humid =
858 new AOSongAM2315_Humidity(&am2315, "12345678-abcd-1234-ef00-1234567890ab");
859Variable* am2315Temp =
860 new AOSongAM2315_Temp(&am2315, "12345678-abcd-1234-ef00-1234567890ab");
861/** End [ao_song_am2315] */
862#endif
863
864
865#if defined(BUILD_SENSOR_AO_SONG_DHT)
866// ==========================================================================
867// AOSong DHT 11/21 (AM2301)/22 (AM2302) Digital Humidity and Temperature
868// ==========================================================================
869/** Start [ao_song_dht] */
870#include <sensors/AOSongDHT.h>
871
872// NOTE: Use -1 for any pins that don't apply or aren't being used.
873const int8_t DHTPower = sensorPowerPin; // Power pin
874const int8_t DHTPin = 10; // DHT data pin
875const int8_t dhtType =
876 DHT11; // DHT type, one of DHT11, DHT12, DHT21, DHT22, or AM2301
877
878// Create an AOSong DHT sensor object
879AOSongDHT dht(DHTPower, DHTPin, dhtType);
880
881// Create humidity, temperature, and heat index variable pointers for the DHT
882Variable* dhtHumid =
883 new AOSongDHT_Humidity(&dht, "12345678-abcd-1234-ef00-1234567890ab");
884Variable* dhtTemp = new AOSongDHT_Temp(&dht,
885 "12345678-abcd-1234-ef00-1234567890ab");
886Variable* dhtHI = new AOSongDHT_HI(&dht,
887 "12345678-abcd-1234-ef00-1234567890ab");
888/** End [ao_song_dht] */
889#endif
890
891
892#if defined(BUILD_SENSOR_APOGEE_SQ212)
893// ==========================================================================
894// Apogee SQ-212 Photosynthetically Active Radiation (PAR) Sensor
895// ==========================================================================
896/** Start [apogee_sq212] */
897#include <sensors/ApogeeSQ212.h>
898
899// NOTE: Use -1 for any pins that don't apply or aren't being used.
900const int8_t SQ212Power = sensorPowerPin; // Power pin
901const int8_t SQ212ADSChannel = 3; // The ADS channel for the SQ212
902const uint8_t SQ212ADSi2c_addr = 0x48; // The I2C address of the ADS1115 ADC
903
904// Create an Apogee SQ212 sensor object
905ApogeeSQ212 SQ212(SQ212Power, SQ212ADSChannel, SQ212ADSi2c_addr);
906
907// Create PAR and raw voltage variable pointers for the SQ212
908Variable* sq212PAR =
909 new ApogeeSQ212_PAR(&SQ212, "12345678-abcd-1234-ef00-1234567890ab");
910Variable* sq212voltage =
911 new ApogeeSQ212_Voltage(&SQ212, "12345678-abcd-1234-ef00-1234567890ab");
912/** End [apogee_sq212] */
913#endif
914
915
916#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_CO2)
917// ==========================================================================
918// Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor
919// ==========================================================================
920/** Start [atlas_scientific_co2] */
921#include <sensors/AtlasScientificCO2.h>
922
923// NOTE: Use -1 for any pins that don't apply or aren't being used.
924const int8_t AtlasCO2Power = sensorPowerPin; // Power pin
925uint8_t AtlasCO2i2c_addr = 0x69; // Default for CO2-EZO is 0x69 (105)
926// All Atlas sensors have different default I2C addresses, but any of them can
927// be re-addressed to any 8 bit number. If using the default address for any
928// Atlas Scientific sensor, you may omit this argument.
929
930// Create an Atlas Scientific CO2 sensor object
931// AtlasScientificCO2 atlasCO2(AtlasCO2Power, AtlasCO2i2c_addr);
932AtlasScientificCO2 atlasCO2(AtlasCO2Power);
933
934// Create concentration and temperature variable pointers for the EZO-CO2
935Variable* atlasCO2CO2 = new AtlasScientificCO2_CO2(
936 &atlasCO2, "12345678-abcd-1234-ef00-1234567890ab");
937Variable* atlasCO2Temp = new AtlasScientificCO2_Temp(
938 &atlasCO2, "12345678-abcd-1234-ef00-1234567890ab");
939/** End [atlas_scientific_co2] */
940#endif
941
942
943#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_DO)
944// ==========================================================================
945// Atlas Scientific EZO-DO Dissolved Oxygen Sensor
946// ==========================================================================
947/** Start [atlas_scientific_do] */
948#include <sensors/AtlasScientificDO.h>
949
950// NOTE: Use -1 for any pins that don't apply or aren't being used.
951const int8_t AtlasDOPower = sensorPowerPin; // Power pin
952uint8_t AtlasDOi2c_addr = 0x61; // Default for DO is 0x61 (97)
953// All Atlas sensors have different default I2C addresses, but any of them can
954// be re-addressed to any 8 bit number. If using the default address for any
955// Atlas Scientific sensor, you may omit this argument.
956
957// Create an Atlas Scientific DO sensor object
958// AtlasScientificDO atlasDO(AtlasDOPower, AtlasDOi2c_addr);
959AtlasScientificDO atlasDO(AtlasDOPower);
960
961// Create concentration and percent saturation variable pointers for the EZO-DO
962Variable* atlasDOconc = new AtlasScientificDO_DOmgL(
963 &atlasDO, "12345678-abcd-1234-ef00-1234567890ab");
964Variable* atlasDOpct = new AtlasScientificDO_DOpct(
965 &atlasDO, "12345678-abcd-1234-ef00-1234567890ab");
966/** End [atlas_scientific_do] */
967#endif
968
969
970#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_ORP)
971// ==========================================================================
972// Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor
973// ==========================================================================
974/** Start [atlas_scientific_orp] */
975#include <sensors/AtlasScientificORP.h>
976
977// NOTE: Use -1 for any pins that don't apply or aren't being used.
978const int8_t AtlasORPPower = sensorPowerPin; // Power pin
979uint8_t AtlasORPi2c_addr = 0x62; // Default for ORP is 0x62 (98)
980// All Atlas sensors have different default I2C addresses, but any of them can
981// be re-addressed to any 8 bit number. If using the default address for any
982// Atlas Scientific sensor, you may omit this argument.
983
984// Create an Atlas Scientific ORP sensor object
985// AtlasScientificORP atlasORP(AtlasORPPower, AtlasORPi2c_addr);
986AtlasScientificORP atlasORP(AtlasORPPower);
987
988// Create a potential variable pointer for the ORP
989Variable* atlasORPot = new AtlasScientificORP_Potential(
990 &atlasORP, "12345678-abcd-1234-ef00-1234567890ab");
991/** End [atlas_scientific_orp] */
992#endif
993
994
995#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_PH)
996// ==========================================================================
997// Atlas Scientific EZO-pH Sensor
998// ==========================================================================
999/** Start [atlas_scientific_ph] */
1000#include <sensors/AtlasScientificpH.h>
1001
1002// NOTE: Use -1 for any pins that don't apply or aren't being used.
1003const int8_t AtlaspHPower = sensorPowerPin; // Power pin
1004uint8_t AtlaspHi2c_addr = 0x63; // Default for pH is 0x63 (99)
1005// All Atlas sensors have different default I2C addresses, but any of them can
1006// be re-addressed to any 8 bit number. If using the default address for any
1007// Atlas Scientific sensor, you may omit this argument.
1008
1009// Create an Atlas Scientific pH sensor object
1010// AtlasScientificpH atlaspH(AtlaspHPower, AtlaspHi2c_addr);
1011AtlasScientificpH atlaspH(AtlaspHPower);
1012
1013// Create a pH variable pointer for the pH sensor
1014Variable* atlaspHpH =
1015 new AtlasScientificpH_pH(&atlaspH, "12345678-abcd-1234-ef00-1234567890ab");
1016/** End [atlas_scientific_ph] */
1017#endif
1018
1019
1020#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_RTD) || \
1021 defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_EC)
1022// ==========================================================================
1023// Atlas Scientific EZO-RTD Temperature Sensor
1024// ==========================================================================
1025/** Start [atlas_scientific_rtd] */
1026#include <sensors/AtlasScientificRTD.h>
1027
1028// NOTE: Use -1 for any pins that don't apply or aren't being used.
1029const int8_t AtlasRTDPower = sensorPowerPin; // Power pin
1030uint8_t AtlasRTDi2c_addr = 0x66; // Default for RTD is 0x66 (102)
1031// All Atlas sensors have different default I2C addresses, but any of them can
1032// be re-addressed to any 8 bit number. If using the default address for any
1033// Atlas Scientific sensor, you may omit this argument.
1034
1035// Create an Atlas Scientific RTD sensor object
1036// AtlasScientificRTD atlasRTD(AtlasRTDPower, AtlasRTDi2c_addr);
1037AtlasScientificRTD atlasRTD(AtlasRTDPower);
1038
1039// Create a temperature variable pointer for the RTD
1040Variable* atlasTemp = new AtlasScientificRTD_Temp(
1041 &atlasRTD, "12345678-abcd-1234-ef00-1234567890ab");
1042/** End [atlas_scientific_rtd] */
1043#endif
1044
1045
1046#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_EC)
1047// ==========================================================================
1048// Atlas Scientific EZO-EC Conductivity Sensor
1049// ==========================================================================
1050/** Start [atlas_scientific_ec] */
1051#include <sensors/AtlasScientificEC.h>
1052
1053// NOTE: Use -1 for any pins that don't apply or aren't being used.
1054const int8_t AtlasECPower = sensorPowerPin; // Power pin
1055uint8_t AtlasECi2c_addr = 0x64; // Default for EC is 0x64 (100)
1056// All Atlas sensors have different default I2C addresses, but any of them can
1057// be re-addressed to any 8 bit number. If using the default address for any
1058// Atlas Scientific sensor, you may omit this argument.
1059
1060// Create an Atlas Scientific Conductivity sensor object
1061// AtlasScientificEC atlasEC(AtlasECPower, AtlasECi2c_addr);
1062AtlasScientificEC atlasEC(AtlasECPower);
1063
1064// Create four variable pointers for the EZO-ES
1065Variable* atlasCond = new AtlasScientificEC_Cond(
1066 &atlasEC, "12345678-abcd-1234-ef00-1234567890ab");
1067Variable* atlasTDS =
1068 new AtlasScientificEC_TDS(&atlasEC, "12345678-abcd-1234-ef00-1234567890ab");
1069Variable* atlasSal = new AtlasScientificEC_Salinity(
1070 &atlasEC, "12345678-abcd-1234-ef00-1234567890ab");
1071Variable* atlasGrav = new AtlasScientificEC_SpecificGravity(
1072 &atlasEC, "12345678-abcd-1234-ef00-1234567890ab");
1073
1074// Create a calculated variable for the temperature compensated conductivity
1075// (that is, the specific conductance). For this example, we will use the
1076// temperature measured by the Atlas RTD above this. You could use the
1077// temperature returned by any other water temperature sensor if desired.
1078// **DO NOT** use your logger board temperature (ie, from the DS3231) to
1079// calculate specific conductance!
1080float calculateAtlasSpCond(void) {
1081 float spCond = -9999; // Always safest to start with a bad value
1082 float waterTemp = atlasTemp->getValue();
1083 float rawCond = atlasCond->getValue();
1084 // ^^ Linearized temperature correction coefficient per degrees Celsius.
1085 // The value of 0.019 comes from measurements reported here:
1086 // Hayashi M. Temperature-electrical conductivity relation of water for
1087 // environmental monitoring and geophysical data inversion. Environ Monit
1088 // Assess. 2004 Aug-Sep;96(1-3):119-28.
1089 // doi: 10.1023/b:emas.0000031719.83065.68. PMID: 15327152.
1090 if (waterTemp != -9999 && rawCond != -9999) {
1091 // make sure both inputs are good
1092 float temperatureCoef = 0.019;
1093 spCond = rawCond / (1 + temperatureCoef * (waterTemp - 25.0));
1094 }
1095 return spCond;
1096}
1097
1098// Properties of the calculated variable
1099// The number of digits after the decimal place
1100const uint8_t atlasSpCondResolution = 0;
1101// This must be a value from http://vocabulary.odm2.org/variablename/
1102const char* atlasSpCondName = "specificConductance";
1103// This must be a value from http://vocabulary.odm2.org/units/
1104const char* atlasSpCondUnit = "microsiemenPerCentimeter";
1105// A short code for the variable
1106const char* atlasSpCondCode = "atlasSpCond";
1107// The (optional) universallly unique identifier
1108const char* atlasSpCondUUID = "12345678-abcd-1234-ef00-1234567890ab";
1109
1110// Finally, create the specific conductance variable and return a pointer to it
1111Variable* atlasSpCond =
1112 new Variable(calculateAtlasSpCond, atlasSpCondResolution, atlasSpCondName,
1113 atlasSpCondUnit, atlasSpCondCode, atlasSpCondUUID);
1114/** End [atlas_scientific_ec] */
1115#endif
1116
1117
1118#if defined(BUILD_SENSOR_BOSCH_BME280)
1119// ==========================================================================
1120// Bosch BME280 Environmental Sensor
1121// ==========================================================================
1122/** Start [bosch_bme280] */
1123#include <sensors/BoschBME280.h>
1124
1125// NOTE: Use -1 for any pins that don't apply or aren't being used.
1126const int8_t BME280Power = sensorPowerPin; // Power pin
1127uint8_t BMEi2c_addr = 0x76;
1128// The BME280 can be addressed either as 0x77 (Adafruit default) or 0x76 (Grove
1129// default) Either can be physically mofidied for the other address
1130
1131// Create a Bosch BME280 sensor object
1132BoschBME280 bme280(BME280Power, BMEi2c_addr);
1133
1134// Create four variable pointers for the BME280
1135Variable* bme280Humid =
1136 new BoschBME280_Humidity(&bme280, "12345678-abcd-1234-ef00-1234567890ab");
1137Variable* bme280Temp =
1138 new BoschBME280_Temp(&bme280, "12345678-abcd-1234-ef00-1234567890ab");
1139Variable* bme280Press =
1140 new BoschBME280_Pressure(&bme280, "12345678-abcd-1234-ef00-1234567890ab");
1141Variable* bme280Alt =
1142 new BoschBME280_Altitude(&bme280, "12345678-abcd-1234-ef00-1234567890ab");
1143/** End [bosch_bme280] */
1144#endif
1145
1146
1147#if defined(BUILD_SENSOR_BOSCH_BMP3XX)
1148// ==========================================================================
1149// Bosch BMP 3xx Barometric Pressure Sensor
1150// ==========================================================================
1151/** Start [bosch_bmp3xx] */
1152#include <sensors/BoschBMP3xx.h>
1153
1154// NOTE: Use -1 for any pins that don't apply or aren't being used.
1155const int8_t bmp3xxPower = -1; // Power pin
1156Mode bmpMode = FORCED_MODE; // The operating mode of the BMP; normal or forced
1157Oversampling bmpPressureOversample = OVERSAMPLING_X32;
1158Oversampling bmpTempOversample = OVERSAMPLING_X2;
1159IIRFilter bmpFilterCoeff = IIR_FILTER_OFF;
1160TimeStandby bmpTimeStandby = TIME_STANDBY_5MS;
1161uint8_t bmpI2C_addr = 0x77;
1162// The BMP3xx can be addressed either as 0x77 or 0x76
1163
1164// Create a Bosch BMP3xx sensor object
1165BoschBMP3xx bmp3xx(bmp3xxPower, bmpMode, bmpPressureOversample,
1166 bmpTempOversample, bmpFilterCoeff, bmpTimeStandby,
1167 bmpI2C_addr);
1168
1169// Create the variable pointers for the BMP3xx
1170Variable* bmp3xxTemp =
1171 new BoschBMP3xx_Temp(&bmp3xx, "12345678-abcd-1234-ef00-1234567890ab");
1172Variable* bmp3xxPress =
1173 new BoschBMP3xx_Pressure(&bmp3xx, "12345678-abcd-1234-ef00-1234567890ab");
1174Variable* bmp3xxAlt =
1175 new BoschBMP3xx_Altitude(&bmp3xx, "12345678-abcd-1234-ef00-1234567890ab");
1176/** End [bosch_bmp3xx] */
1177#endif
1178
1179
1180#if defined(BUILD_SENSOR_CAMPBELL_CLARI_VUE10)
1181// ==========================================================================
1182// Campbell ClariVUE Turbidity Sensor
1183// ==========================================================================
1184/** Start [campbell_clari_vue10] */
1185#include <sensors/CampbellClariVUE10.h>
1186
1187// NOTE: Use -1 for any pins that don't apply or aren't being used.
1188const char* ClariVUESDI12address = "0"; // The SDI-12 Address of the ClariVUE10
1189const int8_t ClariVUEPower = sensorPowerPin; // Power pin
1190const int8_t ClariVUEData = 7; // The SDI-12 data pin
1191// NOTE: you should NOT take more than one readings. THe sensor already takes
1192// and averages 8 by default.
1193
1194// Create a Campbell ClariVUE10 sensor object
1195CampbellClariVUE10 clarivue(*ClariVUESDI12address, ClariVUEPower, ClariVUEData);
1196
1197// Create turbidity, temperature, and error variable pointers for the ClariVUE10
1198Variable* clarivueTurbidity = new CampbellClariVUE10_Turbidity(
1199 &clarivue, "12345678-abcd-1234-ef00-1234567890ab");
1200Variable* clarivueTemp = new CampbellClariVUE10_Temp(
1201 &clarivue, "12345678-abcd-1234-ef00-1234567890ab");
1202Variable* clarivueError = new CampbellClariVUE10_ErrorCode(
1203 &clarivue, "12345678-abcd-1234-ef00-1234567890ab");
1204/** End [campbell_clari_vue10] */
1205#endif
1206
1207
1208#if defined(BUILD_SENSOR_CAMPBELL_OBS3)
1209// ==========================================================================
1210// Campbell OBS 3 / OBS 3+ Analog Turbidity Sensor
1211// ==========================================================================
1212/** Start [campbell_obs3] */
1213#include <sensors/CampbellOBS3.h>
1214
1215// NOTE: Use -1 for any pins that don't apply or aren't being used.
1216const int8_t OBS3Power = sensorPowerPin; // Power pin
1217const uint8_t OBS3NumberReadings = 10;
1218const uint8_t OBS3ADSi2c_addr = 0x48; // The I2C address of the ADS1115 ADC
1219
1220const int8_t OBSLowADSChannel = 0; // ADS channel for *low* range output
1221
1222// Campbell OBS 3+ *Low* Range Calibration in Volts
1223const float OBSLow_A = 0.000E+00; // "A" value (X^2) [*low* range]
1224const float OBSLow_B = 1.000E+00; // "B" value (X) [*low* range]
1225const float OBSLow_C = 0.000E+00; // "C" value [*low* range]
1226
1227// Create a Campbell OBS3+ *low* range sensor object
1228CampbellOBS3 osb3low(OBS3Power, OBSLowADSChannel, OBSLow_A, OBSLow_B, OBSLow_C,
1229 OBS3ADSi2c_addr, OBS3NumberReadings);
1230
1231// Create turbidity and voltage variable pointers for the low range of the OBS3
1232Variable* obs3TurbLow = new CampbellOBS3_Turbidity(
1233 &osb3low, "12345678-abcd-1234-ef00-1234567890ab", "TurbLow");
1234Variable* obs3VoltLow = new CampbellOBS3_Voltage(
1235 &osb3low, "12345678-abcd-1234-ef00-1234567890ab", "TurbLowV");
1236
1237
1238const int8_t OBSHighADSChannel = 1; // ADS channel for *high* range output
1239
1240// Campbell OBS 3+ *High* Range Calibration in Volts
1241const float OBSHigh_A = 0.000E+00; // "A" value (X^2) [*high* range]
1242const float OBSHigh_B = 1.000E+00; // "B" value (X) [*high* range]
1243const float OBSHigh_C = 0.000E+00; // "C" value [*high* range]
1244
1245// Create a Campbell OBS3+ *high* range sensor object
1246CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B,
1247 OBSHigh_C, OBS3ADSi2c_addr, OBS3NumberReadings);
1248
1249// Create turbidity and voltage variable pointers for the high range of the OBS3
1250Variable* obs3TurbHigh = new CampbellOBS3_Turbidity(
1251 &osb3high, "12345678-abcd-1234-ef00-1234567890ab", "TurbHigh");
1252Variable* obs3VoltHigh = new CampbellOBS3_Voltage(
1253 &osb3high, "12345678-abcd-1234-ef00-1234567890ab", "TurbHighV");
1254/** End [campbell_obs3] */
1255#endif
1256
1257#if defined(BUILD_SENSOR_CAMPBELL_RAIN_VUE10)
1258// ==========================================================================
1259// Campbell RainVUE Precipitation Sensor
1260// ==========================================================================
1261/** Start [campbell_rain_vue10] */
1262#include <sensors/CampbellRainVUE10.h>
1263
1264// NOTE: Use -1 for any pins that don't apply or aren't being used.
1265const char* RainVUESDI12address = "0"; // The SDI-12 Address of the RainVUE10
1266const int8_t RainVUEPower = -1; // Power pin, for continous power
1267const int8_t RainVUEData = 5; // The SDI-12 data pin, for continuous power
1268// NOTE: you should NOT take more than one readings. THe sensor counts
1269// cummulative tips and rain accumulation since the last measurement.
1270
1271// Create a Campbell RainVUE10 sensor object
1272CampbellRainVUE10 rainvue(*RainVUESDI12address, RainVUEPower, RainVUEData);
1273
1274// Create turbidity, temperature, and error variable pointers for the RainVUE10
1275Variable* rainvuePrecipitation = new CampbellRainVUE10_Precipitation(
1276 &rainvue, "12345678-abcd-1234-ef00-1234567890ab");
1277Variable* rainvueTips = new CampbellRainVUE10_Tips(
1278 &rainvue, "12345678-abcd-1234-ef00-1234567890ab");
1279Variable* rainvueRainRateAve = new CampbellRainVUE10_RainRateAve(
1280 &rainvue, "12345678-abcd-1234-ef00-1234567890ab");
1281Variable* rainvueRainRateMax = new CampbellRainVUE10_RainRateMax(
1282 &rainvue, "12345678-abcd-1234-ef00-1234567890ab");
1283/** End [campbell_rain_vue10] */
1284#endif
1285
1286
1287#if defined(BUILD_SENSOR_DECAGON_CTD)
1288// ==========================================================================
1289// Decagon CTD-10 Conductivity, Temperature, and Depth Sensor
1290// ==========================================================================
1291/** Start [decagon_ctd] */
1292#include <sensors/DecagonCTD.h>
1293
1294// NOTE: Use -1 for any pins that don't apply or aren't being used.
1295const char* CTDSDI12address = "1"; // The SDI-12 Address of the CTD
1296const uint8_t CTDNumberReadings = 6; // The number of readings to average
1297const int8_t CTDPower = sensorPowerPin; // Power pin
1298const int8_t CTDData = 7; // The SDI-12 data pin
1299
1300// Create a Decagon CTD sensor object
1301DecagonCTD ctd(*CTDSDI12address, CTDPower, CTDData, CTDNumberReadings);
1302
1303// Create conductivity, temperature, and depth variable pointers for the CTD
1304Variable* ctdCond = new DecagonCTD_Cond(&ctd,
1305 "12345678-abcd-1234-ef00-1234567890ab");
1306Variable* ctdTemp = new DecagonCTD_Temp(&ctd,
1307 "12345678-abcd-1234-ef00-1234567890ab");
1308Variable* ctdDepth =
1309 new DecagonCTD_Depth(&ctd, "12345678-abcd-1234-ef00-1234567890ab");
1310/** End [decagon_ctd] */
1311#endif
1312
1313
1314#if defined(BUILD_SENSOR_DECAGON_ES2)
1315// ==========================================================================
1316// Decagon ES2 Conductivity and Temperature Sensor
1317// ==========================================================================
1318/** Start [decagon_es2] */
1319#include <sensors/DecagonES2.h>
1320
1321// NOTE: Use -1 for any pins that don't apply or aren't being used.
1322const char* ES2SDI12address = "3"; // The SDI-12 Address of the ES2
1323const int8_t ES2Power = sensorPowerPin; // Power pin
1324const int8_t ES2Data = 7; // The SDI-12 data pin
1325const uint8_t ES2NumberReadings = 5;
1326
1327// Create a Decagon ES2 sensor object
1328DecagonES2 es2(*ES2SDI12address, ES2Power, ES2Data, ES2NumberReadings);
1329
1330// Create specific conductance and temperature variable pointers for the ES2
1331Variable* es2Cond = new DecagonES2_Cond(&es2,
1332 "12345678-abcd-1234-ef00-1234567890ab");
1333Variable* es2Temp = new DecagonES2_Temp(&es2,
1334 "12345678-abcd-1234-ef00-1234567890ab");
1335/** End [decagon_es2] */
1336#endif
1337
1338
1339#if defined(BUILD_SENSOR_EVERLIGHT_ALSPT19)
1340// ==========================================================================
1341// Everlight ALS-PT19 Ambient Light Sensor
1342// ==========================================================================
1343/** Start [everlight_alspt19] */
1344#include <sensors/EverlightALSPT19.h>
1345
1346// NOTE: Use -1 for any pins that don't apply or aren't being used.
1347const int8_t alsPower = sensorPowerPin; // Power pin
1348const int8_t alsData = A4; // The ALS PT-19 data pin
1349const int8_t alsSupply = 3.3; // The ALS PT-19 supply power voltage
1350const int8_t alsResistance = 10; // The ALS PT-19 loading resistance (in kΩ)
1351const uint8_t alsNumberReadings = 10;
1352
1353// Create a Everlight ALS-PT19 sensor object
1354EverlightALSPT19 alsPt19(alsPower, alsData, alsSupply, alsResistance,
1355 alsNumberReadings);
1356
1357// For an EnviroDIY Mayfly, you can use the abbreviated version
1358// EverlightALSPT19 alsPt19(alsNumberReadings);
1359
1360// Create voltage, current, and illuminance variable pointers for the ALS-PT19
1361Variable* alsPt19Volt = new EverlightALSPT19_Voltage(
1362 &alsPt19, "12345678-abcd-1234-ef00-1234567890ab");
1363Variable* alsPt19Current = new EverlightALSPT19_Current(
1364 &alsPt19, "12345678-abcd-1234-ef00-1234567890ab");
1365Variable* alsPt19Lux = new EverlightALSPT19_Illuminance(
1366 &alsPt19, "12345678-abcd-1234-ef00-1234567890ab");
1367/** End [everlight_alspt19] */
1368#endif
1369
1370
1371#if defined(BUILD_SENSOR_TIADS1X15)
1372// ==========================================================================
1373// External Voltage via TI ADS1115
1374// ==========================================================================
1375/** Start [tiads1x15] */
1376#include <sensors/TIADS1x15.h>
1377
1378// NOTE: Use -1 for any pins that don't apply or aren't being used.
1379const int8_t ADSPower = sensorPowerPin; // Power pin
1380const int8_t ADSChannel = 2; // The ADS channel of interest
1381const float dividerGain = 10; // Gain setting if using a voltage divider
1382const uint8_t evADSi2c_addr = 0x48; // The I2C address of the ADS1115 ADC
1383const uint8_t VoltReadsToAvg = 1; // Only read one sample
1384
1385// Create an External Voltage sensor object
1386TIADS1x15 ads1x15(ADSPower, ADSChannel, dividerGain, evADSi2c_addr,
1387 VoltReadsToAvg);
1388
1389// Create a voltage variable pointer
1390Variable* ads1x15Volt =
1391 new TIADS1x15_Voltage(&ads1x15, "12345678-abcd-1234-ef00-1234567890ab");
1392/** End [tiads1x15] */
1393#endif
1394
1395
1396#if defined(BUILD_SENSOR_FREESCALE_MPL115A2)
1397// ==========================================================================
1398// Freescale Semiconductor MPL115A2 Barometer
1399// ==========================================================================
1400/** Start [freescale_mpl115a2] */
1401#include <sensors/FreescaleMPL115A2.h>
1402
1403// NOTE: Use -1 for any pins that don't apply or aren't being used.
1404const int8_t MPLPower = sensorPowerPin; // Power pin
1405const uint8_t MPL115A2ReadingsToAvg = 1;
1406
1407// Create a FreescaleMPL115A2 barometer sensor object
1408FreescaleMPL115A2 mpl115a2(MPLPower, MPL115A2ReadingsToAvg);
1409
1410// Create pressure and temperature variable pointers for the MPL
1411Variable* mplPress = new FreescaleMPL115A2_Pressure(
1412 &mpl115a2, "12345678-abcd-1234-ef00-1234567890ab");
1413Variable* mplTemp = new FreescaleMPL115A2_Temp(
1414 &mpl115a2, "12345678-abcd-1234-ef00-1234567890ab");
1415/** End [freescale_mpl115a2] */
1416#endif
1417
1418#if defined(BUILD_SENSOR_GRO_POINT_GPLP8)
1419// ==========================================================================
1420// GroPoint Profile GPLP-8 Soil Moisture and Temperature Sensor
1421// ==========================================================================
1422/** Start [gro_point_gplp8] */
1423#include <sensors/GroPointGPLP8.h>
1424
1425// NOTE: Extra hardware and software serial ports are created in the "Settings
1426// for Additional Serial Ports" section
1427
1428// NOTE: Use -1 for any pins that don't apply or aren't being used.
1429byte gplp8ModbusAddress = 0x19; // The modbus address of the gplp8
1430// Raw Request >>> {0x19, 0x03, 0x00, 0xC8, 0x00, 0x01, 0x06, 0x2C}
1431const int8_t gplp8AdapterPower = sensorPowerPin; // RS485 adapter power pin
1432const int8_t gplp8SensorPower = A3; // Sensor power pin
1433const int8_t gplp8EnablePin = -1; // Adapter RE/DE pin
1434const uint8_t gplp8NumberReadings = 1;
1435// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
1436// power consumption
1437
1438// Create a GroPoint Profile GPLP-8 sensor object
1439GroPointGPLP8 gplp8(gplp8ModbusAddress, modbusSerial, gplp8AdapterPower,
1440 gplp8SensorPower, gplp8EnablePin, gplp8NumberReadings);
1441
1442// Create moisture variable pointers for each segment of the GPLP-8
1443Variable* gplp8Moist1 = new GroPointGPLP8_Moist(
1444 &gplp8, 0, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist1");
1445Variable* gplp8Moist2 = new GroPointGPLP8_Moist(
1446 &gplp8, 1, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist2");
1447Variable* gplp8Moist3 = new GroPointGPLP8_Moist(
1448 &gplp8, 2, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist3");
1449Variable* gplp8Moist4 = new GroPointGPLP8_Moist(
1450 &gplp8, 3, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist4");
1451Variable* gplp8Moist5 = new GroPointGPLP8_Moist(
1452 &gplp8, 4, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist5");
1453Variable* gplp8Moist6 = new GroPointGPLP8_Moist(
1454 &gplp8, 5, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist6");
1455Variable* gplp8Moist7 = new GroPointGPLP8_Moist(
1456 &gplp8, 6, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist7");
1457Variable* gplp8Moist8 = new GroPointGPLP8_Moist(
1458 &gplp8, 7, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Moist8");
1459
1460// Create temperature variable pointers for each sensor of the GPLP-8
1461Variable* gplp8Temp1 = new GroPointGPLP8_Temp(
1462 &gplp8, 8, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp1");
1463Variable* gplp8Temp2 = new GroPointGPLP8_Temp(
1464 &gplp8, 9, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp1");
1465Variable* gplp8Temp3 = new GroPointGPLP8_Temp(
1466 &gplp8, 10, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp3");
1467Variable* gplp8Temp4 = new GroPointGPLP8_Temp(
1468 &gplp8, 11, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp4");
1469Variable* gplp8Temp5 = new GroPointGPLP8_Temp(
1470 &gplp8, 12, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp5");
1471Variable* gplp8Temp6 = new GroPointGPLP8_Temp(
1472 &gplp8, 13, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp6");
1473Variable* gplp8Temp7 = new GroPointGPLP8_Temp(
1474 &gplp8, 14, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp7");
1475Variable* gplp8Temp8 = new GroPointGPLP8_Temp(
1476 &gplp8, 15, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp8");
1477Variable* gplp8Temp9 = new GroPointGPLP8_Temp(
1478 &gplp8, 16, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp9");
1479Variable* gplp8Temp10 = new GroPointGPLP8_Temp(
1480 &gplp8, 17, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp10");
1481Variable* gplp8Temp11 = new GroPointGPLP8_Temp(
1482 &gplp8, 18, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp11");
1483Variable* gplp8Temp12 = new GroPointGPLP8_Temp(
1484 &gplp8, 19, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp12");
1485Variable* gplp8Temp13 = new GroPointGPLP8_Temp(
1486 &gplp8, 20, "12345678-abcd-1234-ef00-1234567890ab", "GPLP8Temp13");
1487/** End [gro_point_gplp8] */
1488#endif
1489
1490
1491#if defined(BUILD_SENSOR_IN_SITU_RDO)
1492// ==========================================================================
1493// In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe
1494// ==========================================================================
1495/** Start [in_situ_rdo] */
1496#include <sensors/InSituRDO.h>
1497
1498// NOTE: Use -1 for any pins that don't apply or aren't being used.
1499const char* RDOSDI12address = "5"; // The SDI-12 Address of the RDO PRO-X
1500const int8_t RDOPower = sensorPowerPin; // Power pin
1501const int8_t RDOData = 7; // The SDI-12 data pin
1502const uint8_t RDONumberReadings = 3;
1503
1504// Create an In-Situ RDO PRO-X dissolved oxygen sensor object
1505InSituRDO insituRDO(*RDOSDI12address, RDOPower, RDOData, RDONumberReadings);
1506
1507// Create dissolved oxygen percent, dissolved oxygen concentration, temperature,
1508// and oxygen partial pressure variable pointers for the RDO PRO-X
1509Variable* rdoDOpct =
1510 new InSituRDO_DOpct(&insituRDO, "12345678-abcd-1234-ef00-1234567890ab");
1511Variable* rdoDOmgL =
1512 new InSituRDO_DOmgL(&insituRDO, "12345678-abcd-1234-ef00-1234567890ab");
1513Variable* rdoTemp = new InSituRDO_Temp(&insituRDO,
1514 "12345678-abcd-1234-ef00-1234567890ab");
1515Variable* rdoO2pp =
1516 new InSituRDO_Pressure(&insituRDO, "12345678-abcd-1234-ef00-1234567890ab");
1517/** End [in_situ_rdo] */
1518#endif
1519
1520
1521#if defined(BUILD_SENSOR_IN_SITU_TROLL_SDI12A)
1522// ==========================================================================
1523// In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor
1524// ==========================================================================
1525/** Start [in_situ_troll_sdi12a] */
1526#include <sensors/InSituTrollSdi12a.h>
1527
1528// NOTE: Use -1 for any pins that don't apply or aren't being used.
1529const char* TROLLSDI12address =
1530 "1"; // The SDI-12 Address of the Aqua/Level TROLL
1531const int8_t TROLLPower =
1532 sensorPowerPin; // Pin to switch power on and off (-1 if unconnected)
1533const int8_t TROLLData = 7; // The SDI-12 data pin
1534const uint8_t TROLLNumberReadings = 2; // The number of readings to average
1535
1536// Create an In-Situ TROLL sensor object
1537InSituTrollSdi12a insituTROLL(*TROLLSDI12address, TROLLPower, TROLLData,
1538 TROLLNumberReadings);
1539
1540// Create pressure, temperature, and depth variable pointers for the TROLL
1541Variable* trollPressure = new InSituTrollSdi12a_Pressure(
1542 &insituTROLL, "12345678-abcd-1234-ef00-1234567890ab");
1543Variable* trollTemp = new InSituTrollSdi12a_Temp(
1544 &insituTROLL, "12345678-abcd-1234-ef00-1234567890ab");
1545Variable* trollDepth = new InSituTrollSdi12a_Depth(
1546 &insituTROLL, "12345678-abcd-1234-ef00-1234567890ab");
1547/** End [in_situ_troll_sdi12a] */
1548#endif
1549
1550
1551#if defined(BUILD_SENSOR_KELLER_ACCULEVEL)
1552// ==========================================================================
1553// Keller Acculevel High Accuracy Submersible Level Transmitter
1554// ==========================================================================
1555/** Start [keller_acculevel] */
1556#include <sensors/KellerAcculevel.h>
1557
1558// NOTE: Extra hardware and software serial ports are created in the "Settings
1559// for Additional Serial Ports" section
1560
1561// NOTE: Use -1 for any pins that don't apply or aren't being used.
1562byte acculevelModbusAddress = 0x01; // The modbus address of KellerAcculevel
1563const int8_t acculevelPower = A3; // Acculevel Sensor power pin
1564const int8_t alAdapterPower = sensorPowerPin; // RS485 adapter power pin
1565const int8_t al485EnablePin = -1; // Adapter RE/DE pin
1566const uint8_t acculevelNumberReadings = 5;
1567// The manufacturer recommends taking and averaging a few readings
1568
1569// Create a Keller Acculevel sensor object
1570KellerAcculevel acculevel(acculevelModbusAddress, modbusSerial, alAdapterPower,
1571 acculevelPower, al485EnablePin,
1572 acculevelNumberReadings);
1573
1574// Create pressure, temperature, and height variable pointers for the Acculevel
1575Variable* acculevPress = new KellerAcculevel_Pressure(
1576 &acculevel, "12345678-abcd-1234-ef00-1234567890ab");
1577Variable* acculevTemp = new KellerAcculevel_Temp(
1578 &acculevel, "12345678-abcd-1234-ef00-1234567890ab");
1579Variable* acculevHeight = new KellerAcculevel_Height(
1580 &acculevel, "12345678-abcd-1234-ef00-1234567890ab");
1581/** End [keller_acculevel] */
1582#endif
1583
1584
1585#if defined(BUILD_SENSOR_KELLER_NANOLEVEL)
1586// ==========================================================================
1587// Keller Nanolevel High Accuracy Submersible Level Transmitter
1588// ==========================================================================
1589/** Start [keller_nanolevel] */
1590#include <sensors/KellerNanolevel.h>
1591
1592// NOTE: Extra hardware and software serial ports are created in the "Settings
1593// for Additional Serial Ports" section
1594
1595// NOTE: Use -1 for any pins that don't apply or aren't being used.
1596byte nanolevelModbusAddress = 0x01; // The modbus address of KellerNanolevel
1597const int8_t nlAdapterPower = sensorPowerPin; // RS485 adapter power pin
1598const int8_t nanolevelPower = A3; // Sensor power pin
1599const int8_t nl485EnablePin = -1; // Adapter RE/DE pin
1600const uint8_t nanolevelNumberReadings = 5;
1601// The manufacturer recommends taking and averaging a few readings
1602
1603// Create a Keller Nanolevel sensor object
1604KellerNanolevel nanolevel(nanolevelModbusAddress, modbusSerial, nlAdapterPower,
1605 nanolevelPower, nl485EnablePin,
1606 nanolevelNumberReadings);
1607
1608// Create pressure, temperature, and height variable pointers for the Nanolevel
1609Variable* nanolevPress = new KellerNanolevel_Pressure(
1610 &nanolevel, "12345678-abcd-1234-ef00-1234567890ab");
1611Variable* nanolevTemp = new KellerNanolevel_Temp(
1612 &nanolevel, "12345678-abcd-1234-ef00-1234567890ab");
1613Variable* nanolevHeight = new KellerNanolevel_Height(
1614 &nanolevel, "12345678-abcd-1234-ef00-1234567890ab");
1615/** End [keller_nanolevel] */
1616#endif
1617
1618
1619#if defined(BUILD_SENSOR_MAX_BOTIX_SONAR)
1620// ==========================================================================
1621// Maxbotix HRXL Ultrasonic Range Finder
1622// ==========================================================================
1623/** Start [max_botix_sonar] */
1624#include <sensors/MaxBotixSonar.h>
1625
1626// A Maxbotix sonar with the trigger pin disconnect CANNOT share the serial port
1627// A Maxbotix sonar using the trigger may be able to share but YMMV
1628
1629// NOTE: Extra hardware and software serial ports are created in the "Settings
1630// for Additional Serial Ports" section
1631
1632// NOTE: Use -1 for any pins that don't apply or aren't being used.
1633const int8_t SonarPower = sensorPowerPin; // Excite (power) pin
1634const int8_t Sonar1Trigger = -1; // Trigger pin
1635// Trigger should be a *unique* negative number if unconnected
1636const int16_t Sonar1MaxRange = 9999; // Maximum range of sonar
1637const uint8_t sonar1NumberReadings = 3; // The number of readings to average
1638
1639// Create a MaxBotix Sonar sensor object
1640MaxBotixSonar sonar1(sonarSerial, SonarPower, Sonar1Trigger, Sonar1MaxRange,
1641 sonar1NumberReadings);
1642
1643// Create an ultrasonic range variable pointer
1644Variable* sonar1Range =
1645 new MaxBotixSonar_Range(&sonar1, "12345678-abcd-1234-ef00-1234567890ab");
1646/** End [max_botix_sonar] */
1647#endif
1648
1649
1650#if defined(BUILD_SENSOR_MAXIM_DS18) || \
1651 defined(BUILD_SENSOR_ANALOG_ELEC_CONDUCTIVITY)
1652// ==========================================================================
1653// Maxim DS18 One Wire Temperature Sensor
1654// ==========================================================================
1655/** Start [maxim_ds18] */
1656#include <sensors/MaximDS18.h>
1657
1658// OneWire Address [array of 8 hex characters]
1659// If only using a single sensor on the OneWire bus, you may omit the address
1660DeviceAddress OneWireAddress1 = {0x28, 0xFF, 0xBD, 0xBA,
1661 0x81, 0x16, 0x03, 0x0C};
1662// NOTE: Use -1 for any pins that don't apply or aren't being used.
1663const int8_t OneWirePower = sensorPowerPin; // Power pin
1664const int8_t OneWireBus = A0; // OneWire Bus Pin
1665const int8_t ds18NumberReadings = 3;
1666
1667// Create a Maxim DS18 sensor objects (use this form for a known address)
1668MaximDS18 ds18(OneWireAddress1, OneWirePower, OneWireBus, ds18NumberReadings);
1669
1670// Create a Maxim DS18 sensor object (use this form for a single sensor on bus
1671// with an unknown address)
1672// MaximDS18 ds18(OneWirePower, OneWireBus);
1673
1674// Create a temperature variable pointer for the DS18
1675Variable* ds18Temp = new MaximDS18_Temp(&ds18,
1676 "12345678-abcd-1234-ef00-1234567890ab");
1677/** End [maxim_ds18] */
1678#endif
1679
1680
1681#if defined(BUILD_SENSOR_MEA_SPEC_MS5803)
1682// ==========================================================================
1683// Measurement Specialties MS5803-14BA pressure sensor
1684// ==========================================================================
1685/** Start [mea_spec_ms5803] */
1686#include <sensors/MeaSpecMS5803.h>
1687
1688// NOTE: Use -1 for any pins that don't apply or aren't being used.
1689const int8_t MS5803Power = sensorPowerPin; // Power pin
1690const uint8_t MS5803i2c_addr =
1691 0x76; // The MS5803 can be addressed either as 0x76 (default) or 0x77
1692const int16_t MS5803maxPressure =
1693 14; // The maximum pressure measurable by the specific MS5803 model
1694const uint8_t MS5803ReadingsToAvg = 1;
1695
1696// Create a MeaSpec MS5803 pressure and temperature sensor object
1697MeaSpecMS5803 ms5803(MS5803Power, MS5803i2c_addr, MS5803maxPressure,
1698 MS5803ReadingsToAvg);
1699
1700// Create pressure and temperature variable pointers for the MS5803
1701Variable* ms5803Press =
1702 new MeaSpecMS5803_Pressure(&ms5803, "12345678-abcd-1234-ef00-1234567890ab");
1703Variable* ms5803Temp =
1704 new MeaSpecMS5803_Temp(&ms5803, "12345678-abcd-1234-ef00-1234567890ab");
1705/** End [mea_spec_ms5803] */
1706#endif
1707
1708
1709#if defined(BUILD_SENSOR_DECAGON_5TM)
1710// ==========================================================================
1711// Meter ECH2O Soil Moisture Sensor
1712// ==========================================================================
1713/** Start [decagon_5tm] */
1714#include <sensors/Decagon5TM.h>
1715
1716// NOTE: Use -1 for any pins that don't apply or aren't being used.
1717const char* TMSDI12address = "2"; // The SDI-12 Address of the 5-TM
1718const int8_t TMPower = sensorPowerPin; // Power pin
1719const int8_t TMData = 7; // The SDI-12 data pin
1720
1721// Create a Decagon 5TM sensor object
1722Decagon5TM fivetm(*TMSDI12address, TMPower, TMData);
1723
1724// Create the matric potential, volumetric water content, and temperature
1725// variable pointers for the 5TM
1726Variable* fivetmEa = new Decagon5TM_Ea(&fivetm,
1727 "12345678-abcd-1234-ef00-1234567890ab");
1728Variable* fivetmVWC =
1729 new Decagon5TM_VWC(&fivetm, "12345678-abcd-1234-ef00-1234567890ab");
1730Variable* fivetmTemp =
1731 new Decagon5TM_Temp(&fivetm, "12345678-abcd-1234-ef00-1234567890ab");
1732/** End [decagon_5tm] */
1733#endif
1734
1735
1736#if defined(BUILD_SENSOR_METER_HYDROS21)
1737// ==========================================================================
1738// Meter Hydros 21 Conductivity, Temperature, and Depth Sensor
1739// ==========================================================================
1740/** Start [meter_hydros21] */
1741#include <sensors/MeterHydros21.h>
1742
1743// NOTE: Use -1 for any pins that don't apply or aren't being used.
1744const char* hydros21SDI12address = "1"; // The SDI-12 Address of the Hydros21
1745const uint8_t hydros21NumberReadings = 6; // The number of readings to average
1746const int8_t hydros21Power = sensorPowerPin; // Power pin
1747const int8_t hydros21Data = 7; // The SDI-12 data pin
1748
1749// Create a Decagon Hydros21 sensor object
1750MeterHydros21 hydros21(*hydros21SDI12address, hydros21Power, hydros21Data,
1751 hydros21NumberReadings);
1752
1753// Create conductivity, temperature, and depth variable pointers for the
1754// Hydros21
1755Variable* hydros21Cond =
1756 new MeterHydros21_Cond(&hydros21, "12345678-abcd-1234-ef00-1234567890ab");
1757Variable* hydros21Temp =
1758 new MeterHydros21_Temp(&hydros21, "12345678-abcd-1234-ef00-1234567890ab");
1759Variable* hydros21Depth =
1760 new MeterHydros21_Depth(&hydros21, "12345678-abcd-1234-ef00-1234567890ab");
1761/** End [meter_hydros21] */
1762#endif
1763
1764
1765#if defined(BUILD_SENSOR_METER_TEROS11)
1766// ==========================================================================
1767// Meter Teros 11 Soil Moisture Sensor
1768// ==========================================================================
1769/** Start [meter_teros11] */
1770#include <sensors/MeterTeros11.h>
1771
1772// NOTE: Use -1 for any pins that don't apply or aren't being used.
1773const char* teros11SDI12address = "4"; // The SDI-12 Address of the Teros 11
1774const int8_t terosPower = sensorPowerPin; // Power pin
1775const int8_t terosData = 7; // The SDI-12 data pin
1776const uint8_t teros11NumberReadings = 3; // The number of readings to average
1777
1778// Create a METER TEROS 11 sensor object
1779MeterTeros11 teros11(*teros11SDI12address, terosPower, terosData,
1780 teros11NumberReadings);
1781
1782// Create the matric potential, volumetric water content, and temperature
1783// variable pointers for the Teros 11
1784Variable* teros11Ea =
1785 new MeterTeros11_Ea(&teros11, "12345678-abcd-1234-ef00-1234567890ab");
1786Variable* teros11Temp =
1787 new MeterTeros11_Temp(&teros11, "12345678-abcd-1234-ef00-1234567890ab");
1788Variable* teros11VWC =
1789 new MeterTeros11_VWC(&teros11, "12345678-abcd-1234-ef00-1234567890ab");
1790Variable* teros11Count =
1791 new MeterTeros11_Count(&teros11, "12345678-abcd-1234-ef00-1234567890ab");
1792/** End [meter_teros11] */
1793#endif
1794
1795
1796#if defined(BUILD_SENSOR_PALEO_TERRA_REDOX)
1797// ==========================================================================
1798// PaleoTerra Redox Sensors
1799// ==========================================================================
1800/** Start [paleo_terra_redox] */
1801#include <sensors/PaleoTerraRedox.h>
1802
1803// NOTE: Use -1 for any pins that don't apply or aren't being used.
1804int8_t paleoTerraPower = sensorPowerPin; // Power pin
1805uint8_t paleoI2CAddress = 0x68; // the I2C address of the redox sensor
1806
1807// Create the PaleoTerra sensor object
1808#ifdef MS_PALEOTERRA_SOFTWAREWIRE
1809PaleoTerraRedox ptRedox(&softI2C, paleoTerraPower, paleoI2CAddress);
1810// PaleoTerraRedox ptRedox(paleoTerraPower, softwareSDA, softwareSCL,
1811// paleoI2CAddress);
1812#else
1813PaleoTerraRedox ptRedox(paleoTerraPower, paleoI2CAddress);
1814#endif
1815
1816// Create the voltage variable for the redox sensor
1817Variable* ptVolt = new PaleoTerraRedox_Voltage(
1818 &ptRedox, "12345678-abcd-1234-ef00-1234567890ab");
1819/** End [paleo_terra_redox] */
1820#endif
1821
1822
1823#if defined(BUILD_SENSOR_RAIN_COUNTER_I2C)
1824// ==========================================================================
1825// External I2C Rain Tipping Bucket Counter
1826// ==========================================================================
1827/** Start [rain_counter_i2c] */
1828#include <sensors/RainCounterI2C.h>
1829
1830const uint8_t RainCounterI2CAddress = 0x08;
1831// I2C Address for EnviroDIY external tip counter; 0x08 by default
1832const float depthPerTipEvent = 0.2; // rain depth in mm per tip event
1833
1834// Create a Rain Counter sensor object
1835#ifdef MS_RAIN_SOFTWAREWIRE
1836RainCounterI2C tbi2c(&softI2C, RainCounterI2CAddress, depthPerTipEvent);
1837// RainCounterI2C tbi2c(softwareSDA, softwareSCL, RainCounterI2CAddress,
1838// depthPerTipEvent);
1839#else
1840RainCounterI2C tbi2c(RainCounterI2CAddress, depthPerTipEvent);
1841#endif
1842
1843// Create number of tips and rain depth variable pointers for the tipping bucket
1844Variable* tbi2cTips =
1845 new RainCounterI2C_Tips(&tbi2c, "12345678-abcd-1234-ef00-1234567890ab");
1846Variable* tbi2cDepth =
1847 new RainCounterI2C_Depth(&tbi2c, "12345678-abcd-1234-ef00-1234567890ab");
1848/** End [rain_counter_i2c] */
1849#endif
1850
1851
1852#if defined(BUILD_SENSOR_SENSIRION_SHT4X)
1853// ==========================================================================
1854// Sensirion SHT4X Digital Humidity and Temperature Sensor
1855// ==========================================================================
1856/** Start [sensirion_sht4x] */
1857#include <sensors/SensirionSHT4x.h>
1858
1859// NOTE: Use -1 for any pins that don't apply or aren't being used.
1860const int8_t SHT4xPower = sensorPowerPin; // Power pin
1861const bool SHT4xUseHeater = true;
1862
1863// Create an Sensirion SHT4X sensor object
1864SensirionSHT4x sht4x(SHT4xPower, SHT4xUseHeater);
1865
1866// Create humidity and temperature variable pointers for the SHT4X
1867Variable* sht4xHumid =
1868 new SensirionSHT4x_Humidity(&sht4x, "12345678-abcd-1234-ef00-1234567890ab");
1869Variable* sht4xTemp =
1870 new SensirionSHT4x_Temp(&sht4x, "12345678-abcd-1234-ef00-1234567890ab");
1871/** End [sensirion_sht4x] */
1872#endif
1873
1874
1875#if defined(BUILD_SENSOR_TALLY_COUNTER_I2C)
1876// ==========================================================================
1877// Tally I2C Event Counter for rain or wind reed-switch sensors
1878// ==========================================================================
1879/** Start [tally_counter_i2c] */
1880#include <sensors/TallyCounterI2C.h>
1881
1882const int8_t TallyPower = -1; // Power pin (-1 if continuously powered)
1883// NorthernWidget Tally I2CPower is -1 by default because it is often deployed
1884// with power always on, but Tally also has a super capacitor that enables it
1885// to be self powered between readings/recharge as described at
1886// https://github.com/EnviroDIY/Project-Tally
1887
1888const uint8_t TallyCounterI2CAddress = 0x33;
1889// NorthernWidget Tally I2C address is 0x33 by default
1890
1891// Create a Tally Counter sensor object
1892TallyCounterI2C tallyi2c(TallyPower, TallyCounterI2CAddress);
1893
1894// Create variable pointers for the Tally event counter
1895Variable* tallyEvents = new TallyCounterI2C_Events(
1896 &tallyi2c, "12345678-abcd-1234-ef00-1234567890ab");
1897
1898// For Wind Speed, create a Calculated Variable that converts, similar to:
1899// period = loggingInterval * 60.0; // in seconds
1900// frequency = tallyEventCount/period; // average event frequency in Hz
1901// tallyWindSpeed = frequency * 2.5 * 1.60934; // in km/h
1902// 2.5 mph/Hz & 1.60934 kmph/mph and 2.5 mph/Hz conversion factor from
1903// web: Inspeed-Version-II-Reed-Switch-Anemometer-Sensor-Only-WS2R
1904/** End [tally_counter_i2c] */
1905#endif
1906
1907
1908#if defined(BUILD_SENSOR_TI_INA219)
1909// ==========================================================================
1910// TI INA219 High Side Current/Voltage Sensor (Current mA, Voltage, Power)
1911// ==========================================================================
1912/** Start [ti_ina219] */
1913#include <sensors/TIINA219.h>
1914
1915// NOTE: Use -1 for any pins that don't apply or aren't being used.
1916const int8_t INA219Power = sensorPowerPin; // Power pin
1917uint8_t INA219i2c_addr = 0x40; // 1000000 (Board A0+A1=GND)
1918// The INA219 can have one of 16 addresses, depending on the connections of A0
1919// and A1
1920const uint8_t INA219ReadingsToAvg = 1;
1921
1922// Create an INA219 sensor object
1923TIINA219 ina219(INA219Power, INA219i2c_addr, INA219ReadingsToAvg);
1924
1925// Create current, voltage, and power variable pointers for the INA219
1926Variable* inaCurrent =
1927 new TIINA219_Current(&ina219, "12345678-abcd-1234-ef00-1234567890ab");
1928Variable* inaVolt =
1929 new TIINA219_Voltage(&ina219, "12345678-abcd-1234-ef00-1234567890ab");
1930Variable* inaPower = new TIINA219_Power(&ina219,
1931 "12345678-abcd-1234-ef00-1234567890ab");
1932/** End [ti_ina219] */
1933#endif
1934
1935
1936#if defined(BUILD_SENSOR_TURNER_CYCLOPS)
1937// ==========================================================================
1938// Turner Cyclops-7F Submersible Fluorometer
1939// ==========================================================================
1940/** Start [turner_cyclops] */
1941#include <sensors/TurnerCyclops.h>
1942
1943// NOTE: Use -1 for any pins that don't apply or aren't being used.
1944const int8_t cyclopsPower = sensorPowerPin; // Power pin
1945const uint8_t cyclopsNumberReadings = 10;
1946const uint8_t cyclopsADSi2c_addr = 0x48; // The I2C address of the ADS1115 ADC
1947const int8_t cyclopsADSChannel = 0; // ADS channel
1948
1949// Cyclops calibration information
1950const float cyclopsStdConc = 1.000; // Concentration of the standard used
1951 // for a 1-point sensor calibration.
1952const float cyclopsStdVolt =
1953 1.000; // The voltage (in volts) measured for the conc_std.
1954const float cyclopsBlankVolt =
1955 0.000; // The voltage (in volts) measured for a blank.
1956
1957// Create a Turner Cyclops sensor object
1958TurnerCyclops cyclops(cyclopsPower, cyclopsADSChannel, cyclopsStdConc,
1959 cyclopsStdVolt, cyclopsBlankVolt, cyclopsADSi2c_addr,
1960 cyclopsNumberReadings);
1961
1962// Create the voltage variable pointer - used for any type of Cyclops
1963Variable* cyclopsVoltage =
1964 new TurnerCyclops_Voltage(&cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1965
1966// Create the variable pointer for the primary output parameter. Only use
1967// **ONE** of these! Which is possible depends on your specific sensor!
1968Variable* cyclopsChloro = new TurnerCyclops_Chlorophyll(
1969 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1970Variable* cyclopsRWT = new TurnerCyclops_Rhodamine(
1971 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1972Variable* cyclopsFluoroscein = new TurnerCyclops_Fluorescein(
1973 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1974Variable* cyclopsPhycocyanin = new TurnerCyclops_Phycocyanin(
1975 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1976Variable* cyclopsPhycoerythrin = new TurnerCyclops_Phycoerythrin(
1977 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1978Variable* cyclopsCDOM =
1979 new TurnerCyclops_CDOM(&cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1980Variable* cyclopsCrudeOil = new TurnerCyclops_CrudeOil(
1981 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1982Variable* cyclopsBrighteners = new TurnerCyclops_Brighteners(
1983 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1984Variable* cyclopsTurbidity = new TurnerCyclops_Turbidity(
1985 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1986Variable* cyclopsPTSA =
1987 new TurnerCyclops_PTSA(&cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1988Variable* cyclopsBTEX =
1989 new TurnerCyclops_BTEX(&cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1990Variable* cyclopsTryptophan = new TurnerCyclops_Tryptophan(
1991 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1992Variable* cyclopsRedChloro = new TurnerCyclops_RedChlorophyll(
1993 &cyclops, "12345678-abcd-1234-ef00-1234567890ab");
1994/** End [turner_cyclops] */
1995#endif
1996
1997
1998#if defined(BUILD_SENSOR_TURNER_TURBIDITY_PLUS)
1999// ==========================================================================
2000// Turner Turbidity Plus Turbidity Sensor
2001// ==========================================================================
2002/** Start [turner_turbidity_plus] */
2003#include <sensors/TurnerTurbidityPlus.h>
2004
2005// NOTE: Use -1 for any pins that don't apply or aren't being used.
2006const int8_t turbidityPlusPower = sensorPowerPin; // Power pin
2007const int8_t turbidityPlusWiper = A3; // Wiper pin
2008ttp_adsDiffMux_t turbidityPlusDiffMux = DIFF_MUX_2_3; // Differential voltage config
2009const uint8_t turbidityPlusNumberReadings = 10;
2010const uint8_t turbidityPlusADSi2c_addr = 0x48; // The I2C address of the ADS1115 ADC
2011adsGain_t turbidityPlusGain = GAIN_ONE;// The gain of the ADS
2012float tpVoltageDividerFactor = 1; // The factor for a voltage divider, if any
2013
2014// Turbidity Plus calibration information
2015const float turbidityPlusStdConc = 1.000; // Concentration of the standard used
2016 // for a 1-point sensor calibration.
2017const float turbidityPlusStdVolt =
2018 1.000; // The voltage (in volts) measured for the conc_std.
2019const float turbidityPlusBlankVolt =
2020 0.000; // The voltage (in volts) measured for a blank.
2021
2022// Create a Turner Turbidity Plus sensor object
2023TurnerTurbidityPlus turbidityPlus(turbidityPlusPower, turbidityPlusWiper, turbidityPlusDiffMux,turbidityPlusStdConc,
2024 turbidityPlusStdVolt, turbidityPlusBlankVolt, turbidityPlusADSi2c_addr,turbidityPlusGain,
2025 turbidityPlusNumberReadings,tpVoltageDividerFactor);
2026
2027// Create the variable pointers
2028Variable* turbidityPlusVoltage =
2029 new TurnerTurbidityPlus_Voltage(&turbidityPlus, "12345678-abcd-1234-ef00-1234567890ab");
2030Variable* turbidityPlusTurbidity = new TurnerTurbidityPlus_Turbidity(
2031 &turbidityPlus, "12345678-abcd-1234-ef00-1234567890ab");
2032/** End [turner_turbidity_plus] */
2033#endif
2034
2035
2036#if defined(BUILD_SENSOR_ANALOG_ELEC_CONDUCTIVITY)
2037// ==========================================================================
2038// Analog Electrical Conductivity using the Processor's Analog Pins
2039// ==========================================================================
2040/** Start [analog_elec_conductivity] */
2041#include <sensors/AnalogElecConductivity.h>
2042
2043const int8_t ECpwrPin = A4; // Power pin (-1 if continuously powered)
2044const int8_t ECdataPin1 = A0; // Data pin (must be an analog pin, ie A#)
2045
2046// Create an Analog Electrical Conductivity sensor object
2047AnalogElecConductivity analogEC_phy(ECpwrPin, ECdataPin1);
2048
2049// Create a conductivity variable pointer for the analog sensor
2050Variable* analogEc_cond = new AnalogElecConductivity_EC(
2051 &analogEC_phy, "12345678-abcd-1234-ef00-1234567890ab");
2052
2053// Create a calculated variable for the temperature compensated conductivity
2054// (that is, the specific conductance). For this example, we will use the
2055// temperature measured by the Maxim DS18 saved as ds18Temp several sections
2056// above this. You could use the temperature returned by any other water
2057// temperature sensor if desired. **DO NOT** use your logger board temperature
2058// (ie, from the DS3231) to calculate specific conductance!
2059float calculateAnalogSpCond(void) {
2060 float spCond = -9999; // Always safest to start with a bad value
2061 float waterTemp = ds18Temp->getValue();
2062 float rawCond = analogEc_cond->getValue();
2063 float temperatureCoef = 0.019;
2064 // ^^ Linearized temperature correction coefficient per degrees Celsius.
2065 // The value of 0.019 comes from measurements reported here:
2066 // Hayashi M. Temperature-electrical conductivity relation of water for
2067 // environmental monitoring and geophysical data inversion. Environ Monit
2068 // Assess. 2004 Aug-Sep;96(1-3):119-28.
2069 // doi: 10.1023/b:emas.0000031719.83065.68. PMID: 15327152.
2070 if (waterTemp != -9999 && rawCond != -9999) {
2071 // make sure both inputs are good
2072 spCond = rawCond / (1 + temperatureCoef * (waterTemp - 25.0));
2073 }
2074 return spCond;
2075}
2076
2077// Properties of the calculated variable
2078// The number of digits after the decimal place
2079const uint8_t analogSpCondResolution = 0;
2080// This must be a value from http://vocabulary.odm2.org/variablename/
2081const char* analogSpCondName = "specificConductance";
2082// This must be a value from http://vocabulary.odm2.org/units/
2083const char* analogSpCondUnit = "microsiemenPerCentimeter";
2084// A short code for the variable
2085const char* analogSpCondCode = "anlgSpCond";
2086// The (optional) universallly unique identifier
2087const char* analogSpCondUUID = "12345678-abcd-1234-ef00-1234567890ab";
2088
2089// Finally, Create the specific conductance variable and return a pointer to it
2090Variable* analogEc_spcond = new Variable(
2091 calculateAnalogSpCond, analogSpCondResolution, analogSpCondName,
2092 analogSpCondUnit, analogSpCondCode, analogSpCondUUID);
2093/** End [analog_elec_conductivity] */
2094#endif
2095
2096
2097#if defined(BUILD_SENSOR_VEGA_PULS21)
2098// ==========================================================================
2099// VEGA PULS 21 Radar Sensor
2100// ==========================================================================
2101/** Start [vega_puls21] */
2102#include <sensors/VegaPuls21.h>
2103
2104// NOTE: Use -1 for any pins that don't apply or aren't being used.
2105const char* VegaPulsSDI12address = "0"; // The SDI-12 Address of the VegaPuls10
2106const int8_t VegaPulsPower = sensorPowerPin; // Power pin
2107const int8_t VegaPulsData = 7; // The SDI-12 data pin
2108// NOTE: you should NOT take more than one readings. THe sensor already takes
2109// and averages 8 by default.
2110
2111// Create a Campbell VegaPusl21 sensor object
2112VegaPuls21 VegaPuls(*VegaPulsSDI12address, VegaPulsPower, VegaPulsData);
2113
2114// Create stage, distance, temperature, reliability, and error variable pointers
2115// for the VegaPuls21
2116Variable* VegaPulsStage =
2117 new VegaPuls21_Stage(&VegaPuls, "12345678-abcd-1234-ef00-1234567890ab");
2118Variable* VegaPulsDistance =
2119 new VegaPuls21_Distance(&VegaPuls, "12345678-abcd-1234-ef00-1234567890ab");
2120Variable* VegaPulsTemp =
2121 new VegaPuls21_Temp(&VegaPuls, "12345678-abcd-1234-ef00-1234567890ab");
2122Variable* VegaPulsRelia = new VegaPuls21_Reliability(
2123 &VegaPuls, "12345678-abcd-1234-ef00-1234567890ab");
2124Variable* VegaPulsError =
2125 new VegaPuls21_ErrorCode(&VegaPuls, "12345678-abcd-1234-ef00-1234567890ab");
2126/** End [vega_puls21] */
2127#endif
2128
2129
2130#if defined(BUILD_SENSOR_YOSEMITECH_Y504)
2131// ==========================================================================
2132// Yosemitech Y504 Dissolved Oxygen Sensor
2133// ==========================================================================
2134/** Start [yosemitech_y504] */
2135#include <sensors/YosemitechY504.h>
2136
2137// NOTE: Extra hardware and software serial ports are created in the "Settings
2138// for Additional Serial Ports" section
2139
2140// NOTE: Use -1 for any pins that don't apply or aren't being used.
2141byte y504ModbusAddress = 0x04; // The modbus address of the Y504
2142const int8_t y504AdapterPower = sensorPowerPin; // RS485 adapter power pin
2143const int8_t y504SensorPower = A3; // Sensor power pin
2144const int8_t y504EnablePin = -1; // Adapter RE/DE pin
2145const uint8_t y504NumberReadings = 5;
2146// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2147// power consumption
2148
2149// Create a Yosemitech Y504 dissolved oxygen sensor object
2150YosemitechY504 y504(y504ModbusAddress, modbusSerial, y504AdapterPower,
2151 y504SensorPower, y504EnablePin, y504NumberReadings);
2152
2153// Create the dissolved oxygen percent, dissolved oxygen concentration, and
2154// temperature variable pointers for the Y504
2155Variable* y504DOpct =
2156 new YosemitechY504_DOpct(&y504, "12345678-abcd-1234-ef00-1234567890ab");
2157Variable* y504DOmgL =
2158 new YosemitechY504_DOmgL(&y504, "12345678-abcd-1234-ef00-1234567890ab");
2159Variable* y504Temp =
2160 new YosemitechY504_Temp(&y504, "12345678-abcd-1234-ef00-1234567890ab");
2161/** End [yosemitech_y504] */
2162#endif
2163
2164
2165#if defined(BUILD_SENSOR_YOSEMITECH_Y510)
2166// ==========================================================================
2167// Yosemitech Y510 Turbidity Sensor
2168// ==========================================================================
2169/** Start [yosemitech_y510] */
2170#include <sensors/YosemitechY510.h>
2171
2172// NOTE: Extra hardware and software serial ports are created in the "Settings
2173// for Additional Serial Ports" section
2174
2175// NOTE: Use -1 for any pins that don't apply or aren't being used.
2176byte y510ModbusAddress = 0x0B; // The modbus address of the Y510
2177const int8_t y510AdapterPower = sensorPowerPin; // RS485 adapter power pin
2178const int8_t y510SensorPower = A3; // Sensor power pin
2179const int8_t y510EnablePin = -1; // Adapter RE/DE pin
2180const uint8_t y510NumberReadings = 5;
2181// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2182// power consumption
2183
2184// Create a Y510-B Turbidity sensor object
2185YosemitechY510 y510(y510ModbusAddress, modbusSerial, y510AdapterPower,
2186 y510SensorPower, y510EnablePin, y510NumberReadings);
2187
2188// Create turbidity and temperature variable pointers for the Y510
2189Variable* y510Turb =
2190 new YosemitechY510_Turbidity(&y510, "12345678-abcd-1234-ef00-1234567890ab");
2191Variable* y510Temp =
2192 new YosemitechY510_Temp(&y510, "12345678-abcd-1234-ef00-1234567890ab");
2193/** End [yosemitech_y510] */
2194#endif
2195
2196
2197#if defined(BUILD_SENSOR_YOSEMITECH_Y511)
2198// ==========================================================================
2199// Yosemitech Y511 Turbidity Sensor with Wiper
2200// ==========================================================================
2201/** Start [yosemitech_y511] */
2202#include <sensors/YosemitechY511.h>
2203
2204// NOTE: Extra hardware and software serial ports are created in the "Settings
2205// for Additional Serial Ports" section
2206
2207// NOTE: Use -1 for any pins that don't apply or aren't being used.
2208byte y511ModbusAddress = 0x1A; // The modbus address of the Y511
2209const int8_t y511AdapterPower = sensorPowerPin; // RS485 adapter power pin
2210const int8_t y511SensorPower = A3; // Sensor power pin
2211const int8_t y511EnablePin = -1; // Adapter RE/DE pin
2212const uint8_t y511NumberReadings = 5;
2213// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2214// power consumption
2215
2216// Create a Y511-A Turbidity sensor object
2217YosemitechY511 y511(y511ModbusAddress, modbusSerial, y511AdapterPower,
2218 y511SensorPower, y511EnablePin, y511NumberReadings);
2219
2220// Create turbidity and temperature variable pointers for the Y511
2221Variable* y511Turb =
2222 new YosemitechY511_Turbidity(&y511, "12345678-abcd-1234-ef00-1234567890ab");
2223Variable* y511Temp =
2224 new YosemitechY511_Temp(&y511, "12345678-abcd-1234-ef00-1234567890ab");
2225/** End [yosemitech_y511] */
2226#endif
2227
2228
2229#if defined(BUILD_SENSOR_YOSEMITECH_Y513)
2230// ==========================================================================
2231// Yosemitech Y513 Blue Green Algae (BGA) Sensor
2232// ==========================================================================
2233/** Start [yosemitech_y513] */
2234#include <sensors/YosemitechY513.h>
2235
2236// NOTE: Extra hardware and software serial ports are created in the "Settings
2237// for Additional Serial Ports" section
2238
2239// NOTE: Use -1 for any pins that don't apply or aren't being used.
2240byte y513ModbusAddress = 0x13; // The modbus address of the Y513
2241const int8_t y513AdapterPower = sensorPowerPin; // RS485 adapter power pin
2242const int8_t y513SensorPower = A3; // Sensor power pin
2243const int8_t y513EnablePin = -1; // Adapter RE/DE pin
2244const uint8_t y513NumberReadings = 5;
2245// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2246// power consumption
2247
2248// Create a Y513 Blue Green Algae (BGA) sensor object
2249YosemitechY513 y513(y513ModbusAddress, modbusSerial, y513AdapterPower,
2250 y513SensorPower, y513EnablePin, y513NumberReadings);
2251
2252// Create Blue Green Algae (BGA) concentration and temperature variable
2253// pointers for the Y513
2254Variable* y513BGA =
2255 new YosemitechY513_BGA(&y513, "12345678-abcd-1234-ef00-1234567890ab");
2256Variable* y513Temp =
2257 new YosemitechY513_Temp(&y513, "12345678-abcd-1234-ef00-1234567890ab");
2258/** End [yosemitech_y513] */
2259#endif
2260
2261#if defined(BUILD_SENSOR_YOSEMITECH_Y514)
2262// ==========================================================================
2263// Yosemitech Y514 Chlorophyll Sensor
2264// ==========================================================================
2265/** Start [yosemitech_y514] */
2266#include <sensors/YosemitechY514.h>
2267
2268// NOTE: Extra hardware and software serial ports are created in the "Settings
2269// for Additional Serial Ports" section
2270
2271// NOTE: Use -1 for any pins that don't apply or aren't being used.
2272byte y514ModbusAddress = 0x14; // The modbus address of the Y514
2273const int8_t y514AdapterPower = sensorPowerPin; // RS485 adapter power pin
2274const int8_t y514SensorPower = A3; // Sensor power pin
2275const int8_t y514EnablePin = -1; // Adapter RE/DE pin
2276const uint8_t y514NumberReadings = 5;
2277// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2278// power consumption
2279
2280// Create a Y514 chlorophyll sensor object
2281YosemitechY514 y514(y514ModbusAddress, modbusSerial, y514AdapterPower,
2282 y514SensorPower, y514EnablePin, y514NumberReadings);
2283
2284// Create chlorophyll concentration and temperature variable pointers for the
2285// Y514
2286Variable* y514Chloro = new YosemitechY514_Chlorophyll(
2287 &y514, "12345678-abcd-1234-ef00-1234567890ab");
2288Variable* y514Temp =
2289 new YosemitechY514_Temp(&y514, "12345678-abcd-1234-ef00-1234567890ab");
2290/** End [yosemitech_y514] */
2291#endif
2292
2293
2294#if defined(BUILD_SENSOR_YOSEMITECH_Y520)
2295// ==========================================================================
2296// Yosemitech Y520 Conductivity Sensor
2297// ==========================================================================
2298/** Start [yosemitech_y520] */
2299#include <sensors/YosemitechY520.h>
2300
2301// NOTE: Extra hardware and software serial ports are created in the "Settings
2302// for Additional Serial Ports" section
2303
2304// NOTE: Use -1 for any pins that don't apply or aren't being used.
2305byte y520ModbusAddress = 0x20; // The modbus address of the Y520
2306const int8_t y520AdapterPower = sensorPowerPin; // RS485 adapter power pin
2307const int8_t y520SensorPower = A3; // Sensor power pin
2308const int8_t y520EnablePin = -1; // Adapter RE/DE pin
2309const uint8_t y520NumberReadings = 5;
2310// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2311// power consumption
2312
2313// Create a Y520 conductivity sensor object
2314YosemitechY520 y520(y520ModbusAddress, modbusSerial, y520AdapterPower,
2315 y520SensorPower, y520EnablePin, y520NumberReadings);
2316
2317// Create specific conductance and temperature variable pointers for the Y520
2318Variable* y520Cond =
2319 new YosemitechY520_Cond(&y520, "12345678-abcd-1234-ef00-1234567890ab");
2320Variable* y520Temp =
2321 new YosemitechY520_Temp(&y520, "12345678-abcd-1234-ef00-1234567890ab");
2322/** End [yosemitech_y520] */
2323#endif
2324
2325
2326#if defined(BUILD_SENSOR_YOSEMITECH_Y532)
2327// ==========================================================================
2328// Yosemitech Y532 pH
2329// ==========================================================================
2330/** Start [yosemitech_y532] */
2331#include <sensors/YosemitechY532.h>
2332
2333// NOTE: Extra hardware and software serial ports are created in the "Settings
2334// for Additional Serial Ports" section
2335
2336// NOTE: Use -1 for any pins that don't apply or aren't being used.
2337byte y532ModbusAddress = 0x32; // The modbus address of the Y532
2338const int8_t y532AdapterPower = sensorPowerPin; // RS485 adapter power pin
2339const int8_t y532SensorPower = A3; // Sensor power pin
2340const int8_t y532EnablePin = 4; // Adapter RE/DE pin
2341const uint8_t y532NumberReadings = 1;
2342// The manufacturer actually doesn't mention averaging for this one
2343
2344// Create a Yosemitech Y532 pH sensor object
2345YosemitechY532 y532(y532ModbusAddress, modbusSerial, y532AdapterPower,
2346 y532SensorPower, y532EnablePin, y532NumberReadings);
2347
2348// Create pH, electrical potential, and temperature variable pointers for the
2349// Y532
2350Variable* y532Voltage =
2351 new YosemitechY532_Voltage(&y532, "12345678-abcd-1234-ef00-1234567890ab");
2352Variable* y532pH =
2353 new YosemitechY532_pH(&y532, "12345678-abcd-1234-ef00-1234567890ab");
2354Variable* y532Temp =
2355 new YosemitechY532_Temp(&y532, "12345678-abcd-1234-ef00-1234567890ab");
2356/** End [yosemitech_y532] */
2357#endif
2358
2359
2360#if defined(BUILD_SENSOR_YOSEMITECH_Y533)
2361// ==========================================================================
2362// Yosemitech Y533 Oxidation Reduction Potential (ORP)
2363// ==========================================================================
2364/** Start [yosemitech_y533] */
2365#include <sensors/YosemitechY533.h>
2366
2367// NOTE: Extra hardware and software serial ports are created in the "Settings
2368// for Additional Serial Ports" section
2369
2370// NOTE: Use -1 for any pins that don't apply or aren't being used.
2371byte y533ModbusAddress = 0x32; // The modbus address of the Y533
2372const int8_t y533AdapterPower = sensorPowerPin; // RS485 adapter power pin
2373const int8_t y533SensorPower = A3; // Sensor power pin
2374const int8_t y533EnablePin = 4; // Adapter RE/DE pin
2375const uint8_t y533NumberReadings = 1;
2376// The manufacturer actually doesn't mention averaging for this one
2377
2378// Create a Yosemitech Y533 ORP sensor object
2379YosemitechY533 y533(y533ModbusAddress, modbusSerial, y533AdapterPower,
2380 y533SensorPower, y533EnablePin, y533NumberReadings);
2381
2382// Create ORP and temperature variable pointers for the Y533
2383Variable* y533ORP =
2384 new YosemitechY533_ORP(&y533, "12345678-abcd-1234-ef00-1234567890ab");
2385Variable* y533Temp =
2386 new YosemitechY533_Temp(&y533, "12345678-abcd-1234-ef00-1234567890ab");
2387/** End [yosemitech_y533] */
2388#endif
2389
2390
2391#if defined(BUILD_SENSOR_YOSEMITECH_Y551)
2392// ==========================================================================
2393// Yosemitech Y551 COD Sensor with Wiper
2394// ==========================================================================
2395/** Start [yosemitech_y551] */
2396#include <sensors/YosemitechY551.h>
2397
2398// NOTE: Extra hardware and software serial ports are created in the "Settings
2399// for Additional Serial Ports" section
2400
2401// NOTE: Use -1 for any pins that don't apply or aren't being used.
2402byte y551ModbusAddress = 0x50; // The modbus address of the Y551
2403const int8_t y551AdapterPower = sensorPowerPin; // RS485 adapter power pin
2404const int8_t y551SensorPower = A3; // Sensor power pin
2405const int8_t y551EnablePin = -1; // Adapter RE/DE pin
2406const uint8_t y551NumberReadings = 5;
2407// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2408// power consumption
2409
2410// Create a Y551 chemical oxygen demand sensor object
2411YosemitechY551 y551(y551ModbusAddress, modbusSerial, y551AdapterPower,
2412 y551SensorPower, y551EnablePin, y551NumberReadings);
2413
2414// Create COD, turbidity, and temperature variable pointers for the Y551
2415Variable* y551COD =
2416 new YosemitechY551_COD(&y551, "12345678-abcd-1234-ef00-1234567890ab");
2417Variable* y551Turbid =
2418 new YosemitechY551_Turbidity(&y551, "12345678-abcd-1234-ef00-1234567890ab");
2419Variable* y551Temp =
2420 new YosemitechY551_Temp(&y551, "12345678-abcd-1234-ef00-1234567890ab");
2421/** End [yosemitech_y551] */
2422#endif
2423
2424
2425#if defined(BUILD_SENSOR_YOSEMITECH_Y560)
2426// ==========================================================================
2427// Yosemitech Y560 Ammonium Probe with Wiper
2428// ==========================================================================
2429/** Start [yosemitech_y560] */
2430#include <sensors/YosemitechY560.h>
2431
2432// NOTE: Extra hardware and software serial ports are created in the "Settings
2433// for Additional Serial Ports" section
2434
2435// NOTE: Use -1 for any pins that don't apply or aren't being used.
2436byte y560ModbusAddress =
2437 0x60; // The modbus address of the Y560.
2438 // NOTE: Hexidecimal 0x60 = 96 decimal used by Yosemitech SmartPC
2439const int8_t y560AdapterPower = sensorPowerPin; // RS485 adapter power pin
2440const int8_t y560SensorPower = A3; // Sensor power pin
2441const int8_t y560EnablePin = -1; // Adapter RE/DE pin
2442const uint8_t y560NumberReadings = 3;
2443// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2444// power consumption
2445
2446// Create a Y560 Ammonium Probe object
2447YosemitechY560 y560(y560ModbusAddress, modbusSerial, y560AdapterPower,
2448 y560SensorPower, y560EnablePin, y560NumberReadings);
2449
2450// Create COD, turbidity, and temperature variable pointers for the Y560
2451Variable* y560NH4_N =
2452 new YosemitechY560_NH4_N(&y560, "12345678-abcd-1234-ef00-1234567890ab");
2453Variable* y560pH =
2454 new YosemitechY560_pH(&y560, "12345678-abcd-1234-ef00-1234567890ab");
2455Variable* y560Temp =
2456 new YosemitechY560_Temp(&y560, "12345678-abcd-1234-ef00-1234567890ab");
2457/** End [yosemitech_y560] */
2458#endif
2459
2460
2461#if defined(BUILD_SENSOR_YOSEMITECH_Y700)
2462// ==========================================================================
2463// Yosemitech Y700 Pressure Sensor
2464// ==========================================================================
2465/** Start [yosemitech_y700] */
2466#include <sensors/YosemitechY700.h>
2467
2468// NOTE: Extra hardware and software serial ports are created in the "Settings
2469// for Additional Serial Ports" section
2470
2471// NOTE: Use -1 for any pins that don't apply or aren't being used.
2472byte y700ModbusAddress = 0x70; // The modbus address of the Y700
2473const int8_t y700AdapterPower = sensorPowerPin; // RS485 adapter power pin
2474const int8_t y700SensorPower = A3; // Sensor power pin
2475const int8_t y700EnablePin = -1; // Adapter RE/DE pin
2476const uint8_t y700NumberReadings = 5;
2477// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2478// power consumption
2479
2480// Create a Y700 pressure sensor object
2481YosemitechY700 y700(y700ModbusAddress, modbusSerial, y700AdapterPower,
2482 y700SensorPower, y700EnablePin, y700NumberReadings);
2483
2484// Create pressure and temperature variable pointers for the Y700
2485Variable* y700Pres =
2486 new YosemitechY700_Pressure(&y700, "12345678-abcd-1234-ef00-1234567890ab");
2487Variable* y700Temp =
2488 new YosemitechY700_Temp(&y700, "12345678-abcd-1234-ef00-1234567890ab");
2489/** End [yosemitech_y700] */
2490#endif
2491
2492
2493#if defined(BUILD_SENSOR_YOSEMITECH_Y4000)
2494// ==========================================================================
2495// Yosemitech Y4000 Multiparameter Sonde (DOmgL, Turbidity, Cond, pH, Temp,
2496// ORP, Chlorophyll, BGA)
2497// ==========================================================================
2498/** Start [yosemitech_y4000] */
2499#include <sensors/YosemitechY4000.h>
2500
2501// NOTE: Extra hardware and software serial ports are created in the "Settings
2502// for Additional Serial Ports" section
2503
2504// NOTE: Use -1 for any pins that don't apply or aren't being used.
2505byte y4000ModbusAddress = 0x05; // The modbus address of the Y4000
2506const int8_t y4000AdapterPower = sensorPowerPin; // RS485 adapter power pin
2507const int8_t y4000SensorPower = A3; // Sensor power pin
2508const int8_t y4000EnablePin = -1; // Adapter RE/DE pin
2509const uint8_t y4000NumberReadings = 5;
2510// The manufacturer recommends averaging 10 readings, but we take 5 to minimize
2511// power consumption
2512
2513// Create a Yosemitech Y4000 multi-parameter sensor object
2514YosemitechY4000 y4000(y4000ModbusAddress, modbusSerial, y4000AdapterPower,
2515 y4000SensorPower, y4000EnablePin, y4000NumberReadings);
2516
2517// Create all of the variable pointers for the Y4000
2518Variable* y4000DO =
2519 new YosemitechY4000_DOmgL(&y4000, "12345678-abcd-1234-ef00-1234567890ab");
2520Variable* y4000Turb = new YosemitechY4000_Turbidity(
2521 &y4000, "12345678-abcd-1234-ef00-1234567890ab");
2522Variable* y4000Cond =
2523 new YosemitechY4000_Cond(&y4000, "12345678-abcd-1234-ef00-1234567890ab");
2524Variable* y4000pH =
2525 new YosemitechY4000_pH(&y4000, "12345678-abcd-1234-ef00-1234567890ab");
2526Variable* y4000Temp =
2527 new YosemitechY4000_Temp(&y4000, "12345678-abcd-1234-ef00-1234567890ab");
2528Variable* y4000ORP =
2529 new YosemitechY4000_ORP(&y4000, "12345678-abcd-1234-ef00-1234567890ab");
2530Variable* y4000Chloro = new YosemitechY4000_Chlorophyll(
2531 &y4000, "12345678-abcd-1234-ef00-1234567890ab");
2532Variable* y4000BGA =
2533 new YosemitechY4000_BGA(&y4000, "12345678-abcd-1234-ef00-1234567890ab");
2534/** End [yosemitech_y4000] */
2535#endif
2536
2537
2538#if defined(BUILD_SENSOR_ZEBRA_TECH_D_OPTO)
2539// ==========================================================================
2540// Zebra Tech D-Opto Dissolved Oxygen Sensor
2541// ==========================================================================
2542/** Start [zebra_tech_d_opto] */
2543#include <sensors/ZebraTechDOpto.h>
2544
2545// NOTE: Use -1 for any pins that don't apply or aren't being used.
2546const char* DOptoSDI12address = "5"; // The SDI-12 Address of the D-Opto
2547const int8_t ZTPower = sensorPowerPin; // Power pin
2548const int8_t ZTData = 7; // The SDI-12 data pin
2549
2550// Create a Zebra Tech DOpto dissolved oxygen sensor object
2551ZebraTechDOpto dopto(*DOptoSDI12address, ZTPower, ZTData);
2552
2553// Create dissolved oxygen percent, dissolved oxygen concentration, and
2554// temperature variable pointers for the Zebra Tech
2555Variable* dOptoDOpct =
2556 new ZebraTechDOpto_DOpct(&dopto, "12345678-abcd-1234-ef00-1234567890ab");
2557Variable* dOptoDOmgL =
2558 new ZebraTechDOpto_DOmgL(&dopto, "12345678-abcd-1234-ef00-1234567890ab");
2559Variable* dOptoTemp =
2560 new ZebraTechDOpto_Temp(&dopto, "12345678-abcd-1234-ef00-1234567890ab");
2561/** End [zebra_tech_d_opto] */
2562#endif
2563
2564
2565// ==========================================================================
2566// Calculated Variable[s]
2567// ==========================================================================
2568/** Start [calculated_variables] */
2569// Create the function to give your calculated result.
2570// The function should take no input (void) and return a float.
2571// You can use any named variable pointers to access values by way of
2572// variable->getValue()
2573
2574float calculateVariableValue(void) {
2575 float calculatedResult = -9999; // Always safest to start with a bad value
2576 // float inputVar1 = variable1->getValue();
2577 // float inputVar2 = variable2->getValue();
2578 // make sure both inputs are good
2579 // if (inputVar1 != -9999 && inputVar2 != -9999) {
2580 // calculatedResult = inputVar1 + inputVar2;
2581 // }
2582 return calculatedResult;
2583}
2584
2585// Properties of the calculated variable
2586// The number of digits after the decimal place
2587const uint8_t calculatedVarResolution = 3;
2588// This must be a value from http://vocabulary.odm2.org/variablename/
2589const char* calculatedVarName = "varName";
2590// This must be a value from http://vocabulary.odm2.org/units/
2591const char* calculatedVarUnit = "varUnit";
2592// A short code for the variable
2593const char* calculatedVarCode = "calcVar";
2594// The (optional) universallly unique identifier
2595const char* calculatedVarUUID = "12345678-abcd-1234-ef00-1234567890ab";
2596
2597// Finally, Create a calculated variable and return a variable pointer to it
2598Variable* calculatedVar = new Variable(
2599 calculateVariableValue, calculatedVarResolution, calculatedVarName,
2600 calculatedVarUnit, calculatedVarCode, calculatedVarUUID);
2601/** End [calculated_variables] */
2602
2603
2604#if defined(BUILD_TEST_CREATE_IN_ARRAY)
2605// ==========================================================================
2606// Creating the Variable Array[s] and Filling with Variable Objects
2607// NOTE: This shows three different ways of creating the same variable array
2608// and filling it with variables
2609// ==========================================================================
2610/** Start [variables_create_in_array] */
2611// Version 1: Create pointers for all of the variables from the sensors,
2612// at the same time putting them into an array
2613Variable* variableList[] = {
2614 new ProcessorStats_SampleNumber(&mcuBoard,
2615 "12345678-abcd-1234-ef00-1234567890ab"),
2616 new ProcessorStats_FreeRam(&mcuBoard,
2617 "12345678-abcd-1234-ef00-1234567890ab"),
2618 new ProcessorStats_Battery(&mcuBoard,
2619 "12345678-abcd-1234-ef00-1234567890ab"),
2620 // new MaximDS3231_Temp(&ds3231, "12345678-abcd-1234-ef00-1234567890ab"),
2621 // ... Add more variables as needed!
2622 new Modem_RSSI(&modem, "12345678-abcd-1234-ef00-1234567890ab"),
2623 new Modem_SignalPercent(&modem, "12345678-abcd-1234-ef00-1234567890ab"),
2624 new Modem_Temp(&modem, "12345678-abcd-1234-ef00-1234567890ab"),
2625 new Variable(calculateVariableValue, calculatedVarResolution,
2626 calculatedVarName, calculatedVarUnit, calculatedVarCode,
2627 calculatedVarUUID),
2628};
2629// Count up the number of pointers in the array
2630int variableCount = sizeof(variableList) / sizeof(variableList[0]);
2631// Create the VariableArray object
2632VariableArray varArray(variableCount, variableList);
2633/** End [variables_create_in_array] */
2634// ==========================================================================
2635
2636
2637#elif defined(BUILD_TEST_SEPARATE_UUIDS)
2638/** Start [variables_separate_uuids] */
2639// Version 2: Create two separate arrays, on for the variables and a separate
2640// one for the UUID's, then give both as input to the variable array
2641// constructor. Be cautious when doing this though because order is CRUCIAL!
2642Variable* variableList[] = {
2643 new ProcessorStats_SampleNumber(&mcuBoard),
2644 new ProcessorStats_FreeRam(&mcuBoard),
2645 new ProcessorStats_Battery(&mcuBoard),
2646 // new MaximDS3231_Temp(&ds3231),
2647 // ... Add all of your variables!
2648 new Modem_RSSI(&modem),
2649 new Modem_SignalPercent(&modem),
2650 new Modem_Temp(&modem),
2651 new Variable(calculateVariableValue, calculatedVarResolution,
2652 calculatedVarName, calculatedVarUnit, calculatedVarCode),
2653};
2654const char* UUIDs[] = {
2655 "12345678-abcd-1234-ef00-1234567890ab",
2656 "12345678-abcd-1234-ef00-1234567890ab",
2657 "12345678-abcd-1234-ef00-1234567890ab",
2658 "12345678-abcd-1234-ef00-1234567890ab",
2659 // ... The number of UUID's must match the number of variables!
2660 "12345678-abcd-1234-ef00-1234567890ab",
2661 "12345678-abcd-1234-ef00-1234567890ab",
2662 "12345678-abcd-1234-ef00-1234567890ab",
2663 "12345678-abcd-1234-ef00-1234567890ab",
2664};
2665// Count up the number of pointers in the array
2666int variableCount = sizeof(variableList) / sizeof(variableList[0]);
2667// Create the VariableArray object and attach the UUID's
2668VariableArray varArray(variableCount, variableList, UUIDs);
2669/** End [variables_separate_uuids] */
2670// ==========================================================================
2671
2672
2673#else // BUILD_TEST_PRE_NAMED_VARS
2674/** Start [variables_pre_named] */
2675// Version 3: Fill array with already created and named variable pointers
2676Variable* variableList[] = {
2677 mcuBoardSampNo,
2678 mcuBoardAvailableRAM,
2679 mcuBoardBatt,
2680 calculatedVar,
2681#if defined(ARDUINO_ARCH_AVR) || defined(MS_SAMD_DS3231)
2682 ds3231Temp,
2683#endif
2684#if defined(BUILD_SENSOR_ALPHASENSE_CO2)
2685 asCO2,
2686 asco2voltage,
2687#endif
2688#if defined(BUILD_SENSOR_AO_SONG_AM2315)
2689 am2315Humid,
2690 am2315Temp,
2691#endif
2692#if defined(BUILD_SENSOR_AO_SONG_DHT)
2693 dhtHumid,
2694 dhtTemp,
2695 dhtHI,
2696#endif
2697#if defined(BUILD_SENSOR_APOGEE_SQ212)
2698 sq212PAR,
2699 sq212voltage,
2700#endif
2701#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_CO2)
2702 atlasCO2CO2,
2703 atlasCO2Temp,
2704#endif
2705#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_DO)
2706 atlasDOconc,
2707 atlasDOpct,
2708#endif
2709#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_ORP)
2710 atlasORPot,
2711#endif
2712#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_PH)
2713 atlaspHpH,
2714#endif
2715#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_RTD)
2716 atlasTemp,
2717#endif
2718#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_EC)
2719 atlasCond,
2720 atlasTDS,
2721 atlasSal,
2722 atlasGrav,
2723 atlasSpCond,
2724#endif
2725#if defined(BUILD_SENSOR_BOSCH_BME280)
2726 bme280Temp,
2727 bme280Humid,
2728 bme280Press,
2729 bme280Alt,
2730#endif
2731#if defined(BUILD_SENSOR_BOSCH_BMP3XX)
2732 bmp3xxTemp,
2733 bmp3xxPress,
2734 bmp3xxAlt,
2735#endif
2736#if defined(BUILD_SENSOR_CAMPBELL_CLARI_VUE10)
2737 clarivueTurbidity,
2738 clarivueTemp,
2739 clarivueError,
2740#endif
2741#if defined(BUILD_SENSOR_CAMPBELL_OBS3)
2742 obs3TurbLow,
2743 obs3VoltLow,
2744 obs3TurbHigh,
2745 obs3VoltHigh,
2746#endif
2747#if defined(BUILD_SENSOR_CAMPBELL_RAIN_VUE10)
2748 rainvuePrecipitation,
2749 rainvueTips,
2750 rainvueRainRateAve,
2751 rainvueRainRateMax,
2752#endif
2753#if defined(BUILD_SENSOR_DECAGON_CTD)
2754 ctdCond,
2755 ctdTemp,
2756 ctdDepth,
2757#endif
2758#if defined(BUILD_SENSOR_DECAGON_ES2)
2759 es2Cond,
2760 es2Temp,
2761#endif
2762#if defined(BUILD_SENSOR_EVERLIGHT_ALSPT19)
2763 alsPt19Volt,
2764 alsPt19Current,
2765 alsPt19Lux,
2766#endif
2767#if defined(BUILD_SENSOR_TIADS1X15)
2768 ads1x15Volt,
2769#endif
2770#if defined(BUILD_SENSOR_FREESCALE_MPL115A2)
2771 mplTemp,
2772 mplPress,
2773#endif
2774#if defined(BUILD_SENSOR_GRO_POINT_GPLP8)
2775 gplp8Moist1,
2776 gplp8Moist2,
2777 gplp8Moist3,
2778 gplp8Moist4,
2779 gplp8Moist5,
2780 gplp8Moist6,
2781 gplp8Moist7,
2782 gplp8Moist8,
2783 gplp8Temp1,
2784 gplp8Temp2,
2785 gplp8Temp3,
2786 gplp8Temp4,
2787 gplp8Temp5,
2788 gplp8Temp6,
2789 gplp8Temp7,
2790 gplp8Temp8,
2791 gplp8Temp9,
2792 gplp8Temp10,
2793 gplp8Temp11,
2794 gplp8Temp12,
2795 gplp8Temp13,
2796#endif
2797#if defined(BUILD_SENSOR_IN_SITU_RDO)
2798 rdoTemp,
2799 rdoDOpct,
2800 rdoDOmgL,
2801 rdoO2pp,
2802#endif
2803#if defined(BUILD_SENSOR_IN_SITU_TROLL_SDI12A)
2804 trollPressure,
2805 trollTemp,
2806 trollDepth,
2807#endif
2808#if defined(BUILD_SENSOR_KELLER_ACCULEVEL)
2809 acculevPress,
2810 acculevTemp,
2811 acculevHeight,
2812#endif
2813#if defined(BUILD_SENSOR_KELLER_NANOLEVEL)
2814 nanolevPress,
2815 nanolevTemp,
2816 nanolevHeight,
2817#endif
2818#if defined(BUILD_SENSOR_MAX_BOTIX_SONAR)
2819 sonar1Range,
2820#endif
2821#if defined(BUILD_SENSOR_MAXIM_DS18)
2822 ds18Temp,
2823#endif
2824#if defined(BUILD_SENSOR_MEA_SPEC_MS5803)
2825 ms5803Temp,
2826 ms5803Press,
2827#endif
2828#if defined(BUILD_SENSOR_DECAGON_5TM)
2829 fivetmEa,
2830 fivetmVWC,
2831 fivetmTemp,
2832#endif
2833#if defined(BUILD_SENSOR_METER_HYDROS21)
2834 hydros21Cond,
2835 hydros21Temp,
2836 hydros21Depth,
2837#endif
2838#if defined(BUILD_SENSOR_METER_TEROS11)
2839 teros11Ea,
2840 teros11Temp,
2841 teros11VWC,
2842 teros11Count,
2843#endif
2844#if defined(BUILD_SENSOR_PALEO_TERRA_REDOX)
2845 ptVolt,
2846#endif
2847#if defined(BUILD_SENSOR_RAIN_COUNTER_I2C)
2848 tbi2cTips,
2849 tbi2cDepth,
2850#endif
2851#if defined(BUILD_SENSOR_SENSIRION_SHT4X)
2852 sht4xHumid,
2853 sht4xTemp,
2854#endif
2855#if defined(BUILD_SENSOR_TALLY_COUNTER_I2C)
2856 tallyEvents,
2857#endif
2858#if defined(BUILD_SENSOR_TI_INA219)
2859 inaVolt,
2860 inaCurrent,
2861 inaPower,
2862#endif
2863#if defined(BUILD_SENSOR_TURNER_CYCLOPS)
2864 cyclopsVoltage,
2865 cyclopsChloro,
2866 cyclopsRWT,
2867 cyclopsFluoroscein,
2868 cyclopsPhycocyanin,
2869 cyclopsPhycoerythrin,
2870 cyclopsCDOM,
2871 cyclopsCrudeOil,
2872 cyclopsBrighteners,
2873 cyclopsTurbidity,
2874 cyclopsPTSA,
2875 cyclopsBTEX,
2876 cyclopsTryptophan,
2877 cyclopsRedChloro,
2878#endif
2879#if defined(BUILD_SENSOR_TURNER_TURBIDITY_PLUS)
2880turbidityPlusVoltage,turbidityPlusTurbidity,
2881#endif
2882#if defined(BUILD_SENSOR_ANALOG_ELEC_CONDUCTIVITY)
2883 analogEc_cond,
2884 analogEc_spcond,
2885#endif
2886#if defined(BUILD_SENSOR_VEGA_PULS21)
2887 VegaPulsStage,
2888 VegaPulsDistance,
2889 VegaPulsTemp,
2890 VegaPulsRelia,
2891 VegaPulsError,
2892#endif
2893#if defined(BUILD_SENSOR_YOSEMITECH_Y504)
2894 y504DOpct,
2895 y504DOmgL,
2896 y504Temp,
2897#endif
2898#if defined(BUILD_SENSOR_YOSEMITECH_Y510)
2899 y510Turb,
2900 y510Temp,
2901#endif
2902#if defined(BUILD_SENSOR_YOSEMITECH_Y511)
2903 y511Turb,
2904 y511Temp,
2905#endif
2906#if defined(BUILD_SENSOR_YOSEMITECH_Y513)
2907 y513BGA,
2908 y513Temp,
2909#endif
2910#if defined(BUILD_SENSOR_YOSEMITECH_Y514)
2911 y514Chloro,
2912 y514Temp,
2913#endif
2914#if defined(BUILD_SENSOR_YOSEMITECH_Y520)
2915 y520Cond,
2916 y520Temp,
2917#endif
2918#if defined(BUILD_SENSOR_YOSEMITECH_Y532)
2919 y532Voltage,
2920 y532pH,
2921 y532Temp,
2922#endif
2923#if defined(BUILD_SENSOR_YOSEMITECH_Y533)
2924 y533ORP,
2925 y533Temp,
2926#endif
2927#if defined(BUILD_SENSOR_YOSEMITECH_Y551)
2928 y551COD,
2929 y551Turbid,
2930 y551Temp,
2931#endif
2932#if defined(BUILD_SENSOR_YOSEMITECH_Y560)
2933 y560NH4_N,
2934 y560pH,
2935 y560Temp,
2936#endif
2937#if defined(BUILD_SENSOR_YOSEMITECH_Y700)
2938 y700Pres,
2939 y700Temp,
2940#endif
2941#if defined(BUILD_SENSOR_YOSEMITECH_Y4000)
2942 y4000DO,
2943 y4000Turb,
2944 y4000Cond,
2945 y4000pH,
2946 y4000Temp,
2947 y4000ORP,
2948 y4000Chloro,
2949 y4000BGA,
2950#endif
2951#if defined(BUILD_SENSOR_ZEBRA_TECH_D_OPTO)
2952 dOptoDOpct,
2953 dOptoDOmgL,
2954 dOptoTemp,
2955#endif
2956 modemRSSI,
2957 modemSignalPct,
2958#ifdef TINY_GSM_MODEM_HAS_BATTERY
2959 modemBatteryState,
2960 modemBatteryPct,
2961 modemBatteryVoltage,
2962#endif
2963#ifdef TINY_GSM_MODEM_HAS_TEMPERATURE
2964 modemTemperature,
2965#endif
2966};
2967// Count up the number of pointers in the array
2968int variableCount = sizeof(variableList) / sizeof(variableList[0]);
2969// Create the VariableArray object
2970VariableArray varArray(variableCount, variableList);
2971/** End [variables_pre_named] */
2972#endif
2973
2974
2975// ==========================================================================
2976// The Logger Object[s]
2977// ==========================================================================
2978/** Start [loggers] */
2979// Create a new logger instance
2980Logger dataLogger(LoggerID, loggingInterval, &varArray);
2981/** End [loggers] */
2982
2983
2984#if defined(BUILD_PUB_ENVIRO_DIY_PUBLISHER)
2985// ==========================================================================
2986// A Publisher to Monitor My Watershed / EnviroDIY Data Sharing Portal
2987// ==========================================================================
2988/** Start [enviro_diy_publisher] */
2989// Device registration and sampling feature information can be obtained after
2990// registration at https://monitormywatershed.org or https://data.envirodiy.org
2991const char* registrationToken =
2992 "12345678-abcd-1234-ef00-1234567890ab"; // Device registration token
2993const char* samplingFeature =
2994 "12345678-abcd-1234-ef00-1234567890ab"; // Sampling feature UUID
2995
2996// Create a data publisher for the Monitor My Watershed/EnviroDIY POST endpoint
2997#include <publishers/EnviroDIYPublisher.h>
2998EnviroDIYPublisher EnviroDIYPOST(dataLogger, &modem.gsmClient,
2999 registrationToken, samplingFeature);
3000/** End [enviro_diy_publisher] */
3001#endif
3002
3003
3004#if defined(BUILD_PUB_DREAM_HOST_PUBLISHER)
3005// ==========================================================================
3006// A Publisher to DreamHost
3007// ==========================================================================
3008/** Start [dream_host_publisher] */
3009// NOTE: This is an outdated data collection tool used by the Stroud Center.
3010// It very, very unlikely that you will use this.
3011
3012const char* DreamHostPortalRX = "xxxx";
3013
3014// Create a data publisher to DreamHost
3015#include <publishers/DreamHostPublisher.h>
3016DreamHostPublisher DreamHostGET(dataLogger, &modem.gsmClient,
3017 DreamHostPortalRX);
3018/** End [dream_host_publisher] */
3019#endif
3020
3021
3022#if defined(BUILD_PUB_THING_SPEAK_PUBLISHER)
3023// ==========================================================================
3024// ThingSpeak Data Publisher
3025// ==========================================================================
3026/** Start [thing_speak_publisher] */
3027// Create a channel with fields on ThingSpeak in advance.
3028// The fields will be sent in exactly the order they are in the variable array.
3029// Any custom name or identifier given to the field on ThingSpeak is irrelevant.
3030// No more than 8 fields of data can go to any one channel. Any fields beyond
3031// the eighth in the array will be ignored.
3032const char* thingSpeakMQTTKey =
3033 "XXXXXXXXXXXXXXXX"; // Your MQTT API Key from Account > MyProfile.
3034const char* thingSpeakChannelID =
3035 "######"; // The numeric channel id for your channel
3036const char* thingSpeakChannelKey =
3037 "XXXXXXXXXXXXXXXX"; // The Write API Key for your channel
3038
3039// Create a data publisher for ThingSpeak
3040#include <publishers/ThingSpeakPublisher.h>
3041ThingSpeakPublisher TsMqtt(dataLogger, &modem.gsmClient, thingSpeakMQTTKey,
3042 thingSpeakChannelID, thingSpeakChannelKey);
3043/** End [thing_speak_publisher] */
3044#endif
3045
3046
3047#if defined(BUILD_PUB_UBIDOTS_PUBLISHER)
3048// ==========================================================================
3049// Ubidots Data Publisher
3050// ==========================================================================
3051/** Start [ubidots_publisher] */
3052// The authentication token from Ubdots, either the Organization's Integration
3053// Token (under Users > Organization menu,visible by Admin only) OR the STEM
3054// User's Device Token (under the specific evice's setup panel).
3055const char* ubidotsToken = "XXXXXXXXXXXXXXXX";
3056// The device API Label from Ubidots, derived from the user-specified device
3057// name.
3058const char* ubidotsDeviceID = "######";
3059
3060// Create a data publisher for ThingSpeak
3061#include <publishers/UbidotsPublisher.h>
3062UbidotsPublisher ubidots(dataLogger, &modem.gsmClient, ubidotsToken,
3063 ubidotsDeviceID);
3064/** End [ubidots_publisher] */
3065#endif
3066
3067
3068// ==========================================================================
3069// Working Functions
3070// ==========================================================================
3071/** Start [working_functions] */
3072// Flashes the LED's on the primary board
3073void greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) {
3074 for (uint8_t i = 0; i < numFlash; i++) {
3075 digitalWrite(greenLED, HIGH);
3076 digitalWrite(redLED, LOW);
3077 delay(rate);
3078 digitalWrite(greenLED, LOW);
3079 digitalWrite(redLED, HIGH);
3080 delay(rate);
3081 }
3082 digitalWrite(redLED, LOW);
3083}
3084
3085// Uses the processor sensor object to read the battery voltage
3086// NOTE: This will actually return the battery level from the previous update!
3087float getBatteryVoltage() {
3088 if (mcuBoard.sensorValues[PROCESSOR_BATTERY_VAR_NUM] == -9999 ||
3089 mcuBoard.sensorValues[PROCESSOR_BATTERY_VAR_NUM] == 0) {
3090 mcuBoard.update();
3091 }
3092 return mcuBoard.sensorValues[PROCESSOR_BATTERY_VAR_NUM];
3093}
3094/** End [working_functions] */
3095
3096
3097// ==========================================================================
3098// Arduino Setup Function
3099// ==========================================================================
3100void setup() {
3101/** Start [setup_wait] */
3102// Wait for USB connection to be established by PC
3103// NOTE: Only use this when debugging - if not connected to a PC, this
3104// could prevent the script from starting
3105#if defined(SERIAL_PORT_USBVIRTUAL)
3106 while (!SERIAL_PORT_USBVIRTUAL && (millis() < 10000L)) {
3107 // wait
3108 }
3109#endif
3110 /** End [setup_wait] */
3111
3112 /** Start [setup_prints] */
3113 // Start the primary serial connection
3114 Serial.begin(serialBaud);
3115
3116 // Print a start-up note to the first serial port
3117 Serial.print(F("\n\nNow running "));
3118 Serial.print(sketchName);
3119 Serial.print(F(" on Logger "));
3120 Serial.println(LoggerID);
3121 Serial.println();
3122
3123 Serial.print(F("Using ModularSensors Library version "));
3124 Serial.println(MODULAR_SENSORS_VERSION);
3125 Serial.print(F("TinyGSM Library version "));
3126 Serial.println(TINYGSM_VERSION);
3127 Serial.println();
3128 /** End [setup_prints] */
3129
3130/** Start [setup_softserial] */
3131// Allow interrupts for software serial
3132#if defined(BUILD_TEST_SOFTSERIAL)
3133 enableInterrupt(softSerialRx, SoftwareSerial_ExtInts::handle_interrupt,
3134 CHANGE);
3135#endif
3136#if defined(BUILD_TEST_NEOSWSERIAL)
3137 enableInterrupt(neoSSerial1Rx, neoSSerial1ISR, CHANGE);
3138#endif
3139 /** End [setup_softserial] */
3140
3141 /** Start [setup_serial_begins] */
3142 // Start the serial connection with the modem
3143 modemSerial.begin(modemBaud);
3144
3145 // Start the stream for the modbus sensors;
3146 // all currently supported modbus sensors use 9600 baud
3147 modbusSerial.begin(9600);
3148
3149#if defined(BUILD_SENSOR_MAX_BOTIX_SONAR)
3150 // Start the SoftwareSerial stream for the sonar; it will always be at 9600
3151 // baud
3152 sonarSerial.begin(9600);
3153#endif
3154/** End [setup_serial_begins] */
3155
3156// Assign pins SERCOM functionality for SAMD boards
3157// NOTE: This must happen *after* the various serial.begin statements
3158/** Start [setup_samd_pins] */
3159#if defined(ARDUINO_ARCH_SAMD)
3160#ifndef ENABLE_SERIAL2
3161 pinPeripheral(10, PIO_SERCOM); // Serial2 Tx/Dout = SERCOM1 Pad #2
3162 pinPeripheral(11, PIO_SERCOM); // Serial2 Rx/Din = SERCOM1 Pad #0
3163#endif
3164#ifndef ENABLE_SERIAL3
3165 pinPeripheral(2, PIO_SERCOM); // Serial3 Tx/Dout = SERCOM2 Pad #2
3166 pinPeripheral(5, PIO_SERCOM); // Serial3 Rx/Din = SERCOM2 Pad #3
3167#endif
3168#endif
3169 /** End [setup_samd_pins] */
3170
3171 /** Start [setup_flashing_led] */
3172 // Set up pins for the LED's
3173 pinMode(greenLED, OUTPUT);
3174 digitalWrite(greenLED, LOW);
3175 pinMode(redLED, OUTPUT);
3176 digitalWrite(redLED, LOW);
3177 // Blink the LEDs to show the board is on and starting up
3178 greenredflash();
3179 /** End [setup_flashing_led] */
3180
3181 pinMode(20, OUTPUT); // for proper operation of the onboard flash memory
3182 // chip's ChipSelect (Mayfly v1.0 and later)
3183
3184 /** Start [setup_logger] */
3185 // Set the timezones for the logger/data and the RTC
3186 // Logging in the given time zone
3187 Logger::setLoggerTimeZone(timeZone);
3188 // It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)
3189 Logger::setRTCTimeZone(0);
3190
3191 // Attach the modem and information pins to the logger
3192 dataLogger.attachModem(modem);
3193 modem.setModemLED(modemLEDPin);
3194 dataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin,
3195 greenLED);
3196
3197 // Begin the logger
3198 dataLogger.begin();
3199 /** End [setup_logger] */
3200
3201 /** Start [setup_sensors] */
3202 // Note: Please change these battery voltages to match your battery
3203 // Set up the sensors, except at lowest battery level
3204 if (getBatteryVoltage() > 3.4) {
3205 Serial.println(F("Setting up sensors..."));
3206 varArray.setupSensors();
3207 }
3208 /** End [setup_sensors] */
3209
3210#if (defined BUILD_MODEM_ESPRESSIF_ESP8266 || \
3211 defined BUILD_MODEM_ESPRESSIF_ESP32) && \
3212 F_CPU == 8000000L
3213 /** Start [setup_esp] */
3214 if (modemBaud > 57600) {
3215 modem.modemWake(); // NOTE: This will also set up the modem
3216 modemSerial.begin(modemBaud);
3217 modem.gsmModem.sendAT(GF("+UART_DEF=9600,8,1,0,0"));
3218 modem.gsmModem.waitResponse();
3219 modemSerial.end();
3220 modemSerial.begin(9600);
3221 }
3222/** End [setup_esp] */
3223#endif
3224
3225#if defined(BUILD_TEST_SKYWIRE)
3226 /** Start [setup_skywire] */
3227 modem.setModemStatusLevel(LOW); // If using CTS, LOW
3228 modem.setModemWakeLevel(HIGH); // Skywire dev board inverts the signal
3229 modem.setModemResetLevel(HIGH); // Skywire dev board inverts the signal
3230 /** End [setup_skywire] */
3231#endif
3232
3233#if defined(BUILD_MODEM_SIM_COM_SIM7080)
3234 /** Start [setup_sim7080] */
3235 modem.setModemWakeLevel(HIGH); // ModuleFun Bee inverts the signal
3236 modem.setModemResetLevel(HIGH); // ModuleFun Bee inverts the signal
3237 Serial.println(F("Waking modem and setting Cellular Carrier Options..."));
3238 modem.modemWake(); // NOTE: This will also set up the modem
3239 modem.gsmModem.setBaud(modemBaud); // Make sure we're *NOT* auto-bauding!
3240 modem.gsmModem.setNetworkMode(38); // set to LTE only
3241 // 2 Automatic
3242 // 13 GSM only
3243 // 38 LTE only
3244 // 51 GSM and LTE only
3245 modem.gsmModem.setPreferredMode(1); // set to CAT-M
3246 // 1 CAT-M
3247 // 2 NB-IoT
3248 // 3 CAT-M and NB-IoT
3249 /** End [setup_sim7080] */
3250#endif
3251
3252#if defined(BUILD_MODEM_DIGI_XBEE_CELLULAR_TRANSPARENT)
3253 /** Start [setup_xbeec_carrier] */
3254 // Extra modem set-up
3255 Serial.println(F("Waking modem and setting Cellular Carrier Options..."));
3256 modem.modemWake(); // NOTE: This will also set up the modem
3257 // Go back to command mode to set carrier options
3258 modem.gsmModem.commandMode();
3259 // Carrier Profile - 0 = Automatic selection
3260 // - 1 = No profile/SIM ICCID selected
3261 // - 2 = AT&T
3262 // - 3 = Verizon
3263 // NOTE: To select T-Mobile, you must enter bypass mode!
3264 modem.gsmModem.sendAT(GF("CP"), 2);
3265 modem.gsmModem.waitResponse();
3266 // Cellular network technology - 0 = LTE-M with NB-IoT fallback
3267 // - 1 = NB-IoT with LTE-M fallback
3268 // - 2 = LTE-M only
3269 // - 3 = NB-IoT only
3270 // NOTE: As of 2020 in the USA, AT&T and Verizon only use LTE-M
3271 // T-Mobile uses NB-IOT
3272 modem.gsmModem.sendAT(GF("N#"), 2);
3273 modem.gsmModem.waitResponse();
3274 // Write changes to flash and apply them
3275 Serial.println(F("Wait while applying changes..."));
3276 // Write changes to flash
3277 modem.gsmModem.writeChanges();
3278 // Reset the cellular component to ensure network settings are changed
3279 modem.gsmModem.sendAT(GF("!R"));
3280 modem.gsmModem.waitResponse(30000L);
3281 // Force reset of the Digi component as well
3282 // This effectively exits command mode
3283 modem.gsmModem.sendAT(GF("FR"));
3284 modem.gsmModem.waitResponse(5000L);
3285/** End [setup_xbeec_carrier] */
3286#endif
3287
3288
3289#if defined(BUILD_MODEM_DIGI_XBEE_LTE_BYPASS)
3290 /** Start [setup_r4_carrrier] */
3291 // Extra modem set-up
3292 Serial.println(F("Waking modem and setting Cellular Carrier Options..."));
3293 modem.modemWake(); // NOTE: This will also set up the modem
3294 // Turn off the cellular radio while making network changes
3295 modem.gsmModem.sendAT(GF("+CFUN=0"));
3296 modem.gsmModem.waitResponse();
3297 // Mobile Network Operator Profile - 0 = SW default
3298 // - 1 = SIM ICCID selected
3299 // - 2: ATT
3300 // - 6: China Telecom
3301 // - 100: Standard Europe
3302 // - 4: Telstra
3303 // - 5: T-Mobile US
3304 // - 19: Vodafone
3305 // - 3: Verizon
3306 // - 31: Deutsche Telekom
3307 modem.gsmModem.sendAT(GF("+UMNOPROF="), 2);
3308 modem.gsmModem.waitResponse();
3309 // Selected network technology - 7: LTE Cat.M1
3310 // - 8: LTE Cat.NB1
3311 // Fallback network technology - 7: LTE Cat.M1
3312 // - 8: LTE Cat.NB1
3313 // NOTE: As of 2020 in the USA, AT&T and Verizon only use LTE-M
3314 // T-Mobile uses NB-IOT
3315 modem.gsmModem.sendAT(GF("+URAT="), 7, ',', 8);
3316 modem.gsmModem.waitResponse();
3317 // Restart the module to apply changes
3318 modem.gsmModem.sendAT(GF("+CFUN=1,1"));
3319 modem.gsmModem.waitResponse(10000L);
3320/** End [setup_r4_carrrier] */
3321#endif
3322
3323 /** Start [setup_clock] */
3324 // Sync the clock if it isn't valid or we have battery to spare
3325 if (getBatteryVoltage() > 3.55 || !dataLogger.isRTCSane()) {
3326 // Synchronize the RTC with NIST
3327 // This will also set up the modem
3328 dataLogger.syncRTC();
3329 }
3330 /** End [setup_clock] */
3331
3332 /** Start [setup_file] */
3333 // Create the log file, adding the default header to it
3334 // Do this last so we have the best chance of getting the time correct and
3335 // all sensor names correct
3336 // Writing to the SD card can be power intensive, so if we're skipping
3337 // the sensor setup we'll skip this too.
3338 if (getBatteryVoltage() > 3.4) {
3339 Serial.println(F("Setting up file on SD card"));
3340 dataLogger.turnOnSDcard(true);
3341 // true = wait for card to settle after power up
3342 dataLogger.createLogFile(true); // true = write a new header
3343 dataLogger.turnOffSDcard(true);
3344 // true = wait for internal housekeeping after write
3345 }
3346 /** End [setup_file] */
3347
3348 /** Start [setup_sleep] */
3349 // Call the processor sleep
3350 Serial.println(F("Putting processor to sleep\n"));
3351 dataLogger.systemSleep();
3352 /** End [setup_sleep] */
3353}
3354
3355
3356// ==========================================================================
3357// Arduino Loop Function
3358// ==========================================================================
3359#ifndef BUILD_TEST_COMPLEX_LOOP
3360// Use this short loop for simple data logging and sending
3361/** Start [simple_loop] */
3362void loop() {
3363 // Note: Please change these battery voltages to match your battery
3364 // At very low battery, just go back to sleep
3365 if (getBatteryVoltage() < 3.4) {
3366 dataLogger.systemSleep();
3367 } else if (getBatteryVoltage() < 3.55) {
3368 // At moderate voltage, log data but don't send it over the modem
3369 dataLogger.logData();
3370 } else {
3371 // If the battery is good, send the data to the world
3372 dataLogger.logDataAndPublish();
3373 }
3374}
3375
3376/** End [simple_loop] */
3377
3378#else
3379/** Start [complex_loop] */
3380// Use this long loop when you want to do something special
3381// Because of the way alarms work on the RTC, it will wake the processor and
3382// start the loop every minute exactly on the minute.
3383// The processor may also be woken up by another interrupt or level change on a
3384// pin - from a button or some other input.
3385// The "if" statements in the loop determine what will happen - whether the
3386// sensors update, testing mode starts, or it goes back to sleep.
3387void loop() {
3388 // Reset the watchdog
3389 dataLogger.watchDogTimer.resetWatchDog();
3390
3391 // Assuming we were woken up by the clock, check if the current time is an
3392 // even interval of the logging interval
3393 // We're only doing anything at all if the battery is above 3.4V
3394 if (dataLogger.checkInterval() && getBatteryVoltage() > 3.4) {
3395 // Flag to notify that we're in already awake and logging a point
3396 Logger::isLoggingNow = true;
3397 dataLogger.watchDogTimer.resetWatchDog();
3398
3399 // Print a line to show new reading
3400 Serial.println(F("------------------------------------------"));
3401 // Turn on the LED to show we're taking a reading
3402 dataLogger.alertOn();
3403 // Power up the SD Card, but skip any waits after power up
3404 dataLogger.turnOnSDcard(false);
3405 dataLogger.watchDogTimer.resetWatchDog();
3406
3407 // Turn on the modem to let it start searching for the network
3408 // Only turn the modem on if the battery at the last interval was high
3409 // enough
3410 // NOTE: if the modemPowerUp function is not run before the
3411 // completeUpdate
3412 // function is run, the modem will not be powered and will not
3413 // return a signal strength reading.
3414 if (getBatteryVoltage() > 3.6) modem.modemPowerUp();
3415
3416#ifdef BUILD_TEST_ALTSOFTSERIAL
3417 // Start the stream for the modbus sensors, if your RS485 adapter bleeds
3418 // current from data pins when powered off & you stop modbus serial
3419 // connection with digitalWrite(5, LOW), below.
3420 // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833
3421 altSoftSerial.begin(9600);
3422#endif
3423
3424 // Do a complete update on the variable array.
3425 // This this includes powering all of the sensors, getting updated
3426 // values, and turing them back off.
3427 // NOTE: The wake function for each sensor should force sensor setup
3428 // to run if the sensor was not previously set up.
3429 varArray.completeUpdate();
3430
3431 dataLogger.watchDogTimer.resetWatchDog();
3432
3433#ifdef BUILD_TEST_ALTSOFTSERIAL
3434 // Reset modbus serial pins to LOW, if your RS485 adapter bleeds power
3435 // on sleep, because Modbus Stop bit leaves these pins HIGH.
3436 // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833
3437 digitalWrite(5, LOW); // Reset AltSoftSerial Tx pin to LOW
3438 digitalWrite(6, LOW); // Reset AltSoftSerial Rx pin to LOW
3439#endif
3440
3441 // Create a csv data record and save it to the log file
3442 dataLogger.logToSD();
3443 dataLogger.watchDogTimer.resetWatchDog();
3444
3445 // Connect to the network
3446 // Again, we're only doing this if the battery is doing well
3447 if (getBatteryVoltage() > 3.55) {
3448 dataLogger.watchDogTimer.resetWatchDog();
3449 if (modem.connectInternet()) {
3450 dataLogger.watchDogTimer.resetWatchDog();
3451 // Publish data to remotes
3452 Serial.println(F("Modem connected to internet."));
3453 dataLogger.publishDataToRemotes();
3454
3455 // Sync the clock at noon
3456 dataLogger.watchDogTimer.resetWatchDog();
3457 if (Logger::markedLocalEpochTime != 0 &&
3458 Logger::markedLocalEpochTime % 86400 == 43200) {
3459 Serial.println(F("Running a daily clock sync..."));
3460 dataLogger.setRTClock(modem.getNISTTime());
3461 dataLogger.watchDogTimer.resetWatchDog();
3462 modem.updateModemMetadata();
3463 dataLogger.watchDogTimer.resetWatchDog();
3464 }
3465
3466 // Disconnect from the network
3467 modem.disconnectInternet();
3468 dataLogger.watchDogTimer.resetWatchDog();
3469 }
3470 // Turn the modem off
3471 modem.modemSleepPowerDown();
3472 dataLogger.watchDogTimer.resetWatchDog();
3473 }
3474
3475 // Cut power from the SD card - without additional housekeeping wait
3476 dataLogger.turnOffSDcard(false);
3477 dataLogger.watchDogTimer.resetWatchDog();
3478 // Turn off the LED
3479 dataLogger.alertOff();
3480 // Print a line to show reading ended
3481 Serial.println(F("------------------------------------------\n"));
3482
3483 // Unset flag
3484 Logger::isLoggingNow = false;
3485 }
3486
3487 // Check if it was instead the testing interrupt that woke us up
3488 if (Logger::startTesting) {
3489#ifdef BUILD_TEST_ALTSOFTSERIAL
3490 // Start the stream for the modbus sensors, if your RS485 adapter bleeds
3491 // current from data pins when powered off & you stop modbus serial
3492 // connection with digitalWrite(5, LOW), below.
3493 // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833
3494 altSoftSerial.begin(9600);
3495#endif
3496
3497 dataLogger.testingMode();
3498 }
3499
3500#ifdef BUILD_TEST_ALTSOFTSERIAL
3501 // Reset modbus serial pins to LOW, if your RS485 adapter bleeds power
3502 // on sleep, because Modbus Stop bit leaves these pins HIGH.
3503 // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833
3504 digitalWrite(5, LOW); // Reset AltSoftSerial Tx pin to LOW
3505 digitalWrite(6, LOW); // Reset AltSoftSerial Rx pin to LOW
3506#endif
3507
3508 // Call the processor sleep
3509 dataLogger.systemSleep();
3510}
3511#endif
3512/** End [complex_loop] */