Skip to content

Commit 15c43d1

Browse files
authored
Merge pull request #809 from SignalK/pcnt_min_req
Raise a compile-time error if the pulse counter API is used with the legacy Arduino
2 parents f4ec592 + f98f5df commit 15c43d1

File tree

5 files changed

+113
-9
lines changed

5 files changed

+113
-9
lines changed

examples/pcnt_rpm_counter.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#include <Arduino.h>
2+
3+
// RPM counter example using the Pulse Counter peripheral
4+
5+
// #define SERIAL_DEBUG_DISABLED
6+
7+
#include "sensesp/sensors/digital_pcnt_input.h"
8+
#include "sensesp/signalk/signalk_output.h"
9+
#include "sensesp/transforms/frequency.h"
10+
#include "sensesp_app_builder.h"
11+
12+
using namespace sensesp;
13+
14+
void setup() {
15+
SetupLogging();
16+
17+
SensESPAppBuilder builder;
18+
sensesp_app = builder.get_app();
19+
20+
// The "Signal K path" identifies the output of the sensor to the Signal K
21+
// network. If you have multiple sensors connected to your microcontoller
22+
// (ESP), each one of them will (probably) have its own Signal K path
23+
// variable. For example, if you have two propulsion engines, and you want the
24+
// RPM of each of them to go to Signal K, you might have sk_path_portEngine =
25+
// "propulsion.port.revolutions" and sk_path_starboardEngine =
26+
// "propulsion.starboard.revolutions" In this example, there is only one
27+
// propulsion engine, and its RPM is the only thing being reported to Signal
28+
// K. To find valid Signal K Paths that fits your need you look at this link:
29+
// https://signalk.org/specification/1.4.0/doc/vesselsBranch.html
30+
const char* sk_path = "propulsion.main.revolutions";
31+
32+
// The "Configuration path" is combined with "/config" to formulate a URL
33+
// used by the RESTful API for retrieving or setting configuration data.
34+
// It is ALSO used to specify a path to the SPIFFS file system
35+
// where configuration data is saved on the microcontroller. It should
36+
// ALWAYS start with a forward slash if specified. If left blank,
37+
// that indicates this sensor or transform does not have any
38+
// configuration to save.
39+
// Note that if you want to be able to change the sk_path at runtime,
40+
// you will need to specify a configuration path.
41+
// As with the Signal K path, if you have multiple configurable sensors
42+
// connected to the microcontroller, you will have a configuration path
43+
// for each of them, such as config_path_portEngine =
44+
// "/sensors/portEngine/rpm" and config_path_starboardEngine =
45+
// "/sensor/starboardEngine/rpm".
46+
const char* config_path = "/sensors/engine_rpm";
47+
48+
// These two are necessary until a method is created to synthesize them.
49+
// Everything after "/sensors" in each of these ("/engine_rpm/calibrate" and
50+
// "/engine_rpm/sk") is simply a label to display what you're configuring in
51+
// the Configuration UI.
52+
const char* config_path_calibrate = "/sensors/engine_rpm/calibrate";
53+
const char* config_path_skpath = "/sensors/engine_rpm/sk";
54+
55+
//////////
56+
// connect a RPM meter. A DigitalInputPcntCounter implements
57+
// access to a pulse counter peripheral. Every read_delay ms, it
58+
// reads the number of pulses that have occurred since the last
59+
// read, and reports that number (500ms in the example). A Frequency
60+
// transform takes a number of pulses and converts that into
61+
// a frequency. The sample multiplier converts the 97 tooth
62+
// tach output into Hz, SK native units.
63+
const float multiplier = 1.0 / 97.0;
64+
const unsigned int read_delay = 500;
65+
66+
// Wire it all up by connecting the producer directly to the consumer
67+
// ESP32 pins are specified as just the X in GPIOX
68+
uint8_t pin = 4;
69+
70+
auto* sensor = new DigitalInputPcntCounter(pin, INPUT_PULLUP, RISING, read_delay);
71+
72+
auto frequency = new Frequency(multiplier, config_path_calibrate);
73+
74+
ConfigItem(frequency)
75+
->set_title("Frequency")
76+
->set_description("Frequency of the engine RPM signal")
77+
->set_sort_order(1000);
78+
79+
auto frequency_sk_output = new SKOutput<float>(sk_path, config_path_skpath);
80+
81+
ConfigItem(frequency_sk_output)
82+
->set_title("Frequency SK Output Path")
83+
->set_sort_order(1001);
84+
85+
sensor
86+
->connect_to(frequency) // connect the output of sensor
87+
// to the input of Frequency()
88+
->connect_to(frequency_sk_output); // connect the output of Frequency()
89+
// to a Signal K Output as a number
90+
}
91+
92+
void loop() { event_loop()->tick(); }

examples/rpm_counter.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include <Arduino.h>
22

3+
// RPM counter example using interrupt-based pulse counting
4+
35
// #define SERIAL_DEBUG_DISABLED
46

5-
#include "sensesp/sensors/digital_pcnt_input.h"
7+
#include "sensesp/sensors/digital_input.h"
68
#include "sensesp/signalk/signalk_output.h"
79
#include "sensesp/transforms/frequency.h"
810
#include "sensesp_app_builder.h"
@@ -51,7 +53,7 @@ void setup() {
5153
const char* config_path_skpath = "/sensors/engine_rpm/sk";
5254

5355
//////////
54-
// connect a RPM meter. A DigitalInputPcntCounter implements
56+
// connect a RPM meter. A DigitalInputPcntCounter implements
5557
// access to a pulse counter peripheral. Every read_delay ms, it
5658
// reads the number of pulses that have occurred since the last
5759
// read, and reports that number (500ms in the example). A Frequency
@@ -65,7 +67,7 @@ void setup() {
6567
// ESP32 pins are specified as just the X in GPIOX
6668
uint8_t pin = 4;
6769

68-
auto* sensor = new DigitalInputPcntCounter(pin, INPUT_PULLUP, RISING, read_delay);
70+
auto* sensor = new DigitalInputCounter(pin, INPUT_PULLUP, RISING, read_delay);
6971

7072
auto frequency = new Frequency(multiplier, config_path_calibrate);
7173

src/sensesp/sensors/digital_pcnt_input.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#include "digital_pcnt_input.h"
22

3+
#if ESP_ARDUINO_VERSION_MAJOR < 3
4+
#warning "The Pulse Counter API is only available in ESP32 Arduino Core 3.0.0 and later"
5+
#else
6+
#include "driver/pulse_cnt.h"
7+
38
namespace sensesp {
49

510
DigitalInputPcntCounter::DigitalInputPcntCounter(uint8_t pin, int pin_mode,
@@ -93,4 +98,6 @@ const String ConfigSchema(const DigitalInputPcntCounter& obj) {
9398

9499
bool ConfigRequiresRestart(const DigitalInputPcntCounter& obj) { return true; }
95100

96-
} // namespace sensesp
101+
} // namespace sensesp
102+
103+
#endif // ESP_ARDUINO_VERSION_MAJOR < 3

src/sensesp/sensors/digital_pcnt_input.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
#include "sensesp/sensors/digital_input.h"
77
#include "sensesp/sensors/sensor.h"
88
#include "sensesp_base_app.h"
9-
9+
#if ESP_ARDUINO_VERSION_MAJOR < 3
10+
#warning \
11+
"The Pulse Counter API is only available in ESP32 Arduino Core 3.0.0 and later"
12+
#else
1013
#include "driver/pulse_cnt.h"
1114

1215
namespace sensesp {
@@ -33,13 +36,10 @@ namespace sensesp {
3336
class DigitalInputPcntCounter : public DigitalInput, public Sensor<int> {
3437
public:
3538
DigitalInputPcntCounter(uint8_t pin, int pin_mode, int interrupt_type,
36-
unsigned int read_delay,
37-
String config_path = "");
39+
unsigned int read_delay, String config_path = "");
3840

3941
~DigitalInputPcntCounter();
4042

41-
42-
4343
virtual bool to_json(JsonObject& root) override;
4444
virtual bool from_json(const JsonObject& config) override;
4545

@@ -59,4 +59,5 @@ const String ConfigSchema(const DigitalInputPcntCounter& obj);
5959
bool ConfigRequiresRestart(const DigitalInputPcntCounter& obj);
6060
} // namespace sensesp
6161

62+
#endif // ESP_ARDUINO_VERSION_MAJOR < 3
6263
#endif // SENSESP_SENSORS_DIGITAL_PCNT_INPUT_H_

src/sensesp/types/nullable.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ template <>
2727
uint32_t Nullable<uint32_t>::invalid_value_ = 0xffffffff;
2828
template <>
2929
int32_t Nullable<int32_t>::invalid_value_ = 0x7fffffff;
30+
#if ESP_ARDUINO_VERSION_MAJOR >= 3
3031
template <>
3132
int Nullable<int>::invalid_value_ = 0x7fffffff;
33+
#endif
3234
template <>
3335
uint64_t Nullable<uint64_t>::invalid_value_ = 0xffffffffffffffffLL;
3436
template <>

0 commit comments

Comments
 (0)