Browse Source

sns: clean-up EventSensor

Always do digitalRead() after ISR
Drop trigger, since we can handle this inside of reading routine
(although, pending some changes to make reading interval per-sensor)

Rework read / write through std::atomic
mcspr-patch-1
Maxim Prokhorov 3 years ago
committed by Max Prokhorov
parent
commit
c0af41433a
3 changed files with 82 additions and 163 deletions
  1. +0
    -40
      code/espurna/config/sensors.h
  2. +59
    -87
      code/espurna/sensor.cpp
  3. +23
    -36
      code/espurna/sensors/EventSensor.h

+ 0
- 40
code/espurna/config/sensors.h View File

@ -504,11 +504,6 @@
#define EVENTS_SUPPORT 0 // Do not build with counter support by default
#endif
#ifndef EVENTS1_TRIGGER
#define EVENTS1_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS1_PIN
#define EVENTS1_PIN 2 // GPIO to monitor
#endif
@ -525,11 +520,6 @@
#define EVENTS1_DEBOUNCE 50 // Do not register events within less than 50 millis
#endif
#ifndef EVENTS2_TRIGGER
#define EVENTS2_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS2_PIN
#define EVENTS2_PIN 2 // GPIO to monitor
#endif
@ -546,11 +536,6 @@
#define EVENTS2_DEBOUNCE 50 // Do not register events within less than 50 millis
#endif
#ifndef EVENTS3_TRIGGER
#define EVENTS3_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS3_PIN
#define EVENTS3_PIN 2 // GPIO to monitor
#endif
@ -567,11 +552,6 @@
#define EVENTS3_DEBOUNCE 50 // Do not register events within less than 50 millis
#endif
#ifndef EVENTS4_TRIGGER
#define EVENTS4_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS4_PIN
#define EVENTS4_PIN 2 // GPIO to monitor
#endif
@ -588,11 +568,6 @@
#define EVENTS4_DEBOUNCE 50 // Do not register events within less than 50 millis
#endif
#ifndef EVENTS5_TRIGGER
#define EVENTS5_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS5_PIN
#define EVENTS5_PIN 2 // GPIO to monitor
#endif
@ -609,11 +584,6 @@
#define EVENTS5_DEBOUNCE 50 // Do not register events within less than 50 millis
#endif
#ifndef EVENTS6_TRIGGER
#define EVENTS6_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS6_PIN
#define EVENTS6_PIN 2 // GPIO to monitor
#endif
@ -630,11 +600,6 @@
#define EVENTS6_DEBOUNCE 50 // Do not register events within less than 50 millis
#endif
#ifndef EVENTS7_TRIGGER
#define EVENTS7_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS7_PIN
#define EVENTS7_PIN 2 // GPIO to monitor
#endif
@ -651,11 +616,6 @@
#define EVENTS7_DEBOUNCE 50 // Do not register events within less than 50 millis
#endif
#ifndef EVENTS8_TRIGGER
#define EVENTS8_TRIGGER 1 // 1 to trigger callback on events,
// 0 to only count them and report periodically
#endif
#ifndef EVENTS8_PIN
#define EVENTS8_PIN 2 // GPIO to monitor
#endif


+ 59
- 87
code/espurna/sensor.cpp View File

@ -1777,101 +1777,73 @@ void _sensorLoad() {
#if EVENTS_SUPPORT
{
#if (EVENTS1_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS1_PIN);
sensor->setTrigger(EVENTS1_TRIGGER);
sensor->setPinMode(EVENTS1_PIN_MODE);
sensor->setDebounceTime(EVENTS1_DEBOUNCE);
sensor->setInterruptMode(EVENTS1_INTERRUPT_MODE);
_sensors.push_back(sensor);
}
#endif
#if (EVENTS2_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS2_PIN);
sensor->setTrigger(EVENTS2_TRIGGER);
sensor->setPinMode(EVENTS2_PIN_MODE);
sensor->setDebounceTime(EVENTS2_DEBOUNCE);
sensor->setInterruptMode(EVENTS2_INTERRUPT_MODE);
_sensors.push_back(sensor);
}
#endif
#if (EVENTS3_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS3_PIN);
sensor->setTrigger(EVENTS3_TRIGGER);
sensor->setPinMode(EVENTS3_PIN_MODE);
sensor->setDebounceTime(EVENTS3_DEBOUNCE);
sensor->setInterruptMode(EVENTS3_INTERRUPT_MODE);
_sensors.push_back(sensor);
}
#endif
auto getPin = [](unsigned char index) -> int {
switch (index) {
case 0: return EVENTS1_PIN;
case 1: return EVENTS2_PIN;
case 2: return EVENTS3_PIN;
case 3: return EVENTS4_PIN;
case 4: return EVENTS5_PIN;
case 5: return EVENTS6_PIN;
case 6: return EVENTS7_PIN;
case 7: return EVENTS8_PIN;
default: return GPIO_NONE;
}
};
#if (EVENTS4_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS4_PIN);
sensor->setTrigger(EVENTS4_TRIGGER);
sensor->setPinMode(EVENTS4_PIN_MODE);
sensor->setDebounceTime(EVENTS4_DEBOUNCE);
sensor->setInterruptMode(EVENTS4_INTERRUPT_MODE);
_sensors.push_back(sensor);
}
#endif
auto getMode = [](unsigned char index) -> int {
switch (index) {
case 0: return EVENTS1_PIN_MODE;
case 1: return EVENTS2_PIN_MODE;
case 2: return EVENTS3_PIN_MODE;
case 3: return EVENTS4_PIN_MODE;
case 4: return EVENTS5_PIN_MODE;
case 5: return EVENTS6_PIN_MODE;
case 6: return EVENTS7_PIN_MODE;
case 7: return EVENTS8_PIN_MODE;
default: return INPUT;
}
};
#if (EVENTS5_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS5_PIN);
sensor->setTrigger(EVENTS5_TRIGGER);
sensor->setPinMode(EVENTS5_PIN_MODE);
sensor->setDebounceTime(EVENTS5_DEBOUNCE);
sensor->setInterruptMode(EVENTS5_INTERRUPT_MODE);
_sensors.push_back(sensor);
}
#endif
auto getDebounce = [](unsigned char index) -> unsigned long {
switch (index) {
case 0: return EVENTS1_DEBOUNCE;
case 1: return EVENTS2_DEBOUNCE;
case 2: return EVENTS3_DEBOUNCE;
case 3: return EVENTS4_DEBOUNCE;
case 4: return EVENTS5_DEBOUNCE;
case 5: return EVENTS6_DEBOUNCE;
case 6: return EVENTS7_DEBOUNCE;
case 7: return EVENTS8_DEBOUNCE;
default: return 50;
}
};
#if (EVENTS6_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS6_PIN);
sensor->setTrigger(EVENTS6_TRIGGER);
sensor->setPinMode(EVENTS6_PIN_MODE);
sensor->setDebounceTime(EVENTS6_DEBOUNCE);
sensor->setInterruptMode(EVENTS6_INTERRUPT_MODE);
_sensors.push_back(sensor);
}
#endif
auto getIsrMode = [](unsigned char index) -> int {
switch (index) {
case 0: return EVENTS1_INTERRUPT_MODE;
case 1: return EVENTS2_INTERRUPT_MODE;
case 2: return EVENTS3_INTERRUPT_MODE;
case 3: return EVENTS4_INTERRUPT_MODE;
case 4: return EVENTS5_INTERRUPT_MODE;
case 5: return EVENTS6_INTERRUPT_MODE;
case 6: return EVENTS7_INTERRUPT_MODE;
case 7: return EVENTS8_INTERRUPT_MODE;
default: return RISING;
}
};
#if (EVENTS7_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS7_PIN);
sensor->setTrigger(EVENTS7_TRIGGER);
sensor->setPinMode(EVENTS7_PIN_MODE);
sensor->setDebounceTime(EVENTS7_DEBOUNCE);
sensor->setInterruptMode(EVENTS7_INTERRUPT_MODE);
_sensors.push_back(sensor);
}
#endif
for (unsigned char index = 0; index < GpioPins; ++index) {
const auto pin = getPin(index);
if (pin == GPIO_NONE) break;
#if (EVENTS8_PIN != GPIO_NONE)
{
EventSensor * sensor = new EventSensor();
sensor->setGPIO(EVENTS8_PIN);
sensor->setTrigger(EVENTS8_TRIGGER);
sensor->setPinMode(EVENTS8_PIN_MODE);
sensor->setDebounceTime(EVENTS8_DEBOUNCE);
sensor->setInterruptMode(EVENTS8_INTERRUPT_MODE);
sensor->setGPIO(pin);
sensor->setPinMode(getMode(index));
sensor->setDebounceTime(getDebounce(index));
sensor->setInterruptMode(getIsrMode(index));
_sensors.push_back(sensor);
}
#endif
}
#endif


+ 23
- 36
code/espurna/sensors/EventSensor.h View File

@ -12,6 +12,8 @@
#include "../debug.h"
#include "BaseSensor.h"
#include <atomic>
// we are bound by usable GPIOs
#define EVENTS_SENSORS_MAX 10
@ -38,10 +40,6 @@ class EventSensor : public BaseSensor {
_gpio = gpio;
}
void setTrigger(bool trigger) {
_trigger = trigger;
}
void setPinMode(unsigned char pin_mode) {
_pin_mode = pin_mode;
}
@ -51,7 +49,7 @@ class EventSensor : public BaseSensor {
}
void setDebounceTime(unsigned long ms) {
_debounce = microsecondsToClockCycles(ms * 1000);
_isr_debounce = microsecondsToClockCycles(ms * 1000);
}
// ---------------------------------------------------------------------
@ -60,10 +58,6 @@ class EventSensor : public BaseSensor {
return _gpio;
}
bool getTrigger() {
return _trigger;
}
unsigned char getPinMode() {
return _pin_mode;
}
@ -73,7 +67,7 @@ class EventSensor : public BaseSensor {
}
unsigned long getDebounceTime() {
return _debounce;
return _isr_debounce;
}
// ---------------------------------------------------------------------
@ -84,8 +78,10 @@ class EventSensor : public BaseSensor {
// Defined outside the class body
void begin() {
pinMode(_gpio, _pin_mode);
_value = digitalRead(_gpio);
_counter = 0;
_enableInterrupts(true);
_count = _trigger ? 2 : 1;
_count = 2;
_ready = true;
}
@ -116,14 +112,14 @@ class EventSensor : public BaseSensor {
// Current value for slot # index
double value(unsigned char index) {
if (index == 0) {
double value = _counter;
_counter = 0;
return value;
};
if (index == 1) {
return _value;
auto copy = _counter.load();
_counter = 0ul;
return copy;
} else if (index == 1) {
return _value.load();
}
return 0;
return 0.0;
}
// Handle interrupt calls from isr[GPIO] functions
@ -139,17 +135,12 @@ class EventSensor : public BaseSensor {
// - clockCyclesToMicroseconds(cycles)
// Since the division operation on this chip is pretty slow,
// avoid doing the conversion here
unsigned long cycles = ESP.getCycleCount();
auto cycles = ESP.getCycleCount();
if (cycles - _last > _debounce) {
_last = cycles;
if (cycles - _isr_last > _isr_debounce) {
_isr_last = cycles;
_value = digitalRead(_gpio);
_counter += 1;
// we are handling callbacks in tick()
if (_trigger) {
_trigger_value = digitalRead(gpio);
_trigger_flag = true;
}
}
}
@ -163,28 +154,24 @@ class EventSensor : public BaseSensor {
void _detach(unsigned char gpio);
void _enableInterrupts(bool value) {
if (value) {
_detach(_gpio);
_attach(_gpio, _interrupt_mode);
} else {
_detach(_gpio);
}
}
// ---------------------------------------------------------------------
// Protected
// ---------------------------------------------------------------------
volatile unsigned long _counter = 0;
unsigned char _value = 0;
unsigned long _last = 0;
unsigned long _debounce = microsecondsToClockCycles(EVENTS1_DEBOUNCE * 1000);
// XXX: cannot have default values with GCC 4.8
std::atomic<unsigned long> _counter;
std::atomic<int> _value;
bool _trigger = false;
bool _trigger_flag = false;
unsigned char _trigger_value = false;
unsigned long _isr_last = 0;
unsigned long _isr_debounce = microsecondsToClockCycles(EVENTS1_DEBOUNCE * 1000);
unsigned char _gpio = GPIO_NONE;
unsigned char _pin_mode = INPUT;


Loading…
Cancel
Save