From 3c564796e0f540a5d25243ab23f9929c8312ff9b Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Sun, 17 Jan 2021 15:59:48 -0500 Subject: [PATCH] --- platformio.ini | 2 + proto | 2 +- .../generated/environmental_measurement.pb.c | 12 ++ .../generated/environmental_measurement.pb.h | 53 +++++++++ src/mesh/generated/portnums.pb.h | 1 + src/plugins/Plugins.cpp | 2 + .../esp32/EnvironmentalMeasurementPlugin.cpp | 104 ++++++++++++++++++ .../esp32/EnvironmentalMeasurementPlugin.h | 45 ++++++++ 8 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 src/mesh/generated/environmental_measurement.pb.c create mode 100644 src/mesh/generated/environmental_measurement.pb.h create mode 100644 src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp create mode 100644 src/plugins/esp32/EnvironmentalMeasurementPlugin.h diff --git a/platformio.ini b/platformio.ini index 89cf5a1a..39b57dd9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -104,6 +104,8 @@ build_flags = lib_deps = ${arduino_base.lib_deps} https://github.com/meshtastic/esp32_https_server.git + adafruit/DHT sensor library@^1.4.1 + adafruit/Adafruit Unified Sensor@^1.1.4 # Hmm - this doesn't work yet # board_build.ldscript = linker/esp32.extram.bss.ld lib_ignore = segger_rtt diff --git a/proto b/proto index 0cadaed3..564292ee 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 0cadaed3953f66cf1edc99d0fa53e4fd5ebf56d6 +Subproject commit 564292ee83bbd085d0c51a7f882d3a2aa305d6d6 diff --git a/src/mesh/generated/environmental_measurement.pb.c b/src/mesh/generated/environmental_measurement.pb.c new file mode 100644 index 00000000..b55d14a0 --- /dev/null +++ b/src/mesh/generated/environmental_measurement.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.4 */ + +#include "environmental_measurement.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(EnvironmentalMeasurement, EnvironmentalMeasurement, AUTO) + + + diff --git a/src/mesh/generated/environmental_measurement.pb.h b/src/mesh/generated/environmental_measurement.pb.h new file mode 100644 index 00000000..8adf5774 --- /dev/null +++ b/src/mesh/generated/environmental_measurement.pb.h @@ -0,0 +1,53 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.4 */ + +#ifndef PB_ENVIRONMENTAL_MEASUREMENT_PB_H_INCLUDED +#define PB_ENVIRONMENTAL_MEASUREMENT_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _EnvironmentalMeasurement { + float temperature; + float relative_humidity; + float barometric_pressure; +} EnvironmentalMeasurement; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define EnvironmentalMeasurement_init_default {0, 0, 0} +#define EnvironmentalMeasurement_init_zero {0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define EnvironmentalMeasurement_temperature_tag 1 +#define EnvironmentalMeasurement_relative_humidity_tag 2 +#define EnvironmentalMeasurement_barometric_pressure_tag 3 + +/* Struct field encoding specification for nanopb */ +#define EnvironmentalMeasurement_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, FLOAT, temperature, 1) \ +X(a, STATIC, SINGULAR, FLOAT, relative_humidity, 2) \ +X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 3) +#define EnvironmentalMeasurement_CALLBACK NULL +#define EnvironmentalMeasurement_DEFAULT NULL + +extern const pb_msgdesc_t EnvironmentalMeasurement_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define EnvironmentalMeasurement_fields &EnvironmentalMeasurement_msg + +/* Maximum encoded size of messages (where known) */ +#define EnvironmentalMeasurement_size 15 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h index 2133ecaa..8d262c47 100644 --- a/src/mesh/generated/portnums.pb.h +++ b/src/mesh/generated/portnums.pb.h @@ -18,6 +18,7 @@ typedef enum _PortNum { PortNum_NODEINFO_APP = 4, PortNum_REPLY_APP = 32, PortNum_IP_TUNNEL_APP = 33, + PortNum_ENVIRONMENTAL_MEASUREMENT_APP = 34, PortNum_SERIAL_APP = 64, PortNum_STORE_FORWARD_APP = 65, PortNum_RANGE_TEST_APP = 66, diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index c2dfd73c..233c5f37 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -6,6 +6,7 @@ #include "plugins/TextMessagePlugin.h" #ifndef NO_ESP32 +#include "plugins/esp32/EnvironmentalMeasurementPlugin.h" #include "plugins/esp32/RangeTestPlugin.h" #include "plugins/SerialPlugin.h" #include "plugins/StoreForwardPlugin.h" @@ -19,6 +20,7 @@ void setupPlugins() nodeInfoPlugin = new NodeInfoPlugin(); positionPlugin = new PositionPlugin(); textMessagePlugin = new TextMessagePlugin(); + environmentalMeasurementPlugin = new EnvironmentalMeasurementPlugin(); // Note: if the rest of meshtastic doesn't need to explicitly use your plugin, you do not need to assign the instance // to a global variable. diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp new file mode 100644 index 00000000..75bb0911 --- /dev/null +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp @@ -0,0 +1,104 @@ +#include "EnvironmentalMeasurementPlugin.h" +#include "MeshService.h" +#include "NodeDB.h" +#include "RTC.h" +#include "Router.h" +#include "configuration.h" +#include "main.h" +#include "../mesh/generated/environmental_measurement.pb.h" +#include + +EnvironmentalMeasurementPlugin *environmentalMeasurementPlugin; +EnvironmentalMeasurementPluginRadio *environmentalMeasurementPluginRadio; + +EnvironmentalMeasurementPlugin::EnvironmentalMeasurementPlugin() : concurrency::OSThread("EnvironmentalMeasurementPlugin") {} + +uint32_t sensor_read_error_count = 0; + +#define DHT_11_GPIO_PIN 13 +//TODO: Make a related radioconfig preference to allow less-frequent reads +#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 +#define SENSOR_READ_ERROR_COUNT_THRESHOLD 5 +#define SENSOR_READ_MULTIPLIER 3 + + +DHT dht(DHT_11_GPIO_PIN,DHT11); + +int32_t EnvironmentalMeasurementPlugin::runOnce() { +#ifndef NO_ESP32 + if (firstTime) { + // This is the first time the OSThread library has called this function, so do some setup + DEBUG_MSG("Initializing Environmental Measurement Plugin -- Sender\n"); + environmentalMeasurementPluginRadio = new EnvironmentalMeasurementPluginRadio(); + firstTime = 0; + // begin reading measurements from the sensor + // DHT have a max read-rate of 1HZ, so we should wait at least 1 second + // after initializing the sensor before we try to read from it. + // returning the interval here means that the next time OSThread + // calls our plugin, we'll run the other branch of this if statement + // and actually do a "sendOurEnvironmentalMeasurement()" + dht.begin(); + return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } + else { + // this is not the first time OSThread library has called this function + // so just do what we intend to do on the interval + if(sensor_read_error_count > SENSOR_READ_ERROR_COUNT_THRESHOLD) + { + DEBUG_MSG("Environmental Measurement Plugin: DISABLED; The SENSOR_READ_ERROR_COUNT_THRESHOLD has been exceed: %d\n",SENSOR_READ_ERROR_COUNT_THRESHOLD); + return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } + else if (sensor_read_error_count > 0){ + DEBUG_MSG("Environmental Measurement Plugin: There have been %d sensor read failures.\n",sensor_read_error_count); + } + if (! environmentalMeasurementPluginRadio->sendOurEnvironmentalMeasurement() ){ + // if we failed to read the sensor, then try again + // as soon as we can according to the maximum polling frequency + return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } + } + // The return of runOnce is an int32 representing the desired number of + // miliseconds until the function should be called again by the + // OSThread library. + return(SENSOR_READ_MULTIPLIER * DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); +#endif +} + +bool EnvironmentalMeasurementPluginRadio::handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement &p) +{ + // This plugin doesn't really do anything with the messages it receives. + return false; // Let others look at this message also if they want +} + +bool EnvironmentalMeasurementPluginRadio::sendOurEnvironmentalMeasurement(NodeNum dest, bool wantReplies) +{ + EnvironmentalMeasurement m; + + m.barometric_pressure=0; + float t = dht.readTemperature(); + float h = dht.readHumidity(); + m.relative_humidity= 0; + m.temperature=0; + + DEBUG_MSG("-----------------------------------------\n"); + + DEBUG_MSG("Environmental Measurement Plugin: Read data\n"); + DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n",h); + DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n",t); + + if (isnan(h) || isnan(t) ){ + sensor_read_error_count++; + DEBUG_MSG("Environmental Measurement Plugin: FAILED TO READ DATA\n"); + return false; + } + + sensor_read_error_count = 0; + + MeshPacket *p = allocDataProtobuf(m); + p->to = dest; + p->decoded.want_response = wantReplies; + + service.sendToMesh(p); + return true; +} + diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.h b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h new file mode 100644 index 00000000..31581b31 --- /dev/null +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h @@ -0,0 +1,45 @@ +#pragma once +#include "ProtobufPlugin.h" +#include "../mesh/generated/environmental_measurement.pb.h" + + +class EnvironmentalMeasurementPlugin : private concurrency::OSThread +{ + bool firstTime = 1; + + public: + EnvironmentalMeasurementPlugin(); + + protected: + virtual int32_t runOnce(); +}; + +extern EnvironmentalMeasurementPlugin *environmentalMeasurementPlugin; + +/** + * EnvironmentalMeasurementPluginRadio plugin for sending/receiving environmental measurements to/from the mesh + */ +class EnvironmentalMeasurementPluginRadio : public ProtobufPlugin +{ + public: + /** Constructor + * name is for debugging output + */ + EnvironmentalMeasurementPluginRadio() : ProtobufPlugin("EnvironmentalMeasurement", PortNum_ENVIRONMENTAL_MEASUREMENT_APP, &EnvironmentalMeasurement_msg) {} + + /** + * Send our EnvironmentalMeasurement into the mesh + */ + bool sendOurEnvironmentalMeasurement(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); + + protected: + + /** Called to handle a particular incoming message + + @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + */ + virtual bool handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement &p); + +}; + +extern EnvironmentalMeasurementPluginRadio *environmentalMeasurementPluginRadio; \ No newline at end of file