SensESP 3.3.0
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
digital_input.h
Go to the documentation of this file.
1#ifndef SENSESP_SENSORS_DIGITAL_INPUT_H_
2#define SENSESP_SENSORS_DIGITAL_INPUT_H_
3
4#include <elapsedMillis.h>
5
6#include "ReactESP.h"
8#include "sensesp_base_app.h"
9#include "sensor.h"
10
11namespace sensesp {
12
22 public:
23 DigitalInput(uint8_t pin, int pin_mode) : pin_{pin} {
24 pinMode(pin_, pin_mode);
25 };
26
27 protected:
28 uint8_t pin_;
29};
30
51class DigitalInputState : public DigitalInput, public Sensor<bool> {
52 public:
53 DigitalInputState(uint8_t pin, int pin_mode, int read_delay = 1000,
54 String config_path = "")
55 : DigitalInput{pin, pin_mode},
56 Sensor<bool>(config_path),
57 read_delay_{read_delay},
58 triggered_{false} {
59 load();
60
61 repeat_event_ = event_loop()->onRepeat(read_delay_,
62 [this]() { this->emit(digitalRead(pin_)); });
63 }
64
66 if (repeat_event_ != nullptr) {
67 repeat_event_->remove(event_loop());
68 }
69 }
70
71 private:
72 int read_delay_;
73 bool triggered_;
74 reactesp::RepeatEvent* repeat_event_ = nullptr;
75 virtual bool to_json(JsonObject& root) override;
76 virtual bool from_json(const JsonObject& config) override;
77};
78
79const String ConfigSchema(const DigitalInputState& obj);
80
82
101class DigitalInputCounter : public DigitalInput, public Sensor<int> {
102 public:
103 DigitalInputCounter(uint8_t pin, int pin_mode, int interrupt_type,
104 unsigned int read_delay, String config_path = "")
105 : DigitalInputCounter(pin, pin_mode, interrupt_type, read_delay,
106 config_path, [this]() { this->counter_ = this->counter_ + 1; }) {
107 isr_event_ = event_loop()->onInterrupt(pin_, interrupt_type_, interrupt_handler_);
108
109 repeat_event_ = event_loop()->onRepeat(read_delay_, [this]() {
110 noInterrupts();
112 counter_ = 0;
113 interrupts();
114 notify();
115 });
116 }
117
119 if (repeat_event_ != nullptr) {
120 repeat_event_->remove(event_loop());
121 }
122 if (isr_event_ != nullptr) {
123 isr_event_->remove(event_loop().get());
124 }
125 }
126
127 virtual bool to_json(JsonObject& root) override;
128 virtual bool from_json(const JsonObject& config) override;
129
130 protected:
131 DigitalInputCounter(uint8_t pin, int pin_mode, int interrupt_type,
132 unsigned int read_delay, String config_path,
133 std::function<void()> interrupt_handler)
134 : DigitalInput{pin, pin_mode},
135 Sensor<int>(config_path),
136 read_delay_{read_delay},
137 interrupt_type_{interrupt_type},
138 interrupt_handler_{interrupt_handler} {
139 load();
140 }
141
142 unsigned int read_delay_;
143 volatile unsigned int counter_ = 0;
144 reactesp::RepeatEvent* repeat_event_ = nullptr;
145 reactesp::ISREvent* isr_event_ = nullptr;
146
147 private:
148 int interrupt_type_;
149 std::function<void()> interrupt_handler_;
150};
151
152const String ConfigSchema(const DigitalInputCounter& obj);
153
155
178 public:
179 DigitalInputDebounceCounter(uint8_t pin, int pin_mode, int interrupt_type,
180 unsigned int read_delay,
181 unsigned int ignore_interval_ms,
182 String config_path = "")
183 : DigitalInputCounter(pin, pin_mode, interrupt_type, read_delay,
184 config_path, [this]() { this->handleInterrupt(); }),
185 ignore_interval_ms_{ignore_interval_ms} {}
186
187 private:
188 void handleInterrupt();
189
190 unsigned int ignore_interval_ms_;
191 elapsedMillis since_last_event_;
192 virtual bool to_json(JsonObject& root) override;
193 virtual bool from_json(const JsonObject& config) override;
194};
195
196const String ConfigSchema(const DigitalInputDebounceCounter& obj);
197
199
220class DigitalInputChange : public DigitalInput, public Sensor<bool> {
221 public:
222 DigitalInputChange(uint8_t pin, int pin_mode, int interrupt_type,
223 String config_path = "")
224 : DigitalInput{pin, pin_mode},
225 Sensor<bool>(config_path),
226 interrupt_type_{interrupt_type},
227 triggered_{true} {
228 load();
229 output_ = (bool)digitalRead(pin_);
230 last_output_ = !output_; // ensure that we always send the first output_
231
232 isr_event_ = event_loop()->onInterrupt(pin_, interrupt_type_, [this]() {
233 output_ = (bool)digitalRead(pin_);
234 triggered_ = true;
235 });
236
237 tick_event_ = event_loop()->onTick([this]() {
238 noInterrupts();
239 bool t = triggered_;
240 bool val = output_;
241 if (t && (val != last_output_)) {
242 triggered_ = false;
243 last_output_ = val;
244 interrupts();
245 notify();
246 } else {
247 interrupts();
248 }
249 });
250 }
251
253 if (tick_event_ != nullptr) {
254 tick_event_->remove(event_loop());
255 }
256 if (isr_event_ != nullptr) {
257 isr_event_->remove(event_loop().get());
258 }
259 }
260
261 private:
262 int interrupt_type_;
263 bool triggered_;
264 bool last_output_;
265 reactesp::TickEvent* tick_event_ = nullptr;
266 reactesp::ISREvent* isr_event_ = nullptr;
267 virtual bool to_json(JsonObject& doc) override { return true; }
268 virtual bool from_json(const JsonObject& config) override { return true; }
269};
270
271} // namespace sensesp
272
273#endif
DigitalInputChange(uint8_t pin, int pin_mode, int interrupt_type, String config_path="")
DigitalInputCounter counts interrupts and reports the count every read_delay ms.
volatile unsigned int counter_
DigitalInputCounter(uint8_t pin, int pin_mode, int interrupt_type, unsigned int read_delay, String config_path, std::function< void()> interrupt_handler)
virtual bool to_json(JsonObject &root) override
reactesp::ISREvent * isr_event_
virtual bool from_json(const JsonObject &config) override
DigitalInputCounter(uint8_t pin, int pin_mode, int interrupt_type, unsigned int read_delay, String config_path="")
reactesp::RepeatEvent * repeat_event_
DigitalInputDebounceCounter counts interrupts and reports the count every read_delay ms,...
DigitalInputDebounceCounter(uint8_t pin, int pin_mode, int interrupt_type, unsigned int read_delay, unsigned int ignore_interval_ms, String config_path="")
DigitalInput(uint8_t pin, int pin_mode)
DigitalInputState polls the state of an input pin every read_delay ms.
DigitalInputState(uint8_t pin, int pin_mode, int read_delay=1000, String config_path="")
virtual bool load() override
Load and populate the object from a persistent storage.
Definition saveable.cpp:8
Sensor(String config_path)
Definition sensor.h:44
virtual const int & get() const
void emit(const bool &new_value)
const String ConfigSchema(const SmartSwitchController &obj)
std::shared_ptr< reactesp::EventLoop > event_loop()
Definition sensesp.cpp:9
bool ConfigRequiresRestart(const HTTPServer &obj)