-
Notifications
You must be signed in to change notification settings - Fork 83
Home
SensESP is a library of functions that makes it relatively simple to create a program that will run on an ESP8266 microcontroller ("MCU"), that collects data from various sensors, processes the data, and sends it along to a final "consumer", typically a Signal K server. It must be used with the PlatformIO IDE - it won't work with the Arduino IDE.
As the end user, you create a single main.cpp
file, most of which will be boilerplate - all the code necessary to connect to your network and your SignalK server. Then, with only a few lines of code, you create an instance of a sensor, process the data from the sensor, then send the final result to the Signal K server.
The best way to learn how to use SensESP is by looking at a few examples. In the /examples
folder, rpm_counter.cpp
is a good one to start with, as it illustrates a simple implementation - reading the value of a sensor connected to a GPIO pin on the MCU, converting that value to hertz (the native unit of measurement for a tachometer in Signal K), then sending the value in hertz to the Signal K server.
A Transport is an object that takes a value as input (from a Sensor, or from another Transport), does something with that value, then outputs the new value, either to another Transport, or to the Signal K server. In the rpm_counter.cpp
example referred to above, the meat of the code is these three lines:
auto* pSensor = new DigitalInputCounter(D5, INPUT_PULLUP, RISING, read_delay);
pSensor->connectTo(new Frequency(multiplier, config_path_calibrate))
->connectTo(new SKOutputNumber(sk_path, config_path_skpath));
The first line instantiates a Sensor of type DigitalInputCounter. The second line is a Transport of type Frequency - it takes a raw number from the DigitalInputCounter Sensor and converts it to hertz, then passes it along to SKOutputNumber. SKOutputNumber is a special Transport whose purpose is to send a value to the Signal K server.
A much more complex example is temperature_sender.cpp
, where the meat of the program is this:
auto* pAnalogInput = new AnalogInput();
pAnalogInput->connectTo(new AnalogVoltage()) ->
connectTo(new VoltageDividerR2(R1, Vin, "/gen/temp/sender")) ->
connectTo(new TemperatureInterpreter("/gen/temp/curve")) ->
connectTo(new Linear(1.0, 0.0, "/gen/temp/calibrate")) ->
connectTo(new SKOutputNumber(sk_path, "/gen/temp/sk"));
In this example, there is still only one Sensor (AnalogInput), but several Transports, all required to turn the raw value from the Analog Input pin on the MCU into a temperature that's sent to the Signal K server.
You can also include multiple Sensors, each with at least one Transport, in the same program, such as combining both of the examples above into the same main.cpp
, one after the other. (TODO - add such an example to /examples.)
Some Sensors and Transports have parameters that can be configured "live", by accessing the MCU through its IP address, entered as a URL in any browser. For example, entering 192.168.1.236
(the IP address of the MCU I'm currently using as my example) in a browser will bring up the following web page that's hosted by the MCU itself:
"Device information" does not display any information at this time. "Configure device" will be explained below. "Restart device" will restart the MCU. "Reset device" will erase all the network information and all the Sensor and Transport configuration, and the program. The MCU will be returned to the way it came from the factory.
Click on "Configure device" to bring up the /setup page, which will look something like this:
The only menu item that will always be present is "system", which has two sub-menus: "networking" (which lets you see and edit your wifi SSID and password, and the MCU's hostname), and "sk", which displays some networking info, but can't yet be used for editing that info, although it looks like it can.
The other menu items ("sensors" and "transports") are there only if you've provided a configuration path in the constructor of one or more of the Sensors and Transports in main.cpp
. And the names - in this case, "sensors" and "transports", are completely up to you - you can call them "fred" and "barney" if you like.
Look at the three lines from the rpm_counter.cpp
example above. There are three constructors - the one for the DigitalInputCounter Sensor, the one for the Frequency Transport, and the one for the SKOutputNumber Transport. The latter two have a configuration path included as the last item in their parameter list, but the first one doesn't. That means that the first one - the DigitalInputCounter - has no values that can be configured "live", but the latter two do. Actually, it's a little more complicated than that, because it's not entirely consistent among all Sensors and Transports.
As of this writing (March 2020), here are the ** possible ** configurable parameters for each Sensor and Transport:
- AnalogInput: Read delay (Number of milliseconds between each analogRead(A0))
- DigitalInputValue: none
- DigitalInputCounter: Read delay (The time, in milliseconds, between each read of the input) GPSInput: none OneWireTemperature: OneWire address (the unique address of the specific sensor being used)
AnalogVoltage: none AngleCorrection: Constant offset (value to be added, in radians); Minimum angle value (pi, or 0) ChangeFilter: Minimum delta (Minimum difference in change of value before forwarding); Maximum delta (maximum difference in change of value to allow forwarding); Max skips (maximum number of consecutive filtered values before one is allowed through) CurveInterpolator: input, output (each pair is added to the table of samples) Difference: Input #1 multiplier, Input #2 multiplier Frequency: Multiplier Integrator: Multiplier Linear: Multiplier; Constant offset Median: Sample size (number of samples to take before outputing a value) MovingAverage: Number of samples in average; Multiplier VoltageDivider: Voltage in; Resistance (ohms) of R1 SKOutputNumber, SKOutputInt, SKOutputBool, SKOutputString: Signal K data path