From 5cdc5398e3a9b8ba1f2b812ebdb82704e77481e0 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Thu, 6 Jun 2019 11:54:58 -0400 Subject: [PATCH 1/3] Verbose examples Updated example code to include verbose explanations for people new to SensESP --- examples/analog_input.cpp | 49 +++++++++++++++++++++++++----- examples/rpm_counter.cpp | 64 +++++++++++++++++++++++++-------------- 2 files changed, 83 insertions(+), 30 deletions(-) diff --git a/examples/analog_input.cpp b/examples/analog_input.cpp index 5ee991933..2bd03571d 100644 --- a/examples/analog_input.cpp +++ b/examples/analog_input.cpp @@ -1,26 +1,61 @@ #include #include "sensesp_app.h" -#include "wiring_helpers.h" +#include "devices/analog_input.h" +#include "transforms/linear.h" +// SensESP builds upon the ReactESP framework. Every ReactESP application +// defines an "app" object vs defining a "main()" method. ReactESP app([] () { + + // Some initialization boilerplate when in debug mode... #ifndef SERIAL_DEBUG_DISABLED Serial.begin(115200); // A small arbitrary delay is required to let the // serial port catch up - delay(100); Debug.setSerialEnabled(true); #endif + + // Create the global SensESPApp() object. sensesp_app = new SensESPApp(); - setup_analog_input( - sensesp_app, - "sensors.indoor.illumination", - 1, 0, - "/sensors/indoor_illumination"); + // The "SignalK path" identifies this sensor to the SignalK network. Leaving + // this blank would indicate this particular sensor (or transform) does not + // broadcast SignalK data + const char* sk_path = "sensors.indoor.illumination"; + + + // The "Configuration path" is combined with "/config" to formulate a URL + // used by the RESTful API for retrieving or setting configuration data. + // It is ALSO used to specify a path to the SPIFFS file system + // where configuration data is saved on the MCU board. It should + // ALWAYS start with a forward slash if specified. If left blank, + // that indicates this sensor or transform does not have any + // configuration to save. + // Note that if you want to be able to change the sk_path at runtime, + // you will need to specify a config_path. + const char* config_path = "/sensors/indoor_illumination"; + + + // Create a "device" that is the source of our data + auto* pAnalogInput = new AnalogInput(); + + + // Create a "transform" that can modify the data and/or broadcast it + // over the SignalK network. + const float multiplier = 1.0; + const float offset = 0.0; + auto* pTransform = new Linear(sk_path, multiplier, offset, config_path); + + + // Wire up the output of the analog input to the transform + pAnalogInput->connectTo(pTransform); + + + // Start the SensESP application running sensesp_app->enable(); }); diff --git a/examples/rpm_counter.cpp b/examples/rpm_counter.cpp index e01688abb..a368576e3 100644 --- a/examples/rpm_counter.cpp +++ b/examples/rpm_counter.cpp @@ -7,6 +7,9 @@ #include "transforms/frequency.h" #include "wiring_helpers.h" + +// SensESP builds upon the ReactESP framework. Every ReactESP application +// defines an "app" object vs defining a "main()" method. ReactESP app([]() { #ifndef SERIAL_DEBUG_DISABLED Serial.begin(115200); @@ -20,39 +23,54 @@ ReactESP app([]() { sensesp_app = new SensESPApp(); - ////////// - // connect a RPM meter. A DigitalInputCounter counts pulses - // and reports the readings every read_delay ms - // (500 in the example). A Frequency - // transform takes a number of pulses and converts that into - // a frequency. The sample multiplier converts the 97 tooth - // tach output into Hz, SK native units. - // Three ways to wire up devices and transformations: - // 1. Connect by specifying (aka ): - /* - sensesp_app->connect_1to1( - new DigitalInputCounter(D5, INPUT_PULLUP, RISING, 500), - new Frequency("propulsion.left.revolutions", 1./97., - "/sensors/engine_rpm") - ); - */ + // The "SignalK path" identifies this sensor to the SignalK network. Leaving + // this blank would indicate this particular sensor (or transform) does not + // broadcast SignalK data + const char* sk_path = "propulsion.left.revolutions"; + + + // The "Configuration path" is combined with "/config" to formulate a URL + // used by the RESTful API for retrieving or setting configuration data. + // It is ALSO used to specify a path to the SPIFFS file system + // where configuration data is saved on the MCU board. It should + // ALWAYS start with a forward slash if specified. If left blank, + // that indicates this sensor or transform does not have any + // configuration to save. + // Note that if you want to be able to change the sk_path at runtime, + // you will need to specify a config_path. + const char* config_path = "/sensors/engine_rpm"; - // 2. Connect by specifying data type of Producer's output/Consumer's input + +////////// +// connect a RPM meter. A DigitalInputCounter counts pulses +// and reports the readings every read_delay ms +// (500 in the example). A Frequency +// transform takes a number of pulses and converts that into +// a frequency. The sample multiplier converts the 97 tooth +// tach output into Hz, SK native units. +const float multiplier = 1.0 / 97.0; +const uint read_delay = 500; + + + // Two ways to wire up devices and transformations: + + // 1. Connect by specifying data type of Producer's output/Consumer's input /* sensesp_app->connect( - new DigitalInputCounter(D5, INPUT_PULLUP, RISING, 500), - new Frequency("propulsion.left.revolutions", 1./97., - "/sensors/engine_rpm") + new DigitalInputCounter(D5, INPUT_PULLUP, RISING, read_delay), + new Frequency(sk_path, multiplier, config_path) ); */ // 3. Connect the producer directly to the consumer - (new DigitalInputCounter(D5, INPUT_PULLUP, RISING, 500)) - ->connectTo(new Frequency("propulsion.left.revolutions", 1. / 97., - "/sensors/engine_rpm")); + auto* pDevice = new DigitalInputCounter(D5, INPUT_PULLUP, RISING, read_delay); + + pDevice->connectTo(new Frequency(sk_path, multiplier, config_path)); + + // Start the SensESP application running sensesp_app->enable(); }); From 0d4da0ae05c3357831986809d78daf330cea0865 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Thu, 6 Jun 2019 13:01:46 -0400 Subject: [PATCH 2/3] Added "temperature_sender.cpp" to examples --- examples/temperature_sender.cpp | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 examples/temperature_sender.cpp diff --git a/examples/temperature_sender.cpp b/examples/temperature_sender.cpp new file mode 100644 index 000000000..2e7ba30a5 --- /dev/null +++ b/examples/temperature_sender.cpp @@ -0,0 +1,64 @@ +#include + +#include "sensesp_app.h" +#include "transforms/linear.h" +#include "devices/analog_input.h" + +#include "transforms/analogvoltage.h" +#include "transforms/voltagedividerR2.h" +#include "transforms/temperatureinterpreter.h" + +// SensESP builds upon the ReactESP framework. Every ReactESP application +// defines an "app" object vs defining a "main()" method. +ReactESP app([] () { + + // Some initialization boilerplate when in debug mode... + #ifndef SERIAL_DEBUG_DISABLED + Serial.begin(115200); + + // A small arbitrary delay is required to let the + // serial port catch up + + delay(1000); + Debug.setSerialEnabled(true); + #endif + + // Create the global SensESPApp() object. + sensesp_app = new SensESPApp(); + + + // The "SignalK path" identifies this sensor to the SignalK network. Leaving + // this blank would indicate this particular sensor (or transform) does not + // broadcast SignalK data + const char* sk_path = "electrical.generator.engine.water.temp"; + + + // A blank sk path means you do not want any SignalK generated from that + // particular transform... + const char* no_sk_wanted = ""; + + + // Connecting a "sender" to the MCU involves using a "voltage divider" circuit. A resistor (R1) is connected + // to the voltage output of the board (3.3v or 5v, specified in Vin) to an intersection of two wires. One + // wire connects to the AnalogInput pin of the MCU, and the other wire connects to the sending + // unit doing the measurement. The sender is itself a variable resistor that is then connected to ground, forming + // the "R2" of a voltage divider circuit. The transform "VoltageDividerR2" can take a known + // voltage in, resistance R1, and based on the current voltage read from AnalogInput, compute + // the current resistance of the sender (R2). + const float Vin = 3.3; // Voltage sent into the voltage divider circuit that includes the analog sender + const float R1 = 51.0; // The resistance, in ohms, of the R1 resitor in the analog sender divider circuit + + auto* pAnalogInput = new AnalogInput(); + + // Translating the number returned by AnalogInput into a temperature requires several transformations. + // Wire them up in sequence... + pAnalogInput->connectTo(new AnalogVoltage()) -> + connectTo(new VoltageDividerR2(R1, Vin, no_sk_wanted, "/gen/temp/sender")) -> + connectTo(new TemperatureInterpreter(no_sk_wanted, "/gen/temp/curve")) -> + connectTo(new Linear(sk_path, 1.0, 0.0, "/gen/temp/adjust")); + + + // Start the SensESP application running + sensesp_app->enable(); + +}); From da36f6d2a9f4fe11344e26636c3c0ad6fe542bb8 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Thu, 6 Jun 2019 13:03:14 -0400 Subject: [PATCH 3/3] Corrected typo --- examples/rpm_counter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rpm_counter.cpp b/examples/rpm_counter.cpp index a368576e3..5f4f64beb 100644 --- a/examples/rpm_counter.cpp +++ b/examples/rpm_counter.cpp @@ -65,7 +65,7 @@ const uint read_delay = 500; ); */ - // 3. Connect the producer directly to the consumer + // 2. Connect the producer directly to the consumer auto* pDevice = new DigitalInputCounter(D5, INPUT_PULLUP, RISING, read_delay); pDevice->connectTo(new Frequency(sk_path, multiplier, config_path));