8#if defined(__ESP32__) || defined(__ESP__)
9#define G_INT_ATTR IRAM_ATTR
14#define USTD_MAX_FQ_PIRQS (10)
16volatile unsigned long pFqIrqCounter[USTD_MAX_FQ_PIRQS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
17volatile unsigned long pFqLastIrqTimer[USTD_MAX_FQ_PIRQS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
18volatile unsigned long pFqBeginIrqTimer[USTD_MAX_FQ_PIRQS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
20void G_INT_ATTR ustd_fq_pirq_master(uint8_t irqno) {
21 unsigned long curr = micros();
22 if (pFqBeginIrqTimer[irqno] == 0)
23 pFqBeginIrqTimer[irqno] = curr;
25 ++pFqIrqCounter[irqno];
26 pFqLastIrqTimer[irqno] = curr;
29void G_INT_ATTR ustd_fq_pirq0() {
30 ustd_fq_pirq_master(0);
32void G_INT_ATTR ustd_fq_pirq1() {
33 ustd_fq_pirq_master(1);
35void G_INT_ATTR ustd_fq_pirq2() {
36 ustd_fq_pirq_master(2);
38void G_INT_ATTR ustd_fq_pirq3() {
39 ustd_fq_pirq_master(3);
41void G_INT_ATTR ustd_fq_pirq4() {
42 ustd_fq_pirq_master(4);
44void G_INT_ATTR ustd_fq_pirq5() {
45 ustd_fq_pirq_master(5);
47void G_INT_ATTR ustd_fq_pirq6() {
48 ustd_fq_pirq_master(6);
50void G_INT_ATTR ustd_fq_pirq7() {
51 ustd_fq_pirq_master(7);
53void G_INT_ATTR ustd_fq_pirq8() {
54 ustd_fq_pirq_master(8);
56void G_INT_ATTR ustd_fq_pirq9() {
57 ustd_fq_pirq_master(9);
60void (*ustd_fq_pirq_table[USTD_MAX_FQ_PIRQS])() = {ustd_fq_pirq0, ustd_fq_pirq1, ustd_fq_pirq2, ustd_fq_pirq3,
61 ustd_fq_pirq4, ustd_fq_pirq5, ustd_fq_pirq6, ustd_fq_pirq7,
62 ustd_fq_pirq8, ustd_fq_pirq9};
64unsigned long getFqResetpIrqCount(uint8_t irqno) {
65 unsigned long count = (
unsigned long)-1;
67 if (irqno < USTD_MAX_FQ_PIRQS) {
68 count = pFqIrqCounter[irqno];
69 pFqIrqCounter[irqno] = 0;
75double fQfrequencyMultiplicator = 1000000.0;
76double getFqResetpIrqFrequency(uint8_t irqno,
unsigned long minDtUs = 50) {
77 double frequency = 0.0;
79 if (irqno < USTD_MAX_FQ_PIRQS) {
80 unsigned long count = pFqIrqCounter[irqno];
81 unsigned long dt = timeDiff(pFqBeginIrqTimer[irqno], pFqLastIrqTimer[irqno]);
83 frequency = (count * fQfrequencyMultiplicator) / dt;
86 pFqBeginIrqTimer[irqno] = 0;
87 pFqIrqCounter[irqno] = 0;
88 pFqLastIrqTimer[irqno] = 0;
149 String FREQUENCY_COUNTER_VERSION =
"0.1.0";
157 int8_t interruptIndex_input;
162 bool detectZeroChange =
false;
163 bool irqsAttached =
false;
164 double inputFrequencyVal = 0.0;
167 ustd::sensorprocessor frequency = ustd::sensorprocessor(4, 600, 0.01);
168 double frequencyRenormalisation = 1.0;
173 : name(name), pin_input(pin_input), interruptIndex_input(interruptIndex_input),
174 measureMode(measureMode), irqMode(irqMode) {
188 detachInterrupt(irqno_input);
200 detectZeroChange =
false;
202 frequency.update(4,15,0.01);
205 detectZeroChange =
false;
207 frequency.update(12,120,0.01);
210 detectZeroChange =
false;
212 frequency.update(60,600,0.001);
215 detectZeroChange =
true;
217 frequency.update(1,15,0.1);
220 detectZeroChange =
true;
222 frequency.update(10,120,0.01);
226 detectZeroChange =
true;
228 frequency.update(60,600,0.001);
232 publishMeasureMode();
235 bool begin(Scheduler *_pSched, uint32_t scheduleUs=2000000L) {
244 pinMode(pin_input, INPUT_PULLUP);
246 if (interruptIndex_input >= 0 && interruptIndex_input < USTD_MAX_FQ_PIRQS) {
247 irqno_input = digitalPinToInterrupt(pin_input);
250 attachInterrupt(irqno_input, ustd_fq_pirq_table[interruptIndex_input], FALLING);
251 fQfrequencyMultiplicator = 1000000L;
254 attachInterrupt(irqno_input, ustd_fq_pirq_table[interruptIndex_input], RISING);
255 fQfrequencyMultiplicator = 1000000L;
258 attachInterrupt(irqno_input, ustd_fq_pirq_table[interruptIndex_input], CHANGE);
259 fQfrequencyMultiplicator = 500000L;
267 auto ft = [=]() { this->loop(); };
268 tID = pSched->add(ft, name, scheduleUs);
270 auto fnall = [=](String topic, String msg, String originator) {
271 this->subsMsg(topic, msg, originator);
273 pSched->subscribe(tID, name +
"/#", fnall);
278 void publishMeasureMode() {
279 switch (measureMode) {
281 pSched->publish(name +
"/sensor/mode",
"LOWFREQUENCY_FAST");
284 pSched->publish(name +
"/sensor/mode",
"LOWFREQUENCY_MEDIUM");
287 pSched->publish(name +
"/sensor/mode",
"LOWFREQUENCY_LONGTERM");
290 pSched->publish(name +
"/sensor/mode",
"HIGHFREQUENCY_FAST");
293 pSched->publish(name +
"/sensor/mode",
"HIGHFREQUENCY_MEDIUM");
296 pSched->publish(name +
"/sensor/mode",
"HIGHFREQUENCY_LONGTERM");
301 void publish_frequency() {
303 sprintf(buf,
"%10.3f", inputFrequencyVal);
307 pSched->publish(name +
"/sensor/frequency", p1);
315 double freq = getFqResetpIrqFrequency(interruptIndex_input, 0) * frequencyRenormalisation;
316 if (detectZeroChange) {
317 if ((frequency.lastVal == 0.0 && freq > 0.0) ||
318 (frequency.lastVal > 0.0 && freq == 0.0))
321 if (freq >= 0.0 && freq < 1000000.0) {
322 if (frequency.filter(&freq)) {
323 inputFrequencyVal = freq;
329 void subsMsg(String topic, String msg, String originator) {
330 if (topic == name +
"/sensor/state/get") {
332 }
else if (topic == name +
"/sensor/frequency/get") {
334 }
else if (topic == name +
"/sensor/mode/set") {
335 if (msg ==
"LOWFREQUENCY_FAST" || msg ==
"0") {
338 if (msg ==
"LOWFREQUENCY_MEDIUM" || msg ==
"1") {
341 if (msg ==
"LOWFREQUENCY_LONGTERM" || msg ==
"2") {
344 if (msg ==
"HIGHFREQUENCY_FAST" || msg ==
"3") {
347 if (msg ==
"HIGHFREQUENCY_MEDIUM" || msg ==
"4") {
350 if (msg ==
"HIGHFREQUENCY_LONGTERM" || msg ==
"5") {
353 }
else if (topic == name +
"/sensor/mode/get") {
354 publishMeasureMode();
Definition: mup_frequency_counter.h:131
InterruptMode
Definition: mup_frequency_counter.h:134
@ IM_CHANGE
Definition: mup_frequency_counter.h:136
@ IM_FALLING
Definition: mup_frequency_counter.h:135
@ IM_RISING
Definition: mup_frequency_counter.h:134
void setMeasureMode(MeasureMode mode, bool silent=false)
Definition: mup_frequency_counter.h:192
FrequencyCounter(String name, uint8_t pin_input, int8_t interruptIndex_input, MeasureMode measureMode=HIGHFREQUENCY_MEDIUM, InterruptMode irqMode=InterruptMode::IM_FALLING)
Definition: mup_frequency_counter.h:170
bool begin(Scheduler *_pSched, uint32_t scheduleUs=2000000L)
Definition: mup_frequency_counter.h:235
MeasureMode
Definition: mup_frequency_counter.h:140
@ HIGHFREQUENCY_LONGTERM
Definition: mup_frequency_counter.h:146
@ LOWFREQUENCY_FAST
Definition: mup_frequency_counter.h:141
@ HIGHFREQUENCY_MEDIUM
Definition: mup_frequency_counter.h:145
@ LOWFREQUENCY_MEDIUM
Definition: mup_frequency_counter.h:142
@ LOWFREQUENCY_LONGTERM
Definition: mup_frequency_counter.h:143
@ HIGHFREQUENCY_FAST
Definition: mup_frequency_counter.h:144
The muwerk namespace.
Definition: home_assistant.h:10